Compose における GPU アクセスの有効化

読む時間の目安: 4 分

Docker ホストに GPU デバイスがあり、これに合わせて Docker デーモンを適切に設定していれば、Compose サービスにおいて GPU デバイスの予約設定を定義することができます。 その実現には 前提条件 があるため、まだ実施していない場合は実施しておいてください。

これ以降の節に示す利用例においては、Docker Compose を用いて GPU デバイスに接続するサービスコンテナーの構築方法に焦点を当てています。 コマンドはdocker-composedocker composeのどちらでも利用できます。

Compose v2.3 フォーマットにおけるサービスruntimeプロパティの利用(過去の手法)

Docker Compose v1.27.0 以降では、Compose Specification スキーマを利用するものとなりました。 これは 2.x と 3.x の両バージョンにおけるプロパティをすべて組み合わせたものです。 この利用によって、サービスプロパティは runtime として利用可能となり、サービスコンテナーにおける GPU アクセスが実現できます。 ただしこの場合、GPU デバイスのすべてのプロパティを制御可能となるわけではありません。

services:
  test:
    image: nvidia/cuda:10.2-base
    command: nvidia-smi
    runtime: nvidia

サービスコンテナーにおける GPU アクセスの有効化

Docker Compose v1.28.0 以降においては、Compose Specification にて定義される device 構造を利用して GPU デバイスの予約定義が可能となります。 これによって以下に示すようなデバイスプロパティをカスタム設定できるため、GPU デバイス予約をきめ細かく制御できます。

  • capabilities - 値として文字列リストを指定します。 (たとえばcapabilities: [gpu]) Compose ファイル内でこのフィールドの設定が必須です。 これを行わないと、サービスデプロイ時にエラーが発生します。
  • count - 値として整数値か、あるいはallを指定します。 予約を行う GPU デバイスの数を表します。 (ホストにはそれだけの数の GPU が存在しているものとします。)
  • device_ids - 値として文字列リストを指定します。 ホスト上での GPU デバイス ID を表します。 この ID 値は、ホスト上においてnvidia-smiを実行した出力結果から確認することができます。
  • driver - 値として文字列を指定します。 (たとえばdriver: 'nvidia'
  • options - ドライバーに固有のオプションをキーバリューペアで指定します。

メモ

フィールドcapabilitiesは必ず設定しなければなりません。 これを行わないと、サービスデプロイ時にエラーが発生します。

フィールドcountdevice_idsは排他的なものです。 一度に定義できるのは 1 つだけです。

上のプロパティに関する詳細については Compose Specificationdeployの節を参照してください。

以下に示す Compose ファイルは、GPU デバイスを 1 つ利用してサービスを起動する利用例です。

services:
  test:
    image: nvidia/cuda:10.2-base
    command: nvidia-smi
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

Docker Compose によってこれを実行します。

$ docker-compose up
Creating network "gpu_default" with the default driver
Creating gpu_test_1 ... done
Attaching to gpu_test_1
test_1  | +-----------------------------------------------------------------------------+
test_1  | | NVIDIA-SMI 450.80.02    Driver Version: 450.80.02    CUDA Version: 11.1     |
test_1  | |-------------------------------+----------------------+----------------------+
test_1  | | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
test_1  | | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
test_1  | |                               |                      |               MIG M. |
test_1  | |===============================+======================+======================|
test_1  | |   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
test_1  | | N/A   23C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
test_1  | |                               |                      |                  N/A |
test_1  | +-------------------------------+----------------------+----------------------+
test_1  |
test_1  | +-----------------------------------------------------------------------------+
test_1  | | Processes:                                                                  |
test_1  | |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
test_1  | |        ID   ID                                                   Usage      |
test_1  | |=============================================================================|
test_1  | |  No running processes found                                                 |
test_1  | +-----------------------------------------------------------------------------+
gpu_test_1 exited with code 0

countまたはdevice_idsが設定されていない場合は、デフォルトとしてホスト上にある GPU すべてが利用されることになります。

services:
  test:
    image: tensorflow/tensorflow:latest-gpu
    command: python -c "import tensorflow as tf;tf.test.gpu_device_name()"
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]
$ docker-compose up
Creating network "gpu_default" with the default driver
Creating gpu_test_1 ... done
Attaching to gpu_test_1
test_1  | I tensorflow/stream_executor/platform/default/dso_loader.cc:48] Successfully opened dynamic library libcudart.so.10.1
.....
test_1  | I tensorflow/core/common_runtime/gpu/gpu_device.cc:1402]
Created TensorFlow device (/device:GPU:0 with 13970 MB memory) -> physical GPU (device: 0, name: Tesla T4, pci bus id: 0000:00:1e.0, compute capability: 7.5)
test_1  | /device:GPU:0
gpu_test_1 exited with code 0

GPU を複数持つホストにおいては、device_idsフィールドを使って対象とする GPU デバイスを指定できます。 またサービスコンテナーに割り当てる GPU デバイス数をcountにより制限することができます。 countの設定値がホスト上の実際の GPU 数を超えている場合、デプロイ時にエラーが発生します。

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.80.02    Driver Version: 450.80.02    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| 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  Tesla T4            On   | 00000000:00:1B.0 Off |                    0 |
| N/A   72C    P8    12W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  Tesla T4            On   | 00000000:00:1C.0 Off |                    0 |
| N/A   67C    P8    11W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   2  Tesla T4            On   | 00000000:00:1D.0 Off |                    0 |
| N/A   74C    P8    12W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   3  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
| N/A   62C    P8    11W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

GPU-0 と GPU-3 の 2 つのデバイスのみアクセスするには、以下のようにします。

services:
  test:
    image: tensorflow/tensorflow:latest-gpu
    command: python -c "import tensorflow as tf;tf.test.gpu_device_name()"
    deploy:
      resources:
        reservations:
          devices:
          - driver: nvidia
            device_ids: ['0', '3']
            capabilities: [gpu]

$ docker-compose up
...
Created TensorFlow device (/device:GPU:0 with 13970 MB memory -> physical GPU (device: 0, name: Tesla T4, pci bus id: 0000:00:1b.0, compute capability: 7.5)
...
Created TensorFlow device (/device:GPU:1 with 13970 MB memory) -> physical GPU (device: 1, name: Tesla T4, pci bus id: 0000:00:1e.0, compute capability: 7.5)
...
gpu_test_1 exited with code 0
documentation, docs, docker, compose, GPU access, NVIDIA, samples