View a markdown version of this page

在 Amazon EKS 上使用時間分割搭配 NVIDIA GPUs - Amazon EKS

協助改進此頁面

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

若要為本使用者指南貢獻內容,請點選每個頁面右側面板中的在 GitHub 上編輯此頁面連結。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 Amazon EKS 上使用時間分割搭配 NVIDIA GPUs

時間分割可讓多個 Pod 共用單一實體 NVIDIA GPU。Kubernetes 排程器會將多個 Pod 放置在相同的 GPU 上,GPU 的 CUDA 排程器時間乘以工作。時間分割是最簡單的 GPU 共用策略。它只使用軟體,不需要特殊硬體,並且適用於每個 NVIDIA GPU 執行個體類型 AWS。時間分割不提供共用 GPU 的 Pod 之間的記憶體或運算隔離。它最適合 GPU 使用率低的工作負載,例如在多個使用者共用 GPU 的請求或開發環境之間閒置的推論服務。對於需要硬體層級記憶體和運算隔離的工作負載,請改用多執行個體 GPU (MIG)。

在 Amazon EKS 上,您可以使用 NVIDIA DRA 驅動程式NVIDIA 裝置外掛程式來管理時間分割。

如果您使用靜態容量佈建,則時間分割只能與 Karpenter 搭配使用。EKS Auto 模式目前無法使用時間分割。

在以下情況下,時間分割非常適合:

  • GPU 使用率持續低,例如在請求之間閒置的延遲敏感推論服務。

  • 數個開發人員共用單一 GPU 節點以進行筆記本或開發工作。

  • 您的節點使用不支援 MIG 的 GPU 執行個體類型,例如 g5g6g6e 系列。

  • 您可以接受 Pod 偶爾速度較慢,因為同一 GPU 上的另一個 Pod 忙碌中。

在下列情況下,請考慮不同的方法:

  • 您需要記憶體隔離。時間分割 GPU 上的 Pod 共用相同的 GPU 記憶體,一個 Pod 可能會耗盡其他 Pod 依賴的記憶體。使用 MIG 進行記憶體隔離。

  • 您需要可預測的每個 Pod 延遲或服務品質。GPU 排程器會盡最大努力跨插槽共用運算,無須保證。

  • 您執行訓練工作負載。時間分割新增內容切換,可降低訓練效率。另一個 Pod 減速的檢查點任務必須從其最後一個檢查點重試。

考量事項

在生產環境中使用時間分割之前,請檢閱下列考量事項。

一般考量事項

  • 無記憶體隔離:共用時間分割 GPU 的 Pod 會共用其記憶體。一個 Pod 可以配置其他 Pod 所需的記憶體,這可能會導致out-of-memory錯誤。將共用每個 GPU 的 Pod 數量與工作負載的記憶體使用量配對。如果您的 Pod 定期載入大型模型,則每個 GPU 共用較少的 Pod 或使用 MIG。

  • 最佳運算共用:GPU 排程器會盡最大努力跨 Pod 共用運算,並不保證每個 Pod 的運算比例。

  • 時間分割和 MPS 無法共用相同的 GPU:時間分割會將 GPU 運算模式設定為 DEFAULT,而 NVIDIA 多重程序服務 (MPS) 需要 EXCLUSIVE_PROCESS。您可以在相同的叢集中使用這兩種策略,但不能同時在相同的實體 GPU 上使用。時間分割也不會影響 MIG 執行個體。若要跨容器共用單一 MIG 執行個體,請改用 MPS。

  • 每個容器指標:當時間分割作用中時,NVIDIA Data Center GPU Manager (DCGM) 無法將指標歸因於個別容器。GPU 層級指標仍然可用,但您無法識別哪些 Pod 使用了給定數量的 GPU 資源。

NVIDIA DRA 驅動程式考量事項

  • Alpha 功能:透過 DRA 驅動程式的時間分割需要TimeSlicingSettings功能閘道,這是預設停用的 Alpha 功能。如需詳細資訊,請參閱搭配 NVIDIA DRA 驅動程式使用 GPU 時間分割

  • 僅限使用者媒介的共用:Pod 僅透過參考相同 ResourceClaim或 來共用 GPUResourceClaimTemplate,這是命名空間範圍,因此共用無法跨命名空間。系統媒介共享是未來提議的功能。

  • 在 Bottlerocket 上停用內建裝置外掛程式:DRA 驅動程式無法與相同節點上的 NVIDIA 裝置外掛程式一起執行。在 Bottlerocket 上,停用需要 Bottlerocket 1.63.0 版或更新版本的內建裝置外掛程式。如需詳細資訊,請參閱安裝 NVIDIA DRA 驅動程式

  • 運算支援:Karpenter、EKS 受管節點群組或自我管理節點中的靜態容量佈建支援 NVIDIA DRA 驅動程式,EKS Auto Mode 不支援。如需詳細資訊,請參閱 Karpenter 網站上的 Karpenter 靜態 NodePool 文件

