このトピックでは、GPU共有機能を使用して、Container Service for Kubernetes (ACK) LingjunマネージドクラスターのLingjunノード上のGPUリソースをスケジュールおよび分離する方法について説明します。
前提条件
ACK Lingjun管理クラスターが作成され、クラスターにはGPUアクセラレーションLingjunノードが含まれます。 詳細については、「ACKを有効にしたLingjunクラスターの作成」をご参照ください。
デフォルトでは、GPU共有コンポーネントはACK Lingjun管理クラスターにインストールされます。 GPU高速化ノードに特定のラベルを追加して、GPU共有を有効にすることができます。 詳細については、「GPUスケジューリングポリシーを有効にするためのラベル」をご参照ください。
GPU共有の操作
GPU共有は、次のシナリオで適用できます。
GPUメモリ分離なしでGPU共有を有効にする: このシナリオでは、複数のポッドが同じGPUを共有でき、ポッドに割り当てられたGPUメモリは他のポッドに割り当てられたGPUメモリから分離されません。 この場合、GPUメモリ競合は、上位層アプリケーションによって対処されないか、または対処され得る。
GPUメモリ分離によるGPU共有の有効化: このシナリオでは、複数のポッドが同じGPUを共有できますが、ポッドに割り当てられたGPUメモリは他のポッドに割り当てられたGPUメモリから分離されます。 これは、ポッド間のGPUメモリ競合に対処します。
シナリオ1: GPUメモリ分離によるGPU共有の有効化
一部のシナリオでは、GPUメモリ分離なしでGPU共有が必要になる場合があります。 一部のワークロードはGPUメモリ分離を提供します。 たとえば、Javaアプリケーションを起動するときに、Javaオプションを設定して、アプリケーションが使用できるGPUメモリの最大量を指定できます。 この場合、GPU分離モジュールをインストールすると、リソースの競合が発生する可能性があります。 この問題を回避するには、一部のノードにGPU分離モジュールをインストールせずにGPU共有を有効にします。
ステップ1: ノードのGPU共有を有効にする
ノードに
/etc/lingjun_metadataファイルが存在するかどうかを確認します。ファイルが存在する場合は、
nvidia-smiコマンドを実行します。 出力が返された場合、ノードはLingjunノードです。 次のステップに進むことができます。ファイルが存在しない場合、ノードはLingjunノードではありません。 ノードのGPU共有を有効にすることはできません。 この場合、GPU共有を有効にするには、Lingjunノードを作成する必要があります。 詳細については、「Lingjunノードプールの概要」をご参照ください。
次のコマンドを実行して
ack.node.gpu.scheduleラベルをノードに追加し、GPU共有を有効にします。
kubectl label node <NODE_NAME> ack.node.gpu.schedule=shareステップ2: 共有GPUリソースを使用する
tensorflow.yamlという名前のファイルを作成し、次のコードブロックをファイルにコピーします。apiVersion: batch/v1 kind: Job metadata: name: tensorflow-mnist-share spec: parallelism: 1 template: metadata: labels: app: tensorflow-mnist-share spec: # The YAML template specifies a job that uses a TensorFlow MNIST dataset. The job creates one pod and the pod requests 4 GiB of GPU memory. containers: - name: tensorflow-mnist-share image: registry.cn-beijing.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5 command: - python - tensorflow-sample-code/tfjob/docker/mnist/main.py - --max_steps=100000 - --data_dir=tensorflow-sample-code/data resources: # If you want the pod to request 4 GiB of GPU memory, specify aliyun.com/gpu-mem: 4 in the resources.limits parameter of the pod configurations. limits: aliyun.com/gpu-mem: 4 # The pod requests 4 GiB of GPU memory. workingDir: /root restartPolicy: Never次のコマンドを実行して、ジョブを送信します。
kubectl apply -f tensorflow.yaml
ステップ3: GPUメモリ分離なしでGPU共有を検証する
ジョブによって作成されたポッドを照会し、次のコマンドを実行します。
kubectl get pod | grep tensorflow
kubectl exec -ti tensorflow-mnist-share-xxxxx -- nvidia-smi期待される出力:
Wed Jun 14 06:45:56 2023
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 515.105.01 Driver Version: 515.105.01 CUDA Version: 11.7 |
|-------------------------------+----------------------+----------------------+
| 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 V100-SXM2... On | 00000000:00:09.0 Off | 0 |
| N/A 35C P0 59W / 300W | 334MiB / 16384MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
+-----------------------------------------------------------------------------+出力は、ポッドがGPUによって提供されるすべてのメモリ (サイズは16,384 MiB) を使用できることを示します。 つまり、GPU共有はGPUメモリ分離なしで実装されます。 GPU分離モジュールがインストールされている場合、出力に表示されるメモリサイズは、ポッドによって要求されたメモリの量に等しくなります。
この例では、V100 GPUが使用され、ポッドによって4 GiBのGPUメモリが要求されます。 実際の設定は環境によって異なります。
ポッドは、次の環境変数に基づいて、使用できるGPUメモリの量を決定します。
ALIYUN_COM_GPU_MEM_CONTAINER=4 # The GPU memory available for the pod.
ALIYUN_COM_GPU_MEM_DEV=16 # The memory size of each GPU. ポッドが使用できるGPUメモリとGPUメモリの合計の比率を計算するには、次の式を使用します。
percetange = ALIYUN_COM_GPU_MEM_CONTAINER / ALIYUN_COM_GPU_MEM_DEV = 4 / 16 = 0.25シナリオ2: GPUメモリ分離でGPU共有を有効にする
コンテナの安定性を確保するには、各コンテナに割り当てられているGPUリソースを分離する必要があります。 1つのGPUで複数のコンテナを実行すると、要求に応じて各コンテナにGPUリソースが割り当てられます。 ただし、1つのコンテナが過剰なGPUリソースを占有すると、他のコンテナのパフォーマンスに影響を与える可能性があります。 この問題を解決するために、コンピューティング業界では多くのソリューションが提供されています。 たとえば、NVIDIA vGPU、マルチプロセスサービス (MPS) 、vCUDA、およびeGPUを使用すると、GPUのきめ細かい共有が可能になります。 次のセクションでは、eGPUの使用方法について説明します。
ステップ1: ノードのGPU共有を有効にする
ノードに
/etc/lingjun_metadataファイルが存在するかどうかを確認します。ファイルが存在する場合は、
nvidia-smiコマンドを実行します。 出力が返された場合、ノードはLingjunノードです。 次のステップに進むことができます。ファイルが存在しない場合、ノードはLingjunノードではありません。 ノードのGPU共有を有効にすることはできません。 この場合、GPU共有を有効にするには、Lingjunノードを作成する必要があります。 詳細については、「Lingjunノードプールの概要」をご参照ください。
次のコマンドを実行して
ack.node.gpu.scheduleラベルをノードに追加し、GPU共有を有効にします。kubectl label node <NODE_NAME> ack.node.gpu.schedule=egpu_mem
ラベルの値をegpu_memに設定すると、GPUメモリ分離のみが有効になります。 上記の例では、ラベルの値はegpu_memに設定されています。
ラベルの値をegpu_core_memに設定すると、GPUメモリの分離とコンピューティング電力の分離の両方が有効になります。
GPUメモリと一緒にGPUコンピューティングパワーを要求する必要があります。 GPUメモリのみを個別にリクエストできます。
ステップ2: 共有GPUリソースを使用する
GPU情報がノードによって報告されるまで待ちます。
次のコマンドを実行して、ノードによって提供されるリソースを照会します。
kubectl get node <NODE_NAME> -oyaml期待される出力:
allocatable:
aliyun.com/gpu-count: "1"
aliyun.com/gpu-mem: "80"
...
nvidia.com/gpu: "0"
...
capacity:
aliyun.com/gpu-count: "1"
aliyun.com/gpu-mem: "80
...
nvidia.com/gpu: "0"
...出力は、aliyun.com/gpu-memリソースが使用可能であり、ノードが1 GPUに80 GBのメモリを提供することを示します。
GPU全体をポッドに割り当てる場合は、ack.gpushare.placement=require-whole-deviceラベルをポッドに追加し、必要なGPUメモリ量をgpu-memで指定します。 次に、要求された量のGPUメモリを提供できるGPUがポッドに自動的に割り当てられます。
ステップ3: ジョブを実行してGPU共有を確認する
次のYAMLファイルを使用して、ベンチマーキングジョブを送信します。
apiVersion: batch/v1 kind: Job metadata: name: benchmark-job spec: parallelism: 1 template: spec: containers: - name: benchmark-job image: registry.cn-beijing.aliyuncs.com/ai-samples/gpushare-sample:benchmark-tensorflow-2.2.3 command: - bash - run.sh - --num_batches=500000000 - --batch_size=8 resources: limits: aliyun.com/gpu-mem: 10 # The job requests 10 GB of memory. workingDir: /root restartPolicy: Never hostNetwork: true tolerations: - operator: Exists次のコマンドを実行して、ジョブを送信します。
kubectl apply -f benchmark.yamlポッドの実行後、次のコマンドを実行してポッドにアクセスします。
kubectl exec -ti benchmark-job-xxxx bashポッドで次のコマンドを実行して、GPU分離情報を照会します。
vgpu-smi期待される出力:
+------------------------------------------------------------------------------+ | VGPU_SMI 460.91.03 DRIVER_VERSION: 460.91.03 CUDA Version: 11.2 | +-------------------------------------------+----------------------------------+ | GPU Name Bus-Id | Memory-Usage GPU-Util | |===========================================+==================================| | 0 xxxxxxxx 00000000:00:07.0 | 8307MiB / 10782MiB 100% / 100% | +-------------------------------------------+----------------------------------+出力は、10 GBのGPUメモリがポッドに割り当てられていることを示します。
よくある質問
GPU共有コンポーネントがクラスターにインストールされているかどうかを確認するにはどうすればよいですか。
次のコマンドを実行して、eGPUベースのGPU共有コンポーネントがインストールされているかどうかを確認します。
kubectl get ds -nkube-system | grep gpushare期待される出力:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
gpushare-egpu-device-plugin-ds 0 0 0 0 0 <none>
gpushare-egpucore-device-plugin-ds 0 0 0 0 0 <none>出力は、GPU共有コンポーネントがインストールされていることを示します。