翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
コンピューティングと自動スケーリング
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 Device Plugin を使用して GPUs
GPUs をノードに公開するには、NVIDIA GPU ドライバーをノードのオペレーティングシステムとコンテナランタイムにインストールし、Kubernetes スケジューラが使用可能な GPUs を持つノードにポッドを割り当てることができるように設定する必要があります。NVIDIA Kubernetes Device Plugin のセットアッププロセスは、使用している EKS Accelerated AMI によって異なります。
-
Bottlerocket Accelerated AMI: この AMI には NVIDIA GPU ドライバーが含まれており、NVIDIA Kubernetes Device Plugin
がプリインストールされ、すぐに使用できるため、GPU サポートがすぐに利用できます。GPUs を Kubernetes スケジューラに公開するために、追加の設定は必要ありません。 -
AL2023 Accelerated AMI
: この AMI には NVIDIA GPU ドライバーが含まれていますが、NVIDIA Kubernetes Device Plugin はプリインストールされていません。デバイスプラグインは、通常は DaemonSet を介して個別にインストールおよび設定する必要があります。eksctl を使用してクラスターを作成し、ClusterConfig で GPU インスタンスタイプ ( など g5.xlarge
) を指定すると、eksctl
は自動的に高速 AMI を選択し、ノードグループ内の各インスタンスに NVIDIA Kubernetes Device Plugin をインストールします。詳細については、eksctl ドキュメントの「GPU サポート」を参照してください。
NVIDIA Device Plugin がアクティブで GPUsが正しく公開されていることを確認するには、以下を実行します。
kubectl describe node | grep nvidia.com/gpu
このコマンドは、nvidia.com/gpu
リソースがノードの容量と割り当て可能なリソースにあるかどうかを確認します。たとえば、1 つの GPU を持つノードには が表示されますnvidia.com/gpu: 1
。詳細については、Kubernetes GPU スケジューリングガイド
P インスタンスと Trainium インスタンスの容量保証に ML キャパシティブロックを使用する
ML のキャパシティブロックを使用すると、需要の高い GPU インスタンス、特に P インスタンス (p6-b200、p5、p5e、p5en、p4d、p4de など) と Trainium インスタンス (trn1、trn2 など) を予約して、短期間の機械学習 (ML) ワークロードをサポートするためにほぼ即時または将来の日付に開始できます。これらの予約は、モデルトレーニングやファインチューニングなどの計算負荷の高いタスクの容量を確保するのに最適です。EC2 キャパシティブロックの料金は、予約料金とオペレーティングシステム料金で構成されます。料金の詳細については、「ML 料金の EC2 キャパシティブロック
予測可能なキャパシティ保証のために Amazon EKS の AI/ML ワークロード用の GPUs を予約するには、短期またはオンデマンドキャパシティ予約 (ODCR) に ML キャパシティブロックを活用して汎用キャパシティ保証を行うことをお勧めします。 ODCRs
-
ODCRsを使用すると、特定のアベイラビリティーゾーンの EC2 インスタンス容量 (g5 や p5 などの GPU インスタンスなど) を一定期間予約できるため、需要が高い場合でも可用性を確保できます。ODCRsには長期的なコミットメントはありませんが、使用の有無にかかわらず、リザーブドキャパシティのオンデマンド料金を支払います。EKS では、ODCRs は Karpenter
やマネージド型ノードグループなどのノードタイプでサポートされています。Karpenter で ODCRs に優先順位を付けるには、 capacityReservationSelectorTerms
フィールドを使用するように NodeClass を設定します。Karpenter NodePools ドキュメントを参照してください。 -
キャパシティブロックは、GPU (p5、p4d など) または Trainium (trn1、trn2) インスタンス専用の予約メカニズムであり、モデルトレーニング、ファインチューニング、実験などの短期 ML ワークロード向けに設計されています。将来の日付から始まる定義された期間 (通常は 24 時間~182 日) のキャパシティーを予約し、予約時間に対してのみ支払います。これらは前払いであり、容量のニーズに応じて事前に計画する必要があり、自動スケーリングをサポートしていませんが、低レイテンシーのネットワーキングのために EC2 UltraClusters にコロケーションされています。予約期間中のみ課金されます。詳細については、「キャパシティブロックの検索と購入」を参照するか、「Create a managed node group with Capacity Blocks for ML」の手順に従ってキャパシティブロックでマネージドノードグループを設定して開始してください。
AWS マネジメントコンソールを使用してキャパシティを予約し、ML キャパシティブロックを使用するようにノードを設定します。ワークロードスケジュールに基づいて予約を計画し、ステージングクラスターでテストします。詳細については、キャパシティブロックのドキュメントを参照してください。
G Amazon EC2 インスタンスのオンデマンド、Amazon EC2 スポット、またはオンデマンドキャパシティ予約 (ODCRs) を検討する
G Amazon EC2 インスタンスでは、オンデマンド、Amazon EC2 スポットインスタンス、オンデマンドキャパシティ予約とは異なる購入オプションを検討してください。ODCRsを使用すると、特定のアベイラビリティーゾーンの EC2 インスタンス容量を一定期間予約できるため、需要が高い場合でも可用性を確保できます。P インスタンスと Trainium インスタンスでのみ使用できる ML キャパシティブロックとは異なり、ODCRs は G インスタンスを含む幅広いインスタンスタイプに使用できるため、推論やグラフィックスなど、さまざまな GPU 機能を必要とするワークロードに適しています。Amazon EC2 スポットインスタンスを使用する場合、さまざまなインスタンスタイプ、サイズ、アベイラビリティーゾーンを多様化できることが、スポットに長く留まるための鍵となります。
ODCRsには長期的なコミットメントはありませんが、使用の有無にかかわらず、リザーブドキャパシティのオンデマンド料金を支払います。ODCRs はすぐに使用できるように作成することも、将来の日付にスケジュールすることもできます。これにより、キャパシティプランニングを柔軟に行うことができます。Amazon EKS ODCRs は KarpentercapacityReservationSelectorTerms
フィールドを使用するように NodeClass を設定します。Karpenter NodePools ドキュメント
他の高速インスタンスタイプとサイズを検討する
Amazon EKS の ML ワークロードのパフォーマンスとコストの両方を最適化するには、適切な高速インスタンスとサイズを選択することが不可欠です。例えば、異なる GPU インスタンスファミリーには、GPU メモリなどの異なるパフォーマンスと機能があります。最も価格パフォーマンスの高いオプションを選択するには、高速コンピューティングの EC2 インスタンスタイプページで使用可能な GPU インスタンス
EKS ノードで GPU インスタンスを使用する場合、デフォルトでkube-system
は名前空間にnvidia-device-plugin-daemonset
ポッドがあります。インスタンスで 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 共有は、さまざまなオプションを通じて実現できます。
-
ノードセレクタ/ノードアフィニティを活用してスケジューリングに影響を与える: プロビジョニングされたノードとポッドがワークロードに適した GPUs でスケジュールされていることを確認します (例:
karpenter.k8s.aws/instance-gpu-name: "a100"
) -
タイムスライス: GPU のコンピューティングリソースを経時的に共有するようにワークロードをスケジュールし、物理パーティショニングなしで同時実行できるようにします。これは、コンピューティング需要が変動するワークロードに最適ですが、メモリの分離がない可能性があります。
-
マルチインスタンス GPU (MIG): MIG では、1 つの NVIDIA GPU を複数の独立したインスタンスに分割でき、NVIDIA Ampere (A100 GPU など)、NVIDIA Hopper (H100 GPU など)、NVIDIA Blackwell (Blackwell GPUs など) GPUs。各 MIG インスタンスは専用のコンピューティングリソースとメモリリソースを受け取るため、マルチテナント環境やリソースの保証を必要とするワークロードでリソースを共有できます。これにより、タイムスライスによるバッチサイズの異なる複数のモデルの提供などのシナリオで GPU リソースの使用率を最適化できます。
-
小数 GPU 割り当て: ソフトウェアベースのスケジューリングを使用して GPU のコンピューティングまたはメモリの一部をワークロードに割り当て、動的ワークロードに柔軟性を提供します。Run:ai プラットフォームの一部である NVIDIA KAI スケジューラ
は、ポッドが小数 GPU リソースをリクエストできるようにすることでこれを可能にします。
EKS でこれらの機能を有効にするには、GPUs をスケジュール可能なリソースとして公開し、タイムスライスと MIG をサポートする NVIDIA Device Plugin をデプロイできます。詳細については、「Kubernetes のタイムスライス GPUs
例
たとえば、NVIDIA Device Plugin でタイムスライスを有効にするには:
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 と一緒にデプロイし、ポッド仕様で小数 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
ノードの耐障害性とトレーニングジョブの管理
自動復旧によるノードヘルスチェックの実装
複数のノードにまたがるマルチ GPU モデルトレーニングなど、ノード間の頻繁な通信を必要とする Amazon EKS の分散トレーニングジョブでは、GPU や EFA の障害などのハードウェアの問題により、トレーニングジョブが中断される可能性があります。これらの中断により、特に安定したハードウェアに依存する長時間実行される AI/ML ワークロードでは、トレーニングの進行状況が失われ、コストが増加する可能性があります。
GPU ワークロードを実行している EKS クラスターの GPU 障害など、ハードウェア障害に対する回復力を高めるために、EKS Node Monitoring Agent with Auto Repair または Amazon SageMaker HyperPod のいずれかを利用することをお勧めします。自動修復を備えた EKS Node Monitoring Agent は、ノードのヘルスモニタリングや標準の Kubernetes メカニズムを使用した自動修復などの機能を提供しますが、SageMaker HyperPod は、ディープヘルスチェックや自動ジョブ再開など、大規模な ML トレーニング用に特別に設計されたターゲットを絞った回復力と追加機能を提供します。
-
Node Auto Repair を備えた EKS Node Monitoring Agent は、ログを読み取って NodeConditions を適用することでノードの状態を継続的にモニタリングします。これには、高速ハードウェアに固有の標準条件
Ready
や、GPU やネットワーク障害などの問題を特定するための条件が含まれます。ノードが異常であると判断された場合、ノードの自動修復はノードを遮断し、新しいノードに置き換えます。ポッドの再スケジュールとジョブの再起動は、標準の Kubernetes メカニズムとジョブの再起動ポリシーに依存します。 -
SageMaker HyperPod
のディープヘルスチェックとヘルスモニタリングエージェントは、GPU および Trainium ベースのインスタンスのヘルスステータスを継続的にモニタリングします。これは AI/ML ワークロードに合わせて調整され、ラベル (node-health-status など) を使用してノードの状態を管理します。ノードが異常と見なされると、HyperPod は GPUs。デフォルトでは、基本的なヘルスチェックを通じて EFA のネットワーク関連の障害を検出し、中断されたトレーニングジョブの自動再開をサポートしているため、最後のチェックポイントからジョブを続行できるため、大規模な ML タスクの中断を最小限に抑えることができます。
EFA を使用して Auto Repair を使用する EKS Node Monitoring Agent と SageMaker HyperPod クラスターの両方について、リモートダイレクトメモリアクセス (RDMA) エラーやパケットドロップなどの EFA 固有のメトリクスをモニタリングするには、AWS EFA ドライバーがインストールされていることを確認してください。さらに、CloudWatch Observability アドオンをデプロイするか、Prometheus と Grafana を備えた DCGM Exporter などのツールを使用して EFA、GPU、および SageMaker HyperPod の機能に関連する特定のメトリクスをモニタリングすることをお勧めします。
中断の影響を受けやすいワークロードの Karpenter 統合を無効にする
処理、大規模な AI/ML 予測タスク、トレーニングなどの中断の影響を受けやすいワークロードの場合は、ジョブ実行中の中断を防ぐために Karpenter 統合ポリシー
WhenEmptyOrUnderutilized
統合ポリシーはノードを早期に終了し、実行時間が長くなる可能性があります。例えば、ポッドの再スケジュール、データの再ロードが原因でジョブの再開が中断されると、長時間実行されるバッチ推論ジョブにはコストがかかる可能性があります。これを軽減するには、 consolidationPolicy
を に設定WhenEmpty
し、ワークロードの急増時にノードを保持するように 1 時間などのconsolidateAfter
期間を設定できます。例:
disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m
このアプローチにより、リアルタイムのオンライン推論データ処理やモデルトレーニングなど、急増するバッチ推論ワークロードやその他の中断の影響を受けやすいジョブのポッド起動レイテンシーが改善され、中断のコストがコンピューティングコスト削減を上回るようになります。Karpenter NodePool Disruption Budgets
ttlSecondsAfterFinished を使用して Kubernetes ジョブを自動クリーンアップする
Amazon EKS の Kubernetes ジョブttlSecondsAfterFinished
に対して を設定して、完了したジョブオブジェクトを自動的に削除することをお勧めします。リンガージョブオブジェクトは、API サーバーメモリなどのクラスターリソースを消費し、ダッシュボード (Grafana、Amazon CloudWatch など) を整理してモニタリングを複雑にします。例えば、TTL を 1 時間に設定すると、ジョブは完了直後に削除され、クラスターが整理されます。詳細については、「終了したジョブの自動クリーンアップ
優先度の高いジョブ/ワークロード用に優先度の低いジョブのプリエンプションを設定する
Amazon EKS の混合優先度 AI/ML ワークロードでは、優先度の高いタスク (リアルタイム推論など) がリソースを迅速に受信するように、優先度の低いジョブプリエンプションを設定できます。プリエンプションがない場合、バッチプロセス (バッチ推論、データ処理など)、非バッチサービス (バックグラウンドタスク、cron ジョブなど)、CPU/メモリ集約型ジョブ (ウェブサービスなど) などの優先度の低いワークロードは、ノードを占有することで重要なポッドを遅延させる可能性があります。プリエンプションにより、優先度の高いポッドにリソースが必要な場合に Kubernetes は優先度の低いポッドを削除できるため、GPUs、CPUs、またはメモリを備えたノードで効率的なリソース割り当てが可能になります。Kubernetes を使用して優先順位PriorityClass
を割り当てPodDisruptionBudget
、エビクション動作を制御することをお勧めします。
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 --- spec: priorityClassName: low-priority
詳細については、「Kubernetes Priority and Preemption Documentation
アプリケーションのスケーリングとパフォーマンス
Karpenter または静的ノードを使用して ML ワークロードのコンピューティング容量を調整する
Amazon EKS の機械学習 (ML) ワークフローのコスト効率と応答性を確保するため、ワークロードの特性とコストコミットメントに合わせてノードプロビジョニング戦略を調整することをお勧めします。以下は、Karpenter
-
Karpenter のようなJust-in-timeデータプレーンスケーラー: コンピューティング要求が変化する動的 ML ワークフロー (GPU ベースの推論と CPU ベースのプロットなど) では、Karpenter のようなjust-in-timeデータプレーンスケーラーを使用することをお勧めします。
-
予測可能なワークロードに静的ノードグループを使用する: 予測可能な定常状態の ML ワークロードの場合、またはリザーブドインスタンスを使用する場合、EKS マネージド型ノードグループは、リザーブドキャパシティが完全にプロビジョニングおよび利用され、節約を最大化するのに役立ちます。このアプローチは、RIs または ODCRs を介してコミットされた特定のインスタンスタイプに最適です。
例
これは、インスタンス生成が 3 より大きい g
Amazon EC2 インスタンスの起動を可能にする多様な Karpenter NodePool
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 リソースで高速化されていないワークロードをスケジュールすることはコンピューティング効率が高くないため、テイントと許容度を使用して、高速化されていないワークロードポッドが不適切なノードでスケジュールされないようにすることをお勧めします。詳細については、Kubernetes のドキュメント
モデルのパフォーマンスに基づいてスケールする
推論ワークロードの場合、Kubernetes Event-Driven Auto Scaling (KEDA) を使用して、推論リクエストやトークンスループットなどのモデルパフォーマンスメトリクスに基づいて適切なクールダウン期間でスケーリングすることをお勧めします。静的スケーリングポリシーでは、リソースのプロビジョニングが過剰または過小になり、コストとレイテンシーに影響する可能性があります。詳細については、KEDA ドキュメント
高度な GPU 管理のための動的リソース割り当て
動的リソース割り当て (DRA)
-
きめ細かな GPU 割り当て
-
マルチプロセスサービス (MPS) やマルチインスタンス GPU (MIG) などの高度な共有メカニズム
-
NVIDIA GB200 UltraClusters を含む次世代ハードウェアアーキテクチャのサポート
従来の GPU 割り当てでは、GPUs不透明な整数リソースとして扱われ、使用率が大幅に低下します (多くの場合、本番稼働用クラスターでは 30~40%)。これは、ワークロードが小数リソースのみを必要とする場合でもGPUs 全体への排他的アクセスを受け取るために発生します。DRA は、Kubernetes スケジューラにハードウェアの特性とワークロード要件を完全に可視化する構造化された宣言型割り当てを導入することで、このモデルを変換します。これにより、インテリジェントな配置の決定と効率的なリソース共有が可能になります。
NVIDIA デバイスプラグインの代わりに DRA を使用する利点
NVIDIA デバイスプラグイン (バージョン 以降0.12.0
) は、タイムスライス、MPS、MIG などの GPU 共有メカニズムをサポートしています。ただし、DRA が対処するアーキテクチャ上の制限があります。
NVIDIA デバイスプラグインの制限事項
-
静的設定: GPU 共有設定 (タイムスライスレプリカと MPS 設定) には、 を通じてクラスター全体の事前設定が必要です
ConfigMaps
。これにより、ワークロードごとに異なる共有戦略を提供することが困難になります。 -
きめ細かな選択の制限: デバイスプラグインはノードラベルを介して GPU 特性を公開しますが、ワークロードはスケジューリングの決定の一環として特定の GPU 設定 (メモリサイズとコンピューティング機能) を動的にリクエストすることはできません。
-
クロスノードリソースの調整なし: 複数のノードにまたがる分散 GPU リソースを管理したり、NVIDIA GB200 などのシステムの NVLink ドメインなどの複雑なトポロジ要件を表現したりすることはできません。
-
スケジューラの制約: Kubernetes スケジューラは GPU リソースを不透明な整数として扱い、トポロジ対応の決定や複雑なリソース依存関係の処理能力を制限します。
-
設定の複雑さ: さまざまな共有戦略をセットアップするには
ConfigMaps
、複数のノードに慎重なラベルを付ける必要があり、運用が複雑になります。
DRA を使用したソリューション
-
動的リソース選択: DRA を使用すると、ワークロードは を通じてリクエスト時に詳細な要件 (GPU メモリ、ドライバーバージョン、および特定の属性) を指定できます
resourceclaims
。これにより、より柔軟なリソースマッチングが可能になります。 -
トポロジの認識: DRA は、構造化されたパラメータとデバイスセレクタを通じて、クロスノード GPU 通信やメモリコヒーレント相互接続などの複雑な要件を処理します。
-
クロスノードリソース管理: 複数のノードにまたがる分散 GPU リソースの調整
computeDomains
を可能にします。これは、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): 1 つの GPU で複数の CUDA プロセスの同時実行を有効にします。
-
Internode Memory Exchange (IMEX): GB200 UltraClusters のノード間のメモリコヒーレント通信。
追加リソース
Kubernetes DRA および NVIDIA DRA ドライバーの詳細については、GitHub の以下のリソースを参照してください。
高度な GPU 管理のための動的リソース割り当てを設定する
次のトピックでは、高度な GPU 管理のために動的リソース割り当て (DRA) を設定する方法を示します。
前提条件
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 チャートをデプロイする
-
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
に 2 つを作成します。 -
gpu.nvidia.com
スライスは、物理 A10G GPU デバイスをその仕様 (メモリ、コンピューティング機能など) に登録します。 -
A10G は MIG パーティショニングをサポートしていないため、
compute-domain.nvidia.com
スライスは GPU のコンピューティングコンテキスト全体を表す単一のコンピューティングドメインを作成します。 -
次に
resourceslices
、これらは Kubernetes API サーバーに発行され、GPU リソースが を通じてスケジューリングできるようになりますresourceclaims
。DRA スケジューラは、 を介して GPU リソースをリクエストする Pod にこの GPU をインテリジェントに割り当てることができるようになり
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 ワークロードをスケジュールする」に進みます。
動的リソース割り当てを使用してシンプルな GPU ワークロードをスケジュールする
動的リソース割り当て (DRA) を使用してシンプルな GPU ワークロードをスケジュールするには、次の手順を実行します。先に進む前に、 に従っていることを確認してください高度な GPU 管理のための動的リソース割り当てを設定する。
-
という名前のファイルを使用して GPU 割り当て
ResourceClaimTemplate
の基本 を作成します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
で を使用する Pod を作成しますbasic-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 ワークロードを最適化するを参照してください。
これらの手法により、リソースの使用率が大幅に向上します。組織は、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
-
という名前のファイルでタイムスライスを使用してポッドを定義します
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
最初のポッド (inference-pod-1
)
-
状態:
allocated,reserved
-
意味: DRA が使用可能な GPU を見つけ、この Pod 用に予約しました
-
ポッドステータス: すぐに実行を開始します
2 番目のポッド (training-pod-2
)
-
状態:
pending
-
意味: DRA が同じ GPU でタイムスライスを設定するのを待つ
-
ポッドステータス: スケジュール待ち
-
状態は から
pending
allocated,reserved
に変わりますrunning
MPS で GPU ワークロードを最適化する
マルチプロセスサービス (MPS) を使用すると、タイムスライスよりも優れた分離で、単一の GPU で複数の CUDA コンテキストを同時に実行できます。
次の手順を実行します。
-
という名前のファイルを使用して MPS
ResourceClaimTemplate
の を定義します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 を使用してポッドを定義します
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 ドライバーは Pod ResourceClaim
に 1 つを割り当て、推論コンテナとトレーニングコンテナの両方を同時に実行できるように MPS を自動的に設定します。
各コンテナは、独自の独立した GPU メモリスペースとコンピューティングリソースを取得し、MPS デーモンは基盤となるハードウェアへのアクセスを調整します。これを動作させるには、以下を実行します。
-
をチェックすると
nvidia-smi
、両方のコンテナが同じ GPU デバイスを共有する M+C (MPS + Compute
) プロセスとして表示されます。 -
両方のコンテナからのログをモニタリングします。これにより、同時実行を証明するインターリーブタイムスタンプが表示されます。
このアプローチは、補完的なワークロードが 1 つのプロセスで十分に活用されないままにするのではなく、高価な 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 デプロイを成功させるために不可欠です。
Amazon EKS で 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 チャートは、以下のコンポーネントと複数の MIG プロファイルをデプロイします。
-
Device Plugin (GPU リソーススケジューリング)
-
DCGM Exporter (GPU メトリクスとモニタリング)
-
ノード特徴量検出 (NFD - ハードウェアラベル付け)
-
GPU 機能検出 (GFD - GPU 固有のラベル付け)
-
MIG Manager (マルチインスタンス GPU パーティショニング)
-
Container Toolkit (GPU コンテナランタイム)
-
オペレーターコントローラー (ライフサイクル管理)
-
-
デプロイポッドを確認します。
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
-
MIG の例をテストするための p4De マネージド型ノードグループを使用して Amazon EKS クラスターを作成します。
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 インスタンスに p4de-half-balanced
MIG プロファイルを正常に適用し、設定に従ってハードウェアレベルの 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 オペレーターが作成した内容は次のとおりです。
-
MIG 対応 GPUs (0~3): ハードウェアパーティション分割
-
GPU 0: NVIDIA A100-SXM4-80GB
-
MIG 3g.40gb デバイス 0 – 大規模なワークロード (40 GB メモリ、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
ポッドとテストポッドをデプロイして、DRA ドライバーが使用可能な MIG パーティションにワークロードを配置する方法を確認し、複数のコンテナがハードウェアレベルの分離で GPU リソースを共有できるようにします。
-
MIG を含める
mig-claim-template.yaml
ために を作成しますresourceclaimtemplates
。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'
-
3 つのテンプレートを適用します。
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
-
この仕様を適用し、3 つの Pod をデプロイします。
kubctl apply -f mig-pod.yaml
これらのポッドは 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 ドライバー
allocated,reserved
によって保留中から に移動しました。 -
ノード
nvidia-smi
から を実行します。3 つの 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 チャネルを使用してポッドを定義します
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 の例