🐷

Dockerで研究用Python環境構築

2023/04/26に公開

はじめに

個人的に作った環境構築方法なのでベストプラクティスではない可能性もあります

今回はUbuntu20.04のイメージを使ってCUDA11.7でPytorchのtorch=1.13.1を構築する
torch.cuda.is_available()Trueが返ってきたら成功

  • Pythonのバージョン管理にはasdfを使う
  • 直接 or venv or Poetryで環境を作る

https://asdf-vm.com/

開発環境

VSCodeを前提
Docker拡張機能をインストール
https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker

Python拡張機能も忘れずに入れること

CUDAの確認

ホストOSにCUDAがインストールされていないとGPUが使えない
nvidia-smiで確認
なかったらインストール
https://developer.nvidia.com/cuda-downloads

Docker Desktopのインストール

公式サイトのインストーラーをダウンロードし、指示に従いインストール
https://www.docker.com/products/docker-desktop/

Docker Desktop版じゃないCLI版を入れる場合は他に詳しく書いてる記事があるのでそっちを参照
docker versionと入力して出力がでればOK

プロジェクトの作成

mkdir myproject
mkdir -p myproject/apps
cd myproject

myprojectの名前は自分の好きな名前で

Dockerfileの作成

NVIDIAのcudaイメージを使う
https://hub.docker.com/r/nvidia/cuda
今回はcuda11.7.1のcudnn8のubuntu20.04を使っているが、自分が使うバージョンによってタグを変える
(Tagsの部分で検索して探す)
myprojectディレクトリ直下にDockerfileを作成(拡張子なし)

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を作成

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と表示が出る
次に環境構築方法として

  1. 直接pipでインストール(おすすめ)
  2. venvで作る
  3. 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で作る

  1. Poetryをインストール
asdf plugin-add poetry
asdf install poetry 1.3.2
asdf global install poetry 1.3.2
  1. プロジェクト配下に.venvファイルを生成するように設定
poetry config virtualenvs.in-project true
  1. pyproject.tomlファイルを作成
    /workspace配下にpyproject.tomlを作り以下を記述
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"
  1. パッケージのインストール
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プロパティを用いて

docker-compose.yaml
volumes:
  - type: bind
    source: ./data #データセットのあるパス
    target: /data # バインド先のパス(ここでは/data)
    read_only: true

と設定することで、読み込み専用で/dataにバインド出来る
https://docs.docker.jp/compose/compose-file/compose-file-v3.html#id20

Discussion