使用 NVIDIA MPS 與多個工作負載共用 GPU


本頁面說明如何使用 CUDA Multi-Process Service (MPS),讓多個工作負載共用 Google Kubernetes Engine (GKE) 節點中的單一 NVIDIA GPU 硬體加速器。

總覽

NVIDIA MPS 是一種 GPU 共用解決方案,可讓多個容器共用節點上連接的單一實體 NVIDIA GPU 硬體。

NVIDIA MPS 依賴 CUDA 上的 NVIDIA 多程序服務。NVIDIA MPS 是 CUDA API 的替代方案,與二進位檔相容,可讓多程序 CUDA 應用程式同時在單一 GPU 裝置上執行,且過程完全透明。

透過 NVIDIA MPS,您可以指定實體 GPU 的共用容器數量上限。這個值會決定每個容器可獲得多少實體 GPU 效能,計算依據是下列特徵:

如要進一步瞭解如何使用 NVIDIA MPS 排程 GPU,以及何時應使用 CUDA MPS,請參閱「關於 GKE 中的 GPU 共用解決方案」。

本指南適用對象

如果您屬於下列任一類別,請按照本節的操作說明進行:

  • 平台管理員:建立及管理 GKE 叢集、規劃基礎架構和資源需求,以及監控叢集效能。
  • 應用程式開發人員:在 GKE 叢集上設計及部署工作負載。如需如何使用 GPU 要求 NVIDIA MPS 的操作說明,請參閱「使用 GPU 部署採用 NVIDIA MPS 的工作負載」。

需求條件

  • GKE 版本:您可以在執行 GKE 1.27.7-gke.1088000 以上版本的 GKE Standard 叢集上,透過 NVIDIA MPS 啟用 GPU 共用功能。
  • GPU 類型:您可以為所有 NVIDIA GPU 類型啟用 NVIDIA MPS。

事前準備

開始之前,請確認您已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

在 GKE 叢集上啟用 NVIDIA MPS 和 GPU

平台管理員必須在 GKE 標準叢集上,透過 GPU 啟用 NVIDIA MPS。然後,應用程式開發人員可以部署工作負載,搭配 GPU 使用 NVIDIA MPS。如要在 GKE 上啟用 NVIDIA MPS 和 GPU,請按照下列步驟操作:

  1. 在新 GKE 叢集上啟用 NVIDIA MPS 和 GPU
  2. 安裝 NVIDIA GPU 裝置驅動程式 (如有需要)
  3. 確認節點上可用的 GPU 資源

在 GKE 叢集上啟用 NVIDIA MPS 和 GPU

建立 GKE Standard 叢集時,可以啟用具備 GPU 的 NVIDIA MPS。叢集中的預設節點集區已啟用這項功能。在該叢集中手動建立新的節點集區時,您仍需啟用 NVIDIA MPS 和 GPU。

使用 Google Cloud CLI 建立啟用 NVIDIA MPS 的叢集:

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --cluster-version=CLUSTER_VERSION \
    --machine-type=MACHINE_TYPE \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=mps,max-shared-clients-per-gpu=CLIENTS_PER_GPU,gpu-driver-version=DRIVER_VERSION

更改下列內容:

  • CLUSTER_NAME:新叢集的名稱。
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。為地區叢集提供地區,或為區域叢集提供區域。 所用 GPU 類型必須在所選區域可用
  • CLUSTER_VERSION:叢集控制層和節點的 GKE 版本。使用 GKE 1.27.7-gke.1088000 以上版本。或者,您也可以使用 --release-channel=RELEASE_CHANNEL 標記,指定包含該 GKE 版本的發布管道
  • MACHINE_TYPE:節點的 Compute Engine 機器類型。
  • GPU_TYPE:GPU 類型,必須是 NVIDIA GPU 平台,例如 nvidia-tesla-v100
  • GPU_QUANTITY:要附加至預設節點集區中每個節點的實體 GPU 數量。
  • CLIENTS_PER_GPU:可共用每個實體 GPU 的容器數量上限。
  • DRIVER_VERSION:要安裝的 NVIDIA 驅動程式版本。可以是下列任一值:
    • default:安裝 GKE 版本的預設驅動程式版本。
    • latest:為 GKE 版本安裝最新可用的驅動程式版本。僅適用於使用 Container-Optimized OS 的節點。
    • disabled:略過自動安裝驅動程式。建立節點集區後,您必須 手動安裝驅動程式。如果省略 gpu-driver-version,系統會預設使用這個選項。

