Berechnung und Autoscaling - Amazon EKS

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Berechnung und Autoscaling

Optimierung der GPU-Ressourcen und Kostenmanagement

Planen Sie Workloads mit GPU-Anforderungen mithilfe von bekannten Labels

Für AI/ML Workloads, die empfindlich auf unterschiedliche GPU-Merkmale reagieren (z. B. GPU, GPU-Speicher), empfehlen wir, die GPU-Anforderungen anhand bekannter Scheduling-Labels anzugeben, die von den mit Karpenter verwendeten Knotentypen und verwalteten Knotengruppen unterstützt werden. Wenn diese nicht definiert werden, kann dies dazu führen, dass Pods auf Instanzen mit unzureichenden GPU-Ressourcen geplant werden, was zu Ausfällen oder Leistungseinbußen führen kann. Wir empfehlen, NodeSelector oder Node Affinity zu verwenden, um anzugeben, auf welchem Knoten ein Pod ausgeführt werden soll, und Rechenressourcen (CPU, Speicher GPUs usw.) im Ressourcenbereich des Pods festzulegen.

Beispiel

Verwenden Sie beispielsweise den GPU-Namen-Node-Selektor, wenn Sie Karpenter verwenden:

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

Verwenden Sie das Kubernetes Device Plugin für die Bereitstellung GPUs

Für die Bereitstellung GPUs auf Knoten muss der NVIDIA-GPU-Treiber auf dem Betriebssystem des Knotens installiert und die Container-Laufzeit so konfiguriert sein, dass der Kubernetes-Scheduler Pods Knoten zuweisen kann, auf denen sie verfügbar sind. GPUs Der Einrichtungsprozess für das NVIDIA Kubernetes Device Plugin hängt vom verwendeten EKS Accelerated AMI ab:

  • Bottlerocket Accelerated AMI: Dieses AMI beinhaltet den NVIDIA-GPU-Treiber und das NVIDIA Kubernetes Device Plugin ist vorinstalliert und sofort einsatzbereit, sodass GPU-Unterstützung sofort verfügbar ist. Für die Bereitstellung im Kubernetes-Scheduler ist keine zusätzliche Konfiguration erforderlich. GPUs

  • AL2023 Beschleunigtes AMI: Dieses AMI enthält den NVIDIA-GPU-Treiber, aber das NVIDIA Kubernetes Device Plugin ist nicht vorinstalliert. Sie müssen das Geräte-Plugin separat installieren und konfigurieren, in der Regel über ein. DaemonSet Beachten Sie, dass, wenn Sie eksctl verwenden, um Ihren Cluster zu erstellen und einen GPU-Instanztyp (z. B.g5.xlarge) in Ihrem angeben ClusterConfig, eksctl automatisch das entsprechende AMI ausgewählt und das NVIDIA Kubernetes Device Plugin installiert wird. Weitere Informationen finden Sie unter GPU-Unterstützung in der eksctl-Dokumentation.

Wenn Sie stattdessen den Operator EKS Accelerated AMIs und NVIDIA GPU verwenden möchten, um Komponenten wie das NVIDIA Kubernetes-Geräte-Plugin zu verwalten, beachten Sie, dass Sie die Verwaltung des NVIDIA-GPU-Treibers und des NVIDIA-Container-Toolkits gemäß der NVIDIA-Dokumentation zu den vorinstallierten NVIDIA-GPU-Treibern und dem NVIDIA-Container-Toolkit deaktivieren müssen.

Um zu überprüfen, ob das NVIDIA-Geräte-Plug-in aktiv ist und GPUs korrekt angezeigt wird, führen Sie folgenden Befehl aus:

kubectl describe node | grep nvidia.com/gpu

Dieser Befehl überprüft, ob die nvidia.com/gpu Ressource die Kapazität des Knotens und die zuweisbaren Ressourcen erfüllt. Zum Beispiel sollte ein Knoten mit einer GPU angezeigt werden. nvidia.com/gpu: 1 Weitere Informationen finden Sie im Kubernetes GPU Scheduling Guide.

Verwenden Sie viele verschiedene Instanztypen EC2

Die Verwendung so vieler verschiedener EC2 Instance-Typen wie möglich ist eine wichtige bewährte Methode für die Skalierbarkeit auf Amazon EKS, wie im Kubernetes-Datenebene Abschnitt beschrieben. Diese Empfehlung gilt auch für Instances mit beschleunigter Hardware (z. B. GPUs). Wenn Sie einen Cluster erstellen, der nur einen Instance-Typ verwendet, und versuchen, die Anzahl der Knoten über die Kapazität der Region hinaus zu skalieren, wird möglicherweise ein Fehler mit unzureichender Kapazität (ICE) angezeigt, der darauf hinweist, dass keine Instances verfügbar sind. Es ist wichtig, die einzigartigen Merkmale Ihrer AI/ML Workloads zu verstehen, bevor Sie sie beliebig diversifizieren. Überprüfen Sie die verfügbaren Instance-Typen mithilfe des Tools EC2 Instance Type Explorer, um eine Liste von Instance-Typen zu erstellen, die Ihren spezifischen Rechenanforderungen entsprechen, und vermeiden Sie es, die Art der Instances, die in Ihrem Cluster verwendet werden können, willkürlich einzuschränken.

Accelerated Compute Instances werden in verschiedenen Kaufmodellen angeboten, um kurzfristigen, mittelfristigen und stationären Workloads gerecht zu werden. Für kurzfristige, flexible und fehlertolerante Workloads, bei denen Sie eine Reservierung vermeiden möchten, sollten Sie sich Spot-Instances ansehen. Mit Kapazitätsblöcken, On-Demand-Instances und Speicherplänen können Sie beschleunigte Recheninstanzen für mittel- und langfristige Workloads bereitstellen. Um die Chancen zu erhöhen, erfolgreich auf die benötigte Kapazität in Ihrer bevorzugten Kaufoption zuzugreifen, wird empfohlen, eine vielfältige Liste von Instance-Typen und Availability Zones zu verwenden. Wenn Sie auf ein bestimmtes Kaufmodell stoßen ICEs , versuchen Sie es alternativ erneut mit einem anderen Modell.

Beispiel Das folgende Beispiel zeigt, wie ein Karpenter in die Lage versetzt werden kann NodePool , G- und P-Instanzen bereitzustellen, die größer sind als die Generationen 3 (z. B. p3). Weitere Informationen finden Sie im Bewährte Methoden für EKS-Skalierbarkeit Abschnitt.

- key: karpenter.k8s.aws/instance-category operator: In values: ["g", "p"] # Diversifies across G-series and P-series - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] # Selects instance generations greater than 3

Einzelheiten zur Verwendung von Spot-Instances für finden Sie weiter GPUs unten unter „Erwägen Sie die Verwendung von Amazon EC2 Spot-Instances für GPUs mit Karpenter“.

Erwägen Sie die Verwendung von Amazon EC2 Spot-Instances für GPUs mit Karpenter

Mit Amazon EC2 Spot-Instances können Sie ungenutzte EC2 Kapazitäten in der AWS-Cloud nutzen und sind mit einem discount von bis zu 90% im Vergleich zu On-Demand-Preisen erhältlich. Amazon EC2 Spot-Instances können mit einer Frist von zwei Minuten unterbrochen werden, wenn die Kapazität wieder EC2 benötigt wird. Weitere Informationen finden Sie unter Spot-Instances im EC2 Amazon-Benutzerhandbuch. Amazon EC2 Spot kann eine hervorragende Wahl für fehlertolerante, zustandslose und flexible Workloads (Zeit und Instanztyp) sein. Weitere Informationen darüber, wann Sie Spot-Instances verwenden sollten, finden Sie unter Bewährte Methoden für EC2 Spot-Instances. Sie können Spot-Instances auch für AI/ML Workloads verwenden, wenn sie Spot-freundlich sind.

Anwendungsfälle

Spot-freundliche Workloads können Big Data, containerisierte Workloads, CI/CD, statuslose Webserver, High Performance Computing (HPC) und Rendering-Workloads sein. Spot-Instances eignen sich nicht für Workloads, die unflexibel, zustandsbehaftet, fehlerintolerant oder eng zwischen Instanzknoten gekoppelt sind (z. B. Workloads mit parallel Prozessen, die bei der Berechnung stark voneinander abhängen und eine ständige Kommunikation zwischen den Knoten erfordern, wie MPI-basierte Hochleistungsrechneranwendungen wie Computational Fluid Dynamics oder verteilte Datenbanken mit komplexen Interdependenzen). Hier sind die spezifischen Anwendungsfälle, die wir empfehlen (in keiner bestimmten Reihenfolge):

  • Online-Inferenz in Echtzeit: Verwenden Sie Spot-Instances für eine kostenoptimierte Skalierung Ihrer Echtzeit-Inferenz-Workloads, sofern Ihre Workloads Spot-freundlich sind. Mit anderen Worten, die Inferenzzeit beträgt entweder weniger als zwei Minuten, die Anwendung ist fehlertolerant gegenüber Unterbrechungen und kann auf verschiedenen Instance-Typen ausgeführt werden. Stellen Sie eine hohe Verfügbarkeit durch Instanzvielfalt (z. B. über mehrere Instance-Typen und Availability Zones hinweg) oder Reservierungen sicher und implementieren Sie gleichzeitig Fehlertoleranz auf Anwendungsebene, um potenzielle Spot-Unterbrechungen zu bewältigen.

  • Hyperparameter-Tuning: Verwenden Sie Spot-Instances, um explorative Optimierungsaufträge opportunistisch auszuführen, da Unterbrechungen ohne nennenswerte Verluste toleriert werden können, insbesondere bei Experimenten mit kurzer Dauer.

  • Datenerweiterung: Verwenden Sie Spot-Instances, um Aufgaben zur Datenvorverarbeitung und -erweiterung durchzuführen, die bei einer Unterbrechung von Checkpoints aus neu gestartet werden können, was sie ideal für die variable Verfügbarkeit von Spot macht.

  • Modelle zur Feinabstimmung: Verwenden Sie Spot-Instances für die Feinabstimmung mit robusten Checkpoint-Mechanismen, um den Vorgang mit dem zuletzt gespeicherten Status fortzusetzen und so die Auswirkungen von Instance-Unterbrechungen zu minimieren.

  • Batch-Inferenz: Verwenden Sie Spot-Instances, um große Batch von Offline-Inferenzanfragen non-real-time so zu verarbeiten, dass Jobs angehalten und wieder aufgenommen werden können. Dies bietet die beste Abstimmung mit den Kosteneinsparungen von Spot und die Bewältigung potenzieller Unterbrechungen durch Wiederholungen oder Diversifizierung.

  • Opportunistische Trainingsuntergruppen: Verwenden Sie Spot-Instances für marginale oder experimentelle Trainingsworkloads (z. B. kleinere Modelle mit 10 Millionen Parametern), bei denen Unterbrechungen akzeptabel sind und Effizienzoptimierungen wie Diversifizierung zwischen Instance-Typen oder Regionen angewendet werden können. Für Schulungen im Produktionsmaßstab ist dies jedoch aufgrund potenzieller Unterbrechungen nicht zu empfehlen.

