全部產品
Search
文件中心

Container Service for Kubernetes:使用共用GPU調度

更新時間:Jun 19, 2024

本文介紹如何在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共用調度能力

  1. 尋找/etc/lingjun_metadata檔案是否存在。

    • 如果檔案存在,然後執行命令nvidia-smi,如果輸出正常,表明該節點為預期開啟共用GPU調度能力的靈駿節點,可繼續執行下一步。

    • 如果檔案不存在,表明預期開啟共用GPU調度能力的節點不是靈駿節點,因此此節點無法開啟GPU共用調度能力。如果需要開啟GPU共用調度能力,請建立靈駿節點。具體操作,請參見靈駿節點池概述

  2. 執行如下命令,通過給節點設定標籤ack.node.gpu.schedule為節點開啟共用GPU調度能力。

    kubectl label node <NODE_NAME> ack.node.gpu.schedule=share

步驟二:使用GPU共用資源

  1. 使用以下樣本建立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
  2. 執行如下命令,提交任務。

    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共用調度能力

  1. 尋找/etc/lingjun_metadata檔案是否存在。

    • 如果檔案存在,然後執行命令nvidia-smi,如果輸出正常,表明該節點為預期開啟共用GPU調度能力的靈駿節點,可繼續執行下一步。

    • 如果檔案不存在,表明預期開啟共用GPU調度能力的節點不是靈駿節點,因此此節點無法開啟GPU共用調度能力。如果需要開啟GPU共用調度能力,請建立靈駿節點。具體操作,請參見靈駿節點池概述

  2. 執行如下命令,通過給節點設定標籤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共用資源

  1. 等待節點將共用GPU的資源上報結束。

  2. 執行如下命令,查看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樣本

  1. 使用如下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
  2. 執行如下命令,提交任務。

    kubectl apply -f benchmark.yaml
  3. 等待Pod運行起來後,請使用如下命令進入Pod。

    kubectl exec -ti benchmark-job-xxxx bash
  4. 在容器中執行如下命令,查看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組件已安裝。