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

NVIDIA Container Toolkit を使って Docker のコンテナからホストの GPU を使ってみるという内容です。Docker 19.03 から追加されたオプション --gpus を使って GPU コンテナを作成します。

環境

OS は Ubuntu 18.04。NVIDIA ドライバーはインストール済みであり、Docker も利用可能な状態です。

host
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
NVIDIA
$ nvidia-smi
Fri Nov 29 19:23:30 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 435.21       Driver Version: 435.21       CUDA Version: 10.1     |
|-------------------------------+----------------------+----------------------+
| 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 RTX 2060    Off  | 00000000:01:00.0  On |                  N/A |
| 29%   30C    P8    10W / 160W |    694MiB /  5926MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      3271      G   /usr/lib/xorg/Xorg                            26MiB |
|    0      3326      G   /usr/bin/gnome-shell                          51MiB |
|    0      3641      G   /usr/lib/xorg/Xorg                           307MiB |
|    0      3767      G   /usr/bin/gnome-shell                         168MiB |
|    0      4487      G   ...quest-channel-token=7784788847753370689    96MiB |
|    0     10121      G   ...ring --no-sandbox --gpu-preferences=IAA    41MiB |
+-----------------------------------------------------------------------------+
docker
$ docker -v
Docker version 19.03.5, build 633a0ea838

NVIDIA Container Toolkitのインストール

NVIDIA Container Toolkit をインストールします。これによりコンテナ起動時に --gpus オプションを指定すればホスト側の GPU が認識されるようになります。

# Add the package repositories
$ 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

$ sudo apt update && sudo apt install -y nvidia-container-toolkit
$ sudo systemctl restart docker

参考:https://github.com/NVIDIA/nvidia-docker/tree/master#quickstart

nvidia-container-cli info コマンドを使って NVIDIA Container Toolkit のインストールを確認しておきます。

$ nvidia-container-cli info
NVRM version:   435.21
CUDA version:   10.1

Device Index:   0
Device Minor:   0
Model:          GeForce RTX 2060
Brand:          GeForce
GPU UUID:       GPU-5e24bde2-a217-9a7c-18c6-612911c83722
Bus Location:   00000000:01:00.0
Architecture:   7.5

NVIDIA Container Toolkit がインストールされていることが確認できます。

Dockerコンテナを起動してみる

実際に Docker コンテナ内で nvidia-smi を実行してみます。

$ docker run --gpus all ubuntu nvidia-smi
Fri Nov 29 10:42:43 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 435.21       Driver Version: 435.21       CUDA Version: N/A      |
|-------------------------------+----------------------+----------------------+
| 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 RTX 2060    Off  | 00000000:01:00.0  On |                  N/A |
| 29%   30C    P8    10W / 160W |    732MiB /  5926MiB |      1%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

コンテナからホストの GPU が問題なく認識されています。

docker-compose の場合

2019/11/29 現在、docker-compose では Docker の --gpus と同等のオプションはサポートされていないようです。そのため、別途 nvidia-container-runtime をインストールして、/etc/docker/daemon.json に設定ファイルを作成します。

sudo apt install nvidia-container-runtime
/etc/docker/daemon.json
{
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}

参考:https://github.com/NVIDIA/nvidia-container-runtime#installation

これにて docker-compose で runtime: nvidia オプションが指定できるようになります。

docker-composeで実行

docker-compose 経由でコンテナを実行してみます。

Dockerfile
FROM python:3.7

RUN \
  apt-get update && \
  pip install torch
docker-compose.yml
version: '2.3'

services:
  app:
    build: .
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
      - NVIDIA_DRIVER_CAPABILITIES=all
    volumes:
      - .:/workdir
    working_dir: /workdir
    tty: true
check_gpu.py
import torch

print(torch.cuda.current_device())
print(torch.cuda.get_device_name(0))
print(torch.cuda.is_available())
$ docker-copmose up -d
$ docker-compose exec app python check-gpu.py
0
GeForce RTX 2060
True

GPU 使えてます。

docker-composeでのエラー対応

「runtime: nvidia」の不足

AssertionError:
Found no NVIDIA driver on your system. Please check that you
have an NVIDIA GPU and installed a driver from

docker-compose.ymlruntime: nvidia を追加する必要があります。

nvidia-container-runtime の未インストール

docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
ERRO[0002] error waiting for container: context canceled

ホストに nvidia-container-runtime をインストールします。

NVIDIAドライバーのバージョンが違う

コンテナとホストの NVIDIA ドライバーのバージョンが異なるために発生するエラー。バージョンを統一する必要があります。

環境変数の不足

AssertionError:
Found no NVIDIA driver on your system. Please check that you
have an NVIDIA GPU and installed a driver from
http://www.nvidia.com/Download/index.aspx

環境変数 NVIDIA_VISIBLE_DEVICES,NVIDIA_DRIVER_CAPABILITIES の設定が必要です。

詳細:https://github.com/NVIDIA/nvidia-container-runtime#environment-variables-oci-spec

おわり

無事に Docker (docker-compose) でも GPU が使えるようになりました。おしまい。