Überlegungen

Um Spot-Instances für beschleunigte Workloads auf Amazon EKS zu verwenden, gibt es eine Reihe wichtiger Überlegungen (in keiner bestimmten Reihenfolge):

  • Verwenden Sie Karpenter, um Spot-Instances mit aktivierter erweiterter Konsolidierung zu verwalten. Wenn Sie karpenter.sh/capacity-type in Ihrem Karpenter als „spot“ angeben, stellt Karpenter NodePool Spot-Instances standardmäßig ohne zusätzliche Konfiguration bereit. Um jedoch eine erweiterte Spot-to-Spot Konsolidierung zu ermöglichen, bei der nicht ausgelastete Spot-Knoten durch kostengünstigere Spot-Alternativen ersetzt werden, müssen Sie das Feature-Gate aktivieren, indem Sie --feature-gates =true in den Controller-Argumenten von Karpenter oder SpotToSpotConsolidation über die Umgebungsvariable FEATURE_GATES setzen. SpotToSpotConsolidation Karpenter verwendet EC2 die Zuweisungsstrategie, um Instanzen bereitzustellen. price-capacity-optimized Auf der Grundlage der NodePool Anforderungen und Pod-Einschränkungen packt Karpenter nicht planbare Pods in Sammelbehälter und sendet eine Vielzahl von Instance-Typen an die Amazon Fleet API. EC2 Sie können das Tool EC2 Instance Type Explorer verwenden, um eine Liste von Instance-Typen zu erstellen, die Ihren spezifischen Rechenanforderungen entsprechen.

  • Stellen Sie sicher, dass Workloads zustandslos, fehlertolerant und flexibel sind. Workloads müssen zustandslos, fehlertolerant und in Bezug auf die Größe flexibel sein. instance/GPU Dies ermöglicht eine reibungslose Wiederaufnahme nach Spot-Unterbrechungen, und die Flexibilität der Instances ermöglicht es Ihnen, möglicherweise länger vor Ort zu bleiben. Aktivieren Sie die Behandlung von Spot-Unterbrechungen in Karpenter, indem Sie den Helm-Wert settings.interruptionQueue mit dem Namen der AWS SQS-Warteschlange konfigurieren, um Spot-Unterbrechungsereignisse abzufangen. Verwenden Sie beispielsweise bei der Installation über Helm --set „settings.interruptionQueue=$ {CLUSTER_NAME}“. Ein Beispiel finden Sie im Handbuch Erste Schritte mit Karpenter. Wenn Karpenter ein Spot-Unterbrechungsereignis bemerkt, sperrt, verunreinigt, entleert und beendet es automatisch die Knoten vor dem Unterbrechungsereignis, um die Kündigungsfrist der Pods zu maximieren. Gleichzeitig startet Karpenter sofort einen neuen Knoten, sodass dieser so schnell wie möglich einsatzbereit sein kann.

  • Vermeiden Sie es, die Auswahl des Instanztyps zu stark einzuschränken. Sie sollten es so weit wie möglich vermeiden, die Instanztypen einzuschränken. Wenn die Instance-Typen nicht eingeschränkt werden, ist die Wahrscheinlichkeit höher, Spot-Kapazität in großem Umfang mit einer geringeren Häufigkeit von Spot-Instance-Unterbrechungen zu geringeren Kosten zu erwerben. Vermeiden Sie es beispielsweise, sich auf bestimmte Typen zu beschränken (z. B. g5.xlarge). Erwägen Sie die Angabe verschiedener Instanzkategorien und -generationen mithilfe von Schlüsseln wie karpenter.k8s. aws/instance-category and karpenter.k8s.aws/instance-generation. Karpenter enables easier diversification of on-demand and Spot instance capacity across multiple instance types and Availability Zones (AZs). Moreover, if your AI/MLDer Workload erfordert eine bestimmte oder begrenzte Anzahl von Acceleratoren, ist jedoch zwischen den Regionen flexibel. Sie können Spot Placement Score verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres Workloads zu ermitteln.

  • Erweitern Sie die NodePool Anforderungen auf eine größere Anzahl ähnlicher EC2 Instance-Familien. Jeder Spot-Instance-Pool besteht aus einer ungenutzten EC2 Instance-Kapazität für einen bestimmten Instance-Typ in einer bestimmten Availability Zone (AZ). Wenn Karpenter versucht, einen neuen Knoten bereitzustellen, wählt es einen Instance-Typ aus, der den NodePool Anforderungen entspricht. Wenn in keiner AZ ein kompatibler Instance-Typ über Spot-Kapazität verfügt, schlägt die Bereitstellung fehl. Um dieses Problem zu vermeiden, sollten Sie umfassendere Instanzen der G-Serie (Generation 4 oder höher) von NVIDIA für alle Größen und Availability Zones (AZs) zulassen und dabei Hardwareanforderungen wie GPU-Speicher oder Raytracing berücksichtigen. Da es sich bei Instances um unterschiedliche Typen handeln kann, müssen Sie sicherstellen, dass Ihr Workload auf jedem Typ ausgeführt werden kann und dass die Leistung, die Sie erhalten, Ihren Anforderungen entspricht.

  • Nutzen Sie alle Verfügbarkeitszonen in einer Region. Die verfügbare Kapazität variiert je nach Availability Zone (AZ). Ein bestimmter Instance-Typ ist in einer AZ möglicherweise nicht verfügbar, in einer anderen jedoch reichlich vorhanden. Jede einzigartige Kombination aus einem Instance-Typ und einer Availability Zone bildet einen separaten Spot-Kapazitätspool. Wenn Sie innerhalb Ihrer NodePool Karpenter-Anforderungen für alle Kapazitäten AZs in einer Region anfragen, suchen Sie effektiv nach mehr Pools gleichzeitig. Dadurch wird die Anzahl der Spot-Kapazitätspools maximiert und somit die Wahrscheinlichkeit erhöht, Spot-Kapazität zu erwerben. Um dies zu erreichen, lassen Sie in Ihrer NodePool Konfiguration entweder den Schlüssel topology.kubernetes.io/zone komplett weg, damit Karpenter aus allen in der Region verfügbaren auswählen kann, oder führen Sie die Liste explizit AZs mit dem Operator: AZs In auf und geben Sie die Werte an (z. B. us-west-2a).

  • Erwägen Sie, den Spot Placement Score (SPS) zu verwenden, um sich einen Überblick über die Wahrscheinlichkeit zu verschaffen, mit Spot-Instances erfolgreich auf die erforderliche Kapazität zuzugreifen. Der Spot Placement Score (SPS) ist ein Tool, das eine Bewertung liefert, anhand derer Sie beurteilen können, wie wahrscheinlich es ist, dass eine Spot-Anfrage erfolgreich ist. Wenn Sie SPS verwenden, geben Sie zunächst Ihre Rechenanforderungen für Ihre Spot-Instances an, und dann EC2 gibt Amazon die zehn wichtigsten Regionen oder Availability Zones (AZs) zurück, in denen Ihre Spot-Anfrage wahrscheinlich erfolgreich sein wird. Regionen und Availability Zones werden auf einer Skala von 1 bis 10 bewertet. Eine Punktzahl von 10 bedeutet, dass Ihre Spot-Anfrage mit hoher Wahrscheinlichkeit erfolgreich sein wird, aber nicht garantiert werden kann. Ein Ergebnis von 1 zeigt an, dass Ihre Spot-Anforderung sehr wahrscheinlich nicht erfolgreich sein wird. Dasselbe Ergebnis kann für verschiedene Regionen oder Availability Zones zurückgegeben werden. Weitere Informationen finden Sie unter Anleitung zur Erstellung eines Spot Placement Score Tracker-Dashboards auf AWS. Da die Spot-Kapazität ständig schwankt, hilft Ihnen SPS dabei, herauszufinden, AZs welche Kombination von Instance-Typen und Regionen für Ihre Workload-Einschränkungen (d. h. Flexibilität, Leistung, Größe usw.) am besten geeignet ist. Wenn Ihr AI/ML Workload eine bestimmte oder eine begrenzte Anzahl von Accelerators erfordert, aber zwischen den Regionen flexibel ist, können Sie den Spot-Platzierungswert verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres Workloads zu ermitteln. Damit Sie automatisch ermitteln können, wie wahrscheinlich es ist, Spot-Kapazität zu erwerben, stellen wir Ihnen eine Anleitung zur Erstellung eines SPS-Tracker-Dashboards zur Verfügung. Diese Lösung überwacht die SPS-Scores im Laufe der Zeit mithilfe einer YAML-Konfiguration für unterschiedliche Setups (z. B. einschließlich Instanzanforderungen GPUs), speichert Metriken und stellt Dashboards zum Vergleich CloudWatch von Konfigurationen bereit. Definieren Sie Dashboards pro Workload, um die vCPU-, Speicher- und GPU-Anforderungen zu bewerten und so optimale Setups für EKS-Cluster zu gewährleisten, einschließlich der Berücksichtigung der Verwendung anderer AWS-Regionen. Weitere Informationen finden Sie unter So funktioniert der Spot Placement Score.

  • Gehen Sie sorgsam mit Spot-Unterbrechungen um und testen Sie. Bei einem Pod mit einer Kündigungsfrist von mehr als zwei Minuten wird der alte Knoten unterbrochen, bevor diese Pods neu geplant werden, was sich auf die Verfügbarkeit der Workloads auswirken kann. Berücksichtigen Sie bei der Entwicklung Ihrer Anwendungen die zweiminütige Spot-Unterbrechungsbenachrichtigung, implementieren Sie Checkpointing in lang laufenden Anwendungen (z. B. Speichern des Fortschritts in persistentem Speicher wie Amazon S3), um nach Unterbrechungen wieder aufgenommen zu werden, verlängern Sie die terminationGracePeriod Sekunden (Standard ist 30 Sekunden) in den Pod-Spezifikationen, um mehr Zeit für ein ordnungsgemäßes Herunterfahren zu haben, und behandeln Sie Unterbrechungen mithilfe von and/or PreStop-Lifecycle-Hook-SIGTERM-Signalen innerhalb Ihrer Anwendung, um Aktivitäten wie Bereinigung, Statusspeicherung und Verbindungsabbruch ordnungsgemäß herunterzufahren. Bei Echtzeit-Workloads, bei denen die Skalierungszeit wichtig ist und die Workloads länger als zwei Minuten dauern, bis die Anwendung für den Datenverkehr bereit ist, sollten Sie erwägen, die Startzeiten von Containern und das Laden von ML-Modellen durch Überprüfung Speicher und Skalierung und Leistung von Anwendungen Best Practices zu optimieren. Verwenden Sie zum Testen eines Ersatzknotens den AWS Fault Injection Service (FIS), um Spot-Unterbrechungen zu simulieren.

