本文介紹如何在ACK靈駿託管版叢集中的靈駿節點上使用共用GPU調度,實現GPU的共用和隔離能力。
前提條件
已建立ACK靈駿託管版叢集,並且叢集帶有GPU的靈駿節點。具體操作,請參見建立帶有ACK靈駿託管版的叢集。
ACK靈駿託管版叢集預設會安裝共用GPU調度組件,您可以在ACK靈駿託管叢集中通過給GPU節點打上共用GPU調度的標籤開啟節點共用GPU調度能力。相關資訊,請參見GPU節點調度屬性標籤說明。
使用共用GPU調度
對於使用共用GPU調度,一般分為如下兩種情境:
僅共用不隔離:允許多個Pod共同運行在同一塊GPU上,並不處理(或交由上層應用處理)這塊GPU卡上多個Pod之間相互影響的問題,例如爭搶GPU顯存資源等情況。
既共用又隔離:允許多個Pod運行在同一塊GPU上,同時也處理這塊GPU卡上多個Pod相互影響的問題。
情境1:僅共用不隔離
在部分情境中,不需要GPU隔離模組參與共用GPU調度。有些業務應用本身提供顯存限制能力,例如Java應用啟動時,可以通過選項指定該應用的最大記憶體使用量量。這種情況下,使用GPU隔離模組隔離業務顯存會有資源衝突等問題。因此,共用GPU調度支援某些節點不安裝GPU隔離模組的選項。
步驟一:開啟節點GPU共用調度能力
尋找
/etc/lingjun_metadata
檔案是否存在。如果檔案存在,然後執行命令
nvidia-smi
,如果輸出正常,表明該節點為預期開啟共用GPU調度能力的靈駿節點,可繼續執行下一步。如果檔案不存在,表明預期開啟共用GPU調度能力的節點不是靈駿節點,因此此節點無法開啟GPU共用調度能力。如果需要開啟GPU共用調度能力,請建立靈駿節點。具體操作,請參見靈駿節點池概述。
執行如下命令,通過給節點設定標籤
ack.node.gpu.schedule
為節點開啟共用GPU調度能力。
kubectl label node <NODE_NAME> ack.node.gpu.schedule=share
步驟二:使用GPU共用資源
使用以下樣本建立
tensorflow.yaml
檔案。apiVersion: batch/v1 kind: Job metadata: name: tensorflow-mnist-share spec: parallelism: 1 template: metadata: labels: app: tensorflow-mnist-share spec: # 該YAML定義了一個使用tensorflow mnist範例的Job。Job有1個Pod,該Pod申請4 GiB顯存。 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: # Pod申請4 GiB顯存通過在Pod resources.limits定義aliyun.com/gpu-mem: 4實現。 limits: aliyun.com/gpu-mem: 4 # 總共申請4 GiB顯存。 workingDir: /root restartPolicy: Never
執行如下命令,提交任務。
kubectl apply -f tensorflow.yaml
步驟三:驗證僅共用不隔離能力
找到前一步建立Job的Pod,使用kubectl執行如下命令。
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 |
|=============================================================================|
+-----------------------------------------------------------------------------+
Pod內部能夠發現整塊GPU卡的總顯存為16384 MiB,而在有隔離模組參與的情境下,該值與Pod申請值一致,說明配置生效。
本樣本中使用的GPU卡型號為V100,Pod顯存申請值為4 GiB,實際資料以您的作業環境為準。
業務應用需要從兩個環境變數中讀取該業務能夠使用的顯存值。
ALIYUN_COM_GPU_MEM_CONTAINER=4 # 該Pod能夠使用的顯存值。
ALIYUN_COM_GPU_MEM_DEV=16 # 每塊GPU卡總共的顯存值。
如果需要的是該應用使用的顯存占GPU卡總顯存的百分比。可以使用上述兩個環境變數得出。
percetange = ALIYUN_COM_GPU_MEM_CONTAINER / ALIYUN_COM_GPU_MEM_DEV = 4 / 16 = 0.25
情境2:既共用又隔離
在多個Pod共用一塊GPU前提下,隔離是一個關鍵的需求。如何限制運行在同一個GPU上的多個容器能夠按照自己申請的資源使用量運行,避免因為其資源用量超標影響同一個GPU上的其他容器的正常工作,對此業界也做了很多探索。NVIDIA vGPU、MPS和vCUDA、eGPU等方案,都為更小顆粒度的使用GPU提供了可能,下面以eGPU隔離模組為例進行說明。
步驟一:開啟節點GPU共用調度能力
尋找
/etc/lingjun_metadata
檔案是否存在。如果檔案存在,然後執行命令
nvidia-smi
,如果輸出正常,表明該節點為預期開啟共用GPU調度能力的靈駿節點,可繼續執行下一步。如果檔案不存在,表明預期開啟共用GPU調度能力的節點不是靈駿節點,因此此節點無法開啟GPU共用調度能力。如果需要開啟GPU共用調度能力,請建立靈駿節點。具體操作,請參見靈駿節點池概述。
執行如下命令,通過給節點設定標籤
ack.node.gpu.schedule
為節點開啟共用GPU調度能力。kubectl label node <NODE_NAME> ack.node.gpu.schedule=egpu_mem
如果標籤的Value為egpu_mem,表示只進行GPU顯存隔離。本文以該標籤為例。
如果標籤的Value設定為egpu_core_mem,表示進行GPU顯存和算力雙隔離。
您可以只申請GPU顯存資源,但是如果要申請GPU算力資源,則需要同時申請GPU顯存資源和GPU算力資源。
步驟二:使用GPU共用資源
等待節點將共用GPU的資源上報結束。
執行如下命令,查看Node資源資訊。
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卡,80G顯存。
如果Pod需要調度並使用整卡資源,則需要在目標Pod上增加標籤ack.gpushare.placement=require-whole-device
,然後指定需要使用的GPU顯存數量gpu-mem
,則該Pod會被預設調度到擁有該數量顯存的整塊GPU上。
步驟三:運行共用GPU樣本
使用如下YAML提交Benchmark任務。
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 # 申請10G顯存。 workingDir: /root restartPolicy: Never hostNetwork: true tolerations: - operator: Exists
執行如下命令,提交任務。
kubectl apply -f benchmark.yaml
等待Pod運行起來後,請使用如下命令進入Pod。
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% | +-------------------------------------------+----------------------------------+
預期輸出表明,Pod容器被分配了10 GB的顯存。
常見問題
如何查看是否已安裝共用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組件已安裝。