cGPU は GPU リソースを隔離し、複数のコンテナが単一の GPU カードを共有できるようにします。これは、機械学習、ディープラーニング、科学計算などのハイパフォーマンスコンピューティング (HPC) ワークロード向けに設計された Container Service for Kubernetes (ACK) のコンポーネントです。GPU リソースをより効率的に使用することで、コンピューティングタスクを高速化できます。このトピックでは、 cGPU のインストール方法と使用方法について説明します。
cGPU の隔離は統合仮想メモリ (UVM) をサポートしていないため、cudaMallocManaged() を呼び出して GPU メモリを割り当てることはできません。代わりに、cudaMalloc() を呼び出してください。詳細については、NVIDIA ドキュメントをご参照ください。
前提条件
ご利用の GPU インスタンスが次の要件を満たしていることを確認してください:
-
インスタンスファミリーは、gn7i、gn6i、gn6v、gn6e、gn5i、gn5、ebmgn7i、ebmgn6i、ebmgn7e、ebmgn6e のいずれかです。
-
オペレーティングシステムは、CentOS、Ubuntu、または Alibaba Cloud Linux のいずれかです。
-
Tesla ドライバー 418.87.01 以降がインストールされています。
-
Docker 19.03.5 以降がインストールされています。
cGPU のインストール
ACK Docker ランタイムで cGPU をインストールして使用することを推奨します。
cGPU バージョン 1.5.7 をインストールすると、cGPU カーネルドライバーでデッドロック (同時に実行されているプロセスが互いにブロックし合う状態) が発生し、Linux カーネルパニックにつながる可能性があります。新しいワークロードでカーネルエラーを回避するために、cGPU 1.5.8 以降をインストールするか、以前のバージョンを段階的に 1.5.8 以降にアップグレードすることを推奨します。
-
クラスターを作成します。
詳細については、「ACK マネージドクラスターの作成」をご参照ください。
クラスターリスト ページで、クラスターの名前をクリックします。左側のナビゲーションウィンドウで、 をクリックします。
-
[基本的な機能] セクションで、[スケジューリングポリシー拡張 (バッチタスクスケジューリング、GPU 共有、トポロジー対応 GPU スケジューリング)] を選択します。
-
ページの下部にある [クラウドネイティブ AI スイートのデプロイ] をクリックします。
インストール後、[クラウドネイティブ AI スイート] ページのコンポーネントリストに ack-ai-installer コンポーネントが表示されます。
クラウドネイティブ AI コンポーネントセット ページで、デプロイ をクリックします。
cGPU の使用
このトピックでは、ecs.gn6i-c4g1.xlarge インスタンス上の 2 つのコンテナが単一の GPU を共有する方法を示します。
cGPU を使用したコンテナの実行
-
次のコマンドを実行してコンテナを作成し、各コンテナから見える GPU メモリを設定します。
この例では、
ALIYUN_COM_GPU_MEM_CONTAINERおよびALIYUN_COM_GPU_MEM_DEV環境変数を設定して、コンテナから見える GPU メモリとデバイスの合計 GPU メモリを指定します。-
gpu_test1:6 GiB の GPU メモリを割り当てます。
sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test1 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=6 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3 -
gpu_test2:8 GiB の GPU メモリを割り当てます。
sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test2 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=8 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
説明このコマンドでは、TensorFlow コンテナイメージ
nvcr.io/nvidia/tensorflow:19.10-py3を例として使用しています。ご自身のコンテナイメージに置き換えてください。TensorFlow イメージを使用して TensorFlow 深層学習フレームワークを構築する方法の詳細については、「ディープラーニング開発のための NGC 環境のデプロイ」をご参照ください。 -
-
次のコマンドを実行して、GPU メモリなどのコンテナの GPU 情報を表示します。
sudo docker exec -i gpu_test1 nvidia-smiたとえば、gpu_test1 コンテナから見える GPU メモリは、次の出力に示すように 6,043 MiB です:
NVIDIA-SMI 440.33.01 Driver Version: 440.33.01 CUDA Version: 10.2 +-----------------------------------------------------------------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |=============================================================================| | 0 Tesla T4 On | 00000000:00:08.0 Off | 0 | | N/A 29C P8 9W / 70W | 0MiB / 6043MiB | 0% Default | +-----------------------------------------------------------------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
procfs ノードを使用した cGPU 情報の表示
cGPU の実行中、/proc/cgpu_km ディレクトリに複数のプロセスファイルシステム (procfs) ノードが生成され、自動的に管理されます。これらの procfs ノードを使用して、cGPU 情報を表示および設定できます。
-
次のコマンドを実行して、procfs ノードに関する情報を表示します。
ls /proc/cgpu_km/次の出力が返されます:
0 default_memsize inst_ctl upgrade version -
次のコマンドを実行して、GPU ディレクトリの内容を表示します。
この例では GPU 0 を使用します。
ls /proc/cgpu_km/0次の出力が返されます:
012b2edccd7a 0852a381c0cf free_weight major max_inst policy prio_ratio -
次のコマンドを実行して、コンテナのディレクトリの内容を表示します。
この例では、コンテナ
012b2edccd7aを使用します。ls /proc/cgpu_km/0/012b2edccd7a次の出力が返されます:
highprio id meminfo memsize weight -
(オプション) 次のコマンドを実行して cGPU を設定します。
procfs ノードを使用して GPU インスタンスでコマンドを実行し、スケジューリングポリシーの切り替え、重みの変更、その他の操作を実行できます。次の表にコマンドの例を示します。
コマンド
効果
echo 2 > /proc/cgpu_km/0/policy
スケジューリングポリシーを重み付けプリエンプティブスケジューリングに切り替えます。
cat /proc/cgpu_km/0/free_weight
GPU 上で利用可能な重みを表示します。
free_weight=0の場合、新しく作成されたコンテナには重み 0 が割り当てられます。コンテナは GPU のコンピューティング能力を取得できません。cat /proc/cgpu_km/0/$dockerid/weight
指定されたコンテナの重みを表示します。
echo 4 > /proc/cgpu_km/0/$dockerid/weight
コンテナのコンピューティング能力の重みを変更します。
cgpu-smi を使用した cGPU コンテナの表示
cgpu-smi を使用して、コンテナ ID、GPU 使用率、コンピューティング能力の制限、使用済み GPU メモリ、割り当てられた合計 GPU メモリなど、cGPU コンテナに関する情報を表示できます。
cgpu-smi は cGPU のモニタリング例です。Kubernetes (k8s) にアプリケーションをデプロイする場合、cgpu-smi ツールを使用して、またはそれを応用してカスタム統合を行うことができます。
| Alibaba Cloud cGPU1.0 cGPU Version: 1.0.2
+---+----------------+----------+----------------+-----------------------+
|GPU| pod | highprio | GPU-Util/Limit | GPU Memory Usage/Total|
+===+================+==========+================+=======================+
| 0| 7db8fff70a0d | 0 | 41/ 50 | 9459/11463 |
| 0| 91b1e19795ee | 0 | 30/ 50 | 9457/11463 |
+---+----------------+----------+----------------+-----------------------+
cGPU のアップグレードまたはアンインストール
cGPU のアップグレード
cGPU は、コールドアップデートとホットアップデートの両方をサポートしています。
-
コールドアップデート
Docker が cGPU を使用していないときにコールドアップデートを実行するには:
-
実行中のすべてのコンテナを停止します:
sudo docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2) -
cGPU を最新バージョンにアップグレードします:
sudo sh upgrade.sh
-
-
ホットアップデート
Docker が cGPU を使用している場合は、cGPU カーネルドライバーのホットアップデートを実行できます。ただし、このアップデート方法はバージョンによる制限があります。サポートが必要な場合は、Alibaba Cloud のアフターサービスサポートチームにお問い合わせください。
cGPU のアンインストール
ノードから以前のバージョンの cGPU をアンインストールするには、「ノードの cGPU バージョンのアップグレード」をご参照ください。
cGPU の使用例
コンピューティング能力のスケジューリング
cGPU が cgpu_km モジュールをロードすると、コンテナの最大数 (max_inst) に基づいて、各 GPU のタイムスライス (ミリ秒単位) を設定します。このトピックでは、これらのタイムスライスをスライス 1、スライス 2、スライス N と呼び、コンテナに GPU のコンピューティング能力を割り当てるために使用されます。以下の例では、さまざまなスケジューリングポリシーを示します。
-
フェアシェアスケジューリング (policy=0)
コンテナを作成すると、cGPU は各コンテナにタイムスライスを割り当てます。スケジューラはスライス 1 から開始し、1 タイムスライス分のタスクを物理 GPU に送信してから、次のタイムスライスに切り替わります。各コンテナは、次の図に示すように、
1/max_instの等しいコンピューティング能力を受け取ります。 -
プリエンプティブスケジューリング (policy=1)
コンテナを作成すると、cGPU はそれらにタイムスライスを割り当てます。スケジューラはスライス 1 から開始します。ただし、コンテナ内のプロセスが GPU にアクセスしていない場合、スケジューラはそのコンテナのタイムスライスをスキップして次に進みます。
例:
-
単一のコンテナ Docker 1 を作成し、スライス 1 が割り当てられます。Docker 1 で 2 つの TensorFlow プロセスを実行すると、コンテナは物理 GPU 全体のコンピューティング能力を使用できます。
-
次に、2 番目のコンテナ Docker 2 を作成し、スライス 2 が割り当てられます。Docker 2 内のプロセスが GPU にアクセスしていない場合、スケジューラはそのタイムスライス (スライス 2) をスキップします。
-
Docker 2 内のプロセスが GPU へのアクセスを開始すると、スライス 1 とスライス 2 の両方がスケジューリング周期に含まれます。次の図に示すように、Docker 1 と Docker 2 はそれぞれ、物理 GPU のコンピューティング能力の最大半分を受け取ることができます。
-
-
重み付けプリエンプティブスケジューリング (policy=2)
コンテナを作成するときに
ALIYUN_COM_GPU_SCHD_WEIGHTを 1 より大きい値に設定すると、cGPU はこのポリシーを自動的に使用します。cGPU は、物理 GPU のコンピューティング能力をmax_inst個の部分に分割します。ALIYUN_COM_GPU_SCHD_WEIGHTが 1 より大きい場合、cGPU は複数のタイムスライスを組み合わせて、そのコンテナ用のより大きなスライスを作成します。設定例:
-
Docker 1:ALIYUN_COM_GPU_SCHD_WEIGHT=m
-
Docker 2:ALIYUN_COM_GPU_SCHD_WEIGHT=n
スケジューリングの動作:
-
Docker 1 のみが実行されている場合、物理 GPU 全体のコンピューティング能力をプリエンプトします。
-
Docker 1 と Docker 2 の両方が実行されている場合、それらは理論的に m:n の比率でコンピューティング能力を受け取ります。プリエンプティブスケジューリングとは異なり、Docker 2 内のプロセスが GPU を使用していなくても、Docker 2 は n 個のタイムスライスを消費します。
説明m:n の比率が 2:1 の場合と 8:4 の場合では、パフォーマンスが異なります。2:1 の場合、1 秒あたりのタイムスライス切り替え回数は 8:4 の場合の 4 倍になります。
重み付けプリエンプティブスケジューリングは、コンテナが使用できる GPU コンピューティング能力に理論上の上限を設定します。ただし、NVIDIA V100 のような強力な GPU の場合、短い計算タスクは単一のタイムスライス内で完了する可能性があります。このシナリオでは、m:n の比率が 8:4 の場合、残りのタイムスライスで GPU はアイドル状態になり、制限は効果がなくなります。
-
-
固定スケジューリング (policy=3)
ALIYUN_COM_GPU_SCHD_WEIGHTとmax_instの比率を指定することで、固定された割合のコンピューティング能力を割り当てることができます。 -
ソフトスケジューリング (policy=4)
コンテナを作成すると、cGPU はそれらにタイムスライスを割り当てます。このポリシーは、プリエンプティブスケジューリングよりも弱い隔離を提供します。詳細については、「プリエンプティブスケジューリング (policy=1)」をご参照ください。
-
ネイティブスケジューリング (policy=5)
このポリシーは GPU メモリのみを隔離し、NVIDIA GPU ドライバーのネイティブスケジューリングメソッドに依存します。
コンピューティング能力のスケジューリングポリシーは、Tesla P4、Tesla P100、Tesla T4、Tesla V100、Tesla A10、 を含む、すべての Alibaba Cloud のヘテロジニアス GPU インスタンスとその NVIDIA GPU をサポートしています。以下のテストでは、Tesla A10 GPU を搭載した単一 GPU インスタンスを共有する 2 つのコンテナを使用します。コンテナ間のコンピューティング能力の比率は 1:2 で、GPU メモリは均等に分割され、各コンテナは 12 GB を受け取ります。
以下の性能テストの結果はラボ環境のものであり、参考用です。
-
テスト 1:さまざまな
batch_size値で FP16 精度を使用して TensorFlow フレームワークでトレーニングされた ResNet50 モデルのパフォーマンスを比較します。結果は以下のとおりです:フレームワーク
モデル
batch_size
精度
イメージ/秒 (Docker 1)
イメージ/秒 (Docker 2)
TensorFlow
ResNet50
16
FP16
151
307
TensorFlow
ResNet50
32
FP16
204
418
TensorFlow
ResNet50
64
FP16
247
503
TensorFlow
ResNet50
128
FP16
257
516