在新節點集區中啟用 NVIDIA MPS 和 GPU

在 GKE 叢集中手動建立新的節點集區時,可以啟用 NVIDIA MPS 和 GPU。使用 Google Cloud CLI 建立啟用 NVIDIA MPS 的節點集區:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --machine-type=MACHINE_TYPE \
    --location=CONTROL_PLANE_LOCATION \
    --accelerator=type=GPU_TYPE,count=GPU_QUANTITY,gpu-sharing-strategy=mps,max-shared-clients-per-gpu=CONTAINER_PER_GPU,gpu-driver-version=DRIVER_VERSION

更改下列內容:

  • NODEPOOL_NAME:新節點集區的名稱。
  • :叢集名稱,必須執行 GKE 1.27.7-gke.1088000 以上版本。CLUSTER_NAME
  • CONTROL_PLANE_LOCATION:叢集控制層的 Compute Engine 位置。為地區叢集提供地區,或為區域叢集提供區域。
  • MACHINE_TYPE:節點的 Compute Engine 機器類型。如要使用 A100 GPU,請使用 A2 機器類型。如要使用其他 GPU,請使用 N1 機器類型
  • GPU_TYPE:GPU 類型,必須是 NVIDIA GPU 平台,例如 nvidia-tesla-v100
  • GPU_QUANTITY:要附加至節點集區中每個節點的實體 GPU 數量。
  • CONTAINER_PER_GPU:可共用每個實體 GPU 的容器數量上限。
  • DRIVER_VERSION:要安裝的 NVIDIA 驅動程式版本。可以是下列任一值:

    • default:安裝 GKE 版本的預設驅動程式版本。
    • latest:為 GKE 版本安裝最新可用的驅動程式版本。僅適用於使用 Container-Optimized OS 的節點。
    • disabled:略過自動安裝驅動程式。建立節點集區後,您必須 手動安裝驅動程式。如果省略 gpu-driver-version,系統會預設使用這個選項。

安裝 NVIDIA GPU 裝置驅動程式

如果在建立叢集時選擇停用自動安裝驅動程式,或是使用 1.27.2-gke.1200 之前的 GKE 版本,則必須手動安裝相容的 NVIDIA 驅動程式,才能管理實體 GPU 的 NVIDIA MPS 分割。如要安裝驅動程式,請部署 GKE 安裝 DaemonSet,設定驅動程式。

如需操作說明,請參閱「安裝 NVIDIA GPU 裝置驅動程式」。

確認可用的 GPU 資源

您可以確認節點中的 GPU 數量是否與啟用 NVIDIA MPS 時指定的數量相符。您也可以確認 NVIDIA MPS 控制精靈是否正在執行。

確認節點上可用的 GPU 資源

如要確認節點上可用的 GPU 資源,請執行下列指令:

kubectl describe nodes NODE_NAME

NODE_NAME 替換為節點名稱。

輸出結果會與下列內容相似:

...
Capacity:
  ...
  nvidia.com/gpu:             3
Allocatable:
  ...
  nvidia.com/gpu:             3

在這個輸出內容中,節點上的 GPU 資源數量為 3,原因如下:

  • max-shared-clients-per-gpu 中的值為 3
  • 要附加至節點的實體 GPU 數量為 1count如果實體 GPU 的 count2,輸出內容會顯示 6 可分配的 GPU 資源,每個實體 GPU 上有三個。

確認 MPS 控制常駐程式正在執行

GPU 裝置外掛程式會對 MPS 控制常駐程式執行健康狀態檢查。MPS 控制項 Daemon 正常運作時,您就可以部署容器。

