View a markdown version of this page

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

Tipp

Registrieren Sie sich für bevorstehende Amazon AI/ML EKS-Workshops.

GPU-Ressourcenoptimierung und Kostenmanagement

Planen Sie Workloads anhand von GPU-Anforderungen mithilfe von Labels Well-Known

Für AI/ML Workloads, die auf unterschiedliche GPU-Eigenschaften reagieren (z. B. GPU, GPU-Speicher), empfehlen wir, die GPU-Anforderungen mithilfe bekannter Scheduling-Labels zu spezifizieren, die von den in Karpenter verwendeten Knotentypen und verwalteten Knotengruppen unterstützt werden. Wenn diese nicht definiert werden, kann dies dazu führen, dass Pods auf Instances 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 die Rechenressourcen (CPU, Speicher, GPUs usw.) im Ressourcenbereich des Pods festzulegen.

Beispiel

Verwenden Sie beispielsweise den Knotenselektor für den GPU-Namen, 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, um GPUs verfügbar zu machen

Um GPUs auf Knoten verfügbar zu machen, muss der NVIDIA-GPU-Treiber auf dem Betriebssystem des Knotens installiert und die Container-Runtime so konfiguriert sein, dass der Kubernetes-Scheduler Knoten mit verfügbaren GPUs Pods zuweisen kann. Der Einrichtungsvorgang für das NVIDIA Kubernetes Device Plugin hängt vom verwendeten EKS Accelerated AMI ab:

  • Bottlerocket Accelerated AMI : Dieses AMI enthält den NVIDIA-GPU-Treiber und das NVIDIA Kubernetes Device Plugin ist vorinstalliert und einsatzbereit, sodass die GPU-Unterstützung sofort einsatzbereit ist. Es ist keine zusätzliche Konfiguration erforderlich, um GPUs für den Kubernetes-Scheduler verfügbar zu machen.

  • AL2023 Accelerated AMI : Dieses AMI beinhaltet 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 eine. DaemonSet Beachten Sie, dass, wenn Sie eksctl verwenden, um Ihren Cluster zu erstellen und einen GPU-Instance-Typ (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 sich dafür entscheiden, stattdessen die EKS Accelerated AMIs und den NVIDIA GPU-Operator zur Verwaltung von Komponenten wie dem NVIDIA Kubernetes-Geräte-Plugin zu verwenden, beachten Sie, dass Sie die Verwaltung des NVIDIA-GPU-Treibers und des NVIDIA Container-Toolkits gemäß der NVIDIA-Dokumentation zu den NVIDIA-GPU-Treibern und dem Pre-Installed NVIDIA Container Toolkit deaktivieren müssen.

Führen Sie Folgendes aus, um zu überprüfen, ob das NVIDIA-Geräte-Plug-In aktiv ist und die GPUs korrekt verfügbar sind:

kubectl describe node | grep nvidia.com/gpu

Mit diesem Befehl wird überprüft, ob die nvidia.com/gpu Ressource die Kapazität und die zuweisbaren Ressourcen des Knotens erfüllt. Beispielsweise 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 EC2-Instance-Typen

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, erhalten Sie möglicherweise einen Fehler wegen unzureichender Kapazität (ICE), 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.

Instances für beschleunigte Datenverarbeitung 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 Sparplänen können Sie beschleunigte Recheninstanzen für mittel- und langfristige Workloads bereitstellen. Um die Chancen zu erhöhen, dass Sie mit Ihrer bevorzugten Kaufoption erfolgreich auf die benötigte Kapazität zugreifen, wird empfohlen, eine vielfältige Liste von Instanztypen und Verfügbarkeitszonen zu verwenden. Wenn Sie auf ICEs für ein bestimmtes Kaufmodell stoßen, versuchen Sie es alternativ erneut, ein anderes Modell zu verwenden.

Beispiel Das folgende Beispiel zeigt, wie ein Karpenter in die Lage versetzt wird NodePool , G- und P-Instances bereitzustellen, die älter als Generation 3 sind (z. B. p3). Weitere Informationen finden Sie im Bewährte Methoden zur 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 GPUs finden Sie weiter 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. Sie sind mit einem Rabatt von bis zu 90% im Vergleich zu den Preisen erhältlich. On-Demand Amazon EC2 Spot-Instances können mit einer Frist von zwei Minuten unterbrochen werden, wenn EC2 die Kapazität wieder benötigt. Weitere Informationen finden Sie unter Spot-Instances im Amazon EC2-Benutzerhandbuch. Amazon EC2 Spot kann eine hervorragende Wahl für fehlertolerante, statusfreie und flexible (Zeit und Instance-Typ) Workloads sein. Weitere Informationen darüber, wann Spot-Instances verwendet werden sollten, finden Sie unter Best Practices für EC2 Spot-Instances. Sie können Spot-Instances auch für AI/ML Workloads verwenden, wenn dies der Fall ist. Spot-friendly

Anwendungsfälle

Spot-friendly Bei Workloads kann es sich um Big Data, containerisierte Workloads, statusfreie Webserver CI/CD, High Performance Computing (HPC) und Rendering-Workloads handeln. Spot-Instances eignen sich nicht für Workloads, die unflexibel, statusbehaftet, fehlerintolerant oder eng zwischen Instance-Knoten gekoppelt sind (z. B. Workloads mit parallelen Prozessen, die bei der Berechnung stark voneinander abhängen und eine ständige Kommunikation zwischen den Knoten erfordern, wie z. B. MPI-based Hochleistungsrechneranwendungen wie Computational Fluid Dynamics oder verteilte Datenbanken mit komplexen Interdependenzen). Hier sind die spezifischen Anwendungsfälle, die wir empfehlen (in keiner bestimmten Reihenfolge):

  • Real-time Online-Inferenz: 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) oder Reservierungen sicher und implementieren Sie gleichzeitig Fehlertoleranz auf Anwendungsebene, um potenzielle Spot-Unterbrechungen zu bewältigen.

  • Hyper-parameter Tuning: Verwenden Sie Spot-Instances, um explorative Tuning-Jobs opportunistisch auszuführen, da Unterbrechungen ohne nennenswerten Verlust toleriert werden können, insbesondere bei kurzzeitigen Experimenten.

  • Datenerweiterung: Verwenden Sie Spot-Instances, um Datenvorverarbeitungs- und Augmentierungsaufgaben durchzuführen, die bei einer Unterbrechung von Checkpoints aus neu gestartet werden können. Somit eignen sie sich ideal für die variable Verfügbarkeit von Spot.

  • Fine-tuning Modelle: Verwenden Sie Spot-Instances für die Feinabstimmung mit robusten Checkpoint-Mechanismen, um vom zuletzt gespeicherten Zustand aus fortzufahren und so die Auswirkungen von Instance-Unterbrechungen zu minimieren.

  • Batch-Inferenz: Verwenden Sie Spot-Instances, um große Stapel von Offline-Inferenzanforderungen ohne Echtzeitzugriff zu verarbeiten. Dabei können Jobs unterbrochen und wieder aufgenommen werden. So können Sie die Kosteneinsparungen von Spot optimal nutzen und potenzielle Unterbrechungen durch Wiederholungen oder Diversifizierung bewältigen.

  • Opportunistische Trainingsuntergruppen: Verwenden Sie Spot-Instances für marginale oder experimentelle Trainingsworkloads (z. B. kleinere Modelle mit weniger als 10 Millionen Parametern), bei denen Unterbrechungen akzeptabel sind und Effizienzoptimierungen wie eine Diversifizierung zwischen Instanztypen oder Regionen angewendet werden können. Dies wird jedoch aufgrund potenzieller Unterbrechungen nicht für Schulungen im Produktionsumfang empfohlen.

