2行まとめ
- nvidia-dockerバージョン2.0系では
docker build
時にもGPU、関連ライブラリを使うことができる。 - そのためには、Dockerデーモンの設定を変更し、デフォルトランタイムを
nvidia
に切り替える必要がある。
概要
nvidia-dockerのバージョン2.0系では、Dockerの「ランタイム」という仕組みを用いてGPUデバイスや関連ライブラリのマウントを行っています。(バージョン1.0系ではnvidia-docker
というラッパコマンドが存在しました)
通常、ランタイムはその名の通り、docker run
時に指定します。そのためdocker build
時には有効にならず、ビルド時にGPUや関連ライブラリを必要とするソフトウェアをDockerイメージ化する場合に困ることになります。
そんな中、nvidia-dockerの公式Wiki「Advanced topics」に「デフォルトランタイムを変更するとGPUにアクセスできるよ」との記述を見つけたので実験してみました。
以下、引用です。
Default runtime
The default runtime used by the Docker® Engine is
runc
, our runtime can become the default one by configuring the docker daemon with--default-runtime=nvidia
. Doing so will remove the need to add the--runtime=nvidia
argument to docker run. It is also the only way to have GPU access during docker build.
環境
評価を行った環境は、以下の通りです。
yuya@host$ uname -a
Linux xxx 4.4.0-83-generic #106-Ubuntu SMP Mon Jun 26 17:54:43 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
yuya@host$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS"
yuya@host$ docker version
Client:
Version: 17.12.0-ce
API version: 1.35
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:11:19 2017
OS/Arch: linux/amd64
Server:
Engine:
Version: 17.12.0-ce
API version: 1.35 (minimum version 1.12)
Go version: go1.9.2
Git commit: c97c6d6
Built: Wed Dec 27 20:09:53 2017
OS/Arch: linux/amd64
Experimental: false
yuya@host$ dpkg -l | grep nvidia-docker
ii nvidia-docker2 2.0.2+docker17.12.0-1 all nvidia-docker CLI wrapper
デフォルトランタイムがrunc
の場合(変更前)
デフォルトランタイムはdocker info
コマンドで確認することができます。変更前のデフォルトランタイムはrunc
です。
yuya@host$ docker info 2> /dev/null | grep -i runtime
Runtimes: nvidia runc
Default Runtime: runc
yuya@host$ sudo cat /etc/docker/daemon.json
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
デフォルトランタイムがrunc
の場合でも、docker run
コマンドに--runtime nvidia
オプションを指定することでnvidia
ランタイムを使用することができます。実行例を以下に示します。GPUが認識されていること、関連ライブラリにアクセスできることが確認できます。
yuya@host$ docker pull nvidia/cuda:latest
latest: Pulling from nvidia/cuda
Digest: sha256:74570aef804e30486eb74b284fd3091d14ca7144736c44fb48c13e5e6afb963f
Status: Image is up to date for nvidia/cuda:latest
yuya@host$ docker run --interactive --tty --rm --runtime nvidia nvidia/cuda:latest nvidia-smi
Mon Apr 16 11:02:32 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 387.34 Driver Version: 387.34 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 108... Off | 00000000:03:00.0 On | N/A |
| 0% 34C P8 11W / 280W | 61MiB / 11169MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
yuya@host$ docker run --interactive --tty --rm --runtime nvidia nvidia/cuda:latest ls -l /usr/lib/x86_64-linux-gnu/libcuda.so
lrwxrwxrwx 1 root root 17 Apr 16 11:12 /usr/lib/x86_64-linux-gnu/libcuda.so -> libcuda.so.387.34
なお、ランタイムを指定しない場合(デフォルトのrunc
を使う場合)、nvidia-smi
もlibcuda.so
も参照できません。
yuya@host$ docker run --interactive --tty --rm nvidia/cuda:latest nvidia-smi
docker: Error response from daemon: OCI runtime create failed: container_linux.go:296: starting container process caused "exec: \"nvidia-smi\": executable file not found in $PATH": unknown.
yuya@host$ docker run --interactive --tty --rm nvidia/cuda:latest ls -l /usr/lib/x86_64-linux-gnu/libcuda.so
ls: cannot access '/usr/lib/x86_64-linux-gnu/libcuda.so': No such file or directory
また、docker build
時にも同様に、nvidia-smi
やlibcuda.so
を参照できません。
yuya@host$ cat Dockerfile
FROM nvidia/cuda:latest
RUN ls -l /usr/lib/x86_64-linux-gnu/libcuda.so || true
RUN nvidia-smi
yuya@host$ docker build --no-cache --tag ${USER}/runtime_runc .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM nvidia/cuda:latest
---> 9b8a74e9dc76
Step 2/3 : RUN ls -l /usr/lib/x86_64-linux-gnu/libcuda.so || true
---> Running in 6f9187fc3fab
ls: cannot access '/usr/lib/x86_64-linux-gnu/libcuda.so': No such file or directory
Removing intermediate container 6f9187fc3fab
---> c0b7ad290600
Step 3/3 : RUN nvidia-smi
---> Running in cb7a837d9096
/bin/sh: 1: nvidia-smi: not found
The command '/bin/sh -c nvidia-smi' returned a non-zero code: 127
デフォルトランタイムがnvidia
の場合(変更後)
次に、デフォルトランタイムがnvidia
の場合を見てみます。まずは、Dockerデーモンの設定ファイル/etc/docker/daemon.json
を変更し、設定を反映するためにDockerデーモンを再起動します。docker info
コマンドの結果から、デフォルトランタイムがnvidia
に切り替わっていることが確認できます。
yuya@host$ sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.20180416
yuya@host$ sudo vi /etc/docker/daemon.json
yuya@host$ sudo cat /etc/docker/daemon.json
{
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
yuya@host$ sudo diff -U 2 /etc/docker/daemon.json.20180416 /etc/docker/daemon.json
--- /etc/docker/daemon.json.20180416 2018-04-16 19:10:59.018030162 +0900
+++ /etc/docker/daemon.json 2018-04-16 19:11:50.002551905 +0900
@@ -1,3 +1,4 @@
{
+ "default-runtime": "nvidia",
"runtimes": {
"nvidia": {
yuya@host$ sudo systemctl restart docker
yuya@host$ docker info 2> /dev/null | grep -i runtime
Runtimes: nvidia runc
Default Runtime: nvidia
デフォルトランタイムがnvidia
に切り替わったため、docker run
時に--runtime nvidia
を指定しなくてもnvidia
ランタイムが使用されます。実行例を以下に示します。
yuya@host$ docker run --interactive --tty --rm nvidia/cuda:latest nvidia-smi
Wed Apr 18 02:21:18 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 387.34 Driver Version: 387.34 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 108... Off | 00000000:03:00.0 On | N/A |
| 0% 34C P8 10W / 280W | 61MiB / 11169MiB | 1% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
yuya@host$ docker run --interactive --tty --rm nvidia/cuda:latest ls -l /usr/lib/x86_64-linux-gnu/libcuda.so
lrwxrwxrwx 1 root root 17 Apr 18 02:21 /usr/lib/x86_64-linux-gnu/libcuda.so -> libcuda.so.387.34
デフォルトランタイムはdocker build
時にも使用されます。そのため、デフォルトランタイムがrunc
の時には参照できなかったnvidia-smi
とlibcuda.so
が参照できています。実行例を以下に示します。
yuya@host$ cat Dockerfile
FROM nvidia/cuda:latest
RUN ls -l /usr/lib/x86_64-linux-gnu/libcuda.so || true
RUN nvidia-smi
yuya@host$ docker build --no-cache --tag ${USER}/runtime_nvidia .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM nvidia/cuda:latest
---> 9b8a74e9dc76
Step 2/3 : RUN ls -l /usr/lib/x86_64-linux-gnu/libcuda.so || true
---> Running in 6be189daae11
lrwxrwxrwx 1 root root 17 Apr 18 02:40 /usr/lib/x86_64-linux-gnu/libcuda.so -> libcuda.so.387.34
Removing intermediate container 6be189daae11
---> e1b2e960906a
Step 3/3 : RUN nvidia-smi
---> Running in d140ec1d9142
Wed Apr 18 02:40:19 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 387.34 Driver Version: 387.34 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 108... Off | 00000000:03:00.0 On | N/A |
| 0% 34C P8 11W / 280W | 61MiB / 11169MiB | 1% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+
Removing intermediate container d140ec1d9142
---> 260bc963500d
Successfully built 260bc963500d
Successfully tagged yuya/runtime_nvidia:latest
これでdocker build
時にGPUや関連ライブラリを使うソフトウェアをDockerイメージ化できますね!
参考
-
NVIDIA/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs
- nvidia-dockerの本家サイト。