如要確認 MPS 狀態,請執行下列指令:

kubectl logs -l k8s-app=nvidia-gpu-device-plugin -n kube-system --tail=100 | grep MPS

輸出結果會與下列內容相似:

I1118 08:08:41.732875       1 nvidia_gpu.go:75] device-plugin started
...
I1110 18:57:54.224832       1 manager.go:285] MPS is healthy, active thread percentage = 100.0
...

輸出內容可能會顯示下列事件:

  • failed to start GPU device manager 錯誤發生在 MPS is healthy 錯誤之前。這是暫時性錯誤。如果看到 MPS is healthy 訊息,表示控制項精靈正在執行。
  • active thread percentage = 100.0 訊息表示整個實體 GPU 資源都有完全作用中的執行緒。

部署使用 MPS 的工作負載

應用程式運算子部署 GPU 工作負載時,可以指示 GKE 在同一部實體 GPU 中共用 MPS 共用單元。在下列資訊清單中,您要求一個實體 GPU 並設定 max-shared-clients-per-gpu=3。實體 GPU 會取得三個 MPS 共用單元,並啟動 nvidia/samples:nbody Job,其中包含三個平行執行的 Pod (容器)。

  1. 將資訊清單儲存為 gpu-mps.yaml

      apiVersion: batch/v1
      kind: Job
      metadata:
        name: nbody-sample
      spec:
        completions: 3
        parallelism: 3
        template:
          spec:
            hostIPC: true
            nodeSelector:
              cloud.google.com/gke-gpu-sharing-strategy: mps
            containers:
              - name: nbody-sample
                image: nvidia/samples:nbody
                command: ["/tmp/nbody"]
                args: ["-benchmark", "-i=5000"]
                resources:
                  limits:
                    nvidia.com/gpu: 1
            restartPolicy: "Never"
        backoffLimit: 1
    

    在這個資訊清單中:

    • hostIPC: true 可讓 Pod 與 MPS 控制項精靈通訊。這是必填欄位。不過,請注意,hostIPC: true 設定允許容器存取主機資源,因此會帶來安全風險。
    • 基準測試模式會執行 5,000 次疊代。
  2. 套用資訊清單:

    kubectl apply -f gpu-mps.yaml
    
  3. 確認所有 Pod 都在執行中:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                           READY   STATUS    RESTARTS   AGE
    nbody-sample-6948ff4484-54p6q   1/1     Running   0          2m6s
    nbody-sample-6948ff4484-5qs6n   1/1     Running   0          2m6s
    nbody-sample-6948ff4484-5zpdc   1/1     Running   0          2m5s
    
  4. 查看 Pod 的記錄檔,確認工作已完成:

    kubectl logs -l job-name=nbody-sample -f
    

    輸出結果會與下列內容相似:

    ...
    > Compute 8.9 CUDA device: [NVIDIA L4]
    18432 bodies, total time for 5000 iterations: 9907.976 ms
    = 171.447 billion interactions per second
    = 3428.941 single-precision GFLOP/s at 20 flops per interaction
    ...
    

    由於 GKE 會執行 50,000 次疊代,記錄可能需要幾分鐘才會顯示。

清除所用資源

執行下列指令,刪除 Job 和所有 Pod:

kubectl delete job --all

使用 NVIDIA MPS 限制釘選的裝置記憶體和作用中執行緒

根據預設,在 GKE 上使用 GPU 和 NVIDIA MPS 時,系統會將下列 CUDA 環境變數注入 GPU 工作負載:

  • CUDA_MPS_ACTIVE_THREAD_PERCENTAGE:這個變數表示每個 MPS 共用單元可使用的可用執行緒百分比。根據預設,GPU 的每個 MPS 共用單元都會設為 100 / MaxSharedClientsPerGPU,以取得同等比例的 GPU 運算資源 (以串流多處理器為準)。
  • CUDA_MPS_PINNED_DEVICE_MEM_LIMIT:這個變數會限制 GPU 的 MPS 共用單元可分配的 GPU 記憶體量。根據預設,GPU 的每個 MPS 共用單元都會設為 total mem / MaxSharedClientsPerGPU,以取得 GPU 記憶體的相等切片。