Überlegungen

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

  • Verwenden Sie Karpenter, um Spot-Instances mit aktivierter erweiterter Konsolidierung zu verwalten. Durch Angabe von Karpenter. sh/capacityWenn Sie in Ihrem Karpenter „spot“ eingeben NodePool, stellt Karpenter standardmäßig Spot-Instances ohne zusätzliche Konfiguration bereit. Um jedoch eine erweiterte Spot-to-Spot Konsolidierung zu ermöglichen, bei der nicht ausgelastete Spot-Knoten durch günstigere Spot-Alternativen ersetzt werden, müssen Sie das Feature-Gate aktivieren, indem Sie --feature-gates SpotToSpotConsolidation =true in den SpotToSpotConsolidation Controller-Argumenten von Karpenter oder über die Umgebungsvariable FEATURE_GATES setzen. Karpenter verwendet für die Bereitstellung von EC2-Instances die Strategie der preis-/kapazitätsoptimierten Zuweisung. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-allocation-strategy.html Basierend auf den NodePool Anforderungen und Pod-Einschränkungen packt Karpenter unplanbare Pods in Bin-Packs und sendet eine Vielzahl von Instance-Typen an die Amazon EC2 Fleet API. https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-fleet-request-type.html Sie können das EC2 Instance Type Explorer-Tool verwenden, um eine Liste von Instance-Typen zu generieren, die Ihren spezifischen Rechenanforderungen entsprechen.

  • Stellen Sie sicher, dass Workloads statusfrei, fehlertolerant und flexibel sind. Workloads müssen statusfrei, fehlertolerant und hinsichtlich ihrer Größe flexibel sein. instance/GPU Dies ermöglicht eine reibungslose Wiederaufnahme nach Spot-Unterbrechungen, und die Flexibilität der Instance ermöglicht es Ihnen, möglicherweise länger auf Spot 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-Unterbrechungen abzufangen. Verwenden Sie beispielsweise bei der Installation über Helm --set „settings.interruptionQueue=$ {CLUSTER_NAME}“. Ein Beispiel finden Sie im Handbuch Erste Schritte mit Karpenter. https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/ Wenn Karpenter ein Spot-Unterbrechungsereignis bemerkt, sperrt es die Knoten automatisch ab, verunreinigt, entleert und schließt sie vor dem Unterbrechungsereignis, um die Übergangszeit der Pods zu maximieren. Gleichzeitig startet Karpenter sofort einen neuen Knoten, damit dieser so schnell wie möglich einsatzbereit ist.

  • 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 Sie die Instance-Typen nicht einschränken, besteht eine höhere Wahrscheinlichkeit, 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, mithilfe von Schlüsseln wie karpenter.k8s eine Vielzahl von Instanzkategorien und -generationen anzugeben. aws/instance-category und karpenter.k8s. aws/instance-Generation. Karpenter ermöglicht eine einfachere Diversifizierung der On-Demand- und Spot-Instance-Kapazität über mehrere Instance-Typen und Availability Zones (AZs) hinweg. Darüber hinaus können Sie Spot Placement Score verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres AI/ML Workloads zu ermitteln, wenn Ihr Workload eine bestimmte oder eine begrenzte Anzahl von Beschleunigern erfordert, aber zwischen den Regionen flexibel ist.

  • Erweitern Sie die NodePool Anforderungen, um eine größere Anzahl ähnlicher EC2-Instance-Familien einzubeziehen. 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 von Karpenter entspricht. Wenn in keinem AZ ein kompatibler Instanztyp über Spot-Kapazität verfügt, schlägt die Bereitstellung fehl. Um dieses Problem zu vermeiden, sollten Sie umfassendere Instances der G-Serie (Generation 4 oder höher) von NVIDIA in verschiedenen Größen und Availability Zones (AZs) zulassen und gleichzeitig Hardwareanforderungen wie GPU-Speicher oder Raytracing berücksichtigen. Da es sich um verschiedene Typen von Instances handeln kann, müssen Sie sicherstellen, dass Ihre 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. Jede einzigartige Kombination aus einem Instance-Typ und einer Availability Zone bildet einen separaten Spot-Kapazitätspool. Indem Sie Kapazität für alle AZs in einer Region anfordern, die Ihren NodePool Karpenter-Anforderungen entspricht, durchsuchen Sie effektiv mehrere Pools gleichzeitig. Dadurch wird die Anzahl der Spot-Kapazitätspools maximiert und somit die Wahrscheinlichkeit, Spot-Kapazität zu erwerben, erhöht. Um dies zu erreichen, lassen Sie in Ihrer NodePool Konfiguration entweder topology.kubernetes weg. io/zone Geben Sie die Taste vollständig ein, damit Karpenter aus allen verfügbaren AZs in der Region auswählen kann, oder listen Sie die AZs explizit auf, indem Sie den Operator: In verwenden und die Werte angeben (z. B. us-west-2a).

  • Erwägen Sie, den Spot Placement Score (SPS) zu verwenden, um einen Überblick über die Wahrscheinlichkeit zu erhalten, mit Spot-Instances erfolgreich auf die erforderliche Kapazität zuzugreifen. Der Spot Placement Score (SPS) ist ein Tool, das Ihnen anhand einer Bewertung hilft, einzuschätzen, wie wahrscheinlich es ist, dass eine Spot-Anfrage erfolgreich ist. Wenn Sie SPS verwenden, geben Sie zuerst Ihre Rechenanforderungen für Ihre Spot-Instances an, und dann gibt Amazon EC2 die 10 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. Ein Wert von 10 gibt an, dass Ihre Spot-Anfrage sehr wahrscheinlich, aber nicht garantiert erfolgreich ist. 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 zum Erstellen eines Spot Placement Score Tracker-Dashboards auf AWS. Da die Spot-Kapazität ständig schwankt, hilft Ihnen SPS dabei, herauszufinden, welche Kombination aus Instance-Typen, AZs 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 bestimmte oder eine begrenzte Anzahl von Beschleunigern erfordert, aber zwischen den Regionen flexibel ist, können Sie den Spot Placement Score verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres Workloads zu ermitteln. Damit Sie die Wahrscheinlichkeit, Spot-Kapazität zu erwerben, automatisch ermitteln können, stellen wir Ihnen eine Anleitung zur Erstellung eines SPS-Tracker-Dashboards zur Verfügung. Diese Lösung überwacht die SPS-Ergebnisse im Zeitverlauf mithilfe einer YAML-Konfiguration für unterschiedliche Setups (z. B. Instance-Anforderungen einschließlich GPUs), speichert Metriken darin und stellt Dashboards zum Vergleich von Konfigurationen CloudWatch bereit. Definieren Sie Dashboards pro Workload, um die vCPU-, Speicher- und GPU-Anforderungen zu bewerten und so optimale Setups für EKS-Cluster sicherzustellen, 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 beim Entwerfen Ihrer Anwendungen den zweiminütigen Spot-Unterbrechungshinweis, implementieren Sie Checkpoints in lang laufenden Anwendungen (z. B. Speichern des Fortschritts in einem persistenten Speicher wie Amazon S3), um sie nach Unterbrechungen fortzusetzen, verlängern Sie die Beendigung GracePeriodSeconds (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 PreStop-Lifecycle-Hooks and/or SIGTERM-Signale in Ihrer Anwendung für ordnungsgemäßes Herunterfahren wie Bereinigen, Speichern des Status und Schließen der Verbindung. Bei Echtzeit-Workloads, bei denen die Skalierungszeit wichtig ist und Workloads länger als zwei Minuten dauern, bis die Anwendung bereit ist, den Traffic zu verarbeiten, sollten Sie erwägen, die Startzeiten von Containern und ML-Modellen durch Überprüfung Speicher und Skalierung und Leistung von Anwendungen Best Practices zu optimieren. Um einen Ersatzknoten zu testen, verwenden Sie den AWS Fault Injection Service (FIS), um Spot-Unterbrechungen zu simulieren.

Zusätzlich zu diesen bewährten Kernmethoden für Spot sollten Sie diese Faktoren bei der Verwaltung von GPU-Workloads auf Amazon EKS berücksichtigen. Im Gegensatz zu CPU-based Workloads reagieren GPU-Workloads besonders empfindlich auf Hardwaredetails wie GPU-Funktionen und verfügbaren GPU-Speicher. GPU-Workloads sind möglicherweise durch die Instance-Typen, die sie verwenden können, eingeschränkt, sodass im Vergleich zu CPUs weniger Optionen verfügbar sind. Prüfen Sie zunächst, ob Ihre Arbeitslast 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 Arbeitslast durch Diversifizierung am Laufen bleibt, und verstehen Sie alle Auswirkungen auf die Leistung (z. B. auf den Durchsatz oder die Abschlusszeit). Beachten Sie bei der Diversifizierung Ihrer Workloads Folgendes:

  • Überprüfen Sie die CUDA- und Framework-Kompatibilität. Ihre GPU-Workloads sind möglicherweise für bestimmte Hardware, GPU-Typen (z. B. V100 in P3 gegenüber A100 in P4) optimiert oder für bestimmte CUDA-Versionen für Bibliotheken wie TensorFlow geschrieben. Überprüfen Sie daher unbedingt die Kompatibilität für Ihre 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 die Ausführung verhindern) oder um Hardwarefunktionen wie Präzision nutzen zu können. FP16/INT8

  • GPU-Speicher. Stellen Sie sicher, dass Sie die Speicheranforderungen Ihrer Modelle auswerten und die Speichernutzung Ihres Modells während der Laufzeit mithilfe von Tools wie dem DCGM-Exporter profilieren. Stellen Sie den minimalen GPU-Speicher ein, der für den Instance-Typ erforderlich ist, in bekannten Labels wie karpenter.k8s. aws/instance-gpu-speicher. GPU-VRAM variiert je nach Instance-Typ (z. B. NVIDIA T4 hat 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 OOM-Fehlern oder Abstürzen führen kann. Bei Spot-Instances in EKS kann dies die Diversifizierung einschränken. Beispielsweise können Sie keine Typen mit niedrigerem VRAM einbeziehen, wenn Ihr Modell nicht passt. Dadurch kann der Zugriff auf Kapazitätspools eingeschränkt und das Unterbrechungsrisiko erhöht werden. Beachten Sie, dass bei Inferenz mit einer einzelnen GPU und einem 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.

  • Floating-point Präzision und Leistung. Nicht alle Nvidia-GPU-Architekturen haben die gleiche Gleitkommagenauigkeit (z. B. FP16/INT8). Bewerten Sie die Leistung der Kerntypen (CUDA/Tensor/RT) und die Gleitkommagenauigkeit, die für Ihre Workloads erforderlich sind. Wenn Sie auf einer preisgünstigeren, leistungsschwächeren GPU arbeiten, bedeutet das nicht, dass sie besser ist. Sie sollten also erwägen, die Leistung anhand der innerhalb eines bestimmten Zeitrahmens abgeschlossenen Arbeit zu bewerten, um die Auswirkungen der Diversifizierung zu verstehen.

Szenario: Diversifizierung bei Inferenz-Workloads in Echtzeit

Für eine Online-Inferenz-Arbeitslast in Echtzeit auf Spot-Instances können Sie einen Karpenter konfigurieren, um die Verteilung zwischen kompatiblen GPU-Instance-Familien und Generationen NodePool zu diversifizieren. Dieser Ansatz gewährleistet eine hohe Verfügbarkeit, indem er aus mehreren Spot-Pools schöpft und gleichzeitig die Leistung aufgrund von Einschränkungen der GPU-Funktionen, des Speichers und der Architektur aufrechterhalten wird. 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 Sie Instanzen der Serien G und P verwenden sollten, die größer als 3 sind und ü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 Trainingsjobs mit langer Laufzeit

Checkpointing ist eine Technik zur Fehlertoleranz, bei der der Status eines Prozesses in regelmäßigen Abständen gespeichert wird, sodass er im Falle von Unterbrechungen am zuletzt gespeicherten Punkt fortgesetzt werden kann. Beim maschinellen Lernen wird es häufig mit Training in Verbindung gebracht. Bei Jobs mit langer Laufzeit können Modellgewichte und Optimizer-Status eingespart werden, sodass das Training nach Ausfällen wie Hardwareproblemen oder Spot-Instance-Unterbrechungen wieder aufgenommen werden kann.

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 Modell-Snapshots während des Trainings aufgrund einer unerwarteten Unterbrechung des Trainingsauftrags oder der Trainingsinstanz. Auf diese Weise können Sie das Training des Modells in Zukunft von einem Checkpoint aus fortsetzen. Zusätzlich zur Implementierung eines Node-Resilienzsystems empfehlen wir die Implementierung von Checkpointing, um die Auswirkungen von Unterbrechungen, einschließlich solcher, die durch Hardwareausfälle oder Unterbrechungen der Amazon EC2 Spot-Instance verursacht werden, zu minimieren.

Ohne Checkpointing können Unterbrechungen zu vergeudeter Rechenzeit und Fortschrittsverlusten führen, was bei lang andauernden Trainingsaufträgen kostspielig ist. Durch Checkpointing können Jobs ihren Status regelmäßig speichern (z. B. Modellgewichte und Optimiererstatus) und nach einer Unterbrechung am letzten Checkpoint (zuletzt verarbeiteter Batch) fortgesetzt werden. Um Checkpointing zu implementieren, entwerfen Sie Ihre Anwendung so, dass sie Daten in großen Batches verarbeitet und Zwischenergebnisse während des Trainingsauftrags über den Mountpoint for Amazon S3 CSI Driver in einem persistenten Speicher, z. B. in einem Amazon S3-Bucket, speichert.

Anwendungsfälle

Checkpointing ist besonders in bestimmten Szenarien von Vorteil, um ein Gleichgewicht zwischen Fehlertoleranz und Leistungsaufwand herzustellen. Erwägen Sie den Einsatz von Checkpointing in den folgenden Fällen:

  • Die Auftragsdauer überschreitet einige Stunden: Für lange Trainingsjobs (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 des Fortschritts aufgrund von Unterbrechungen kostspielig ist. Kürzere Aufträge rechtfertigen den Aufwand möglicherweise nicht. I/O

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

  • Verteiltes Training in großem Maßstab: Für Setups mit hundreds/thousands mehreren 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 Checkpoint-Zugriff zu verarbeiten und komplette Neustarts zu vermeiden.

  • Large-scale Modelle mit hohem Ressourcenbedarf: Bei LLM-Trainings im Petabyte-Bereich, bei denen Ausfälle aufgrund der Clustergröße unvermeidlich sind, optimieren abgestufte Ansätze (schnelle lokale Abläufe alle 5-30 Minuten bei vorübergehenden Störungen, dauerhaft stündlich bei größeren Ausfällen) die Wiederherstellungszeit im Vergleich zur Effizienz.

Verwenden Sie ML Capacity Blocks zur Sicherung der Kapazität von P- und Trainium-Instances

Capacity Blocks for ML ermöglichen es Ihnen, sehr gefragte GPU-Instances zu reservieren, insbesondere P-Instances (z. B. p6-b200, p5, p5e, p5en, p4d, p4de) und Trainium-Instances (z. B. trn1, trn2), um entweder fast sofort oder zu einem späteren 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. Die Preise für EC2 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 GPUs für AI/ML Workloads auf Amazon EKS zu reservieren, um eine vorhersehbare Kapazitätsabsicherung zu gewährleisten, empfehlen wir, ML-Kapazitätsblöcke für kurzfristige oder Kapazitätsreservierungen (ODCRs) für On-Demand allgemeine Kapazitätsabsicherungen zu nutzen.

  • 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, um die Verfügbarkeit auch bei hoher Nachfrage sicherzustellen. ODCRs sind nicht langfristig gebunden, aber Sie zahlen den On-Demand Tarif für die reservierte Kapazität, unabhängig davon, ob sie genutzt oder inaktiv ist. In EKS werden ODCRs von Knotentypen wie https://karpenter.sh/ Karpenter und verwalteten Knotengruppen unterstützt. https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html Um ODCRs in Karpenter zu priorisieren, konfigurieren Sie das so, dass das Feld 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- (trn1, trn2) -Instances, der für kurzfristige ML-Workloads wie Modelltraining, Feinabstimmung oder Experimente konzipiert ist. Sie reservieren Kapazität für einen bestimmten Zeitraum (in der Regel 24 Stunden bis 182 Tage), der an einem zukünftigen Datum beginnt, und zahlen nur für die reservierte Zeit. Sie sind im Voraus bezahlt, erfordern eine vorherige Planung des Kapazitätsbedarfs und unterstützen keine automatische Skalierung. Sie werden jedoch in EC2 gespeichert, um Netzwerke mit niedriger Latenz zu ermöglichen. 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 dazu 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 in einem Staging-Cluster. Weitere Informationen finden Sie in der Dokumentation zu Capacity Blocks.

On-DemandErwägen Sie Amazon EC2 Spot oder On-Demand Capacity Reservations (ODCRs) für G Amazon EC2-Instances

Für G Amazon EC2-Instances sollten Sie die verschiedenen Kaufoptionen von Amazon EC2 Spot-Instances On-Demand und Kapazitätsreservierungen in Betracht ziehen. On-Demand ODCRs ermöglichen es Ihnen, EC2-Instance-Kapazitäten in einer bestimmten Availability Zone für eine bestimmte Dauer zu reservieren, sodass die Verfügbarkeit auch bei hoher Nachfrage gewährleistet ist. Im Gegensatz zu ML Capacity Blocks, die nur für P- und Trainium-Instances verfügbar sind, können ODCRs für eine breitere Palette von Instance-Typen verwendet werden, einschließlich G-Instances. Dadurch eignen sie sich für Workloads, die unterschiedliche GPU-Funktionen wie Inferenz oder Grafik erfordern. Wenn Sie Amazon EC2 Spot-Instances verwenden, ist die Möglichkeit, zwischen verschiedenen Instance-Typen, Größen und Verfügbarkeitszonen zu variieren, entscheidend, um länger auf Spot bleiben zu können.

ODCRs haben keine langfristige Bindung, aber Sie zahlen den On-Demand Tarif für die reservierte Kapazität, unabhängig davon, ob sie genutzt oder inaktiv ist. ODCRs können für den sofortigen Einsatz erstellt oder für einen späteren Zeitpunkt geplant werden, was Flexibilität bei der Kapazitätsplanung bietet. In Amazon EKS werden ODCRs von Knotentypen wie https://karpenter.sh/ Karpenter und verwalteten Knotengruppen unterstützt. https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html Um ODCRs in Karpenter zu priorisieren, konfigurieren Sie das so, dass das Feld verwendet wird. NodeClass capacityReservationSelectorTerms Weitere Informationen finden Sie in der Karpenter-Dokumentation. NodePools Weitere Informationen zum Erstellen von ODCRs, einschließlich CLI-Befehlen, finden Sie unter Erste Schritte mit der On-Demand Kapazitätsreservierung.

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

Die Auswahl der geeigneten beschleunigten Instance und Größe ist unerlässlich, um sowohl die Leistung als auch die Kosten Ihrer ML-Workloads auf Amazon EKS zu optimieren. Beispielsweise haben verschiedene GPU-Instance-Familien unterschiedliche Leistungen und Funktionen, wie z. B. GPU-Speicher. Um Ihnen bei der Auswahl der Option mit dem besten Preis-Leistungs-Verhältnis zu helfen, überprüfen Sie die verfügbaren GPU-Instances auf der Seite EC2-Instance-Typen unter Accelerated Computing. 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 die Anzahl der GPUs, den Arbeitsspeicher und die 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 Überblick darüber zu bekommen, ob Sie die GPU (s) in Ihrer Instance voll ausnutzen, können Sie https://docs.nvidia.com/deploy/nvidia-smi/index.html 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 Ihre Codes 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 das nicht unbedingt, dass die GPU voll ausgelastet ist. Eine bessere Kennzahl 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 voll aus.

  • Die -l 5 Flagge besagt, dass die Metriken alle 5 Sekunden ausgegeben werden sollen. Bei einem einzelnen GPU-Instanztyp wird das Indexabfrage-Flag 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 einzige GPU teilen, indem sie ihre Rechenressourcen gemeinsam nutzen, was potenziell die Effizienz verbessert und die Verschwendung reduziert. Die gemeinsame Nutzung der GPU kann durch 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 für die jeweilige Arbeitslast geeigneten GPUs geplant sind (z. B.) karpenter.k8s.aws/instance-gpu-name: "a100"

  • Time-Slicing: Plant Workloads so, dass sie sich im Laufe der Zeit die Rechenressourcen einer GPU teilen, sodass eine gleichzeitige Ausführung ohne physische Partitionierung möglich ist. Dies ist ideal für Workloads mit variablen Rechenanforderungen, denen es jedoch möglicherweise an Speicherisolierung mangelt.

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

  • Fraktionierte GPU-Zuweisung: Verwendet softwarebasierte Planung, um Teile der Rechenleistung oder des Speichers einer GPU Workloads zuzuweisen und bietet so Flexibilität für dynamische Workloads. Der NVIDIA KAI Scheduler, Teil der Run:ai Plattform, ermöglicht dies, indem er es Pods ermöglicht, Bruchteile von GPU-Ressourcen anzufordern.

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

Beispiel

Um beispielsweise Time-Slicing mit dem NVIDIA Device Plugin zu aktivieren:

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

Ausfallsicherheit der Knoten und Verwaltung von Trainingsaufträgen

Implementieren Sie Node-Integritätsprüfungen mit automatisierter Wiederherstellung

Bei verteilten Trainingsjobs 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 Trainingsjobs führen. Diese Unterbrechungen können zum Verlust des Trainingsfortschritts und zu erhöhten Kosten führen, insbesondere bei AI/ML Workloads mit langer Laufzeit, die auf stabiler Hardware angewiesen sind.

Um die Widerstandsfähigkeit gegen Hardwareausfälle wie GPU-Ausfälle in EKS-Clustern, auf denen GPU-Workloads ausgeführt werden, zu erhöhen, empfehlen wir, entweder den EKS Node Monitoring Agent mit Auto Repair oder Amazon zu nutzen. SageMaker HyperPod Der EKS Node Monitoring Agent mit Auto Repair bietet zwar Funktionen wie die Überwachung des Knotenzustands und die automatische Reparatur mithilfe von Kubernetes-Standardmechanismen, SageMaker HyperPod bietet aber auch gezielte Ausfallsicherheit und zusätzliche Funktionen, die speziell für groß angelegte ML-Schulungen entwickelt wurden, wie z. B. gründliche Zustandsprüfungen und automatische Wiederaufnahme der Arbeit.

  • Der EKS Node Monitoring Agent mit Node Auto Repair überwacht kontinuierlich den Zustand der Knoten, indem er Protokolle liest und anwendet. Dazu gehören auch Standardbedingungen wie Ready Bedingungen NodeConditions, die für beschleunigte Hardware spezifisch sind, um Probleme wie GPU- oder Netzwerkfehler zu erkennen. 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 Standard-Kubernetes-Mechanismen und der Neustartrichtlinie des Jobs.

  • Der Agent für SageMaker HyperPod gründliche Integritätsprüfungen und Statusüberwachung überwacht kontinuierlich den Zustand der GPU und der Instances. Trainium-based Er ist auf AI/ML Workloads zugeschnitten und verwendet Labels (z. B. Node-Health-Status), um den Zustand der Knoten zu verwalten. Wenn ein Knoten als fehlerhaft eingestuft wird, wird der automatische Austausch der fehlerhaften Hardware, wie GPUs, HyperPod ausgelöst. Es erkennt standardmäßig netzwerkbedingte Ausfälle für EFA anhand seiner grundlegenden Integritätsprüfungen und unterstützt die automatische Wiederaufnahme bei unterbrochenen Trainingsjobs, sodass Jobs vom letzten Checkpoint aus 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, sicher, dass der AWS-EFA-Treiber installiert ist, um EFA-specific Messwerte wie RDMA-Fehler (Remote Direct Memory Access) und Paketverluste zu überwachen. https://docs.aws.amazon.com/eks/latest/userguide/node-efa.html Darüber hinaus empfehlen wir, CloudWatch Observability bereitzustellen Add-on oder Tools wie DCGM Exporter mit Prometheus und Grafana zu verwenden, um EFA, GPU und, falls, bestimmte Metriken im Zusammenhang mit ihren Funktionen zu überwachen. SageMaker HyperPod

Deaktivieren Sie Karpenter Consolidation für unterbrechungssensitive Workloads

Für Workloads, die empfindlich auf Unterbrechungen reagieren, z. B. bei der Verarbeitung, umfangreichen AI/ML Prognoseaufgaben oder Schulungen, empfehlen wir, die Konsolidierungsrichtlinien von Karpenter so anzupassen, dass Unterbrechungen während der Auftragsausführung vermieden werden. Die Konsolidierungsfunktion von Karpenter optimiert automatisch die Cluster-Kosten, indem nicht ausgelastete Knoten beendet oder durch kostengünstigere Alternativen ersetzt werden. Aber selbst wenn ein Workload eine GPU voll ausnutzt, kann Karpenter Knoten konsolidieren, wenn es einen kostengünstigen Instance-Typ mit der richtigen Größe identifiziert, der die Anforderungen des Pods erfüllt, was zu Arbeitsunterbrechungen führt.

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

disruption: consolidationPolicy: WhenEmpty consolidateAfter: 60m

Dieser Ansatz verbessert die Pod-Startlatenz für hohe Batch-Inferenz-Workloads und andere unterbrechungssensitive 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 in Karpenter NodePool . Mithilfe von Budgets können Sie sicherstellen, dass zu einem bestimmten Zeitpunkt nicht mehr als eine bestimmte Anzahl von Knoten im ausgewählten NodePool Knoten unterbrochen wird. Sie können auch Unterbrechungsbudgets verwenden, um zu verhindern, dass alle Knoten zu einer bestimmten Zeit (z. B. zu Spitzenzeiten) unterbrochen werden. Weitere Informationen finden Sie in der Dokumentation zu Karpenter Consolidation.

Verwenden Sie ttl, um Kubernetes-Jobs SecondsAfterFinished zu automatisieren Clean-Up

Wir empfehlen, die Einstellung ttlSecondsAfterFinished für Kubernetes-Jobs in Amazon EKS so einzustellen, dass abgeschlossene Auftragsobjekte automatisch gelöscht werden. Verbleibende Auftragsobjekte verbrauchen Cluster-Ressourcen wie API-Serverspeicher und erschweren die Überwachung, da die Dashboards überladen sind (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 stets sauber bleibt. Weitere Informationen finden Sie unter Automatische Bereinigung für abgeschlossene Jobs.

Konfigurieren Sie Low-Priority Job Preemption für Higher-Priority Jobs/workloads

Für AI/ML Workloads mit gemischter Priorität in Amazon EKS können Sie die Auftragsprävention 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 Jobs (z. B. Webservices) kritische Pods verzögern, indem sie Knoten belegen. CPU/memory-intensive Mithilfe der Präemption kann Kubernetes Pods mit niedriger Priorität entfernen, wenn Pods mit hoher Priorität Ressourcen benötigen. Dadurch wird eine effiziente Ressourcenzuweisung auf Knoten mit GPUs, CPUs oder Arbeitsspeicher gewährleistet. Wir empfehlen, Kubernetes zu verwenden, um Prioritäten zuzuweisen und das Räumungsverhalten zu kontrollieren. PriorityClass PodDisruptionBudget

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

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

Skalierung und Leistung von Anwendungen

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

Um eine kosteneffiziente und reaktionsschnelle Rechenkapazität für Machine-Learning-Workflows (ML) auf Amazon EKS sicherzustellen, empfehlen wir, Ihre Node-Provisioning-Strategie an die Merkmale und Kostenverpflichtungen Ihrer Workloads anzupassen. Im Folgenden finden Sie zwei Ansätze, die Sie in Betracht ziehen sollten: Just-in-Time-Skalierung mit Karpenter und statische Knotengruppen für reservierte Kapazität.

Beispiel

Dies ist ein Beispiel für ein vielseitiges Karpenter NodePool, das den Start von g Amazon EC2-Instances ermöglicht, bei denen mehr als drei Instanzen generiert werden.

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 eine Trainingslast:

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 Einschränkungen 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 die Verwendung von Taints und Tolerance, 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 Inferenzanforderungen oder Token-Durchsatz mit angemessenen Abklingzeiten. Statische Skalierungsrichtlinien können zu viel oder zu wenig Ressourcen bereitstellen, was sich auf Kosten und Latenz auswirkt. Erfahren Sie mehr 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 Grenzen herkömmlicher Geräte-Plug-ins hinaus und ermöglicht eine ausgeklügelte gemeinsame Nutzung von GPUs, Topologieerkennung und knotenübergreifende Ressourcenkoordination. DRA ist in Amazon EKS-Version 1.33 verfügbar und begegnet kritischen Herausforderungen im Zusammenhang mit AI/ML Workloads, indem es Folgendes bietet:

  • Fine-grained GPU-Zuweisung

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

  • Unterstützung für Hardwarearchitekturen der nächsten Generation, einschließlich NVIDIA GB200 UltraServers

Bei der herkömmlichen GPU-Zuweisung werden GPUs als undurchsichtige Ganzzahlressourcen behandelt, was zu einer erheblichen Unterauslastung führt (in Produktionsclustern häufig 30-40%). Dies liegt daran, dass Workloads exklusiven Zugriff auf ganze GPUs erhalten, auch wenn nur ein Bruchteil der Ressourcen benötigt wird. 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-Plug-ins

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 beim NVIDIA-Geräte-Plug-In

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

  • Eingeschränkte granulare Auswahl: Während das Geräte-Plug-In GPU-Eigenschaften über Node-Labels verfügbar macht, können Workloads bestimmte GPU-Konfigurationen (Speichergröße und Rechenkapazitäten) nicht dynamisch 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 GB200 zu formulieren.

  • 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 bewältigen.

  • 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 bei der Anforderung detaillierte Anforderungen (GPU-Speicher, Treiberversionen und spezifische Attribute) angeben. resourceclaims Dies ermöglicht einen flexibleren Ressourcenabgleich.

  • Topologiebewusstsein: Mithilfe strukturierter Parameter und Geräteselektoren bewältigt DRA komplexe Anforderungen wie knotenübergreifende GPU-Kommunikation und speicherkohärente Verbindungen.

  • Cross-node Ressourcenmanagement: computeDomains ermöglicht die Koordination verteilter GPU-Ressourcen über mehrere Knoten hinweg, was für Systeme wie GB200 mit IMEX-Kanälen von entscheidender Bedeutung ist.

  • Workload-specific Konfiguration: Jede Konfiguration ResourceClaim spezifiziert unterschiedliche Strategien und Konfigurationen für die gemeinsame Nutzung und ermöglicht so eine feinkörnige Steuerung pro Workload statt clusterweiter 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-Plug-In nicht vollständig. Der NVIDIA DRA-Treiber arbeitet zusammen mit dem Geräte-Plug-In, um erweiterte Funktionen bereitzustellen. Das Geräte-Plug-In übernimmt weiterhin die grundlegende GPU-Erkennung und -Verwaltung, während DRA erweiterte Zuweisungs- und Planungsfunktionen bietet.

Von DRA unterstützte Instanzen und ihre Funktionen

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

Instance-Familie GPU-Typ Time-slicing 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

Large-scale Schulung und HPC

P5

NVIDIA H100

Ja

Ja

Ja

Nein

Schulung zum Grundmodell

P6

NVIDIA B200

Ja

Ja

Ja

Nein

Modelle mit Milliarden oder Billionen Parametern, verteiltes Training und Inferenz

P6e

NVIDIA GB200

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): Hardware-level Partitionierung, die isolierte GPU-Instanzen erzeugt.

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

  • Internode Memory Exchange (IMEX): Memory-coherent Kommunikation zwischen Knoten für GB200. 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 eine erweiterte GPU-Verwaltung ein

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

Voraussetzungen

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

Cluster-Konfiguration
  • Amazon EKS-Cluster mit ausgeführter Version 1.33 oder höher

  • Von Amazon EKS verwaltete Knotengruppen (DRA wird derzeit nur von verwalteten Knotengruppen mit AL2023- und Bottlerocket NVIDIA-optimierten AMIs unterstützt, nicht von Karpenter)

  • NVIDIA-Worker-Knoten GPU-enabled mit den entsprechenden Instance-Typen

Erforderliche Komponenten
  • Version des NVIDIA-Geräte-Plugins 0.17.1 oder höher

  • NVIDIA DRA-Treiberversion 25.3.0 oder höher

Schritt 1: Erstellen Sie einen Cluster mit einer DRA-enabled Knotengruppe mithilfe von eksctl

  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 0.17.1 \ --values nvidia-device-plugin-values.yaml

Schritt 3: Stellen Sie den NVIDIA DRA-Treiber Helm Chart 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

    Das Folgende 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

    Das Folgende ist 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 mit aktiviertem DRA Ihrem Amazon EKS-Cluster 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, Rechenleistung und mehr).

    • Da A10G keine MIG-Partitionierung 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 resourceclaimtemplates die GPU-Ressourcen angefordert werden. Dies ermöglicht eine flexiblere Ressourcenverwaltung im Vergleich zu herkömmlichen Geräte-Plug-in-Ansätzen. Dies geschieht automatisch ohne manuelles Eingreifen. Der Knoten wird einfach für GPU-Workloads verfügbar, sobald der DRA-Treiber den Ressourcenermittlungs- und Registrierungsprozess 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 eine einfache GPU-Arbeitslast mithilfe der dynamischen Ressourcenzuweisung.

Planen Sie eine einfache GPU-Arbeitslast 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 den Anweisungen gefolgt sindRichten Sie eine dynamische Ressourcenzuweisung für eine erweiterte GPU-Verwaltung ein.

  1. Erstellen Sie eine Basisdatei 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 eine Beispielausgabe:

    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üfe 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

    Im Folgenden finden Sie 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)