Zusätzlich zu diesen zentralen Best Practices für Spot sollten Sie diese Faktoren bei der Verwaltung von GPU-Workloads auf Amazon EKS berücksichtigen. Im Gegensatz zu CPU-basierten Workloads reagieren GPU-Workloads besonders empfindlich auf Hardwaredetails wie GPU-Fähigkeiten und verfügbaren GPU-Speicher. GPU-Workloads können durch die Instance-Typen, die sie verwenden können, eingeschränkt werden, wobei im Vergleich zu weniger Optionen verfügbar sind. CPUs Prüfen Sie zunächst, ob Ihr Workload instanzflexibel ist. Wenn Sie nicht wissen, wie viele Instance-Typen Ihr Workload verwenden kann, testen Sie sie einzeln, um Kompatibilität und Funktionalität sicherzustellen. Identifizieren Sie, wie flexibel Sie sein können, um so viel wie möglich zu diversifizieren, und stellen Sie gleichzeitig sicher, dass die Diversifizierung den Workload am Laufen hält, und verstehen Sie alle Auswirkungen auf die Leistung (z. B. auf den Durchsatz oder die Fertigstellungszeit). Beachten Sie bei der Diversifizierung Ihrer Workloads Folgendes:

  • Überprüfen Sie die Kompatibilität von CUDA und Framework. Ihre GPU-Workloads sind möglicherweise für bestimmte Hardware und GPU-Typen (z. B. V100 in p3 gegenüber A100 in p4) optimiert oder für bestimmte CUDA-Versionen für Bibliotheken wie geschrieben. Überprüfen Sie daher unbedingt die TensorFlow Kompatibilität Ihrer Workloads. Diese Kompatibilität ist entscheidend, um Laufzeitfehler, Abstürze, Ausfälle bei der GPU-Beschleunigung (z. B. nicht übereinstimmende CUDA-Versionen mit Frameworks wie PyTorch oder TensorFlow können deren Ausführung verhindern) oder Hardwarefunktionen wie/precision nutzen zu können, zu verhindern. FP16 INT8

  • GPU-Speicher. Stellen Sie sicher, dass Sie die Speicheranforderungen Ihrer Modelle evaluieren und die Speichernutzung Ihres Modells während der Laufzeit mithilfe von Tools wie dem DCGM-Exporter profilieren. Geben Sie in bekannten Labels wie karpenter.k8s.aws/ den für den Instance-Typ mindestens erforderlichen GPU-Speicher an. instance-gpu-memory GPU-VRAM variiert je nach Instance-Typ (z. B. hat NVIDIA T4 16 GB, A10G hat 24 GB, V100 hat 16-32 GB), und ML-Modelle (z. B. große Sprachmodelle) können den verfügbaren Speicher überschreiten, was zu out-of-memory (OOM-) Fehlern oder Abstürzen führt. Bei Spot-Instances in EKS kann dies die Diversifizierung einschränken. Sie können beispielsweise keine Typen mit niedrigerem VRAM verwenden, wenn Ihr Modell nicht passt. Dies kann den Zugriff auf Kapazitätspools einschränken und das Risiko von Unterbrechungen erhöhen. Beachten Sie, dass dies bei Inferenz mit einem einzelnen GPU und einem einzelnen Knoten (z. B. mehrere Pods, die auf demselben Knoten geplant sind, um dessen GPU-Ressourcen zu nutzen) die Diversifizierung einschränken kann, da Sie nur Instance-Typen mit ausreichend VRAM in Ihre Spot-Konfiguration aufnehmen können.

  • Fließkomma-Präzision und Leistung. Nicht alle Nvidia-GPU-Architekturen haben dieselbe Gleitkomma-Präzision (z. B./). FP16 INT8 Bewerten Sie die Leistung und die Gleitkomma-Präzision der Kerntypen (CUDA/Tensor/RT), die für Ihre Workloads erforderlich sind. Der Betrieb auf einer kostengünstigeren, weniger leistungsfähigen GPU bedeutet nicht, dass sie besser ist. Daher sollten Sie die Leistung anhand der innerhalb eines bestimmten Zeitrahmens abgeschlossenen Arbeit bewerten, um die Auswirkungen der Diversifizierung zu verstehen.

Szenario: Diversifizierung für Inferenz-Workloads in Echtzeit

Für einen Online-Inferenz-Workload in Echtzeit auf Spot-Instances können Sie einen Karpenter so konfigurieren, dass er zwischen kompatiblen NodePool GPU-Instance-Familien und Generationen diversifiziert ist. Dieser Ansatz gewährleistet eine hohe Verfügbarkeit, indem er auf mehrere Spot-Pools zurückgreift und gleichzeitig die Leistung trotz Einschränkungen der GPU-Kapazitäten, des Speichers und der Architektur aufrecht erhält. Er unterstützt die Verwendung von Alternativen, wenn die Instance-Kapazität begrenzt ist, wodurch Unterbrechungen minimiert und die Inferenzlatenz optimiert wird. Dieses Beispiel NodePool besagt, dass Instances der Serien G und P mit mehr als 3 verwendet werden sollten, die über mehr als 20 GB GPU-Speicher verfügen.

Beispiel

apiVersion: karpenter.sh/v1 kind: NodePool metadata: name: gpu-inference-spot spec: template: metadata: labels: role: gpu-spot-worker spec: requirements: - key: karpenter.sh/capacity-type operator: In values: ["spot"] # Use Spot Instances - key: karpenter.k8s.aws/instance-category operator: In values: ["g", "p"] # Diversifies across G-series and P-series - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["3"] # Selects instance generations greater than 3 - key: kubernetes.io/arch operator: In values: ["amd64"] # Specifies AMD64 architecture, compatible with NVIDIA GPUs - key: karpenter.k8s.aws/instance-gpu-memory operator: Gt values: ["20480"] # Ensures more than 20GB (20480 MiB) total GPU memory taints: - key: nvidia.com/gpu effect: NoSchedule nodeClassRef: name: gpu-inference-ec2 group: karpenter.k8s.aws kind: EC2NodeClass expireAfter: 720h limits: cpu: 100 memory: 100Gi disruption: consolidationPolicy: WhenEmptyOrUnderutilized consolidateAfter: 5m # Enables consolidation of underutilized nodes after 5 minutes

Implementieren Sie Checkpointing für lang andauernde Trainingsjobs

Checkpointing ist eine Technik zur Fehlertoleranz, bei der der Status eines Prozesses in regelmäßigen Abständen gespeichert wird, sodass er bei Unterbrechungen vom zuletzt gespeicherten Punkt aus wieder aufgenommen werden kann. Beim maschinellen Lernen wird es häufig mit Training in Verbindung gebracht, bei dem lang andauernde Jobs Modellgewichte und Optimizerstatus speichern können, um das Training nach Ausfällen wie Hardwareproblemen oder Spot-Instance-Unterbrechungen wieder aufzunehmen.

Sie verwenden Checkpoints, um den Status von Modellen für maschinelles Lernen (ML) während des Trainings zu speichern. Checkpoints sind Schnappschüsse des Modells und können mit den Callback-Funktionen von ML-Frameworks konfiguriert werden. Sie können die gespeicherten Checkpoints verwenden, um einen Trainingsjob vom zuletzt gespeicherten Checkpoint aus neu zu starten. Mithilfe von Checkpoints speichern Sie Ihre Modellschnappschüsse während des Trainings aufgrund einer unerwarteten Unterbrechung des Trainingsjobs oder der Trainingsinstanz. Auf diese Weise können Sie das Training des Modells in future von einem Checkpoint aus fortsetzen. Zusätzlich zur Implementierung eines Node-Resiliency-Systems empfehlen wir die Implementierung von Checkpointing, um die Auswirkungen von Unterbrechungen zu minimieren, einschließlich solcher, die durch Hardwareausfälle oder Amazon EC2 Spot-Instance-Unterbrechungen verursacht werden.

Ohne Checkpoints können Unterbrechungen zu verschwendeter Rechenzeit und verlorenen Fortschritten führen, was bei lang andauernden Schulungsaufträgen kostspielig ist. Checkpointing ermöglicht es Jobs, ihren Status regelmäßig zu speichern (z. B. Modellgewichte und Status des Optimierers) und nach einer Unterbrechung ab dem letzten Checkpoint (zuletzt verarbeiteter Stapel) fortzufahren. Um Checkpointing zu implementieren, entwerfen Sie Ihre Anwendung so, dass sie Daten in großen Batches verarbeitet und Zwischenergebnisse in einem persistenten Speicher speichert, z. B. in einem Amazon S3-Bucket über den Mountpoint for Amazon S3 CSI-Treiber, während die Schulung voranschreitet.

Anwendungsfälle

Checkpointing ist in bestimmten Szenarien besonders nützlich, um ein Gleichgewicht zwischen Fehlertoleranz und Leistungsaufwand zu finden. Erwägen Sie die Verwendung von Checkpointing in den folgenden Fällen:

  • Die Auftragsdauer überschreitet einige Stunden: Für Trainingsjobs mit langer Laufzeit (z. B. > 1-2 Stunden für kleine Modelle oder days/weeks für große Basismodelle mit Milliarden von Parametern), bei denen der Verlust von Fortschritten aufgrund von Unterbrechungen kostspielig ist. Kürzere Aufträge rechtfertigen möglicherweise nicht den Mehraufwand. I/O

  • Für Spot-Instances oder Hardwarefehler: In Umgebungen, die anfällig für Unterbrechungen wie EC2 Spot (2 Minuten im Voraus) oder Hardwarefehler (z. B. GPU-Speicherfehler) sind, ermöglicht Checkpointing eine schnelle Wiederaufnahme, sodass Spot für Kosteneinsparungen bei fehlertoleranten Workloads rentabel ist.

  • Verteiltes Training im großen Maßstab: Für Setups mit hundreds/thousands Beschleunigern (z. B. >100 GPUs), bei denen die mittlere Zeit zwischen Ausfällen linear mit der Skalierung abnimmt. Wird für model/data Parallelität verwendet, um den gleichzeitigen Zugriff auf Checkpoints zu handhaben und vollständige Neustarts zu vermeiden.

  • Umfangreiche Modelle mit hohem Ressourcenbedarf: Bei LLM-Schulungen im Petabyte-Bereich, bei denen Ausfälle aufgrund der Clustergröße unvermeidlich sind, optimieren mehrstufige Ansätze (schnell lokal alle 5—30 Minuten für Transienten, dauerhaft stündlich für größere Ausfälle) die Wiederherstellungszeit im Verhältnis zur Effizienz.

Verwenden Sie ML-Kapazitätsblöcke für die Kapazitätssicherung von P- und Trainium-Instances

