はじめに
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-smi
を叩きましたがエラーは変わらず。。
ちなみにDockerfileではGPU対応のイメージを利用しています。
https://github.com/Kaggle/docker-python
2. Docker runでコンテナを立てる
こちらの記事のコマンドを実行してみました。
$ 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
を設定
{
"runtimes": {
"nvidia": {
"path": "nvidia-container-runtime",
"runtimeArgs": []
}
}
}
そして、docker-compose.ymlに環境変数とruntime
を設定
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が使えないよう。
ですので、設定ファイルに情報を追加します。
{
"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に以下を追加します。
(省略)
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の環境変数を追加します。
(省略)
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
そしてDockerfileのイメージはPython:3.7
やnvidia/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
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
詳しい使い方は以下のリポジトリから確認してください。
おわりに
長い長い戦いがついに終わりました。
参考
- 待ってました CUDA on WSL 2
- 【環境構築】docker-composeでGPU(on Ubuntu20.04)を使用するためには
- Kaggle docker image
- " 'devices' properties is not allowed" while creating docker-compose with nvidia gpu
- PyTorchでGPU情報を確認(使用可能か、デバイス数など)
- DockerでGPUを使おうとしたらError response from daemon: linux runtime spec devices: could not select device driver “” with capabilities: [[gpu]]