Weiter unter finden Sie GPU-Optimierungstechniken mit dynamischer Ressourcenzuweisung fortgeschrittenere GPU-Optimierungstechniken mit DRA.

GPU-Optimierungstechniken mit dynamischer Ressourcenzuweisung

Moderne GPU-Workloads erfordern ein ausgeklügeltes Ressourcenmanagement, um eine optimale Auslastung 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. Unternehmen berichten, dass die GPU-Auslastung bei herkömmlicher Zuweisung von 30-40% auf 80-90% bei optimierten Strategien zur gemeinsamen Nutzung gestiegen ist. Die Wahl der Technik hängt von den Merkmalen 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 eine ResourceClaimTemplate für Time-Slicing mit einer Datei namens: 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. Überwachen Sie die Ressourcenansprüche:

    kubectl get resourceclaims -n timeslicing-gpu -w

    Das Folgende ist eine Beispielausgabe:

    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: Beginnt sofort zu laufen

Zweiter Pod (training-pod-2)

  • Bundesland: pending

  • Bedeutung: Warten darauf, dass DRA Time-Slicing auf derselben GPU konfiguriert

  • Pod-Status: Wartet auf einen Termin

  • Der Staat wechselt von pending bis allocated,reserved bis 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 eine 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, der MPS verwendet, 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 eine Beispielausgabe:

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

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

