こんにちは。アドバンストテクノロジー部のR&Dチーム所属岩原です。
今回は、nvidia-dockerをdocker-composeから使う - WonderPlanet DEVELOPER BLOGの記事が、
nvidia-dockerのversion2.0の登場によって過去のものになってしまったので、対応した記事を新たに書きました。
検証環境
- AWS(p2.xlarge)
- Ubuntu 16.04 LTS
CUDAやドライバー,Dockerのインストールなど
nvidia-dockerをdocker-composeから使う - WonderPlanet DEVELOPER BLOGの各項目を参照してください。
バージョンなどは上がっているかと思うので、そこは最新に合わせてください。
念のため、各項目のインストールページを載せておきます。
また、前回書き忘れていたのですが、dockerグループにユーザーを所属させると、
dockerの実行にsudoが必要なくなるので、やっておくと良いかと思います。
手順は以下のとおりです。
- 現在のユーザーをdockerグループに所属させる
sudo gpasswd -a $USER docker
docker-compose対応
add support for runtime
option in service definitions by cuckoohello · Pull Request #5405 · docker/composeによると、
docker-composeの正式対応(runtime指定)は1.19ぐらいになりそうです。
したがって、それまではdocker deamonのデフォルトのコンテナランタイムをnvidia-dockerに変える必要があります。
兎にも角にも、最新のdocker-composeを入れましょう。
前回と同じ手順ですが、バージョン変わってるのでついでにコマンドを載せておきます。
現在(2017/12/13)の最新安定版は1.17のようです。
sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-uname -s
-uname -m
-o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
でバージョン情報が出力されればOKです。
nvidia-dockerのインストール
前準備として、GPGキーの登録やリポジトリの追加などを行います。
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update
上記が正常終了したら、次はnvidia-docker2のインストールです。
sudo apt-get install nvidia-docker2
インストールが完了したら、docker daemonの設定をリロードさせます。
sudo pkill -SIGHUP dockerd
問題なければ動作確認してみましょう。
docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi
nvidia-smiの結果が出力されればOKです。
出力例(AWSのp2.xlargeの場合)
Wed Dec 13 05:28:55 2017 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 387.26 Driver Version: 387.26 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla K80 Off | 00000000:00:1E.0 Off | 0 | | N/A 50C P0 57W / 149W | 0MiB / 11439MiB | 99% Default | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
docker-composeで使う(v1.19.0未満の場合)
dockerdのdefault runtimeをnvidiaに設定します。
nvidia-dockerのインストール直後は未設定なので、runc
と言うものDockerデフォルトのものになっています。
sudo vi /etc/docker/daemon.json
でDocker daemonの設定ファイルを開き、"default-runtime": "nvidia",
を追加します。
追加後のファイルの内容は以下の通りになるかと思います。
{ "default-runtime": "nvidia", "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime", "runtimeArgs": [] } } }
これで、デフォルトで使われるdockerコンテナのランタイムがrunc
からnvidia
に変わります。
一旦、この状態で再起動かけると設定が適用されます。
この状態で、以下をdocker-compose.yml
として保存し、
version: '3' services: nvidia: image: nvidia/cuda command: nvidia-smi
docker-compose up
してnvidia-smiの結果が出力されればOKです。
出力例(AWS
のp2.xlargeの場合)
Creating network "ubuntu_default" with the default driver Creating ubuntu_nvidia_1 ... Creating ubuntu_nvidia_1 ... done Attaching to ubuntu_nvidia_1 nvidia_1 | Wed Dec 13 05:13:22 2017 nvidia_1 | +-----------------------------------------------------------------------------+ nvidia_1 | | NVIDIA-SMI 387.26 Driver Version: 387.26 | nvidia_1 | |-------------------------------+----------------------+----------------------+ nvidia_1 | | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | nvidia_1 | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | nvidia_1 | |===============================+======================+======================| nvidia_1 | | 0 Tesla K80 Off | 00000000:00:1E.0 Off | 0 | nvidia_1 | | N/A 49C P0 57W / 149W | 0MiB / 11439MiB | 99% Default | nvidia_1 | +-------------------------------+----------------------+----------------------+ nvidia_1 | nvidia_1 | +-----------------------------------------------------------------------------+ nvidia_1 | | Processes: GPU Memory | nvidia_1 | | GPU PID Type Process name Usage | nvidia_1 | |=============================================================================| nvidia_1 | | No running processes found | nvidia_1 | +-----------------------------------------------------------------------------+
volumesとかdevicesとかは必要なくなりましたが、Docker daemonの設定を弄らないといけないのは面倒です。
また、コンテナごとにコンテナランタイムを変えられないのはちょっと不便ですね。
そこら辺はdocker-composeのバージョンアップを待ちましょう。
docker-composeで使う(v1.19.0以上の場合)
まだリリースされていません(2017/12/13時点では1.18rc2が最新)が、前述のプルリクエストを見る限り、
以下のようにdocker-compose.ymlにruntime: nvidia
を追記するだけです。
version: '3' services: nvidia: image: nvidia/cuda runtime: nvidia command: nvidia-smi
簡単ですね。
Docker daemonの設定を弄る必要はありません。
コンテナごとにruntimeを変えることも可能となるでしょう。
実践
nvidia-dockerをdocker-composeから使う - WonderPlanet DEVELOPER BLOGでやったのと同じ、Kerasのサンプルの1つである、mnist + CNNを動かすDockerイメージを作ります。
詳細は元記事を参照してください。
元記事と違う点として、docker-compose.ymlからvolume周りの設定が全て消えました。
version: "3" services: tensorflow_keras: build: context: ./tensorflow_keras dockerfile: Dockerfile
上記以外は元記事と一緒です。
結果
tensorflow_keras_1 | 2017-12-13 05:55:43.084455: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0)
きちんとGPUが認識されているようです。
複数GPUは認識されるのか
インスタンスタイプをp2.8xlarge(8GPU)に上げてやってみました。
これで複数GPUが認識されるのかどうか確かめてみます。
tensorflow_keras_1 | 2017-12-13 06:09:22.743220: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:17.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743232: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:1) -> (device: 1, name: Tesla K80, pci bus id: 0000:00:18.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743238: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:2) -> (device: 2, name: Tesla K80, pci bus id: 0000:00:19.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743243: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:3) -> (device: 3, name: Tesla K80, pci bus id: 0000:00:1a.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743252: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:4) -> (device: 4, name: Tesla K80, pci bus id: 0000:00:1b.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743257: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:5) -> (device: 5, name: Tesla K80, pci bus id: 0000:00:1c.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743262: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:6) -> (device: 6, name: Tesla K80, pci bus id: 0000:00:1d.0) tensorflow_keras_1 | 2017-12-13 06:09:22.743270: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:7) -> (device: 7, name: Tesla K80, pci bus id: 0000:00:1e.0)
全て認識されています。
使用するGPUを指定する方法
環境変数NVIDIA_VISIBLE_DEVICES
を使います。
以下のように、NVIDIA_VISIBLE_DEVICES
の値として0,1,2
を指定すると、
0番目、1番目、2番目のGPUを指定したことになります。
他にもall
やnone
なども指定できます。
詳細はNVIDIA/nvidia-container-runtime: NVIDIA container runtimeで確認してください。
version: "3" services: tensorflow_keras: build: context: ./tensorflow_keras dockerfile: Dockerfile environment: - NVIDIA_VISIBLE_DEVICES=0,1,2
実行してみると、
tensorflow_keras_1 | 2017-12-13 06:19:44.448613: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: 0000:00:17.0) tensorflow_keras_1 | 2017-12-13 06:19:44.448624: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:1) -> (device: 1, name: Tesla K80, pci bus id: 0000:00:18.0) tensorflow_keras_1 | 2017-12-13 06:19:44.448630: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:2) -> (device: 2, name: Tesla K80, pci bus id: 0000:00:19.0)
のように3つ使用されているのが確認できます。
結論
docker-composeは1.19が出るまで待つと良いです。
現状では、docker-composeを使用するとnvidiaのランタイムかDockerのランタイムどちらかしか使用できません。
ただし、volumeとか作る必要はなくなったので、そこは良くなった点ですね。