Dockerで研究用Python環境構築
はじめに
個人的に作った環境構築方法なのでベストプラクティスではない可能性もあります
今回はUbuntu20.04のイメージを使ってCUDA11.7でPytorchのtorch=1.13.1を構築する
torch.cuda.is_available()でTrueが返ってきたら成功
- Pythonのバージョン管理にはasdfを使う
- 直接 or venv or Poetryで環境を作る
開発環境
VSCodeを前提
Docker拡張機能をインストール
Python拡張機能も忘れずに入れること
CUDAの確認
ホストOSにCUDAがインストールされていないとGPUが使えない
nvidia-smiで確認
なかったらインストール
Docker Desktopのインストール
公式サイトのインストーラーをダウンロードし、指示に従いインストール
Docker Desktop版じゃないCLI版を入れる場合は他に詳しく書いてる記事があるのでそっちを参照
docker versionと入力して出力がでればOK
プロジェクトの作成
mkdir myproject
mkdir -p myproject/apps
cd myproject
myprojectの名前は自分の好きな名前で
Dockerfileの作成
NVIDIAのcudaイメージを使う
今回はcuda11.7.1のcudnn8のubuntu20.04を使っているが、自分が使うバージョンによってタグを変える
(Tagsの部分で検索して探す)
myprojectディレクトリ直下にDockerfileを作成(拡張子なし)
FROM nvidia/cuda:11.7.1-cudnn8-runtime-ubuntu20.04
WORKDIR /workspace
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
sudo \
build-essential \
tzdata \
git \
vim \
wget \
zsh \
curl \
libbz2-dev \
libffi-dev \
liblzma-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
libxmlsec1-dev \
llvm \
make \
tk-dev \
xz-utils \
zlib1g-dev \
&& apt-get upgrade -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# add asdf install
RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.3
SHELL ["/bin/bash", "-c"]
RUN echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc \
&& echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc \
&& echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.zshrc \
&& echo -e '\nfpath=(${ASDF_DIR}/completions $fpath)\nautoload -Uz compinit && compinit' >> ~/.zshrc
CMD ["/bin/bash"]
docker-compose.yamlの作成
myprojectディレクトリ直下にdocker-compose.yamlを作成
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- type: bind
source: ./apps
target: /workspace
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
tty: true
shm_size: '8gb'
-
volumesで先ほど作成したappsディレクトリをworkspaceディレクトリにマウントしている -
tty: trueにすることで終了しないようにしてる -
shm_sizeを8GBとしてるが、環境によって減らす
コンテナの作成・起動
この2つのファイルが作成できてこんな感じになってればOK

ターミナル上で
docker compose up -d --build
としてコンテナを作成する
めちゃめちゃ時間がかかるので気長に待つ
うまく作成ができたら、VSCodeのタブのDockerの部分を開いて該当のコンテナを右クリ→Attatch Visual Studio Codeをクリックしてコンテナ中へ→フォルダを開くから/workspaceへ移動
/workspaceに作成したファイルはホスト側のmyproject/apps中に存在する
pythonの環境作成
コンテナ中なので極論もう自由に環境作ってもらっていいが、asdfコマンドを使ってバージョン管理する
ここではPython3.9系を使うことにする
asdf plugin-add python
asdf install python 3.9.13
asdf global python 3.9.13
これでpython -Vと打てば3.9.13と表示が出る
次に環境構築方法として
- 直接pipでインストール(おすすめ)
- venvで作る
- Poetryで作る
の3種類ある
コンテナの場合は1の直接pipでインストールするのがおすすめ
仮想環境をコンテナ内で作りたい場合は2,3の手法を取る
また、PoetryだとPytorchのインストールとの相性が良かったり悪かったりするので適宜読み替え推奨
今回はPoetryでもPytorchをインストールすることができる
1. 直接pipでインストール
直接作るとコンテナ内にインストールする形なのでコンテナを削除すれば環境も廃棄される
pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117
2. venvで作る
venvだと/workspace下に作った場合ホスト側にも保存されるのでコンテナ作り直したときにも残るので微妙
# 仮想環境の作成
python -m venv .venv
# 仮想環境に入る
source .venv/bin/activate
pip install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117
インストールが終わったらターミナルでpythonで対話モードに入り、
>>> import torch
>>> torch.cuda.is_available()
としてTrueが返ってきたら成功
3. Poetryで作る
- Poetryをインストール
asdf plugin-add poetry
asdf install poetry 1.3.2
asdf global install poetry 1.3.2
- プロジェクト配下に.venvファイルを生成するように設定
poetry config virtualenvs.in-project true
- pyproject.tomlファイルを作成
/workspace配下にpyproject.tomlを作り以下を記述
[tool.poetry]
name = "torch-project"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.8"
torch = "^1.13.0"
torchvision = "^0.14.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
- パッケージのインストール
poetry install
poetry shell
あとは同じように対話モードに入って
>>> import torch
>>> torch.cuda.is_available()
としてTrueが返ってきたら成功
poetryの場合は追加する場合はpip installではなくpoetry addを用いること
コンテナの削除
他にもインストールしたり何かおかしくなってやり直したい時にはコンテナを削除してやり直しが可能
# コンテナの削除
docker compose down
# コンテナの作成
docker compose up -d --build
これでもう一度Dockerfileに従ってビルドし直す
appsの中身は消えない(逆にapps以外のものは消える)
メモ
今回はホスト側のappsディレクトリのみをバインドしてるが、データセットを読み込ませたいときは、read_onlyプロパティを用いて
volumes:
- type: bind
source: ./data #データセットのあるパス
target: /data # バインド先のパス(ここでは/data)
read_only: true
と設定することで、読み込み専用で/dataにバインド出来る
Discussion