Jeder Container erhält seinen eigenen isolierten GPU-Speicherplatz und seine eigenen 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, bei der 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 eine gleichzeitige Ausführung belegen.

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

Container 1: Inferenzcontainer
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: Trainingscontainer
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 GPU Multi-Instance

Multi-instance GPU (MIG) bietet 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 die GPU-Instanzen wie P4D, P4De, P5, P6 und mehr neu zu starten, um die Konfigurationsänderungen anzuwenden. Der GPU Operator bietet umfassende MIG-Verwaltungsfunktionen über die MIG Manager-Komponente, die auf Änderungen der Node-Label achtet und automatisch die entsprechende MIG-Konfiguration anwendet. 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 Vorgang erfordert einen Node-Neustart für GPU-Instances, um saubere GPU-Statusübergänge sicherzustellen. 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 das NVIDIA Device Plugin und den DCGM Exporter nicht, da diese Teil des NVIDIA GPU Operators sind. Da die EKS-NVIDIA-AMIs mit vorinstallierten NVIDIA-Treibern geliefert werden, 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 Instances vorhanden sind. Der NVIDIA DRA-Treiber kümmert sich um die dynamische Ressourcenzuweisung für MIG-Instances, während der GPU-Operator den gesamten GPU-Lebenszyklus verwaltet. Dazu gehören die MIG-Konfiguration, die Funktionalität des 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 Funktionen zur 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 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 Node-Funktionen (NFD — Hardwarekennzeichnung)

    • Erkennung von GPU-Funktionen (GFD — GPU-specific Kennzeichnung)

    • MIG Manager (Multi-instance GPU-Partitionierung)

    • Container-Toolkit (GPU-Container-Laufzeit)

    • Operator Controller (Lebenszyklusmanagement)

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

    kubectl get pods -n gpu-operator

    Das Folgende ist eine Beispielausgabe:

    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-Instance angewendet und GPU-Partitionen auf Hardwareebene wie konfiguriert 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-enabled GPUs (0-3): hardwarepartitioniert

    • GRAFIKPROZESSOR 0: NVIDIA A100-SXM4-80GB

      • MIG 3g.40gb Device 0 — Große Workloads (40 GB Arbeitsspeicher, 42 SMs)

      • MIG 2g.20gb Gerät 1 — Mittlere Arbeitslasten (20 GB Arbeitsspeicher, 28 SMs)

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

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

    • GPU 1: NVIDIA A100-SXM4-80GB

      • 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 — Das gleiche Muster wie GPU 0 und GPU 1

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

    • GPU 4: NVIDIA A100-SXM4-80GB — Volle 80-GB-GPU

    • GPU 5: NVIDIA A100-SXM4-80GB — Volle 80-GB-GPU

    • GPU 6: NVIDIA A100-SXM4-80GB — Volle 80-GB-GPU

    • GPU 7: NVIDIA A100-SXM4-80GB — Volle 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.10gb, 2g.20gb, 3g.40gb) und macht sie über die Geräteklasse als planbare Ressourcen verfügbar. mig.nvidia.com

Der DRA-Treiber überwacht kontinuierlich die MIG-Topologie und führt ein Inventar der verfügbaren Instanzen auf allen GPUs. Wenn ein Pod ein bestimmtes MIG-Profil über a anfordertResourceClaimTemplate, wählt der DRA-Treiber intelligent eine geeignete MIG-Instance 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, während 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 mit Isolierung auf Hardwareebene gemeinsam nutzen können.

  1. Erstellen Sie, mig-claim-template.yaml um 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 eine Beispielausgabe:

    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 dies 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-Protokolle des DRA-Treibers und Sie werden eine Ausgabe sehen, 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 Sie dasresourceclaims, um den Pod-Status zu sehen:

    kubectl get resourceclaims -n mig-gpu -w

    Das Folgende ist eine Beispielausgabe:

    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, hat der DRA-Treiber für alle Pods den Status „Ausstehend“ geändert. allocated,reserved

  8. Laufen Sie nvidia-smi vom Knoten 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 GB200 P6e-Instances

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

Führen Sie die folgenden Schritte aus.

  1. Definieren Sie eine ComputeDomain für 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 mit dem Namen: 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 GB200-Instances.

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

    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üfe 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

    Das Folgende ist 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.