-
テスト 2:さまざまな
batch_size値で FP16 精度を使用して TensorRT フレームワークでトレーニングされた ResNet50 モデルのパフォーマンスを比較します。結果は以下のとおりです:フレームワーク
モデル
batch_size
精度
イメージ/秒 (Docker 1)
イメージ/秒 (Docker 2)
TensorRT
ResNet50
1
FP16
568.05
1132.08
TensorRT
ResNet50
2
FP16
940.36
1884.12
TensorRT
ResNet50
4
FP16
1304.03
2571.91
TensorRT
ResNet50
8
FP16
1586.87
3055.66
TensorRT
ResNet50
16
FP16
1783.91
3381.72
TensorRT
ResNet50
32
FP16
1989.28
3695.88
TensorRT
ResNet50
64
FP16
2105.81
3889.35
TensorRT
ResNet50
128
FP16
2205.25
3901.94

マルチ GPU メモリパーティショニング
この例では、4 つの GPU にまたがってメモリをパーティショニングする方法を示します。GPU 0 に 3 GB、GPU 1 に 4 GB、GPU 2 に 5 GB、GPU 3 に 6 GB を割り当てます。サンプルコードは次のとおりです:
docker run -d -t --runtime=nvidia --name gpu_test0123 --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6 -e ALIYUN_COM_GPU_MEM_DEV=23 -e NVIDIA_VISIBLE_DEVICES=0,1,2,3 nvcr.io/nvidia/tensorflow:21.03-tf1-py3
docker exec -i gpu_test0123 nvidia-smi
コマンドの出力には、4 つの GPU のメモリ詳細が表示されます。
NVIDIA-SMI 510.39 Driver Version: 510.39 CUDA Version: 11.6
-------------------------------+----------------------+----------------------+
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 NVIDIA A10 On | 00000000:61:00.0 Off | 0 |
0% 31C P8 15W / 150W | 0MiB / 3003MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
1 NVIDIA A10 On | 00000000:6B:00.0 Off | 0 |
0% 31C P8 16W / 150W | 0MiB / 4004MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
2 NVIDIA A10 On | 00000000:CA:00.0 Off | 0 |
0% 30C P8 15W / 150W | 0MiB / 5006MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
3 NVIDIA A10 On | 00000000:E3:00.0 Off | 0 |
0% 31C P8 16W / 150W | 0MiB / 6007MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
次の表では、マルチ GPU 構成における ALIYUN_COM_GPU_MEM_CONTAINER パラメーターについて説明します。
|
値 |
説明 |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3 |
4 つすべての GPU の GPU メモリを 3 GB に設定します。 |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3,1 |
4 つの GPU の GPU メモリをそれぞれ 3 GB、1 GB、1 GB、1 GB に設定します。 |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6 |
4 つの GPU の GPU メモリをそれぞれ 3 GB、4 GB、5 GB、6 GB に設定します。 |
|
ALIYUN_COM_GPU_MEM_CONTAINER が指定されていない |
cGPU を無効にします。 |
|
ALIYUN_COM_GPU_MEM_CONTAINER=0 |
|
|
ALIYUN_COM_GPU_MEM_CONTAINER=1,0,0 |