NVIDIA 裝置外掛程式考量事項

  • 使用插槽進行最佳運算共用:裝置外掛程式會公告每個 GPU 固定數量的插槽。如果單一 Pod 請求多個插槽,則不會收到額外的運算。啟用 fail-requests-greater-than-one選項以拒絕請求多個槽的 Pod。

  • 使用 Karpenter 佈建:即使 GPU 上已啟用時間分割,Karpenter 仍會將每個nvidia.com/gpu請求計為實體 GPU。如需詳細資訊,請參閱 GitHub 上的 Karpenter 問題 #2140

  • 不支援 EKS Auto Mode:EKS Auto Mode 會管理 NVIDIA 裝置外掛程式,而不會公開其組態。由於時間分割需要裝置外掛程式組態,您無法在 EKS Auto Mode 節點上套用時間分割組態。

  • 時間分割組態變更:NVIDIA 裝置外掛程式不會監控時間分割ConfigMap的變更。更新組態後重新啟動裝置外掛程式。

組態選項

您可以將 NVIDIA GPUs 的時間分割與 EKS 最佳化 AL2023 和 Bottlerocket NVIDIA AMIs 搭配使用。時間分割設定會根據您使用的是 NVIDIA DRA 驅動程式或 NVIDIA 裝置外掛程式而有所不同。

NVIDIA DRA driver

EKS 最佳化的加速 AMIs 不包含 NVIDIA DRA 驅動程式。如果您使用的是 Bottlerocket,您必須先停用內建的 NVIDIA 裝置外掛程式,才能使用 NVIDIA DRA 驅動程式,方法是在節點使用者資料settings.kubelet-device-plugins.nvidia.enabled = false中設定 ,這需要 Bottlerocket 1.63.0 版或更新版本。如需詳細資訊,請參閱安裝 NVIDIA DRA 驅動程式

使用 NVIDIA DRA 驅動程式時,時間分割是透過 ResourceClaimTemplates 設定。interval 欄位控制 CUDA 時間配量持續時間。

Interval 描述

預設

使用 NVIDIA GPU 驅動程式的內建預設間隔

Short

較短的間隔;內容更頻繁切換

中繼間隔

Long

每個內容在被先佔之前,每個回合執行的時間會更長

NVIDIA device plugin
  • Bottlerocket – AMI 包含預先安裝的 NVIDIA 裝置外掛程式。您可以透過 Bottlerocket 設定設定時間分割,無需個別的裝置外掛程式安裝、Helm Chart 或 ConfigMap

  • AL2023 – 您可以安裝 NVIDIA 裝置外掛程式,如中所述安裝 NVIDIA Kubernetes 裝置外掛程式,並透過 提供時間分割組態ConfigMap

    下列選項控制 NVIDIA 裝置外掛程式如何公告和管理時間分割 GPUs。Bottlerocket 設定和 AL2023 之間的欄位名稱不同ConfigMap,如以下程序所示。

    選項 建議值 說明

    複本

    2–8

    每個實體 GPU 要公告的可排程插槽數量。較高的值允許更多共用,但會增加 Pod 之間的爭用。

    預設重新命名

    false

    當 時false,Pod 會請求 nvidia.com/gpu,這可確保與現有資訊清單的相容性。當 時true,裝置外掛程式會將資源公告為 nvidia.com/gpu.shared,Pod 必須請求該名稱。當您同時執行共用和專用 GPU 節點集區,並希望工作負載明確選取共用資源true時,請將此設定為 。

    大於 1 的失敗請求

    true

    拒絕請求多個時段的 Pod。請求多個插槽的 Pod 不會接收比例運算。啟用此設定以防止常見的組態錯誤。

    如需 GPU 共用選項的完整清單及其預設值,請參閱 GitHub 上的 NVIDIA Kubernetes 裝置外掛程式文件

搭配 NVIDIA DRA 驅動程式使用 GPU 時間分割

透過 NVIDIA DRA 驅動程式,Pod 會參考gpu.nvidia.comDeviceClass使用時間分割 請求 ResourceClaim的常見 來共用 GPUGpuConfig

