本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
運算和自動擴展
GPU 資源最佳化和成本管理
使用 Well-Known 標籤以 GPU 需求排程工作負載
對於對不同 GPU 特性 (例如 GPU、GPU 記憶體) 敏感的 AI/ML 工作負載,建議使用與 Karpenter
範例
例如,使用 Karpenter 時使用 GPU 名稱節點選擇器:
apiVersion: v1 kind: Pod metadata: name: gpu-pod-example spec: containers: - name: ml-workload image: <image> resources: limits: nvidia.com/gpu: 1 # Request one NVIDIA GPU nodeSelector: karpenter.k8s.aws/instance-gpu-name: "l40s" # Run on nodes with NVIDIA L40S GPUs
使用 Kubernetes 裝置外掛程式公開 GPUs
若要在節點上公開 GPUs,NVIDIA GPU 驅動程式必須安裝在節點的作業系統和容器執行時間上,設定成允許 Kubernetes 排程器將 Pod 指派給具有可用 GPUs 的節點。NVIDIA Kubernetes 裝置外掛程式的設定程序取決於您使用的 EKS 加速 AMI:
-
Bottlerocket Accelerated AMI:此 AMI 包含 NVIDIA GPU 驅動程式,且已預先安裝 NVIDIA Kubernetes 裝置外掛程式
並可供使用,可立即支援 GPU。向 Kubernetes 排程器公開 GPUs 不需要額外的組態。 -
AL2023 加速 AMI
:此 AMI 包含 NVIDIA GPU 驅動程式,但未預先安裝 NVIDIA Kubernetes 裝置外掛程式 。您必須分別安裝和設定裝置外掛程式,通常是透過 DaemonSet。請注意,如果您使用 eksctl 建立叢集,並在 ClusterConfig 中指定 GPU 執行個體類型 (例如 g5.xlarge
),eksctl
會自動選取加速 AMI,並在節點群組中的每個執行個體上安裝 NVIDIA Kubernetes 裝置外掛程式。若要進一步了解,請參閱 eksctl 文件中的 GPU 支援。
若要驗證 NVIDIA 裝置外掛程式是否作用中且 GPUs 已正確公開,請執行:
kubectl describe node | grep nvidia.com/gpu
此命令會檢查nvidia.com/gpu
資源是否在節點的容量和可配置的資源中。例如,具有一個 GPU 的節點應該會顯示 nvidia.com/gpu: 1
。如需詳細資訊,請參閱 Kubernetes GPU 排程指南
使用 ML 容量區塊來確保 P 和 Trainium 執行個體的容量
ML 的容量區塊可讓您保留熱門的 GPU 執行個體,特別是 P 執行個體 (例如 p6-b200、p5、p5e、p5en、p4d、p4de) 和 Trainium 執行個體 (例如 trn1、trn2),以幾乎立即開始或在未來日期開始,以支援您的短期機器學習 (ML) 工作負載。這些保留非常適合確保運算密集型任務的容量,例如模型訓練和微調。EC2 容量區塊定價包含保留費和作業系統費用。若要進一步了解定價,請參閱適用於 ML 定價的 EC2 容量區塊
若要為 Amazon EKS 上的 AI/ML 工作負載保留 GPUs,以保證可預測的容量,我們建議將 ML 容量區塊用於短期或隨需容量保留 ODCRs),以保證一般用途的容量。
-
ODCRs 可讓您在特定可用區域中保留 EC2 執行個體容量 (例如 g5 或 p5 等 GPU 執行個體),即使在高需求期間也能確保可用性。ODCRs沒有長期承諾,但您要支付預留容量的隨需費率,無論是已使用或閒置。在 EKS 中,Karpenter
和受管節點群組等節點類型支援 ODCRs。若要排定 Karpenter 中的 ODCRs優先順序,請將 NodeClass 設定為使用 capacityReservationSelectorTerms
欄位。請參閱 Karpenter NodePools 文件。 -
容量區塊是 GPU (例如 p5、p4d) 或 Trainium (trn1、trn2) 執行個體的特殊保留機制,專為模型訓練、微調或實驗等短期 ML 工作負載而設計。您從未來日期開始,在定義的期間內 (通常為 24 小時至 182 天) 保留容量,僅支付預留時間的費用。它們是預付的,需要預先規劃容量需求,且不支援自動擴展,但會共置在 EC2 UltraClusters 中以進行低延遲聯網。它們只會收取預留期間的費用。若要進一步了解,請參閱尋找和購買容量區塊,或使用建立具有 ML 容量區塊的受管節點群組中的指示來設定具有容量區塊的受管節點群組。
透過 AWS 管理主控台預留容量,並將節點設定為使用 ML 容量區塊。根據工作負載排程規劃保留,並在預備叢集中進行測試。如需詳細資訊,請參閱容量區塊文件。
考慮 G Amazon EC2 執行個體的隨需、Amazon EC2 Spot 或隨需容量保留 (ODCRs)
對於 G Amazon EC2 執行個體,請考慮與隨需、Amazon EC2 Spot 執行個體和隨需容量保留不同的購買選項。ODCRs 可讓您在特定的可用區域中保留 EC2 執行個體容量一段時間,即使在高需求期間也能確保可用性。與僅適用於 P 和 Trainium 執行個體的 ML 容量區塊不同,ODCRs 可用於更廣泛的執行個體類型,包括 G 執行個體,使其適用於需要不同 GPU 功能的工作負載,例如推論或圖形。使用 Amazon EC2 Spot 執行個體時,能夠跨不同的執行個體類型、大小和可用區域進行多樣化,是讓 Spot 停留更久的關鍵。
ODCRs沒有長期承諾,但您要支付預留容量的隨需費率,無論是已使用或閒置。您可以建立 ODCRs以供立即使用,或排定未來日期,提供容量規劃的彈性。在 Amazon EKS 中,KarpentercapacityReservationSelectorTerms
欄位。請參閱 Karpenter NodePools 文件
考慮其他加速執行個體類型和大小
選取適當的加速執行個體和大小對於在 Amazon EKS 上最佳化 ML 工作負載的效能和成本至關重要。例如,不同的 GPU 執行個體系列具有不同的效能和功能,例如 GPU 記憶體。為了協助您選擇價格效能最佳的選項,請檢閱加速運算下 EC2 執行個體類型頁面中可用的 GPU 執行個體
如果您在 EKS 節點中使用 GPU 執行個體,則預設在kube-system
命名空間中會有 nvidia-device-plugin-daemonset
Pod。若要快速了解您是否充分利用執行個體中的 GPU,您可以使用 nvidia-smi
kubectl exec nvidia-device-plugin-daemonset-xxxxx \ -n kube-system -- nvidia-smi \ --query-gpu=index,power.draw,power.limit,temperature.gpu,utilization.gpu,utilization.memory,memory.free,memory.used \ --format=csv -l 5
-
如果
utilization.memory
(接近 100%),則您的程式碼可能已繫結記憶體。這表示 GPU (記憶體) 已充分利用,但可能表示應調查進一步的效能最佳化。 -
如果
utilization.gpu
接近 100%,這不一定表示 GPU 已充分利用。要查看的較佳指標是power.draw
與 的比率power.limit
。如果此比率為 100% 或以上,則您的程式碼會充分利用 GPU 的運算容量 (運算容量)。 -
-l 5
旗標指出 每 5 秒輸出一次指標。如果是單一 GPU 執行個體類型,則不需要索引查詢旗標。
若要進一步了解,請參閱 AWS 文件中的 GPU 執行個體。
使用時間分割、MIG 和分量 GPU 配置來最佳化 GPU 資源配置
Kubernetes 中的靜態資源限制 (例如 CPU、記憶體、GPU 計數) 可能會導致過度佈建或利用率不足,尤其是推論等動態 AI/ML 工作負載。選取正確的 GPU 非常重要。對於低容量或尖峰工作負載,時間分割允許多個工作負載透過共用其運算資源來共用單一 GPU,進而提高效率並減少浪費。GPU 共用可以透過不同的選項達成:
-
利用節點選擇器/節點親和性來影響排程:確保佈建的節點和 Pod 已排程在工作負載的適當 GPUs 上 (例如
karpenter.k8s.aws/instance-gpu-name: "a100"
) -
時間分割:排程工作負載以隨時間共用 GPU 的運算資源,允許並行執行,無需實體分割。這非常適合具有可變運算需求的工作負載,但可能缺乏記憶體隔離。
-
多執行個體 GPU (MIG):MIG 允許單一 NVIDIA GPU 分割成多個隔離的執行個體,並支援 NVIDIA Ampere (例如 A100 GPU)、NVIDIA Hopper (例如 H100 GPU) 和 NVIDIA Blackwell (例如 Blackwell GPUs) GPUs。每個 MIG 執行個體都會接收專用運算和記憶體資源,在需要資源保證的多租用戶環境或工作負載中啟用資源共用,這可讓您最佳化 GPU 資源使用率,包括透過時間分割提供不同批次大小的多個模型。
-
分數 GPU 分配:使用軟體型排程,將部分 GPU 運算或記憶體分配給工作負載,為動態工作負載提供彈性。NVIDIA KAI 排程器
是 Run:ai 平台的一部分,透過允許 Pod 請求部分 GPU 資源來啟用此功能。
若要在 EKS 中啟用這些功能,您可以部署 NVIDIA 裝置外掛程式,將 GPUs 公開為可排程的資源,並支援時間分割和 MIG。若要進一步了解,請參閱 Kubernetes 中的時間分割 GPUs
範例
例如,若要使用 NVIDIA 裝置外掛程式啟用時間分割:
apiVersion: v1 kind: ConfigMap metadata: name: nvidia-device-plugin-config namespace: kube-system data: config.yaml: | version: v1 sharing: timeSlicing: resources: - name: nvidia.com/gpu replicas: 4 # Allow 4 pods to share each GPU
範例
例如,若要使用 KAI 排程器配置分數 GPU,請將其與 NVIDIA GPU Operator 一起部署,並在 Pod 規格中指定分數 GPU 資源:
apiVersion: v1 kind: Pod metadata: name: fractional-gpu-pod-example annotations: gpu-fraction: "0.5" # Annotation for 50% GPU labels: runai/queue: "default" # Required queue assignment spec: containers: - name: ml-workload image: nvcr.io/nvidia/pytorch:25.04-py3 resources: limits: nvidia.com/gpu: 1 nodeSelector: nvidia.com/gpu: "true" schedulerName: kai-scheduler
節點彈性和訓練任務管理
使用自動復原實作節點運作狀態檢查
對於需要頻繁節點間通訊的 Amazon EKS 分散式訓練任務,例如跨多個節點的多 GPU 模型訓練,GPU 或 EFA 失敗等硬體問題可能會導致訓練任務中斷。這些中斷可能會導致訓練進度的損失和成本增加,尤其是依賴穩定硬體的長期執行 AI/ML 工作負載。
為了協助增加硬體故障的彈性,例如執行 GPU 工作負載的 EKS 叢集中的 GPU 失敗,我們建議您利用 EKS 節點監控代理程式搭配自動修復或 Amazon SageMaker HyperPod。雖然具有自動修復功能的 EKS 節點監控代理程式提供節點運作狀態監控和使用標準 Kubernetes 機制的自動修復等功能,但 SageMaker HyperPod 提供目標彈性和其他專為大規模 ML 訓練而設計的功能,例如深度運作狀態檢查和自動恢復任務。
-
EKS Node Monitoring Agent with Node Auto Repair 透過讀取日誌和套用 NodeConditions 來持續監控節點運作狀態,包括加速硬體的特定標準條件,例如
Ready
和 條件,以識別 GPU 或網路故障等問題。當節點視為運作狀態不佳時,Node Auto Repair 會將其封鎖,並將其取代為新的節點。重新排程 Pod 和重新啟動任務取決於標準 Kubernetes 機制和任務的重新啟動政策。 -
SageMaker HyperPod
深度運作狀態檢查和運作狀態監控代理程式會持續監控 GPU 和 Trainium 型執行個體的運作狀態。它專為 AI/ML 工作負載量身打造,使用標籤 (例如 node-health-status) 來管理節點運作狀態。當節點視為運作狀態不佳時,HyperPod 會觸發自動取代故障的硬體,例如 GPUs。它預設透過 EFA 的基本運作狀態檢查來偵測網路相關的故障,並支援自動恢復中斷的訓練任務,允許任務從最後一個檢查點繼續進行,將大規模 ML 任務的中斷降至最低。
對於具有自動修復的 EKS 節點監控代理程式和使用 EFA 的 SageMaker HyperPod 叢集,若要監控 EFA 特定指標,例如遠端直接記憶體存取 (RDMA) 錯誤和封包捨棄,請確定已安裝 AWS EFA 驅動程式。此外,我們建議部署 CloudWatch 可觀測性附加元件或使用 DCGM Exporter 和 Prometheus 和 Grafana 等工具來監控 EFA、GPU,以及針對 SageMaker HyperPod,與其功能相關的特定指標。
針對中斷敏感工作負載停用 Karpenter 合併
對於對處理、大規模 AI/ML 預測任務或訓練等中斷敏感的工作負載,我們建議調校 Karpenter 整合政策
WhenEmptyOrUnderutilized
合併政策可能會提早終止節點,導致執行時間延長。例如,由於 Pod 重新排程、資料重新載入,中斷可能會延遲任務恢復,這對於長時間執行的批次推論任務可能非常昂貴。若要緩解這種情況,您可以將 consolidationPolicy
設定為 ,WhenEmpty
並設定consolidateAfter
持續時間,例如 1 小時,以在工作負載尖峰期間保留節點。例如:
disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m
此方法可改善尖峰批次推論工作負載和其他干擾敏感任務的 Pod 啟動延遲,例如即時線上推論資料處理或模型訓練,其中中斷成本高於運算成本節省。Karpenter NodePool 中斷預算
使用 ttlSecondsAfterFinished 自動清除 Kubernetes 任務
我們建議ttlSecondsAfterFinished
在 Amazon EKS 中設定 Kubernetes 任務,以自動刪除已完成的任務物件。內嵌任務物件會耗用叢集資源,例如 API 伺服器記憶體,並透過雜亂儀表板 (例如 Grafana、Amazon CloudWatch) 來複雜化監控。例如,將 TTL 設定為 1 小時可確保任務會在完成後不久移除,讓您的叢集保持整齊。如需詳細資訊,請參閱完成任務的自動清除
設定較高優先順序任務/工作負載的低優先順序任務先佔
對於 Amazon EKS 上的混合優先順序 AI/ML 工作負載,您可以設定低優先順序任務先佔,以確保較高優先順序的任務 (例如即時推論) 可快速接收資源。如果沒有先佔,低優先順序工作負載,例如批次程序 (例如批次推論、資料處理)、非批次服務 (例如背景任務、cron 任務) 或 CPU/記憶體密集型任務 (例如 Web 服務),可以透過佔用節點來延遲關鍵 Pod。先佔允許 Kubernetes 在高優先順序 Pod 需要資源時移出低優先順序 Pod,確保在具有 GPUs、CPUs 或記憶體的節點上進行有效率的資源配置。建議使用 Kubernetes PriorityClass
來指派優先順序PodDisruptionBudget
並控制移出行為。
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 --- spec: priorityClassName: low-priority
如需詳細資訊,請參閱 Kubernetes 優先順序和先佔文件
應用程式擴展和效能
使用 Karpenter 或靜態節點的 ML 工作負載量身訂做運算容量
為了確保 Amazon EKS 上機器學習 (ML) 工作流程的成本效益和回應性運算容量,我們建議您根據工作負載的特性和成本承諾量身打造節點佈建策略。以下是兩個要考慮的方法:使用 Karpenter
-
Just-in-time資料平面縮放器,例如 Karpenter:對於具有可變運算需求的動態 ML 工作流程 (例如,GPU 型推論,後面接著 CPU 型繪圖),我們建議使用just-in-time資料平面縮放器,例如 Karpenter。
-
將靜態節點群組用於可預測的工作負載:對於可預測、穩定狀態的 ML 工作負載或使用預留執行個體時,EKS 受管節點群組可協助確保預留容量已完全佈建和使用,從而最大限度地節省成本。此方法非常適合透過 RIs 或 ODCRs 遞交的特定執行個體類型。
範例
這是各種 Karpenter NodePoolg
Amazon EC2 執行個體。
apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inference spec: template: spec: nodeClassRef: group: karpenter.k8s.aws kind: EC2NodeClass name: default requirements: - key: karpenter.sh/capacity-type operator: In values: ["on-demand"] - key: karpenter.k8s.aws/instance-category operator: In values: ["g"] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] - key: kubernetes.io/arch operator: In values: ["amd64"] taints: - key: nvidia.com/gpu effect: NoSchedule limits: cpu: "1000" memory: "4000Gi" nvidia.com/gpu: "10" *# Limit the total number of GPUs to 10 for the NodePool* disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m expireAfter: 720h
範例
使用靜態節點群組訓練工作負載的範例:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: ml-cluster region: us-west-2 managedNodeGroups: - name: gpu-node-group instanceType: p4d.24xlarge minSize: 2 maxSize: 2 desiredCapacity: 2 taints: - key: nvidia.com/gpu effect: NoSchedule
使用污點和容錯,防止在加速執行個體上排程非加速工作負載
在 GPU 資源上排程非加速工作負載不具運算效率,建議您使用污點和容錯,以確保非加速工作負載 Pod 不會排程在不適當的節點上。如需詳細資訊,請參閱 Kubernetes 文件
根據模型效能擴展
對於推論工作負載,建議使用 Kubernetes Event-Driven Autoscaling (KEDA) 根據模型效能指標進行擴展,例如推論請求或字符輸送量,並具有適當的冷卻時間。靜態擴展政策可能會過度佈建或佈建不足的資源,影響成本和延遲。如需進一步了解,請參閱 KEDA 文件
進階 GPU 管理的動態資源配置
動態資源配置 (DRA)
-
精細的 GPU 配置
-
進階共用機制,例如多程序服務 (MPS) 和多執行個體 GPU (MIG)
-
支援新一代硬體架構,包括 NVIDIA GB200 UltraClusters
傳統 GPU 配置會將 GPUs 視為不透明的整數資源,造成顯著的使用不足 (通常在生產叢集中為 30-40%)。這是因為即使只需要部分資源,工作負載也會取得整個 GPUs 的專屬存取權。DRA 透過引入結構化的宣告式配置來轉換此模型,讓 Kubernetes 排程器完全了解硬體特性和工作負載需求。這可實現智慧型配置決策和有效率的資源共用。
使用 DRA 而非 NVIDIA 裝置外掛程式的優點
NVIDIA 裝置外掛程式 (從版本 開始0.12.0
) 支援 GPU 共用機制,包括時間分割、MPS 和 MIG。不過,該 DRA 地址存在架構限制。
NVIDIA 裝置外掛程式限制
-
靜態組態:GPU 共用組態 (時間分割複本和 MPS 設定) 需要透過 進行整個叢集的預先組態
ConfigMaps
。這使得為不同的工作負載提供不同的共用策略變得困難。 -
有限精細選擇:雖然裝置外掛程式透過節點標籤公開 GPU 特性,但工作負載無法在排程決策中動態請求特定 GPU 組態 (記憶體大小和運算功能)。
-
無跨節點資源協調:無法管理跨多個節點的分散式 GPU 資源,或表達複雜的拓撲需求,例如 NVIDIA GB200 等系統的 NVLink 網域。
-
排程器限制:Kubernetes 排程器會將 GPU 資源視為不透明整數,限制其做出拓撲感知決策或處理複雜資源相依性的能力。
-
組態複雜性:設定不同的共用策略需要多個仔細
ConfigMaps
的節點標記,從而產生操作複雜性。
搭配 DRA 的解決方案
-
動態資源選擇:DRA 允許工作負載在透過 的請求時間指定詳細需求 (GPU 記憶體、驅動程式版本和特定屬性)
resourceclaims
。這可讓資源比對更具彈性。 -
拓撲感知:透過結構化參數和裝置選擇器,DRA 可處理複雜的需求,例如跨節點 GPU 通訊和記憶體一致性互連。
-
跨節點資源管理:
computeDomains
啟用跨多個節點的分散式 GPU 資源協調,對於具有 IMEX 通道的 GB200 等系統至關重要。 -
工作負載特定的組態:每個
ResourceClaim
指定不同的共用策略和組態,允許每個工作負載的精細控制,而不是整個叢集的設定。 -
增強型排程器整合:DRA 提供排程器詳細的裝置資訊,並根據硬體拓撲和資源特性進行更明智的置放決策。
重要:DRA 不會完全取代 NVIDIA 裝置外掛程式。NVIDIA DRA 驅動程式可與裝置外掛程式搭配使用,以提供增強功能。裝置外掛程式會繼續處理基本的 GPU 探索和管理,而 DRA 新增進階配置和排程功能。
DRA 支援的執行個體及其功能
DRA 支援因 Amazon EC2 執行個體系列和 GPU 架構而異,如下表所示。
執行個體系列 | GPU 類型 | 時間分割 | MIG 支援 | MPS 支援 | IMEX 支援 | 使用案例 |
---|---|---|---|---|---|---|
G5 |
NVIDIA A10G |
是 |
否 |
是 |
否 |
推論和圖形工作負載 |
G6 |
NVIDIA L4 |
是 |
否 |
是 |
否 |
AI 推論和影片處理 |
G6e |
NVIDIA L40S |
是 |
否 |
是 |
否 |
訓練、推論和圖形 |
P4d/P4de |
NVIDIA A100 |
是 |
是 |
是 |
否 |
大規模訓練和 HPC |
P5 |
NVIDIA H100 |
是 |
是 |
是 |
否 |
基礎模型訓練 |
P6 |
NVIDIA B200 |
是 |
是 |
是 |
否 |
十億或兆參數模型、分散式訓練和推論 |
P6e |
NVIDIA GB200 |
是 |
是 |
是 |
是 |
十億或兆參數模型、分散式訓練和推論 |
以下是 資料表中每個功能的描述:
-
時間分割:允許多個工作負載隨時間共用 GPU 運算資源。
-
多執行個體 GPU (MIG):建立隔離 GPU 執行個體的硬體層級分割。
-
多程序服務 (MPS):在單一 GPU 上同時執行多個 CUDA 程序。
-
節點間記憶體交換 (IMEX):GB200 UltraClusters 跨節點的記憶體一致性通訊。
其他資源
如需 Kubernetes DRA 和 NVIDIA DRA 驅動程式的詳細資訊,請參閱 GitHub 上的下列資源:
設定動態資源配置以進行進階 GPU 管理
下列主題說明如何設定動態資源配置 (DRA) 以進行進階 GPU 管理。
先決條件
在 Amazon EKS 上實作 DRA 之前,請確定您的環境符合下列要求。
叢集組態
-
執行版本
1.33
或更新版本的 Amazon EKS 叢集 -
Amazon EKS 受管節點群組 (DRA 目前僅支援具有 AL2023 和 Bottlerocket NVIDIA 最佳化 AMIs,【非 Karpenter】(https://github.com/kubernetes-sigs/karpenter/issues/1231://))
-
具有適當執行個體類型的 NVIDIA GPU 工作者節點
必要元件
-
NVIDIA 裝置外掛程式版本
0.17.1
或更新版本 -
NVIDIA DRA 驅動程式版本
25.3.0
或更新版本
步驟 1:使用 eksctl 使用已啟用 DRA 的節點群組建立叢集
-
建立名為 的叢集組態檔案
dra-eks-cluster.yaml
:--- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-west-2 version: '1.33' managedNodeGroups: - name: gpu-dra-nodes amiFamily: AmazonLinux2023 instanceType: g6.12xlarge desiredCapacity: 2 minSize: 1 maxSize: 3 labels: node-type: "gpu-dra" nvidia.com/gpu.present: "true" taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule
-
建立叢集:
eksctl create cluster -f dra-eks-cluster.yaml
步驟 2:部署 NVIDIA 裝置外掛程式
部署 NVIDIA 裝置外掛程式以啟用基本 GPU 探索:
-
新增 NVIDIA 裝置外掛程式 Helm 儲存庫:
helm repo add nvidia https://nvidia.github.io/k8s-device-plugin helm repo update
-
為裝置外掛程式建立自訂值:
cat <<EOF > nvidia-device-plugin-values.yaml gfd: enabled: true nfd: enabled: true tolerations: - key: [nvidia.com/gpu](http://nvidia.com/gpu) operator: Exists effect: NoSchedule EOF
-
安裝 NVIDIA 裝置外掛程式:
helm install nvidia-device-plugin nvidia/nvidia-device-plugin \ --namespace nvidia-device-plugin \ --create-namespace \ --version v0.17.1 \ --values nvidia-device-plugin-values.yaml
步驟 3:部署 NVIDIA DRA 驅動程式 Helm Chart
-
建立 DRA 驅動程式
dra-driver-values.yaml
的值檔案:--- nvidiaDriverRoot: / gpuResourcesEnabledOverride: true resources: gpus: enabled: true computeDomains: enabled: true # Enable for GB200 IMEX support controller: tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule kubeletPlugin: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "nvidia.com/gpu.present" operator: In values: ["true"] tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
-
新增 NVIDIA NGC Helm 儲存庫:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm repo update
-
安裝 NVIDIA DRA 驅動程式:
helm install nvidia-dra-driver nvidia/nvidia-dra-driver-gpu \ --version="25.3.0-rc.2" \ --namespace nvidia-dra-driver \ --create-namespace \ --values dra-driver-values.yaml
步驟 4:驗證 DRA 安裝
-
驗證 DRA API 資源是否可用:
kubectl api-resources | grep [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1)
以下是預期的輸出:
deviceclasses [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) false DeviceClass resourceclaims [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) true ResourceClaim resourceclaimtemplates [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) true ResourceClaimTemplate resourceslices [resource.k8s.io/v1beta1](http://resource.k8s.io/v1beta1) false ResourceSlice
-
檢查可用的裝置類別:
kubectl get deviceclasses
以下是預期輸出的範例:
NAME AGE compute-domain-daemon.nvidia.com 4h39m compute-domain-default-channel.nvidia.com 4h39m gpu.nvidia.com 4h39m mig.nvidia.com 4h39m
當新建立的 G6 GPU 執行個體加入已啟用 DRA 的 Amazon EKS 叢集時,會發生下列動作:
-
NVIDIA DRA 驅動程式會自動探索 A10G GPU,並在該節點
resourceslices
上建立兩個 GPU。 -
gpu.nvidia.com
配量會將實體 A10G GPU 裝置與其規格 (記憶體、運算功能等) 註冊。 -
由於 A10G 不支援 MIG 分割,
compute-domain.nvidia.com
配量會建立代表 GPU 整個運算內容的單一運算網域。 -
這些
resourceslices
接著會發佈至 Kubernetes API 伺服器,讓 GPU 資源可透過 進行排程resourceclaims
。DRA 排程器現在可以智慧地將此 GPU 配置給透過 請求 GPU 資源的 Pod
resourceclaimtemplates
,提供比傳統裝置外掛程式方法更靈活的資源管理。這會自動發生,無需手動介入。一旦 DRA 驅動程式完成資源探索和註冊程序,節點即可直接用於 GPU 工作負載。當您執行下列命令時:
kubectl get resourceslices
以下是預期輸出的範例:
NAME NODE DRIVER POOL AGE ip-100-64-129-47.ec2.internal-compute-domain.nvidia.com-rwsts ip-100-64-129-47.ec2.internal compute-domain.nvidia.com ip-100-64-129-47.ec2.internal 35m ip-100-64-129-47.ec2.internal-gpu.nvidia.com-6kndg ip-100-64-129-47.ec2.internal gpu.nvidia.com ip-100-64-129-47.ec2.internal 35m
-
使用動態資源配置排程簡單的 GPU 工作負載
若要使用動態資源配置 (DRA) 排程簡單的 GPU 工作負載,請執行下列步驟。在繼續之前,請確定您已遵循 設定動態資源配置以進行進階 GPU 管理。
-
使用名為
ResourceClaimTemplate
的檔案建立 GPU 配置的基本basic-gpu-claim-template.yaml
:--- apiVersion: v1 kind: Namespace metadata: name: gpu-test1 --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: namespace: gpu-test1 name: single-gpu spec: spec: devices: requests: - name: gpu deviceClassName: gpu.nvidia.com
-
套用範本:
kubectl apply -f basic-gpu-claim-template.yaml
-
驗證狀態:
kubectl get resourceclaimtemplates -n gpu-test1
下列為範例輸出:
NAME AGE single-gpu 9m16s
-
建立使用
ResourceClaimTemplate
檔案名為 的 Podbasic-gpu-pod.yaml
:--- apiVersion: v1 kind: Pod metadata: namespace: gpu-test1 name: gpu-pod labels: app: pod spec: containers: - name: ctr0 image: ubuntu:22.04 command: ["bash", "-c"] args: ["nvidia-smi -L; trap 'exit 0' TERM; sleep 9999 & wait"] resources: claims: - name: gpu0 resourceClaims: - name: gpu0 resourceClaimTemplateName: single-gpu nodeSelector: NodeGroupType: gpu-dra nvidia.com/gpu.present: "true" tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule"
-
套用和監控 Pod:
kubectl apply -f basic-gpu-pod.yaml
-
檢查 Pod 狀態:
kubectl get pod -n gpu-test1
以下是預期的輸出範例:
NAME READY STATUS RESTARTS AGE gpu-pod 1/1 Running 0 13m
-
檢查
ResourceClaim
狀態:kubectl get resourceclaims -n gpu-test1
以下是預期的輸出範例:
NAME STATE AGE gpu-pod-gpu0-l76cg allocated,reserved 9m6s
-
檢視 Pod 日誌以查看 GPU 資訊:
kubectl logs gpu-pod -n gpu-test1
以下是預期的輸出範例:
GPU 0: NVIDIA L4 (UUID: GPU-da7c24d7-c7e3-ed3b-418c-bcecc32af7c5)
如需使用 DRA 具有動態資源配置的 GPU 最佳化技術 的更進階 GPU 最佳化技術,請繼續前往 。
具有動態資源配置的 GPU 最佳化技術
現代 GPU 工作負載需要複雜的資源管理,才能達到最佳的使用率和成本效益。DRA 啟用多種進階最佳化技術,可解決不同的使用案例和硬體功能:
-
時間分割可讓多個工作負載隨時間共用 GPU 運算資源,因此非常適合偶爾使用 GPU 的推論工作負載。如需範例,請參閱「使用時間分割最佳化 GPU 工作負載」。
-
多程序服務 (MPS) 可在單一 GPU 上並行執行多個 CUDA 程序,其隔離程度優於時間分割。如需範例,請參閱「使用 MPS 最佳化 GPU 工作負載」。
-
多執行個體 GPU (MIG) 提供硬體層級分割,建立具有專用運算和記憶體資源的隔離 GPU 執行個體。如需範例,請參閱「使用多執行個體 GPU 最佳化 GPU 工作負載」。
-
Internode Memory Exchange (IMEX) 可讓跨節點的記憶體一致性通訊,以便在 NVIDIA GB200 系統上進行分散式訓練。如需範例,請參閱「使用 GB200 P6e 執行個體透過 IMEX 最佳化 GPU 工作負載」。
這些技術可以大幅改善資源使用率。Organizations 報告 GPU 使用率從傳統配置的 30-40% 增加到最佳化共用策略的 80-90%。技術選擇取決於工作負載特性、隔離要求和硬體功能。
使用時間分割最佳化 GPU 工作負載
時間分割可讓多個工作負載透過排程在相同的實體 GPU 上循序執行,來共用 GPU 運算資源。它非常適合使用零星 GPU 的推論工作負載。
執行下列步驟。
-
使用名為 的檔案定義時間分割
ResourceClaimTemplate
的timeslicing-claim-template.yaml
:--- apiVersion: v1 kind: Namespace metadata: name: timeslicing-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: timeslicing-gpu-template namespace: timeslicing-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: TimeSlicing
-
使用具有名為 的檔案的時間分割來定義 Pod
timeslicing-pod.yaml
:--- # Pod 1 - Inference workload apiVersion: v1 kind: Pod metadata: name: inference-pod-1 namespace: timeslicing-gpu labels: app: gpu-inference spec: restartPolicy: Never containers: - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 1 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate inference workload for i in range(20): x = torch.randn(1000, 1000).cuda() y = torch.mm(x, x.t()) print(f"Pod 1 - Iteration {i+1} completed at {time.strftime('%H:%M:%S')}") time.sleep(60) else: print("No GPU available!") time.sleep(5) resources: claims: - name: shared-gpu-claim resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule --- # Pod 2 - Training workload apiVersion: v1 kind: Pod metadata: name: training-pod-2 namespace: timeslicing-gpu labels: app: gpu-training spec: restartPolicy: Never containers: - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import time import os print(f"=== POD 2 STARTING ===") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Simulate training workload with heavier compute for i in range(15): x = torch.randn(2000, 2000).cuda() y = torch.mm(x, x.t()) loss = torch.sum(y) print(f"Pod 2 - Training step {i+1}, Loss: {loss.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(5) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim-2 resourceClaims: - name: shared-gpu-claim-2 resourceClaimTemplateName: timeslicing-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
-
套用範本和 Pod:
kubectl apply -f timeslicing-claim-template.yaml kubectl apply -f timeslicing-pod.yaml
-
監控資源宣告:
kubectl get resourceclaims -n timeslicing-gpu -w
下列為範例輸出:
NAME STATE AGE inference-pod-1-shared-gpu-claim-9p97x allocated,reserved 21s training-pod-2-shared-gpu-claim-2-qghnb pending 21s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb pending 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s training-pod-2-shared-gpu-claim-2-qghnb allocated,reserved 105s inference-pod-1-shared-gpu-claim-9p97x pending 105s
第一個 Pod (inference-pod-1
)
-
狀態:
allocated,reserved
-
意義:DRA 找到可用的 GPU,並預留給此 Pod
-
Pod 狀態:立即開始執行
第二個 Pod (training-pod-2
)
-
狀態:
pending
-
意義:等待 DRA 在相同 GPU 上設定時間分割
-
Pod 狀態:等待排程
-
狀態將從 移至
pending
allocated,reserved
至running
使用 MPS 最佳化 GPU 工作負載
多程序服務 (MPS) 可在單一 GPU 上並行執行多個 CUDA 內容,比時間分割具有更好的隔離能力。
執行下列步驟。
-
使用名為 的檔案為
ResourceClaimTemplate
MPS 定義mps-claim-template.yaml
:--- apiVersion: v1 kind: Namespace metadata: name: mps-gpu --- apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mps-gpu-template namespace: mps-gpu spec: spec: devices: requests: - name: shared-gpu deviceClassName: gpu.nvidia.com config: - requests: ["shared-gpu"] opaque: driver: gpu.nvidia.com parameters: apiVersion: resource.nvidia.com/v1beta1 kind: GpuConfig sharing: strategy: MPS
-
使用 MPS 搭配名為 的檔案來定義 Pod
mps-pod.yaml
:--- # Single Pod with Multiple Containers sharing GPU via MPS apiVersion: v1 kind: Pod metadata: name: mps-multi-container-pod namespace: mps-gpu labels: app: mps-demo spec: restartPolicy: Never containers: # Container 1 - Inference workload - name: inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== INFERENCE CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create inference model model = nn.Sequential( nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 100) ).cuda() # Run inference for i in range(1, 999999): with torch.no_grad(): x = torch.randn(128, 1000).cuda() output = model(x) result = torch.sum(output) print(f"Inference Container PID {os.getpid()}: Batch {i}, Result: {result.item():.2f} at {time.strftime('%H:%M:%S')}") time.sleep(2) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu # Container 2 - Training workload - name: training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "-c"] args: - | import torch import torch.nn as nn import time import os print(f"=== TRAINING CONTAINER STARTING ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Current GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB") # Create training model model = nn.Sequential( nn.Linear(2000, 1000), nn.ReLU(), nn.Linear(1000, 500), nn.ReLU(), nn.Linear(500, 10) ).cuda() criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # Run training for epoch in range(1, 999999): x = torch.randn(64, 2000).cuda() target = torch.randn(64, 10).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, target) loss.backward() optimizer.step() print(f"Training Container PID {os.getpid()}: Epoch {epoch}, Loss: {loss.item():.4f} at {time.strftime('%H:%M:%S')}") time.sleep(3) else: print("No GPU available!") time.sleep(60) resources: claims: - name: shared-gpu-claim request: shared-gpu resourceClaims: - name: shared-gpu-claim resourceClaimTemplateName: mps-gpu-template nodeSelector: NodeGroupType: "gpu-dra" nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
-
套用範本並建立多個 MPS Pod:
kubectl apply -f mps-claim-template.yaml kubectl apply -f mps-pod.yaml
-
監控資源宣告:
kubectl get resourceclaims -n mps-gpu -w
下列為範例輸出:
NAME STATE AGE mps-multi-container-pod-shared-gpu-claim-2p9kx allocated,reserved 86s
此組態透過動態資源分配 (DRA),使用 NVIDIA Multi-Process Service (MPS) 示範真正的 GPU 共用。與使用 GPU 依序輪換工作負載的時間分割不同,MPS 可讓兩個容器同時在相同的實體 GPU 上執行。關鍵洞見是 DRA MPS 共用需要單一 Pod 中的多個容器,而不是多個單獨的 Pod。部署時,DRA 驅動程式會將一個配置ResourceClaim
給 Pod,並自動設定 MPS,以允許推論和訓練容器同時執行。
每個容器都有自己的隔離 GPU 記憶體空間和運算資源,搭配 MPS 協助程式來協調基礎硬體的存取。您可以執行下列動作來驗證是否正常運作:
-
檢查
nvidia-smi
,這會將兩個容器顯示為共用相同 GPU 裝置的 M+C (MPS + Compute
) 程序。 -
從兩個容器監控日誌,這會顯示可同時執行的交錯時間戳記。
這種方法允許互補工作負載有效率地共用昂貴的 GPU 硬體,而不是讓單一程序未充分利用 GPU 使用率,從而最大限度地提高 GPU 使用率。
Container1: inference-container
root@mps-multi-container-pod:/workspace# nvidia-smi
Wed Jul 16 21:09:30 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| 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 NVIDIA L4 On | 00000000:35:00.0 Off | 0 |
| N/A 48C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 1 M+C python 246MiB |
+-----------------------------------------------------------------------------------------+
Container2: training-container
root@mps-multi-container-pod:/workspace# nvidia-smi
Wed Jul 16 21:16:00 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.9 |
|-----------------------------------------+------------------------+----------------------+
| 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 NVIDIA L4 On | 00000000:35:00.0 Off | 0 |
| N/A 51C P0 28W / 72W | 597MiB / 23034MiB | 0% E. Process |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 1 M+C python 314MiB |
+-----------------------------------------------------------------------------------------+
使用多執行個體 GPU 最佳化 GPU 工作負載
多執行個體 GPU (MIG) 提供硬體層級分割,以專用運算和記憶體資源建立隔離的 GPU 執行個體。
搭配各種設定檔使用動態 MIG 分割需要 NVIDIA GPU OperatorWITH0—REBOOT=true
中啟用 對成功的 MIG 部署至關重要。
您需要 NVIDIA DRA 驅動程式
步驟 1:部署 NVIDIA GPU Operator
-
新增 NVIDIA GPU Operator 儲存庫:
helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update
-
建立
gpu-operator-values.yaml
檔案:driver: enabled: false mig: strategy: mixed migManager: enabled: true env: - name: WITH_REBOOT value: "true" config: create: true name: custom-mig-parted-configs default: "all-disabled" data: config.yaml: |- version: v1 mig-configs: all-disabled: - devices: all mig-enabled: false # P4D profiles (A100 40GB) p4d-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.5gb": 2 "2g.10gb": 1 "3g.20gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false # P4DE profiles (A100 80GB) p4de-half-balanced: - devices: [0, 1, 2, 3] mig-enabled: true mig-devices: "1g.10gb": 2 "2g.20gb": 1 "3g.40gb": 1 - devices: [4, 5, 6, 7] mig-enabled: false devicePlugin: enabled: true config: name: "" create: false default: "" toolkit: enabled: true nfd: enabled: true gfd: enabled: true dcgmExporter: enabled: true serviceMonitor: enabled: true interval: 15s honorLabels: false additionalLabels: release: kube-prometheus-stack nodeStatusExporter: enabled: false operator: defaultRuntime: containerd runtimeClass: nvidia resources: limits: cpu: 500m memory: 350Mi requests: cpu: 200m memory: 100Mi daemonsets: tolerations: - key: "nvidia.com/gpu" operator: "Exists" effect: "NoSchedule" nodeSelector: accelerator: nvidia priorityClassName: system-node-critical
-
使用
gpu-operator-values.yaml
檔案安裝 GPU Operator:helm install gpu-operator nvidia/gpu-operator \ --namespace gpu-operator \ --create-namespace \ --version v25.3.1 \ --values gpu-operator-values.yaml
此 Helm Chart 部署下列元件和多個 MIG 設定檔:
-
裝置外掛程式 (GPU 資源排程)
-
DCGM Exporter (GPU 指標和監控)
-
節點功能探索 (NFD - 硬體標籤)
-
GPU 功能探索 (GFD - GPU 特定標籤)
-
MIG Manager (多執行個體 GPU 分割)
-
Container Toolkit (GPU 容器執行時間)
-
運算子控制器 (生命週期管理)
-
-
驗證部署 Pod:
kubectl get pods -n gpu-operator
下列為範例輸出:
NAME READY STATUS RESTARTS AGE gpu-feature-discovery-27rdq 1/1 Running 0 3h31m gpu-operator-555774698d-48brn 1/1 Running 0 4h8m nvidia-container-toolkit-daemonset-sxmh9 1/1 Running 1 (3h32m ago) 4h1m nvidia-cuda-validator-qb77g 0/1 Completed 0 3h31m nvidia-dcgm-exporter-cvzd7 1/1 Running 0 3h31m nvidia-device-plugin-daemonset-5ljm5 1/1 Running 0 3h31m nvidia-gpu-operator-node-feature-discovery-gc-67f66fc557-q5wkt 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-master-5d8ffddcsl6s6 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-6t4w7 1/1 Running 1 (3h32m ago) 4h1m nvidia-gpu-operator-node-feature-discovery-worker-9w7g8 1/1 Running 0 4h8m nvidia-gpu-operator-node-feature-discovery-worker-k5fgs 1/1 Running 0 4h8m nvidia-mig-manager-zvf54 1/1 Running 1 (3h32m ago) 3h35m
-
使用 p4De 受管節點群組建立 Amazon EKS 叢集,以測試 MIG 範例:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: dra-eks-cluster region: us-east-1 version: '1.33' managedNodeGroups: # P4DE MIG Node Group with Capacity Block Reservation - name: p4de-mig-nodes amiFamily: AmazonLinux2023 instanceType: p4de.24xlarge # Capacity settings desiredCapacity: 0 minSize: 0 maxSize: 1 # Use specific subnet in us-east-1b for capacity reservation subnets: - us-east-1b # AL2023 NodeConfig for RAID0 local storage only nodeadmConfig: apiVersion: node.eks.aws/v1alpha1 kind: NodeConfig spec: instance: localStorage: strategy: RAID0 # Node labels for MIG configuration labels: nvidia.com/gpu.present: "true" nvidia.com/gpu.product: "A100-SXM4-80GB" nvidia.com/mig.config: "p4de-half-balanced" node-type: "p4de" vpc.amazonaws.com/efa.present: "true" accelerator: "nvidia" # Node taints taints: - key: nvidia.com/gpu value: "true" effect: NoSchedule # EFA support efaEnabled: true # Placement group for high-performance networking placementGroup: groupName: p4de-placement-group strategy: cluster # Capacity Block Reservation (CBR) # Ensure CBR ID matches the subnet AZ with the Nodegroup subnet spot: false capacityReservation: capacityReservationTarget: capacityReservationId: "cr-abcdefghij" # Replace with your capacity reservation ID
NVIDIA GPU Operator 使用新增至節點的標籤,
nvidia.com/mig.config: "p4de-half-balanced"
並以指定的設定檔分割 GPU。 -
登入
p4de
執行個體。 -
執行以下命令:
nvidia-smi -L
您應該會看到下列範例輸出:
[root@ip-100-64-173-145 bin]# nvidia-smi -L GPU 0: NVIDIA A100-SXM4-80GB (UUID: GPU-ab52e33c-be48-38f2-119e-b62b9935925a) MIG 3g.40gb Device 0: (UUID: MIG-da972af8-a20a-5f51-849f-bc0439f7970e) MIG 2g.20gb Device 1: (UUID: MIG-7f9768b7-11a6-5de9-a8aa-e9c424400da4) MIG 1g.10gb Device 2: (UUID: MIG-498adad6-6cf7-53af-9d1a-10cfd1fa53b2) MIG 1g.10gb Device 3: (UUID: MIG-3f55ef65-1991-571a-ac50-0dbf50d80c5a) GPU 1: NVIDIA A100-SXM4-80GB (UUID: GPU-0eabeccc-7498-c282-0ac7-d3c09f6af0c8) MIG 3g.40gb Device 0: (UUID: MIG-80543849-ea3b-595b-b162-847568fe6e0e) MIG 2g.20gb Device 1: (UUID: MIG-3af1958f-fac4-59f1-8477-9f8d08c55029) MIG 1g.10gb Device 2: (UUID: MIG-401088d2-716f-527b-a970-b1fc7a4ac6b2) MIG 1g.10gb Device 3: (UUID: MIG-8c56c75e-5141-501c-8f43-8cf22f422569) GPU 2: NVIDIA A100-SXM4-80GB (UUID: GPU-1c7a1289-243f-7872-a35c-1d2d8af22dd0) MIG 3g.40gb Device 0: (UUID: MIG-e9b44486-09fc-591a-b904-0d378caf2276) MIG 2g.20gb Device 1: (UUID: MIG-ded93941-9f64-56a3-a9b1-a129c6edf6e4) MIG 1g.10gb Device 2: (UUID: MIG-6c317d83-a078-5c25-9fa3-c8308b379aa1) MIG 1g.10gb Device 3: (UUID: MIG-2b070d39-d4e9-5b11-bda6-e903372e3d08) GPU 3: NVIDIA A100-SXM4-80GB (UUID: GPU-9a6250e2-5c59-10b7-2da8-b61d8a937233) MIG 3g.40gb Device 0: (UUID: MIG-20e3cd87-7a57-5f1b-82e7-97b14ab1a5aa) MIG 2g.20gb Device 1: (UUID: MIG-04430354-1575-5b42-95f4-bda6901f1ace) MIG 1g.10gb Device 2: (UUID: MIG-d62ec8b6-e097-5e99-a60c-abf8eb906f91) MIG 1g.10gb Device 3: (UUID: MIG-fce20069-2baa-5dd4-988a-cead08348ada) GPU 4: NVIDIA A100-SXM4-80GB (UUID: GPU-5d09daf0-c2eb-75fd-3919-7ad8fafa5f86) GPU 5: NVIDIA A100-SXM4-80GB (UUID: GPU-99194e04-ab2a-b519-4793-81cb2e8e9179) GPU 6: NVIDIA A100-SXM4-80GB (UUID: GPU-c1a1910f-465a-e16f-5af1-c6aafe499cd6) GPU 7: NVIDIA A100-SXM4-80GB (UUID: GPU-c2cfafbc-fd6e-2679-e955-2a9e09377f78)
NVIDIA GPU Operator 已成功將 p4de-half-balanced
MIG 設定檔套用至 P4DE 執行個體,並依設定建立硬體層級 GPU 分割區。以下是分割的運作方式:
GPU Operator 從您的內嵌 MIG 設定檔套用此組態:
p4de-half-balanced:
- devices: [0, 1, 2, 3] # First 4 GPUs: MIG enabled
mig-enabled: true
mig-devices:
"1g.10gb": 2 # 2x small instances (10GB each)
"2g.20gb": 1 # 1x medium instance (20GB)
"3g.40gb": 1 # 1x large instance (40GB)
- devices: [4, 5, 6, 7] # Last 4 GPUs: Full GPUs
mig-enabled: false
從您的nvidia-smi -L
輸出中,GPU Operator 建立的內容如下:
-
啟用 MIG 的 GPUs (0-3):硬體分割
-
GPU 0:NVIDIA A100-SXM4-80GB
-
MIG 3g.40gb 裝置 0 – 大型工作負載 (40GB 記憶體、42 個 SMs)
-
MIG 2g.20gb 裝置 1 – 中型工作負載 (20GB 記憶體、28 個 SMs)
-
MIG 1g.10gb 裝置 2 – 小型工作負載 (10GB 記憶體、14 個 SMs)
-
MIG 1g.10gb 裝置 3 – 小型工作負載 (10GB 記憶體、14 個 SMs)
-
-
GPU 1:NVIDIA A100-SXM4-80GB
-
MIG 3g.40gb 裝置 0 – 相同的分割區配置
-
MIG 2g.20gb 裝置 1
-
MIG 1g.10gb 裝置 2
-
MIG 1g.10gb 裝置 3
-
-
GPU 2 和 GPU 3 – 與 GPU 0 和 GPU 1 相同的模式
-
-
完整 GPUs (4-7):無 MIG 分割
-
GPU 4:NVIDIA A100-SXM4-80GB – 完整 80GB GPU
-
GPU 5:NVIDIA A100-SXM4-80GB – 完整 80GB GPU
-
GPU 6:NVIDIA A100-SXM4-80GB – 完整 80GB GPU
-
GPU 7:NVIDIA A100-SXM4-80GB – 完整 80GB GPU
-
NVIDIA GPU Operator 建立 MIG 分割區後,NVIDIA DRA 驅動程式會自動偵測這些硬體隔離的執行個體,並將其用於 Kubernetes 中的動態資源配置。DRA 驅動程式會使用其特定設定檔 (1g.10gb、2g.20gb、3g.40gb) 探索每個 MIG 執行個體,並透過mig.nvidia.com
裝置類別將其公開為可排程的資源。
DRA 驅動程式會持續監控 MIG 拓撲,並維護所有 GPUs 中可用執行個體的庫存。當 Pod 透過 請求特定 MIG 設定檔時ResourceClaimTemplate
,DRA 驅動程式會智慧地從任何可用的 GPU 選取適當的 MIG 執行個體,從而實現真正的硬體層級多租用戶。此動態配置可讓多個隔離的工作負載同時在相同的實體 GPU 上執行,同時維持嚴格的資源界限和效能保證。
步驟 2:測試 MIG 資源配置
現在,讓我們執行一些範例,示範 DRA 如何將 MIG 執行個體動態分配給不同的工作負載。部署 resourceclaimtemplates
和 測試 Pod,以查看 DRA 驅動程式如何在可用的 MIG 分割區之間放置工作負載,允許多個容器與硬體層級隔離共用 GPU 資源。
-
建立
mig-claim-template.yaml
以包含 MIGresourceclaimtemplates
:apiVersion: v1 kind: Namespace metadata: name: mig-gpu --- # Template for 3g.40gb MIG instance (Large training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-large-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-large deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '3g.40gb' --- # Template for 2g.20gb MIG instance (Medium training) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-medium-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-medium deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '2g.20gb' --- # Template for 1g.10gb MIG instance (Small inference) apiVersion: resource.k8s.io/v1beta1 kind: ResourceClaimTemplate metadata: name: mig-small-template namespace: mig-gpu spec: spec: devices: requests: - name: mig-small deviceClassName: mig.nvidia.com selectors: - cel: expression: | device.attributes['gpu.nvidia.com'].profile == '1g.10gb'
-
套用三個範本:
kubectl apply -f mig-claim-template.yaml
-
執行以下命令:
kubectl get resourceclaimtemplates -n mig-gpu
下列為範例輸出:
NAME AGE mig-large-template 71m mig-medium-template 71m mig-small-template 71m
-
建立
mig-pod.yaml
以排程多個任務,以利用此resourceclaimtemplates
:--- # ConfigMap containing Python scripts for MIG pods apiVersion: v1 kind: ConfigMap metadata: name: mig-scripts-configmap namespace: mig-gpu data: large-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== LARGE TRAINING POD (3g.40gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Large model for 3g.40gb instance model = nn.Sequential( nn.Linear(2048, 1024), nn.ReLU(), nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Large batch for 3g.40gb x = torch.randn(256, 2048).cuda() y = torch.randint(0, 10, (256,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Large Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(3) print("Large training completed on 3g.40gb MIG instance") medium-training-script.py: | import torch import torch.nn as nn import torch.optim as optim import time import os print(f"=== MEDIUM TRAINING POD (2g.20gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Medium model for 2g.20gb instance model = nn.Sequential( nn.Linear(1024, 512), nn.ReLU(), nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() optimizer = optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Training loop for epoch in range(100): # Medium batch for 2g.20gb x = torch.randn(128, 1024).cuda() y = torch.randint(0, 10, (128,)).cuda() optimizer.zero_grad() output = model(x) loss = criterion(output, y) loss.backward() optimizer.step() if epoch % 10 == 0: print(f"Medium Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(4) print("Medium training completed on 2g.20gb MIG instance") small-inference-script.py: | import torch import torch.nn as nn import time import os print(f"=== SMALL INFERENCE POD (1g.10gb) ===") print(f"Process ID: {os.getpid()}") print(f"GPU available: {torch.cuda.is_available()}") print(f"GPU count: {torch.cuda.device_count()}") if torch.cuda.is_available(): device = torch.cuda.current_device() print(f"Using GPU: {torch.cuda.get_device_name(device)}") print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB") # Small model for 1g.10gb instance model = nn.Sequential( nn.Linear(512, 256), nn.ReLU(), nn.Linear(256, 10) ).cuda() print(f"Model parameters: {sum(p.numel() for p in model.parameters())}") # Inference loop for i in range(200): with torch.no_grad(): # Small batch for 1g.10gb x = torch.randn(32, 512).cuda() output = model(x) prediction = torch.argmax(output, dim=1) if i % 20 == 0: print(f"Small Inference - Batch {i}, Predictions: {prediction[:5].tolist()}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB") time.sleep(2) print("Small inference completed on 1g.10gb MIG instance") --- # Pod 1: Large training workload (3g.40gb) apiVersion: v1 kind: Pod metadata: name: mig-large-training-pod namespace: mig-gpu labels: app: mig-large-training workload-type: training spec: restartPolicy: Never containers: - name: large-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/large-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-large-claim resourceClaims: - name: mig-large-claim resourceClaimTemplateName: mig-large-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 2: Medium training workload (2g.20gb) - can run on SAME GPU as Pod 1 apiVersion: v1 kind: Pod metadata: name: mig-medium-training-pod namespace: mig-gpu labels: app: mig-medium-training workload-type: training spec: restartPolicy: Never containers: - name: medium-training-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/medium-training-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-medium-claim resourceClaims: - name: mig-medium-claim resourceClaimTemplateName: mig-medium-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755 --- # Pod 3: Small inference workload (1g.10gb) - can run on SAME GPU as Pod 1 & 2 apiVersion: v1 kind: Pod metadata: name: mig-small-inference-pod namespace: mig-gpu labels: app: mig-small-inference workload-type: inference spec: restartPolicy: Never containers: - name: small-inference-container image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["python", "/scripts/small-inference-script.py"] volumeMounts: - name: script-volume mountPath: /scripts readOnly: true resources: claims: - name: mig-small-claim resourceClaims: - name: mig-small-claim resourceClaimTemplateName: mig-small-template nodeSelector: node.kubernetes.io/instance-type: p4de.24xlarge nvidia.com/gpu.present: "true" tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule volumes: - name: script-volume configMap: name: mig-scripts-configmap defaultMode: 0755
-
套用此規格,應部署三個 Pod:
kubctl apply -f mig-pod.yaml
這些 Pod 應由 DRA 驅動程式排程。
-
檢查 DRA 驅動程式 Pod 日誌,您會看到類似以下的輸出:
I0717 21:50:22.925811 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:22.932499 1 driver.go:129] Returning newly prepared devices for claim '933e9c72-6fd6-49c5-933c-a896407dc6d1': [&Device{RequestNames:[mig-large],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-0-mig-9-4-4,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-0-mig-9-4-4**],}] I0717 21:50:23.186472 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.191226 1 driver.go:129] Returning newly prepared devices for claim '61e5ddd2-8c2e-4c19-93ae-d317fecb44a4': [&Device{RequestNames:[mig-medium],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-2-mig-14-0-2,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-2-mig-14-0-2**],}] I0717 21:50:23.450024 1 driver.go:87] NodePrepareResource is called: number of claims: 1 I0717 21:50:23.455991 1 driver.go:129] Returning newly prepared devices for claim '1eda9b2c-2ea6-401e-96d0-90e9b3c111b5': [&Device{RequestNames:[mig-small],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-1-mig-19-2-1,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-1-mig-19-2-1**],}]
-
驗證
resourceclaims
以查看 Pod 狀態:kubectl get resourceclaims -n mig-gpu -w
下列為範例輸出:
NAME STATE AGE mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 pending 0s mig-large-training-pod-mig-large-claim-6dpn8 allocated,reserved 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 pending 0s mig-medium-training-pod-mig-medium-claim-bk596 allocated,reserved 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 pending 0s mig-small-inference-pod-mig-small-claim-d2t58 allocated,reserved 0s
如您所見,DRA 驅動程式會將所有 Pod 從待定移至
allocated,reserved
。 -
nvidia-smi
從節點執行 。您會注意到有三個 Python 處理器正在執行:root@ip-100-64-173-145 bin]# nvidia-smi +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.8 | |-----------------------------------------+------------------------+----------------------+ | 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 NVIDIA A100-SXM4-80GB On | 00000000:10:1C.0 Off | On | | N/A 63C P0 127W / 400W | 569MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA A100-SXM4-80GB On | 00000000:10:1D.0 Off | On | | N/A 56C P0 121W / 400W | 374MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 2 NVIDIA A100-SXM4-80GB On | 00000000:20:1C.0 Off | On | | N/A 63C P0 128W / 400W | 467MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 3 NVIDIA A100-SXM4-80GB On | 00000000:20:1D.0 Off | On | | N/A 57C P0 118W / 400W | 249MiB / 81920MiB | N/A Default | | | | Enabled | +-----------------------------------------+------------------------+----------------------+ | 4 NVIDIA A100-SXM4-80GB On | 00000000:90:1C.0 Off | 0 | | N/A 51C P0 77W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 5 NVIDIA A100-SXM4-80GB On | 00000000:90:1D.0 Off | 0 | | N/A 46C P0 69W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 6 NVIDIA A100-SXM4-80GB On | 00000000:A0:1C.0 Off | 0 | | N/A 52C P0 74W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 7 NVIDIA A100-SXM4-80GB On | 00000000:A0:1D.0 Off | 0 | | N/A 47C P0 72W / 400W | 0MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | MIG devices: | +------------------+----------------------------------+-----------+-----------------------+ | GPU GI CI MIG | Memory-Usage | Vol| Shared | | ID ID Dev | BAR1-Usage | SM Unc| CE ENC DEC OFA JPG | | | | ECC| | |==================+==================================+===========+=======================| | 0 2 0 0 | 428MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 2MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 3 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 9 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 0 10 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 13 0 2 | 161MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 2MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 1 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 5 0 1 | 289MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 2MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 2 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 | | | 0MiB / 32767MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 | | | 0MiB / 16383MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ | 3 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 | | | 0MiB / 8191MiB | | | +------------------+----------------------------------+-----------+-----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| **| 0 2 0 64080 C python 312MiB | | 1 13 0 64085 C python 118MiB | | 2 5 0 64073 C python 210MiB |** +-----------------------------------------------------------------------------------------+
使用 GB200 P6e 執行個體透過 IMEX 最佳化 GPU 工作負載
IMEX (Internode Memory Exchange) 可讓跨節點的記憶體一致性通訊,以便在 NVIDIA GB200 UltraClusters 上進行分散式訓練。
執行下列步驟。
-
使用名為 的檔案為
ComputeDomain
多節點訓練定義imex-compute-domain.yaml
:apiVersion: resource.nvidia.com/v1beta1 kind: ComputeDomain metadata: name: distributed-training-domain namespace: default spec: numNodes: 2 channel: resourceClaimTemplate: name: imex-channel-template
-
使用 IMEX 頻道搭配名為 的檔案來定義 Pod
imex-pod.yaml
:apiVersion: v1 kind: Pod metadata: name: imex-distributed-training namespace: default labels: app: imex-training spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: nvidia.com/gpu.clique operator: Exists containers: - name: distributed-training image: nvcr.io/nvidia/pytorch:25.04-py3 command: ["bash", "-c"] args: - | echo "=== IMEX Channel Verification ===" ls -la /dev/nvidia-caps-imex-channels/ echo "" echo "=== GPU Information ===" nvidia-smi echo "" echo "=== NCCL Test (if available) ===" python -c " import torch import torch.distributed as dist import os print(f'CUDA available: {torch.cuda.is_available()}') print(f'CUDA device count: {torch.cuda.device_count()}') if torch.cuda.is_available(): for i in range(torch.cuda.device_count()): print(f'GPU {i}: {torch.cuda.get_device_name(i)}') # Check for IMEX environment variables imex_vars = [k for k in os.environ.keys() if 'IMEX' in k or 'NVLINK' in k] if imex_vars: print('IMEX Environment Variables:') for var in imex_vars: print(f' {var}={os.environ[var]}') print('IMEX channel verification completed') " # Keep container running for inspection sleep 3600 resources: claims: - name: imex-channel-0 - name: imex-channel-1 resourceClaims: - name: imex-channel-0 resourceClaimTemplateName: imex-channel-template - name: imex-channel-1 resourceClaimTemplateName: imex-channel-template tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule
注意
這需要 P6e GB200 執行個體。
-
透過套用
ComputeDomain
和 範本來部署 IMEX:kubectl apply -f imex-claim-template.yaml kubectl apply -f imex-compute-domain.yaml kubectl apply -f imex-pod.yaml
-
檢查
ComputeDomain
狀態。kubectl get computedomain distributed-training-domain
-
監控 IMEX 協助程式部署。
kubectl get pods -n nvidia-dra-driver -l [resource.nvidia.com/computeDomain](http://resource.nvidia.com/computeDomain)
-
檢查 Pod 中的 IMEX 頻道:
kubectl exec imex-distributed-training -- ls -la /dev/nvidia-caps-imex-channels/
-
檢視 Pod 日誌:
kubectl logs imex-distributed-training
以下是預期輸出的範例:
=== IMEX Channel Verification === total 0 drwxr-xr-x. 2 root root 80 Jul 8 10:45 . drwxr-xr-x. 6 root root 380 Jul 8 10:45 .. crw-rw-rw-. 1 root root 241, 0 Jul 8 10:45 channel0 crw-rw-rw-. 1 root root 241, 1 Jul 8 10:45 channel1
如需詳細資訊,請參閱 GitHub 上的 NVIDIA 範例