Mit Kapazitätsblöcken für ML können Sie sehr gefragte GPU-Instances, insbesondere P-Instances (z. B. p6-b200, p5, p5e, p5en, p4d, p4de) und Trainium-Instances (z. B. trn1, trn2), reservieren, um entweder fast sofort oder zu einem future Zeitpunkt zu starten, um Ihre kurzfristigen Machine-Learning-Workloads (ML) zu unterstützen. Diese Reservierungen sind ideal, um die Kapazität für rechenintensive Aufgaben wie Modelltraining und Feinabstimmung sicherzustellen. EC2 Die Preise für Capacity Blocks setzen sich aus einer Reservierungsgebühr und einer Betriebssystemgebühr zusammen. Weitere Informationen zur Preisgestaltung finden Sie unter Preise für EC2 Kapazitätsblöcke für ML.

Um AI/ML Workloads auf Amazon EKS GPUs für eine vorhersehbare Kapazitätssicherung zu reservieren, empfehlen wir die Nutzung von ML-Kapazitätsblöcken für kurzfristige oder On-Demand-Kapazitätsreservierungen (ODCRs) zur allgemeinen Kapazitätssicherung.

  • ODCRs ermöglichen es Ihnen, EC2 Instance-Kapazität (z. B. GPU-Instances wie g5 oder p5) in einer bestimmten Availability Zone für einen bestimmten Zeitraum zu reservieren und so die Verfügbarkeit auch bei hoher Nachfrage sicherzustellen. ODCRs Sie haben kein langfristiges Abonnement, aber Sie zahlen den On-Demand-Tarif für die reservierte Kapazität, unabhängig davon, ob sie genutzt oder nicht genutzt wird. In EKS ODCRs werden Knotentypen wie Karpenter und verwaltete Knotengruppen unterstützt. Um ODCRs in Karpenter Prioritäten zu setzen, konfigurieren Sie das Feld so, dass es verwendet wird NodeClass . capacityReservationSelectorTerms Weitere Informationen finden Sie in der Karpenter Dokumentation. NodePools

  • Kapazitätsblöcke sind ein spezieller Reservierungsmechanismus für GPU- (z. B. p5, p4d) oder Trainium-Instances (trn1, trn2), der für kurzfristige ML-Workloads wie Modelltraining, Feinabstimmung oder Experimente konzipiert wurde. Sie reservieren Kapazität für einen bestimmten Zeitraum (in der Regel 24 Stunden bis 182 Tage), der an einem future Datum beginnt, und zahlen nur für die reservierte Zeit. Sie sind im Voraus bezahlt, erfordern eine vorausschauende Planung des Kapazitätsbedarfs und unterstützen keine automatische Skalierung. Sie sind jedoch für Netzwerke mit niedriger Latenz vorgesehen. EC2 UltraClusters Sie berechnen nur für den reservierten Zeitraum. Weitere Informationen finden Sie unter Suchen und Kaufen von Kapazitätsblöcken oder richten Sie zunächst verwaltete Knotengruppen mit Kapazitätsblöcken ein. Folgen Sie dabei den Anweisungen unter Erstellen einer verwalteten Knotengruppe mit Kapazitätsblöcken für ML.

Reservieren Sie Kapazität über die AWS-Managementkonsole und konfigurieren Sie Ihre Knoten für die Verwendung von ML-Kapazitätsblöcken. Planen Sie Reservierungen auf der Grundlage von Workload-Zeitplänen und testen Sie sie in einem Staging-Cluster. Weitere Informationen finden Sie in der Dokumentation zu Kapazitätsblöcken.

Erwägen Sie On-Demand-, Amazon EC2 Spot- oder On-Demand-Kapazitätsreservierungen (ODCRs) für G EC2 Amazon-Instances

Beachten Sie bei G EC2 Amazon-Instances die verschiedenen Kaufoptionen On-Demand, Amazon EC2 Spot-Instances und On-Demand-Kapazitätsreservierungen. ODCRsermöglichen es Ihnen, EC2 Instance-Kapazität in einer bestimmten Availability Zone für einen bestimmten Zeitraum zu reservieren und so die Verfügbarkeit auch bei hoher Nachfrage sicherzustellen. Im Gegensatz zu ML Capacity Blocks, die nur für P- und Trainium-Instances verfügbar sind, ODCRs können sie für ein breiteres Spektrum von Instance-Typen, einschließlich G-Instances, verwendet werden. Dadurch eignen sie sich für Workloads, die unterschiedliche GPU-Fähigkeiten wie Inferenz oder Grafik erfordern. Bei der Verwendung von Amazon EC2 Spot-Instances ist die Möglichkeit, zwischen verschiedenen Instance-Typen, Größen und Verfügbarkeitszonen zu variieren, entscheidend, um länger vor Ort bleiben zu können.

ODCRs Sie haben kein langfristiges Engagement, aber Sie zahlen den On-Demand-Tarif für die reservierte Kapazität, unabhängig davon, ob sie genutzt oder nicht genutzt wird. ODCRs kann für die sofortige Nutzung erstellt oder für einen future Zeitpunkt geplant werden, was Flexibilität bei der Kapazitätsplanung bietet. In Amazon EKS ODCRs werden sie von Knotentypen wie Karpenter und verwalteten Knotengruppen unterstützt. Um ODCRs in Karpenter Prioritäten zu setzen, konfigurieren Sie das Feld so, dass es verwendet wird NodeClass . capacityReservationSelectorTerms Weitere Informationen finden Sie in der Karpenter Dokumentation. NodePools Weitere Informationen zum Erstellen ODCRs, einschließlich CLI-Befehlen, finden Sie unter On-Demand-Kapazitätsreservierung — Erste Schritte.

Ziehen Sie andere beschleunigte Instance-Typen und -Größen in Betracht

Die Auswahl der geeigneten beschleunigten Instance und Größe ist entscheidend für die Optimierung von Leistung und Kosten Ihrer ML-Workloads auf Amazon EKS. Beispielsweise verfügen verschiedene GPU-Instance-Familien über unterschiedliche Leistungen und Funktionen, z. B. GPU-Speicher. Um Ihnen bei der Auswahl der Option mit dem besten Preis-Leistungs-Verhältnis zu helfen, sehen Sie sich die verfügbaren GPU-Instances auf der Seite EC2 Instance-Typen unter Accelerated Computing an. Evaluieren Sie mehrere Instance-Typen und -Größen, um die beste Lösung für Ihre spezifischen Workload-Anforderungen zu finden. Berücksichtigen Sie Faktoren wie Anzahl GPUs, Arbeitsspeicher und Netzwerkleistung. Durch die sorgfältige Auswahl des richtigen GPU-Instance-Typs und der richtigen Größe können Sie eine bessere Ressourcennutzung und Kosteneffizienz in Ihren EKS-Clustern erreichen.

Wenn Sie eine GPU-Instanz in einem EKS-Knoten verwenden, befindet sich der nvidia-device-plugin-daemonset Pod standardmäßig im kube-system Namespace. Um einen schnellen Eindruck davon zu bekommen, ob Sie die GPU (s) in Ihrer Instanz vollständig nutzen, können Sie nvidia-smi wie hier gezeigt verwenden:

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
  • Wenn der utilization.memory Wert nahe bei 100% liegt, sind Ihr (e) Code (s) wahrscheinlich speichergebunden. Dies bedeutet, dass die GPU (Speicher) voll ausgelastet ist, könnte aber darauf hindeuten, dass weitere Leistungsoptimierungen untersucht werden sollten.

  • Wenn der nahe bei 100% utilization.gpu liegt, bedeutet dies nicht unbedingt, dass die GPU voll ausgelastet ist. Eine bessere Metrik, die man sich ansehen sollte, ist das Verhältnis von power.draw zupower.limit. Wenn dieses Verhältnis 100% oder mehr beträgt, nutzen Ihre Codes die Rechenkapazität der GPU vollständig aus.

  • Die -l 5 Flagge besagt, dass die Metriken alle 5 Sekunden ausgegeben werden sollen. Im Fall eines einzelnen GPU-Instanztyps wird das Indexabfrageflag nicht benötigt.

Weitere Informationen finden Sie unter GPU-Instances in der AWS-Dokumentation.

Optimieren Sie die GPU-Ressourcenzuweisung mit Time-Slicing, MIG und fraktionierter GPU-Zuweisung