NVIDIA DRA 驅動程式目前實作使用者媒介的時間分割:GPU 只會在您明確指向相同宣告的 Pod 和容器之間共用。由於 ResourceClaimResourceClaimTemplate是命名空間範圍,因此以這種方式共用 GPU 的 Pod 必須位於相同的命名空間中。若要在單一 Pod 中跨容器共用 GPU,請讓每個容器在宣告中參考相同的請求名稱。參考不同請求名稱的容器都會收到個別的 GPU。ResourceClaimTemplate 為每個您需要的時段間隔建立個別的 ,並在您要共用 GPUs 的每個命名空間中建立個別的 。

系統媒介的時間分割是指驅動程式根據系統定義的條件而非您設定的宣告,跨獨立宣告 (包括跨命名空間) 共用 GPU。如需系統媒介時間分割的詳細資訊,請參閱 GitHub 上 GPUs 的系統媒介時間分割 (問題 #659)提取請求 #1257

重要

透過 DRA 驅動程式的時間分割需要TimeSlicingSettings功能閘道,這是預設停用的 Alpha 功能。如果您在未啟用此功能閘道的情況下請求TimeSlicing共用策略,驅動程式將無法準備裝置,且 Pod ContainerCreating會與報告 FailedPrepareDynamicResources的事件一起保持在 中error validating GPU config: unknown GPU sharing strategy: TimeSlicing。只有在您接受使用 alpha 功能的風險時,才啟用功能閘道。

先決條件

  • 執行 Kubernetes 1.34 版或更新版本的 Amazon EKS 叢集。在 Karpenter、EKS 受管節點群組或自我管理節點中,靜態容量佈建支援 NVIDIA DRA 驅動程式。

  • 使用 EKS 最佳化 AL2023 NVIDIA AMI 搭配 NVIDIA GPU 執行個體類型的節點。

  • 如中所述安裝的 NVIDIA DRA 驅動程式安裝 NVIDIA DRA 驅動程式,已啟用TimeSlicingSettings功能閘道。

程序

  1. 使用TimeSlicing共用策略建立ResourceClaim請求 GPU 的 。參考此宣告的多個 Pod 共用相同的實體 GPU。

    cat <<EOF | kubectl apply -f - apiVersion: resource.k8s.io/v1 kind: ResourceClaim metadata: name: shared-timeslice-gpu spec: devices: requests: - name: gpu exactly: deviceClassName: gpu.nvidia.com count: 1 config: - requests: ["gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing timeSlicingConfig: interval: Long EOF
  2. 部署參考ResourceClaim依名稱共用的兩個或多個 Pod。每個 Pod 透過 resourceClaims和 參考宣告resources.claims

    cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: share-a spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["nvidia-smi", "-L"] resources: claims: - name: gpu resourceClaims: - name: gpu resourceClaimName: shared-timeslice-gpu restartPolicy: OnFailure EOF
  3. 確認 Pod 共用相同的實體 GPU。在每個 Pod nvidia-smi -L中執行,並確認它們報告相同的 GPU UUID。

    kubectl logs share-a

    範例輸出如下。參考相同宣告的第二個 Pod 會報告相同的 GPU UUID,以確認兩個 Pod 共用一個實體 GPU。

    GPU 0: NVIDIA L4 (UUID: GPU-b41973ee-5d0a-cde8-6287-12b53f861f02)

在 Bottlerocket 節點上使用 GPU 時間分割搭配 NVIDIA 裝置外掛程式

在 Bottlerocket 上,EKS 最佳化的加速 AMI 包含 NVIDIA 裝置外掛程式。您可以透過settings.kubelet-device-plugins.nvidia設定啟用時間分割,當節點啟動時, Bottlerocket 會轉譯為裝置外掛程式組態。

先決條件

  • Amazon EKS 叢集。下列程序使用 EKS 最佳化 Bottlerocket NVIDIA AMI 佈建 NVIDIA GPU 節點。

  • 叢集中已安裝和設定的 Karpenter,因為下列程序使用 Karpenter EC2NodeClass 在 Bottlerocket 節點使用者資料中提供時間分割設定。如需詳細資訊,請參閱 Karpenter 網站上的 Karpenter 入門

  • kubectl 設定為與您的叢集通訊,安裝或更新 kubectl如需詳細資訊,請參閱 。

程序

將時間分割設定新增至 GPU 節點的 Bottlerocket 使用者資料。下列範例為每個 GPU 設定四個插槽。您提供使用者資料的方式取決於您佈建節點的方式。下列範例顯示 Karpenter EC2NodeClass

cat <<EOF | kubectl apply -f - apiVersion: karpenter.k8s.aws/v1 kind: EC2NodeClass metadata: name: gpu-bottlerocket-timeslicing spec: amiFamily: Bottlerocket amiSelectorTerms: - alias: bottlerocket@latest role: eksctl-KarpenterNodeRole-<cluster-name> subnetSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> securityGroupSelectorTerms: - tags: karpenter.sh/discovery: <cluster-name> userData: | [settings.kubelet-device-plugins.nvidia] device-sharing-strategy = "time-slicing" [settings.kubelet-device-plugins.nvidia.time-slicing] replicas = 4 rename-by-default = false fail-requests-greater-than-one = true EOF

當使用這些設定佈建的節點加入叢集時,裝置外掛程式會為每個實體 GPU 公告四個nvidia.com/gpu插槽。您可以在工作負載規格中使用容器資源請求或nvidia.com/gpu延伸資源的限制來請求它們。

在 AL2023 節點上使用 GPU 時間分割搭配 NVIDIA 裝置外掛程式

在 AL2023 上,您可以安裝 NVIDIA 裝置外掛程式,如中所述安裝 NVIDIA Kubernetes 裝置外掛程式,並在 中提供時間分割組態ConfigMap

先決條件

  • 具有使用 NVIDIA GPU 執行個體類型和 EKS 最佳化 AL2023 NVIDIA AMI 之節點的 Amazon EKS 叢集。

  • 已在命令列環境中安裝 Helm,如需詳細資訊,請參閱安裝 Helm 說明

  • kubectl 設定為與您的叢集通訊,安裝或更新 kubectl如需詳細資訊,請參閱 。

程序

  1. nvidia命名空間ConfigMap中建立時間分割,其中您在 中安裝裝置外掛程式安裝 NVIDIA Kubernetes 裝置外掛程式。此範例為每個 GPU 設定四個插槽。

    cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: nvidia data: config.yaml: | version: v1 sharing: timeSlicing: renameByDefault: false failRequestsGreaterThanOne: true resources: - name: nvidia.com/gpu replicas: 4 EOF
  2. 更新現有的 NVIDIA 裝置外掛程式版本,以ConfigMap使用 config.name值參考 。--reuse-values 旗標會保留您在 中安裝裝置外掛程式時設定的值安裝 NVIDIA Kubernetes 裝置外掛程式

    helm upgrade nvdp nvdp/nvidia-device-plugin \ --namespace nvidia \ --reuse-values \ --set config.name=nvidia-device-plugin-config
注意

當您變更 時,裝置外掛程式不會自動重新載入ConfigMap。更新時間分割組態後,請重新啟動裝置外掛程式 Pod 以套用變更。

驗證 GPU 時間分割是否作用中

時間分割節點為 之後Ready,請確認裝置外掛程式公告預期的插槽數量,以及 Pod 共用實體 GPU。

注意

此程序中的共用 UUID 檢查會在 Pod 落在相同的實體 GPU 上時,示範最清楚的時間分割。在具有單一 GPU 的節點上,裝置外掛程式會公告四個插槽,而所有四個 Pod 都會共用該 GPU,因此它們會報告相同的 UUID。在具有多個實體 GPUs 的節點上,排程器可以將 Pod 放置在不同的 GPUs 上。即使時間分割處於作用中狀態,這些 Pod 仍會報告不同的 UUIDs。若要示範在一個 GPU 上共用,請將工作負載排程到單一 GPU 執行個體類型。例如,將 等節點選擇器node.kubernetes.io/instance-type: g6.2xlarge新增至 Pod 規格。

  1. 確認節點公告設定的 GPU 插槽數量。每個 GPU 有四個插槽,具有一個實體 GPU 的節點會報告 4

    kubectl get nodes "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"

    範例輸出如下。

    NAME GPU ip-192-168-11-225.us-west-2.compute.internal 4
  2. 建立執行四個複本的部署,每個複本請求一個 GPU 插槽。

    cat <<EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: timeslicing-demo spec: replicas: 4 selector: matchLabels: app: timeslicing-demo template: metadata: labels: app: timeslicing-demo spec: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule containers: - name: cuda image: nvidia/cuda:12.6.0-base-ubuntu22.04 command: ["bash", "-c", "nvidia-smi --query-gpu=uuid --format=csv,noheader; sleep infinity"] resources: limits: nvidia.com/gpu: 1 EOF
  3. 確認所有四個 Pod 都已排程在相同的節點上。

    kubectl get pods -l app=timeslicing-demo -o wide
  4. 確認所有四個 Pod 都報告相同的 GPU UUID。所有四個 Pod 之間的單一共用 UUID 會確認一個實體 GPU 正在多工。

    kubectl logs -l app=timeslicing-demo --prefix

    範例輸出如下。

    [pod/timeslicing-demo-xxxxxxxxxx-aaaaa/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-bbbbb/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ccccc/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03 [pod/timeslicing-demo-xxxxxxxxxx-ddddd/cuda] GPU-c0583cce-87c5-c736-db7f-6d3128c84d03