LoginSignup
31
19

More than 5 years have passed since last update.

nvidia-dockerのbuild時にGPU、関連ライブラリを有効にする

Posted at

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-smilibcuda.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-smilibcuda.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-smilibcuda.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イメージ化できますね!

参考

31
19
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
31
19