Statische Ressourcenbeschränkungen in Kubernetes (z. B. CPU-, Arbeitsspeicher-, GPU-Anzahl) können zu einer Über- oder Unterauslastung führen, insbesondere bei dynamischen Workloads wie Inferenz. AI/ML Die Auswahl der richtigen GPU ist wichtig. Bei Workloads mit geringem Volumen oder hoher Auslastung ermöglicht Time-Slicing, dass sich mehrere Workloads eine einzelne GPU teilen, indem sie ihre Rechenressourcen gemeinsam nutzen, was potenziell die Effizienz verbessert und Verschwendung reduziert. Die gemeinsame Nutzung der GPU kann über verschiedene Optionen erreicht werden:

  • Nutzen Sie die Knotenauswahl und die Knotenaffinität, um die Planung zu beeinflussen: Stellen Sie sicher, dass die bereitgestellten Knoten und Pods auf den GPUs für die Arbeitslast geeigneten Knoten und Pods eingeplant werden (z. B. karpenter.k8s.aws/instance-gpu-name: "a100"

  • Time-Slicing: Plant Workloads so, dass sie die Rechenressourcen einer GPU im Laufe der Zeit gemeinsam nutzen, was eine gleichzeitige Ausführung ohne physische Partitionierung ermöglicht. Dies ist ideal für Workloads mit variablem Rechenbedarf, aber möglicherweise fehlt es an Speicherisolierung.

  • Multi-Instance-GPU (MIG): MIG ermöglicht die Partitionierung einer einzelnen NVIDIA-GPU in mehrere isolierte Instanzen und wird von NVIDIA Ampere (z. B. A100-GPU), NVIDIA Hopper (z. B. H100-GPU) und NVIDIA Blackwell (z. B. Blackwell) unterstützt. GPUs GPUs Jede MIG-Instanz erhält dedizierte Rechen- und Speicherressourcen und ermöglicht so die gemeinsame Nutzung von Ressourcen in Umgebungen mit mehreren Mandanten oder Workloads, für die Ressourcengarantien erforderlich sind. Dadurch können Sie die GPU-Ressourcennutzung optimieren, einschließlich Szenarien wie der Bereitstellung mehrerer Modelle mit unterschiedlichen Batchgrößen durch Timeslicing.

  • Teilweise GPU-Zuweisung: Nutzt softwarebasiertes Scheduling, um Teile der Rechenleistung oder des Speichers einer GPU Workloads zuzuweisen, was Flexibilität für dynamische Workloads bietet. Der NVIDIA KAI Scheduler, Teil der Run:AI-Plattform, ermöglicht dies, indem er es Pods ermöglicht, fraktionierte GPU-Ressourcen anzufordern.

Um diese Funktionen in EKS zu aktivieren, können Sie das NVIDIA Device Plugin einsetzen, das GPUs als planbare Ressourcen verfügbar ist und Time-Slicing und MIG unterstützt. Weitere Informationen finden Sie unter Time-Slicing GPUs in Kubernetes und GPU-Sharing auf Amazon EKS mit NVIDIA Time-Slicing und beschleunigten Instances. EC2

Beispiel

Um beispielsweise Time-Slicing mit dem NVIDIA Device Plugin zu aktivieren, gehen Sie wie folgt vor:

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

Beispiel

Um beispielsweise den KAI Scheduler für die fraktionierte GPU-Zuweisung zu verwenden, stellen Sie ihn zusammen mit dem NVIDIA-GPU-Operator bereit und geben Sie fraktionierte GPU-Ressourcen in der Pod-Spezifikation an:

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

Knotenausfallsicherheit und Verwaltung von Schulungsaufträgen

Implementieren Sie Node Health Checks mit automatisierter Wiederherstellung

Bei verteilten Trainingsaufgaben auf Amazon EKS, die eine häufige Kommunikation zwischen den Knoten erfordern, wie z. B. das Training mehrerer GPU-Modelle über mehrere Knoten hinweg, können Hardwareprobleme wie GPU- oder EFA-Ausfälle zu Unterbrechungen der Trainingsaufgaben führen. Diese Störungen können zum Verlust von Trainingsfortschritten und zu höheren Kosten führen, insbesondere bei lang andauernden AI/ML Workloads, die auf stabiler Hardware basieren.

Um die Widerstandsfähigkeit gegen Hardwarefehler zu erhöhen, wie z. B. GPU-Ausfälle in EKS-Clustern, auf denen GPU-Workloads ausgeführt werden, empfehlen wir, entweder den EKS Node Monitoring Agent mit Auto Repair oder Amazon zu nutzen. SageMaker HyperPod Der EKS Node Monitoring Agent with Auto Repair bietet Funktionen wie die Überwachung des Knotenzustands und die automatische Reparatur mithilfe von Kubernetes-Standardmechanismen, SageMaker HyperPod bietet gezielte Resilienz und zusätzliche Funktionen, die speziell für groß angelegte ML-Trainings entwickelt wurden, wie z. B. eingehende Gesundheitschecks und automatische Wiederaufnahme von Jobs.

  • Der EKS Node Monitoring Agent mit Node Auto Repair überwacht kontinuierlich den Zustand der Knoten NodeConditions, liest Protokolle und wendet Standardbedingungen wie Ready und spezifische Bedingungen für beschleunigte Hardware an, um Probleme wie GPU- oder Netzwerkausfälle zu identifizieren. Wenn ein Knoten als fehlerhaft eingestuft wird, sperrt Node Auto Repair ihn ab und ersetzt ihn durch einen neuen Knoten. Die Neuplanung von Pods und der Neustart von Jobs basieren auf den Standardmechanismen von Kubernetes und der Neustartrichtlinie des Jobs.

  • Der Agent für SageMaker HyperPodeingehende Integritätsprüfungen und die Zustandsüberwachung überwacht kontinuierlich den Integritätsstatus von GPU- und Trainium-basierten Instances. Er ist auf AI/ML Workloads zugeschnitten und verwendet Labels (z. B.) zur Verwaltung des Knotenzustands. node-health-status Wenn ein Knoten als fehlerhaft eingestuft wird, wird der automatische Austausch der fehlerhaften Hardware HyperPod ausgelöst, z. B. GPUs Es erkennt standardmäßig netzwerkbedingte Ausfälle für EFA durch seine grundlegenden Integritätsprüfungen und unterstützt die automatische Wiederaufnahme unterbrochener Trainingsjobs, sodass Jobs ab dem letzten Checkpoint fortgesetzt werden können, wodurch Unterbrechungen bei umfangreichen ML-Aufgaben minimiert werden.

Stellen Sie sowohl für EKS Node Monitoring Agent mit Auto Repair als auch für SageMaker HyperPod Cluster, die EFA verwenden, zur Überwachung EFA-spezifischer Metriken wie Remote Direct Memory Access (RDMA) -Fehler und Paketabbrüche sicher, dass der AWS EFA-Treiber installiert ist. Darüber hinaus empfehlen wir, das CloudWatch Observability Add-on einzusetzen oder Tools wie DCGM Exporter mit Prometheus und Grafana zu verwenden, um EFA, GPU und damit spezifische Metriken im Zusammenhang mit seinen Funktionen zu überwachen. SageMaker HyperPod

Deaktivieren Sie Karpenter Consolidation für unterbrechungssensitive Workloads

Für Workloads, die empfindlich auf Unterbrechungen reagieren, wie etwa bei der Verarbeitung, umfangreichen AI/ML Prognoseaufgaben oder Schulungen, empfehlen wir, die Konsolidierungsrichtlinien von Karpenter zu optimieren, um Unterbrechungen bei der Auftragsausführung zu vermeiden. Die Konsolidierungsfunktion von Karpenter optimiert automatisch die Cluster-Kosten, indem sie nicht ausgelastete Knoten beendet oder durch kostengünstigere Alternativen ersetzt. Selbst wenn ein Workload eine GPU vollständig ausnutzt, kann Karpenter Knoten konsolidieren, wenn es einen kostengünstigeren Instance-Typ mit passender Größe identifiziert, der die Anforderungen des Pods erfüllt, was zu Jobunterbrechungen führt.

Die WhenEmptyOrUnderutilized Konsolidierungsrichtlinie kann Knoten vorzeitig beenden, was zu längeren Ausführungszeiten führt. Beispielsweise können Unterbrechungen die Wiederaufnahme von Jobs verzögern, da Pods neu geplant und Daten neu geladen werden, was bei Batch-Inferenzjobs mit langer Laufzeit kostspielig sein kann. Um dies zu vermeiden, können Sie den Wert consolidationPolicy auf festlegen WhenEmpty und eine consolidateAfter Dauer, z. B. 1 Stunde, konfigurieren, damit Knoten auch bei Arbeitslastspitzen erhalten bleiben. Zum Beispiel:

disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m

Dieser Ansatz verbessert die Latenz beim Pod-Start bei hohen Batch-Inferenz-Workloads und anderen unterbrechungssensitiven Aufgaben, wie z. B. Online-Inferenzdatenverarbeitung in Echtzeit oder Modelltraining, bei denen die Kosten einer Unterbrechung die Einsparungen bei den Rechenkosten überwiegen. Karpenter Disruption Budgets ist eine weitere Funktion zur Verwaltung von Störungen bei KarpenterNodePool . Mit Budgets können Sie sicherstellen, dass zu einem bestimmten Zeitpunkt nicht mehr als eine bestimmte Anzahl von Knotenknoten in den ausgewählten NodePool Knoten unterbrochen wird. Sie können auch Unterbrechungsbudgets verwenden, um zu verhindern, dass alle Knoten zu einem bestimmten Zeitpunkt (z. B. zu Spitzenzeiten) unterbrochen werden. Weitere Informationen finden Sie in der Dokumentation zu Karpenter Consolidation.

Verwenden Sie ttlSecondsAfter Finished, um Kubernetes-Jobs automatisch zu bereinigen

Wir empfehlen, ttlSecondsAfterFinished für Kubernetes-Jobs in Amazon EKS so einzustellen, dass abgeschlossene Auftragsobjekte automatisch gelöscht werden. Verbleibende Auftragsobjekte verbrauchen Clusterressourcen wie API-Serverspeicher und erschweren die Überwachung durch überladene Dashboards (z. B. Grafana, Amazon). CloudWatch Wenn Sie beispielsweise eine TTL von 1 Stunde festlegen, wird sichergestellt, dass Jobs kurz nach Abschluss entfernt werden, sodass Ihr Cluster tidy bleibt. Weitere Informationen finden Sie unter Automatische Bereinigung abgeschlossener Jobs.

Job-Präemption mit niedriger Priorität für Aufträge/Workloads mit höherer Priorität konfigurieren

Für AI/ML Workloads mit gemischter Priorität auf Amazon EKS können Sie das Preemption von Jobs mit niedriger Priorität konfigurieren, um sicherzustellen, dass Aufgaben mit höherer Priorität (z. B. Echtzeit-Inferenz) umgehend Ressourcen erhalten. Ohne Präemption können Workloads mit niedriger Priorität wie Batch-Prozesse (z. B. Batch-Inferenz, Datenverarbeitung), Nicht-Batch-Dienste (z. B. Hintergrundaufgaben, Cron-Jobs) oder CPU-/speicherintensive Jobs (z. B. Webdienste) kritische Pods verzögern, indem sie Knoten belegen. Mit Preemption kann Kubernetes Pods mit niedriger Priorität entfernen, wenn Pods mit hoher Priorität Ressourcen benötigen, wodurch eine effiziente Ressourcenzuweisung auf Knoten mit, oder Speicher gewährleistet wird. GPUs CPUs Wir empfehlen die Verwendung von PriorityClass Kubernetes, um Prioritäten zuzuweisen und das Räumungsverhalten zu kontrollieren. PodDisruptionBudget

apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: low-priority value: 100 --- spec: priorityClassName: low-priority

Weitere Informationen finden Sie in der Dokumentation zu Kubernetes Priority and Preemption.

Skalierung und Leistung von Anwendungen

Passen Sie die Rechenkapazität für ML-Workloads mit Karpenter oder Static Nodes an

Um kosteneffiziente und reaktionsschnelle Rechenkapazitäten für maschinelles Lernen (ML) -Workflows auf Amazon EKS sicherzustellen, empfehlen wir, Ihre Node-Bereitstellungsstrategie an die Merkmale und Kostenverpflichtungen Ihres Workloads anzupassen. Im Folgenden sind zwei Ansätze aufgeführt, die Sie in Betracht ziehen sollten: just-in-time Skalierung mit Karpenter und statische Knotengruppen für reservierte Kapazität.

  • Just-in-time Datenebenen-Skalierer wie Karpenter: Für dynamische ML-Workflows mit variablen Rechenanforderungen (z. B. GPU-basierte Inferenz gefolgt von CPU-basierter Darstellung) empfehlen wir die Verwendung von Datenebenen-Skalierern wie Karpenter. just-in-time

  • Verwenden Sie statische Knotengruppen für vorhersehbare Workloads: Bei vorhersagbaren, stationären ML-Workloads oder bei der Verwendung von Reserved Instances können von EKS verwaltete Knotengruppen dazu beitragen, dass die reservierte Kapazität vollständig bereitgestellt und genutzt wird, wodurch die Einsparungen maximiert werden. Dieser Ansatz ist ideal für bestimmte Instance-Typen, die über oder festgeschrieben werden. RIs ODCRs

Beispiel

Dies ist ein Beispiel für ein vielseitiges Karpenter NodePool, das das Starten von g EC2 Amazon-Instances ermöglicht, bei denen die Instance-Generierung mehr als drei beträgt.

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

Beispiel

Beispiel für die Verwendung statischer Knotengruppen für einen Trainings-Workload:

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

Verwenden Sie Taints und Toleranzen, um zu verhindern, dass nicht beschleunigte Workloads auf beschleunigten Instances geplant werden

Die Planung nicht beschleunigter Workloads auf GPU-Ressourcen ist nicht recheneffizient. Wir empfehlen, Taints und Toleration zu verwenden, um sicherzustellen, dass Pods für nicht beschleunigte Workloads nicht auf ungeeigneten Knoten geplant werden. Weitere Informationen finden Sie in der Kubernetes-Dokumentation.

Skalieren Sie basierend auf der Modellleistung

Für Inferenz-Workloads empfehlen wir die Verwendung von Kubernetes Event-Driven Autoscaling (KEDA) zur Skalierung auf der Grundlage von Modellleistungskennzahlen wie Inferenzanfragen oder Token-Durchsatz mit entsprechenden Abklingzeiten. Statische Skalierungsrichtlinien können zu viel oder zu wenig Ressourcen bereitstellen, was sich auf Kosten und Latenz auswirkt. Weitere Informationen finden Sie in der KEDA-Dokumentation.

Dynamische Ressourcenzuweisung für erweitertes GPU-Management

Die dynamische Ressourcenzuweisung (DRA) stellt einen grundlegenden Fortschritt im Kubernetes-GPU-Ressourcenmanagement dar. DRA geht über die Beschränkungen herkömmlicher Geräte-Plug-ins hinaus und ermöglicht ausgeklügelte GPU-Sharing, Topologieerkennung und knotenübergreifende Ressourcenkoordination. DRA ist in Amazon EKS Version 1.33 verfügbar und adressiert kritische Herausforderungen bei AI/ML Workloads, indem es Folgendes bietet:

  • Feinkörnige GPU-Zuweisung

  • Fortschrittliche Sharing-Mechanismen wie Multi-Process Service (MPS) und Multi-Instance-GPU (MIG)

  • Support für Hardwarearchitekturen der nächsten Generation, einschließlich NVIDIA 00 GB2 UltraServers

Herkömmliche GPU-Zuweisung behandelt Ressourcen GPUs als undurchsichtige Integer-Ressourcen, was zu einer erheblichen Unterauslastung führt (häufig 30-40% in Produktionsclustern). Dies liegt daran, dass Workloads exklusiven Zugriff auf Gesamtressourcen erhalten, GPUs auch wenn sie nur Bruchteile der Ressourcen benötigen. DRA transformiert dieses Modell, indem es eine strukturierte, deklarative Zuweisung einführt, die dem Kubernetes-Scheduler einen vollständigen Überblick über Hardwaremerkmale und Workload-Anforderungen bietet. Dies ermöglicht intelligente Platzierungsentscheidungen und eine effiziente gemeinsame Nutzung von Ressourcen.

Vorteile der Verwendung von DRA anstelle des NVIDIA-Geräte-Plugins

Das NVIDIA-Geräte-Plugin (ab Version0.12.0) unterstützt GPU-Sharing-Mechanismen wie Time-Slicing, MPS und MIG. Es gibt jedoch architektonische Einschränkungen, die DRA behebt.

Einschränkungen des NVIDIA-Geräte-Plugins

  • Statische Konfiguration: Konfigurationen zur gemeinsamen Nutzung von GPUs (Time-Slicing-Replikate und MPS-Einstellungen) erfordern eine clusterweite Vorkonfiguration. ConfigMaps Dies macht es schwierig, unterschiedliche Sharing-Strategien für unterschiedliche Workloads bereitzustellen.

  • Eingeschränkte detaillierte Auswahl: Das Geräte-Plug-In macht zwar GPU-Merkmale anhand von Knotenbezeichnungen verfügbar, Workloads können jedoch nicht dynamisch bestimmte GPU-Konfigurationen (Speichergröße und Rechenkapazität) als Teil der Planungsentscheidung anfordern.

  • Keine knotenübergreifende Ressourcenkoordination: Es ist nicht möglich, verteilte GPU-Ressourcen über mehrere Knoten zu verwalten oder komplexe Topologieanforderungen wie NVLink Domänen für Systeme wie NVIDIA 00 zu formulieren. GB2

  • Scheduler-Einschränkungen: Der Kubernetes-Scheduler behandelt GPU-Ressourcen als undurchsichtige Ganzzahlen, was seine Fähigkeit einschränkt, topologiebewusste Entscheidungen zu treffen oder komplexe Ressourcenabhängigkeiten zu handhaben.

  • Komplexität der Konfiguration: Die Einrichtung verschiedener Strategien zur gemeinsamen Nutzung erfordert mehrere ConfigMaps und sorgfältige Knotenkennzeichnungen, was zu betrieblicher Komplexität führt.

Lösungen mit DRA

  • Dynamische Ressourcenauswahl: Mit DRA können Workloads detaillierte Anforderungen (GPU-Speicher, Treiberversionen und spezifische Attribute) zum Zeitpunkt der Anfrage angeben. resourceclaims Dies ermöglicht einen flexibleren Ressourcenabgleich.

  • Topologiebewusstsein: Durch strukturierte Parameter und Geräteauswahlen bewältigt DRA komplexe Anforderungen wie knotenübergreifende GPU-Kommunikation und speicherkohärente Verbindungen.

  • Knotenübergreifendes Ressourcenmanagement: computeDomains ermöglicht die Koordination verteilter GPU-Ressourcen auf mehrere Knoten, was für Systeme wie 00 mit IMEX-Kanälen von entscheidender Bedeutung ist. GB2

  • Workload-spezifische Konfiguration: Jede Konfiguration ResourceClaim spezifiziert unterschiedliche Strategien und Konfigurationen für die gemeinsame Nutzung und ermöglicht so eine feinkörnige Steuerung pro Workload anstelle von clusterweiten Einstellungen.

  • Verbesserte Scheduler-Integration: DRA stellt dem Scheduler detaillierte Geräteinformationen zur Verfügung und ermöglicht intelligentere Platzierungsentscheidungen auf der Grundlage der Hardwaretopologie und der Ressourceneigenschaften.

Wichtig: DRA ersetzt das NVIDIA-Geräte-Plugin nicht vollständig. Der NVIDIA DRA-Treiber arbeitet zusammen mit dem Geräte-Plug-In, um erweiterte Funktionen bereitzustellen. Das Geräte-Plugin übernimmt weiterhin die grundlegende Erkennung und Verwaltung von GPUs, während DRA erweiterte Zuweisungs- und Planungsfunktionen hinzufügt.

Von DRA unterstützte Instanzen und ihre Funktionen

Die DRA-Unterstützung variiert je nach EC2 Amazon-Instance-Familie und GPU-Architektur, wie in der folgenden Tabelle dargestellt.

Instance-Familie GPU-Typ Zeiteinteilung MIG-Unterstützung MPS-Unterstützung IMEX-Unterstützung Anwendungsfälle

G5

NVIDIA A10G

Ja

Nein

Ja

Nein

Inferenz- und Grafik-Workloads

G6

NVIDIA L4

Ja

Nein

Ja

Nein

KI-Inferenz und Videoverarbeitung

G6e

NVIDIA L40S

Ja

Nein

Ja

Nein

Training, Inferenz und Grafik

P4d/P4de

NVIDIA A100

Ja

Ja

Ja

Nein

Umfangreiches Training und HPC

P5

NVIDIA H100

Ja

Ja

Ja

Nein

Modelltraining für die Stiftung

P6

NVIDIA B200

Ja

Ja

Ja

Nein

Modelle mit Milliarden oder Billionen Parametern, verteiltes Training und Inferenz

P6e

NVIDIA 00 GB2

Ja

Ja

Ja

Ja

Modelle mit Milliarden oder Billionen Parametern, verteiltes Training und Inferenz

Im Folgenden werden die einzelnen Funktionen in der Tabelle beschrieben:

  • Time-Slicing: Ermöglicht es mehreren Workloads, GPU-Rechenressourcen im Laufe der Zeit gemeinsam zu nutzen.

  • Multi-Instance-GPU (MIG): Partitionierung auf Hardwareebene, die isolierte GPU-Instanzen erstellt.

  • Multi-Process-Service (MPS): Ermöglicht die gleichzeitige Ausführung mehrerer CUDA-Prozesse auf einer einzigen GPU.

  • Internode Memory Exchange (IMEX): Speicherkohärente Kommunikation zwischen Knoten für 00. GB2 UltraServers

Weitere Ressourcen

Weitere Informationen zu Kubernetes DRA- und NVIDIA DRA-Treibern finden Sie in den folgenden Ressourcen unter: GitHub

Richten Sie eine dynamische Ressourcenzuweisung für erweitertes GPU-Management ein

Das folgende Thema zeigt Ihnen, wie Sie die dynamische Ressourcenzuweisung (DRA) für erweitertes GPU-Management einrichten.

Voraussetzungen

Stellen Sie vor der Implementierung von DRA auf Amazon EKS sicher, dass Ihre Umgebung die folgenden Anforderungen erfüllt.

Cluster-Konfiguration
Erforderliche Komponenten
  • NVIDIA-Geräte-Plug-in-Version 0.17.1 oder höher

  • NVIDIA DRA-Treiberversion 25.3.0 oder höher

Schritt 1: Erstellen Sie mithilfe von eksctl einen Cluster mit einer DRA-fähigen Knotengruppe

  1. Erstellen Sie eine Cluster-Konfigurationsdatei mit dem Namen: 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
  2. Erstellen Sie den Cluster:

    eksctl create cluster -f dra-eks-cluster.yaml

Schritt 2: Stellen Sie das NVIDIA-Geräte-Plugin bereit

Stellen Sie das NVIDIA-Geräte-Plugin bereit, um die grundlegende GPU-Erkennung zu ermöglichen:

  1. Fügen Sie das Helm-Repository für das NVIDIA-Geräte-Plugin hinzu:

    helm repo add nvidia https://nvidia.github.io/k8s-device-plugin helm repo update
  2. Erstellen Sie benutzerdefinierte Werte für das Geräte-Plugin:

    cat <<EOF > nvidia-device-plugin-values.yaml gfd: enabled: true nfd: enabled: true tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule EOF
  3. Installieren Sie das NVIDIA-Geräte-Plug-In:

    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

Schritt 3: Stellen Sie das Helm-Diagramm für den NVIDIA-DRA-Treiber bereit

  1. Erstellen Sie eine dra-driver-values.yaml Wertedatei für den DRA-Treiber:

    --- 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
  2. Fügen Sie das NVIDIA NGC Helm-Repository hinzu:

    helm repo add nvidia https://helm.ngc.nvidia.com/nvidia helm repo update
  3. Installieren Sie den NVIDIA DRA-Treiber:

    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

Schritt 4: Überprüfen Sie die DRA-Installation

  1. Stellen Sie sicher, dass die DRA API-Ressourcen verfügbar sind:

    kubectl api-resources | grep resource.k8s.io/v1beta1

    Folgendes ist die erwartete Ausgabe:

    deviceclasses resource.k8s.io/v1beta1 false DeviceClass resourceclaims resource.k8s.io/v1beta1 true ResourceClaim resourceclaimtemplates resource.k8s.io/v1beta1 true ResourceClaimTemplate resourceslices resource.k8s.io/v1beta1 false ResourceSlice
  2. Überprüfen Sie die verfügbaren Geräteklassen:

    kubectl get deviceclasses

    Im Folgenden finden Sie ein Beispiel für die erwartete Ausgabe:

    NAME AGE compute-domain-daemon.nvidia.com 4h39m compute-domain-default-channel.nvidia.com 4h39m gpu.nvidia.com 4h39m mig.nvidia.com 4h39m

    Wenn eine neu erstellte G6-GPU-Instance Ihrem Amazon EKS-Cluster mit aktiviertem DRA beitritt, werden die folgenden Aktionen ausgeführt:

    • Der NVIDIA DRA-Treiber erkennt automatisch die A10G-GPU und erstellt zwei resourceslices auf diesem Knoten.

    • Der gpu.nvidia.com Slice registriert das physische A10G-GPU-Gerät mit seinen Spezifikationen (Speicher, Rechenkapazität und mehr).

    • Da A10G die MIG-Partitionierung nicht unterstützt, erstellt der compute-domain.nvidia.com Slice eine einzelne Rechendomäne, die den gesamten Rechenkontext der GPU darstellt.

    • Diese resourceslices werden dann auf dem Kubernetes-API-Server veröffentlicht, sodass die GPU-Ressourcen für die Planung zur Verfügung stehen. resourceclaims

      Der DRA-Scheduler kann diese GPU nun intelligent Pods zuweisen, über die GPU-Ressourcen angefordert werden, was im Vergleich zu herkömmlichen resourceclaimtemplates Geräte-Plug-in-Ansätzen eine flexiblere Ressourcenverwaltung ermöglicht. Dies geschieht automatisch ohne manuelles Eingreifen. Der Knoten wird einfach für GPU-Workloads verfügbar, sobald der DRA-Treiber die Ressourcenerkennung und Registrierung abgeschlossen hat.

      Wenn Sie den folgenden Befehl ausführen:

      kubectl get resourceslices

      Das Folgende ist ein Beispiel für die erwartete Ausgabe:

      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

Fahren Sie fort mit Planen Sie einen einfachen GPU-Workload mithilfe der dynamischen Ressourcenzuweisung.

Planen Sie einen einfachen GPU-Workload mithilfe der dynamischen Ressourcenzuweisung

Gehen Sie wie folgt vor, um einen einfachen GPU-Workload mithilfe der dynamischen Ressourcenzuweisung (DRA) zu planen. Bevor Sie fortfahren, stellen Sie sicher, dass Sie die folgenden Anweisungen befolgt habenRichten Sie eine dynamische Ressourcenzuweisung für erweitertes GPU-Management ein.

  1. Erstellen Sie eine Grundlage ResourceClaimTemplate für die GPU-Zuweisung mit einer Datei mit dem Namenbasic-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
  2. Wenden Sie die Vorlage an:

    kubectl apply -f basic-gpu-claim-template.yaml
  3. Überprüfen Sie den Status:

    kubectl get resourceclaimtemplates -n gpu-test1

    Das Folgende ist Ausgabebeispiel:

    NAME AGE single-gpu 9m16s
  4. Erstellen Sie einen Pod, der den verwendet, ResourceClaimTemplate mit einer Datei namensbasic-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"
  5. Wenden Sie den Pod an und überwachen Sie ihn:

    kubectl apply -f basic-gpu-pod.yaml
  6. Überprüfen Sie den Pod-Status:

    kubectl get pod -n gpu-test1

    Im Folgenden finden Sie ein Beispiel für eine erwartete Ausgabe:

    NAME READY STATUS RESTARTS AGE gpu-pod 1/1 Running 0 13m
  7. Überprüfen Sie den ResourceClaim Status:

    kubectl get resourceclaims -n gpu-test1

    Das Folgende ist ein Beispiel für eine erwartete Ausgabe:

    NAME STATE AGE gpu-pod-gpu0-l76cg allocated,reserved 9m6s
  8. Sehen Sie sich die Pod-Logs an, um GPU-Informationen zu sehen:

    kubectl logs gpu-pod -n gpu-test1

    Im Folgenden finden Sie ein Beispiel für eine erwartete Ausgabe:

    GPU 0: NVIDIA L4 (UUID: GPU-da7c24d7-c7e3-ed3b-418c-bcecc32af7c5)

Weitere fortgeschrittene Techniken Techniken zur GPU-Optimierung mit dynamischer Ressourcenzuweisung zur GPU-Optimierung mithilfe von DRA finden Sie weiter.

Techniken zur GPU-Optimierung mit dynamischer Ressourcenzuweisung

Moderne GPU-Workloads erfordern ein ausgeklügeltes Ressourcenmanagement, um eine optimale Nutzung und Kosteneffizienz zu erreichen. DRA ermöglicht mehrere fortschrittliche Optimierungstechniken, die auf unterschiedliche Anwendungsfälle und Hardwarefunktionen zugeschnitten sind:

Diese Techniken können die Ressourcennutzung erheblich verbessern. Organizations berichten, dass die GPU-Auslastung von 30 bis 40% bei herkömmlicher Zuweisung auf 80 bis 90% bei optimierten Sharing-Strategien steigt. Die Wahl der Technik hängt von den Eigenschaften der Arbeitslast, den Isolationsanforderungen und den Hardwarefunktionen ab.

Optimieren Sie GPU-Workloads mit Time-Slicing

Time-Slicing ermöglicht es mehreren Workloads, GPU-Rechenressourcen gemeinsam zu nutzen, indem sie so geplant werden, dass sie sequentiell auf derselben physischen GPU ausgeführt werden. Es ist ideal für Inferenz-Workloads mit sporadischer GPU-Nutzung.

Führen Sie die folgenden Schritte aus.

  1. Definieren Sie a ResourceClaimTemplate für Timeslicing mit einer Datei mit dem Namen: 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
  2. Definieren Sie einen Pod mithilfe von Timeslicing mit einer Datei namens: 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
  3. Wenden Sie die Vorlage und den Pod an:

    kubectl apply -f timeslicing-claim-template.yaml kubectl apply -f timeslicing-pod.yaml
  4. Ressourcenansprüche überwachen:

    kubectl get resourceclaims -n timeslicing-gpu -w

    Das Folgende ist Ausgabebeispiel:

    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

Erster Pod (inference-pod-1)

  • Bundesland: allocated,reserved

  • Das heißt: DRA hat eine verfügbare GPU gefunden und sie für diesen Pod reserviert

  • Pod-Status: Startet sofort

Zweiter Pod (training-pod-2)

  • Bundesland: pending

  • Das heißt: Ich warte darauf, dass DRA Time-Slicing auf derselben GPU konfiguriert

  • Pod-Status: Wartet darauf, geplant zu werden

  • Der Status wird von bis pending allocated,reserved zu wechseln running

Optimieren Sie GPU-Workloads mit MPS

Multi-Process Service (MPS) ermöglicht die gleichzeitige Ausführung mehrerer CUDA-Kontexte auf einer einzigen GPU mit besserer Isolierung als Time-Slicing.

Führen Sie die folgenden Schritte aus.

  1. Definieren Sie a ResourceClaimTemplate für MPS mit einer Datei namensmps-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
  2. Definieren Sie einen Pod mithilfe von MPS mit einer Datei namensmps-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
  3. Wenden Sie die Vorlage an und erstellen Sie mehrere MPS-Pods:

    kubectl apply -f mps-claim-template.yaml kubectl apply -f mps-pod.yaml
  4. Überwachen Sie die Ressourcenansprüche:

    kubectl get resourceclaims -n mps-gpu -w

    Das Folgende ist Ausgabebeispiel:

    NAME STATE AGE mps-multi-container-pod-shared-gpu-claim-2p9kx allocated,reserved 86s

Diese Konfiguration demonstriert echte GPU-Sharing mithilfe von NVIDIA Multi-Process Service (MPS) durch dynamische Ressourcenzuweisung (DRA). Im Gegensatz zum Time-Slicing, bei dem Workloads die GPU nacheinander verwenden, ermöglicht MPS, dass beide Container gleichzeitig auf derselben physischen GPU ausgeführt werden. Die wichtigste Erkenntnis ist, dass die gemeinsame Nutzung von DRA MPS mehrere Container innerhalb eines einzigen Pods erfordert, nicht mehrere separate Pods. Bei der Bereitstellung weist der DRA-Treiber dem Pod einen ResourceClaim zu und konfiguriert MPS automatisch so, dass sowohl der Inferenz- als auch der Trainingscontainer gleichzeitig ausgeführt werden können.

Jeder Container erhält seinen eigenen isolierten GPU-Speicherplatz und eigene Rechenressourcen, wobei der MPS-Daemon den Zugriff auf die zugrunde liegende Hardware koordiniert. Sie können überprüfen, ob dies funktioniert, indem Sie wie folgt vorgehen:

  • Überprüfungnvidia-smi, wodurch beide Container als M+C (MPS + Compute) -Prozesse angezeigt werden, die sich dasselbe GPU-Gerät teilen.

  • Überwachung der Logs aus beiden Containern, wobei verschachtelte Zeitstempel angezeigt werden, die die gleichzeitige Ausführung belegen.

Dieser Ansatz maximiert die GPU-Auslastung, indem ergänzende Workloads die teure GPU-Hardware effizient gemeinsam nutzen können, anstatt sie durch einen einzelnen Prozess ungenutzt zu lassen.

Behälter 1: 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 | +-----------------------------------------------------------------------------------------+
Behälter 2: 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 | +-----------------------------------------------------------------------------------------+

Optimieren Sie GPU-Workloads mit Multi-Instance-GPU

Die Multi-Instance-GPU (MIG) ermöglicht Partitionierung auf Hardwareebene und erstellt isolierte GPU-Instanzen mit dedizierten Rechen- und Speicherressourcen.

Für die Verwendung der dynamischen MIG-Partitionierung mit verschiedenen Profilen ist der NVIDIA-GPU-Operator erforderlich. Der NVIDIA GPU-Operator verwendet MIG Manager, um MIG-Profile zu erstellen, und startet die GPU-Instanzen wie P4D, P4De, P5, P6 und mehr neu, um die Konfigurationsänderungen zu übernehmen. Der GPU-Operator verfügt über die MIG Manager-Komponente, die auf Änderungen der Knotenbezeichnung achtet und automatisch die entsprechende MIG-Konfiguration anwendet, umfassende MIG-Verwaltungsfunktionen. Wenn eine Änderung des MIG-Profils angefordert wird, fährt der Operator alle GPU-Clients ordnungsgemäß herunter, wendet die neue Partitionsgeometrie an und startet die betroffenen Dienste neu. Dieser Prozess erfordert einen Neustart des Knotens für GPU-Instanzen, um saubere GPU-Statusübergänge zu gewährleisten. Aus diesem Grund ist die Aktivierung WITH–0—REBOOT=true in der MIG Manager-Konfiguration für erfolgreiche MIG-Bereitstellungen unerlässlich.

Sie benötigen sowohl den NVIDIA DRA-Treiber als auch den NVIDIA GPU Operator, um mit MIG in Amazon EKS zu arbeiten. Darüber hinaus benötigen Sie weder das NVIDIA Device Plugin noch den DCGM Exporter, da diese Teil des NVIDIA GPU Operators sind. Da auf den EKS NVIDIA die NVIDIA-Treiber vorinstalliert AMIs sind, haben wir die Bereitstellung von Treibern durch den GPU-Operator deaktiviert, um Konflikte zu vermeiden und die optimierten Treiber zu nutzen, die bereits auf den Instanzen vorhanden sind. Der NVIDIA DRA-Treiber kümmert sich um die dynamische Ressourcenzuweisung für MIG-Instanzen, während der GPU-Operator den gesamten GPU-Lebenszyklus verwaltet. Dazu gehören die MIG-Konfiguration, die Funktionalität von Geräte-Plug-ins, die Überwachung durch DCGM und die Erkennung von Knotenfunktionen. Dieser integrierte Ansatz bietet eine Komplettlösung für das GPU-Management in Unternehmen mit Isolierung auf Hardwareebene und Funktionen zur dynamischen Ressourcenzuweisung.

Schritt 1: Stellen Sie NVIDIA GPU Operator bereit
  1. Fügen Sie das NVIDIA GPU Operator-Repository hinzu:

    helm repo add nvidia https://nvidia.github.io/gpu-operator helm repo update
  2. Erstellen Sie eine gpu-operator-values.yaml Datei:

    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
  3. Installieren Sie GPU Operator mithilfe der gpu-operator-values.yaml folgenden Datei:

    helm install gpu-operator nvidia/gpu-operator \ --namespace gpu-operator \ --create-namespace \ --version v25.3.1 \ --values gpu-operator-values.yaml

    Dieses Helm-Diagramm stellt die folgenden Komponenten und mehrere MIG-Profile bereit:

    • Geräte-Plugin (GPU-Ressourcenplanung)

    • DCGM Exporter (GPU-Metriken und Überwachung)

    • Erkennung von Knotenmerkmalen (NFD — Hardwarekennzeichnung)

    • GPU Feature Discovery (GFD — GPU-spezifische Kennzeichnung)

    • MIG Manager (GPU-Partitionierung mit mehreren Instanzen)

    • Container-Toolkit (GPU-Container-Laufzeit)

    • Operator Controller (Lebenszyklusmanagement)

  4. Überprüfen Sie die Bereitstellungs-Pods:

    kubectl get pods -n gpu-operator

    Das Folgende ist Ausgabebeispiel:

    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
  5. Erstellen Sie einen Amazon EKS-Cluster mit einer von P4de verwalteten Knotengruppe, um die MIG-Beispiele zu testen:

    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 verwendet das Label, das den Knoten hinzugefügt wurde, nvidia.com/mig.config: "p4de-half-balanced" und partitioniert die GPU mit dem angegebenen Profil.

  6. Melden Sie sich bei der p4de Instanz an.

  7. Führen Sie den folgenden Befehl aus:

    nvidia-smi -L

    Sie sollten die folgende Beispielausgabe sehen:

    [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 hat das p4de-half-balanced MIG-Profil erfolgreich auf Ihre P4DE-Instanz angewendet und dabei wie konfiguriert GPU-Partitionen auf Hardwareebene erstellt. So funktioniert die Partitionierung:

Der GPU-Operator hat diese Konfiguration aus Ihrem eingebetteten MIG-Profil übernommen:

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

Aus Ihrer nvidia-smi -L Ausgabe hat der GPU-Operator Folgendes erstellt:

  • MIG-fähig GPUs (0-3): Hardware partitioniert

    • GPU 0: NVIDIA A100- -80 GB SXM4

      • MIG 3G.40 GB Gerät 0 — Große Arbeitslasten (40 GB Speicher, 42) SMs

      • MIG 2G.20 GB Gerät 1 — Mittlere Arbeitslasten (20 GB Speicher, 28) SMs

      • MIG 1g.10gb Gerät 2 — Kleine Workloads (10 GB Speicher, 14) SMs

      • MIG 1G.10GB Gerät 3 — Kleine Workloads (10 GB Speicher, 14) SMs

    • GPU 1: NVIDIA A100-80 GB SXM4

      • MIG 3G.40gb Gerät 0 — Identisches Partitionslayout

      • MIG 2g.20gb Gerät 1

      • MIG 1g.10gb Gerät 2

      • MIG 1g.10gb Gerät 3

    • GPU 2 und GPU 3 — Gleiches Muster wie GPU 0 und GPU 1

  • Vollständig GPUs (4-7): Keine MIG-Partitionierung

    • GPU 4: NVIDIA A100-80 GB — Vollständige SXM4 80-GB-GPU

    • GPU 5: NVIDIA A100- SXM4 -80 GB — Vollständige 80-GB-GPU

    • GPU 6: NVIDIA A100- SXM4 -80 GB — Vollständige 80-GB-GPU

    • GPU 7: NVIDIA A100- SXM4 -80 GB — Vollständige 80-GB-GPU

Sobald der NVIDIA-GPU-Operator die MIG-Partitionen erstellt hat, erkennt der NVIDIA DRA-Treiber diese hardwareisolierten Instanzen automatisch und stellt sie für die dynamische Ressourcenzuweisung in Kubernetes zur Verfügung. Der DRA-Treiber erkennt jede MIG-Instanz mit ihrem spezifischen Profil (1G.10 GB, 2G.20 GB, 3G.40 GB) und stellt sie über die Geräteklasse als planbare Ressourcen zur Verfügung. mig.nvidia.com

Der DRA-Treiber überwacht kontinuierlich die MIG-Topologie und führt eine Bestandsaufnahme aller verfügbaren Instanzen. GPUs Wenn ein Pod über ein ein bestimmtes MIG-Profil anfordertResourceClaimTemplate, wählt der DRA-Treiber auf intelligente Weise eine geeignete MIG-Instanz aus jeder verfügbaren GPU aus und ermöglicht so eine echte Mehrmandantenfähigkeit auf Hardwareebene. Durch diese dynamische Zuweisung können mehrere isolierte Workloads gleichzeitig auf derselben physischen GPU ausgeführt werden, wobei strenge Ressourcengrenzen und Leistungsgarantien eingehalten werden.

Schritt 2: Testen Sie die MIG-Ressourcenzuweisung

Lassen Sie uns nun anhand einiger Beispiele demonstrieren, wie DRA MIG-Instanzen dynamisch verschiedenen Workloads zuweist. Stellen Sie die Pods bereit resourceclaimtemplates und testen Sie sie, um zu sehen, wie der DRA-Treiber Workloads auf die verfügbaren MIG-Partitionen verteilt, sodass mehrere Container GPU-Ressourcen gemeinsam nutzen können, wobei die Isolierung auf Hardwareebene erfolgt.

  1. Erstellen, um mig-claim-template.yaml die MIG einzuschließen: 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'
  2. Wenden Sie die drei Vorlagen an:

    kubectl apply -f mig-claim-template.yaml
  3. Führen Sie den folgenden Befehl aus:

    kubectl get resourceclaimtemplates -n mig-gpu

    Das Folgende ist Ausgabebeispiel:

    NAME AGE mig-large-template 71m mig-medium-template 71m mig-small-template 71m
  4. Erstellen Siemig-pod.yaml, um mehrere Jobs zu planen und diese Vorteile zu nutzenresourceclaimtemplates:

    --- # 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
  5. Wenden Sie diese Spezifikation an, die drei Pods bereitstellen sollte:

    kubctl apply -f mig-pod.yaml

    Diese Pods sollten vom DRA-Treiber geplant werden.

  6. Überprüfen Sie die Pod-Logs des DRA-Treibers und Sie erhalten eine Ausgabe, die der folgenden ähnelt:

    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**],}]
  7. Überprüfen Sieresourceclaims, um den Pod-Status zu sehen:

    kubectl get resourceclaims -n mig-gpu -w

    Das Folgende ist Ausgabebeispiel:

    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

    Wie Sie sehen, allocated,reserved wurden alle Pods vom DRA-Treiber von „Ausstehend“ zu „Ausstehend“ verschoben.

  8. Führen Sie nvidia-smi vom Knoten aus aus. Sie werden feststellen, dass drei Python-Prozessoren laufen:

    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 |** +-----------------------------------------------------------------------------------------+

