4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

docker-composeでGPU環境(+PyTorch)を構築する

Posted at

はじめに

Google Colabratory便利ですよね。
特に何も設定しなくても無料でGPUを利用できます。

しかし、Colabratoryは不自由な部分もありできたらローカルにGPU環境を用意したいものです。
過去にGPU対応に挑戦したことがありましたが、3度ほど挑戦して失敗。

そしてつい先日WSL2のGPU対応によりWSL2でGPUが認識するようになりました。
設定は以下の記事を参考にしてみてください。

また、WSLのDocker環境構築は以下の記事で行えます。

ここまでで、WSL2上でnvidia-smiをすると認識しています。
今回はここからDockerコンテナ上でGPUを認識するように設定していきます。

環境

  • GPU: GEFORCE GTX 1650
  • Ubuntu20.04 LTS
  • Windows

問題

まず、WSL2でGPUが認識する状態でいつも通りにコンテナを立ち上げます。
そして、nvidia-smiコマンドをコンテナ内でたたくと、

root@0da4a867f15b:/# nvidia-smi
bash: nvidia-smi: command not found

とエラーが出てしまいます。今回はコンテナ内でGPUを使えるようにしていきます。

試行錯誤

1. イメージを変更する

まず、Dockerのイメージをnvidiaのイメージを利用してみました。

NVIDIA CUDA

コンテナを起動して、nvidia-smiを叩きましたがエラーは変わらず。。

ちなみにDockerfileではGPU対応のイメージを利用しています。
https://github.com/Kaggle/docker-python

2. Docker runでコンテナを立てる

DockerコンテナでもGPUが使いたい

こちらの記事のコマンドを実行してみました。

$ docker run --gpus all ubuntu nvidia-smi
jinwatanabe@DESKTOP-4DGUR4Q:~/workspace/data_analysis$ docker run --gpus all ubuntu nvidia-smi
Tue Oct 19 10:56:31 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 495.29.05    Driver Version: 496.13       CUDA Version: 11.5     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| N/A   43C    P8     5W /  N/A |    134MiB /  4096MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

するとコンテナ内で認識していました。

``--gpu`というオプションで起動するとGPUがコンテナ内で使えるようになるそうでした。
これをdocker-compose.ymlで再現できるように調べていきました。

3. runtimeの設定

先ほどの記事にdocker-composeでのGPU設定があったので行います。

$ sudo apt install nvidia-container-runtime

nvidia-container-runtimeをインストールして、/etc/docker/daemon.jsonを設定

daemon.json
{
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}

そして、docker-compose.ymlに環境変数とruntimeを設定

docker-compose.yml
version: "3"
services:
    jupyter:
        build: ./libraries
        container_name: jupyter
        runtime: nvidia # 追加
        volumes:
            - ./notebook/:/tmp/working
        ports:
            - 80:8888
        environment: # 追加
            NVIDIA_VISIBLE_DEVICES: all # 追加
            NVIDIA_DRIVER_CAPABILITIES: all # 追加
        command: jupyter notebook --ip=0.0.0.0 --allow-root --no-browser

これで、docker-compose upしたところ、以下のようなエラーが発生。

Unsupported config option for services.nvidia: 'runtime'

どうもruntimeが利用できないよう。

調べてみると、version: "3"にしているとruntimeが使えないよう。
ですので、設定ファイルに情報を追加します。

daemon.json
 {
  "default-runtime": "nvidia", # 追加
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }

再起動して、docker-compose.ymlからruntimeの行を消して起動。

しかし、nvidia-smiコマンドは動かず。。。

4. deplpoyの設定

nvidia-dockerをdocker-composeで動かす(ver3系)

こちらの記事を参考にdocker-compose.ymlに以下を追加します。

docker-compose.yml
(省略)
    deploy:
      resources:
        reservations:
          devices:
           - driver: nvidia
             capabilities: [utility, compute, video]

この状態で、コンテナを起動したところ、
deploy.resources.reservations.deviceでエラーになりました。

# こんな感じ (転載)
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.testserver.deploy.resources.reservations value Additional properties are not allowed ('devices' was unexpected)

調べてみると以下の記事にたどり着きます。

" 'devices' properties is not allowed" while creating docker-compose with nvidia gpu

この記事によるとdocker-composeのバージョンに起因しているとのこと、この時点でインストールしていたのが1.26.0だったので、バージョンアップしました。

$ sudo rm -rf docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose -v

これで1.29.0にバージョンアップできました。

この状態で、コンテナを立ち上げて、nvidia-smiを叩くと、

root@270fc08efdcb:/# nvidia-smi
Tue Oct 19 11:23:28 2021       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 495.29.05    Driver Version: 496.13       CUDA Version: 11.5     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  NVIDIA GeForce ...  On   | 00000000:01:00.0 Off |                  N/A |
| N/A   43C    P8    10W /  N/A |    134MiB /  4096MiB |     N/A      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

コンテナの中で認識されています!

次にPyTorchでGPUが使えるか確認します。

$ python
$ import torch
$ print(torch.cuda.is_available())

# TRUE

うまくいきました。

また、docker-composeを更新したところ、runtimeがエラーにならなくなりました。
バージョンが原因でした。runtimeでもGPUを認識することができるのでこちらを採用することにしました。

解決方法

解決するための方法をまとめます。

NVIDIA container ToolKitをインストール

$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list

$ sudo apt-get update
$ sudo apt-get install -y nvidia-docker2
$ sudo usermod -aG docker $USER

そのあとでDockerを再起動する。

$ sudo service docker restart

しないと以下のようなエラーになります。
DockerでGPUを使おうとしたらError response from daemon: linux runtime spec devices: could not select device driver “” with capabilities: [[gpu]]

$ docker run --gpus all ubuntu nvidia-smi

# エラー
Error response from daemon: linux runtime spec devices: could not select device driver “” with capabilities: [[gpu]]

次にdocker-composeのバージョンを上げます。

$ sudo rm -rf docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

そのあとで、docker-compose.ymlにruntimeとGPUの環境変数を追加します。

docker-compose.yml
(省略)
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all

そしてDockerfileのイメージはPython:3.7nvidia/cuda:11.0-devel-ubuntu20.04を利用する。
gcr.io/kaggle-gpu-images/pythonはなぜか利用できなかった。。

結果以下のようなPyTorchの環境が出来上がりました。

FROM jupyter/datascience-notebook

ENV GRANT_SUDO=yes
USER root

RUN apt-get update
RUN apt-get install -y vim
RUN pip install \
		japanize-matplotlib \
		torch

COPY ./settings/jupyter_notebook_config.py .jupyter
docker-compose.yml
version: "3"
services:
    jupyter:
        build: ./libraries
        container_name: jupyter
        runtime: nvidia
        volumes:
            - ./notebook/:/tmp/working
        ports:
            - 80:8888
        environment:
            NVIDIA_VISIBLE_DEVICES: all
            NVIDIA_DRIVER_CAPABILITIES: all

詳しい使い方は以下のリポジトリから確認してください。

おわりに

長い長い戦いがついに終わりました。

参考

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?