如要為 GPU 工作負載設定資源限制,請設定下列 NVIDIA MPS 環境變數:

  1. 查看並建構 GitHub 上的 cuda-mps 範例圖片

  2. 將下列資訊清單儲存為 cuda-mem-and-sm-count.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: cuda-mem-and-sm-count
    spec:
      hostIPC: true
      nodeSelector:
        cloud.google.com/gke-gpu-sharing-strategy: mps
      containers:
        - name: cuda-mem-and-sm-count
          image: CUDA_MPS_IMAGE
          securityContext:
            privileged: true
          resources:
            limits:
              nvidia.com/gpu: 1
    

    CUDA_MPS_IMAGE 替換為您為 cuda-mps 範例建構的映像檔名稱。

    NVIDIA MPS 要求您在 Pod 上設定 hostIPC:truehostIPC:true 設定可讓容器存取主機資源,這會帶來安全風險。

  3. 套用資訊清單:

    kubectl apply -f cuda-mem-and-sm-count.yaml
    
  4. 檢查這個 Pod 的記錄:

    kubectl logs cuda-mem-and-sm-count
    

    在搭配 gpu-sharing-strategy=mpsmax-shared-clients-per-gpu=3 使用 NVIDIA Tesla L4 的範例中,輸出內容與下列類似:

    For device 0:  Free memory: 7607 M, Total memory: 22491 M
    For device 0:  multiProcessorCount: 18
    

    在本範例中,NVIDIA Tesla L4 GPU 具有 60 個 SM 數和 24 GB 記憶體。每個 MPS 分享單元大約可取得 33% 的作用中執行緒和 8 GB 的記憶體。

  5. 更新資訊清單,要求 2 個 nvidia.com/gpu

      resources:
            limits:
              nvidia.com/gpu: 2
    

    輸出結果會與下列內容相似:

    For device 0:  Free memory: 15230 M, Total memory: 22491 M
    For device 0:  multiProcessorCount: 38
    
  6. 更新資訊清單,覆寫 CUDA_MPS_ACTIVE_THREAD_PERCENTAGECUDA_MPS_PINNED_DEVICE_MEM_LIMIT 變數:

      env:
        - name: CUDA_MPS_ACTIVE_THREAD_PERCENTAGE
          value: "20"
        - name: CUDA_MPS_PINNED_DEVICE_MEM_LIMIT
          value: "0=8000M"
    

    輸出結果會與下列內容相似:

    For device 0:  Free memory: 7952 M, Total memory: 22491 M
    For device 0:  multiProcessorCount: 10
    

限制

  • Volta 和後續版本中的 GPU 類型相比,前 Volta GPU (P100) 的 MPS 功能有限
  • 透過 NVIDIA MPS,GKE 可確保每個容器獲得的固定裝置記憶體和作用中執行緒有限。不過,記憶體頻寬、編碼器或解碼器等其他資源不會計入這些資源限制。因此,如果所有容器都要求使用相同的無限制資源,可能會對其他容器的效能造成負面影響。
  • NVIDIA MPS 有記憶體保護和錯誤遏止限制。建議您評估這項限制,確保與工作負載相容。
  • NVIDIA MPS 要求您在 Pod 上設定 hostIPC:truehostIPC:true 設定可讓容器存取主機資源,這會帶來安全風險。
  • 使用 NVIDIA MPS 時,GKE 可能會拒絕某些 GPU 要求,以避免在容量分配期間發生非預期行為。
  • 透過 NVIDIA MPS 共用一部實體 GPU 的容器數量上限為 48 個 (前 Volta GPU 僅支援 16 個)。規劃 NVIDIA MPS 設定時,請考量工作負載的資源需求和基礎實體 GPU 的容量,以最佳化效能和回應速度。

後續步驟