Optimieren Sie GPU-Workloads mit IMEX mithilfe von GB2 00 P6e-Instanzen

IMEX (Internode Memory Exchange) ermöglicht eine speicherkohärente Kommunikation zwischen Knoten für verteiltes Training auf NVIDIA 00. GB2 UltraServers

Führen Sie die folgenden Schritte aus.

  1. Definieren Sie ein ComputeDomain für ein Training mit mehreren Knoten mit einer Datei namensimex-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
  2. Definieren Sie einen Pod mithilfe von IMEX-Kanälen mit einer Datei namens: 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
    Anmerkung

    Dies erfordert P6e GB2 00-Instanzen.

  3. Stellen Sie IMEX bereit, indem Sie die ComputeDomain beiden Vorlagen anwenden:

    kubectl apply -f imex-claim-template.yaml kubectl apply -f imex-compute-domain.yaml kubectl apply -f imex-pod.yaml
  4. Überprüfen Sie den ComputeDomain Status.

    kubectl get computedomain distributed-training-domain
  5. Überwachen Sie die Bereitstellung des IMEX-Daemons.

    kubectl get pods -n nvidia-dra-driver -l resource.nvidia.com/computeDomain
  6. Überprüfen Sie die IMEX-Kanäle im Pod:

    kubectl exec imex-distributed-training -- ls -la /dev/nvidia-caps-imex-channels/
  7. Sehen Sie sich die Pod-Logs an:

    kubectl logs imex-distributed-training

    Im Folgenden finden Sie ein Beispiel für die erwartete Ausgabe:

    === 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

Weitere Informationen finden Sie im NVIDIA-Beispiel unter GitHub.