本文介紹如何在ACK託管叢集Pro版的靈駿節點池中使用共用GPU調度,實現GPU的共用和隔離能力。
適用範圍
靈駿節點池的共用GPU調度功能僅針對以下節點標籤生效:
ack.node.gpu.schedule=share:僅共用不隔離。ack.node.gpu.schedule=egpu_mem:既共用又隔離,且僅進行GPU顯存隔離。ack.node.gpu.schedule=egpu_core_mem:既共用又隔離,且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也可通過控制台的節點標籤(Labels)功能為節點設定標籤。
步驟二:使用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 get pod | grep tensorflow執行
nvidia-smi命令驗證僅共用不隔離能力。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也可通過控制台的節點標籤(Labels)功能為節點設定標籤。
如果標籤的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組件已安裝。