Compose における GPU アクセスの有効化
読む時間の目安: 4 分
Docker ホストに GPU デバイスがあり、これに合わせて Docker デーモンを適切に設定していれば、Compose サービスにおいて GPU デバイスの予約設定を定義することができます。 その実現には 前提条件 があるため、まだ実施していない場合は実施しておいてください。
これ以降の節に示す利用例においては、Docker Compose を用いて GPU デバイスに接続するサービスコンテナーの構築方法に焦点を当てています。
コマンドはdocker-compose
とdocker 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
は必ず設定しなければなりません。 これを行わないと、サービスデプロイ時にエラーが発生します。フィールド
count
とdevice_ids
は排他的なものです。 一度に定義できるのは 1 つだけです。
上のプロパティに関する詳細については Compose Specification のdeploy
の節を参照してください。
以下に示す 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