

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
<a name="aiml-compute"></a>

**Tipp**  
 [Informieren Sie](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el) sich in Amazon EKS-Workshops über bewährte Verfahren.

## Optimierung der GPU-Ressourcen und Kostenmanagement
<a name="_gpu_resource_optimization_and_cost_management"></a>

### Planen Sie Workloads mit GPU-Anforderungen mithilfe von Labels Well-Known
<a name="_schedule_workloads_with_gpu_requirements_using_well_known_labels"></a>

[Für AI/ML Workloads, die empfindlich auf unterschiedliche GPU-Merkmale reagieren (z. B. GPU, GPU-Speicher), empfehlen wir, die GPU-Anforderungen anhand [bekannter Scheduling-Labels](https://kubernetes.io/docs/reference/labels-annotations-taints/) anzugeben, die von den mit [Karpenter](https://karpenter.sh/v1.0/concepts/scheduling/#labels) verwendeten Knotentypen und verwalteten Knotengruppen unterstützt werden.](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) Wenn diese nicht definiert werden, kann dies dazu führen, dass Pods auf Instanzen mit unzureichenden GPU-Ressourcen geplant werden, was zu Ausfällen oder Leistungseinbußen führen kann. Wir empfehlen, [NodeSelector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) oder [Node Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity) zu verwenden, um anzugeben, auf welchem Knoten ein Pod ausgeführt werden soll, und [Rechenressourcen](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) (CPU, Arbeitsspeicher, GPUs usw.) im Ressourcenbereich des Pods festzulegen.

 **Beispiel** 

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

```
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod-example
spec:
  containers:
  - name: ml-workload
    image: <image>
    resources:
      limits:
        nvidia.com/gpu: 1  # Request one NVIDIA GPU
  nodeSelector:
    karpenter.k8s.aws/instance-gpu-name: "l40s"  # Run on nodes with NVIDIA L40S GPUs
```

### Verwenden Sie das Kubernetes Device Plugin, um GPUs verfügbar zu machen
<a name="_use_kubernetes_device_plugin_for_exposing_gpus"></a>

Um GPUs auf Knoten verfügbar zu machen, muss der NVIDIA-GPU-Treiber auf dem Betriebssystem des Knotens installiert und die Container-Laufzeit so konfiguriert sein, dass der Kubernetes-Scheduler den Knoten mit verfügbaren GPUs Pods zuweisen kann. Der Einrichtungsprozess für das NVIDIA Kubernetes Device Plugin hängt von dem EKS Accelerated AMI ab, das Sie verwenden:
+  **[Bottlerocket Accelerated AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami-bottlerocket.html)**: Dieses AMI beinhaltet den NVIDIA-GPU-Treiber **und** das [NVIDIA Kubernetes Device Plugin](https://github.com/NVIDIA/k8s-device-plugin) ist vorinstalliert und sofort einsatzbereit, sodass GPU-Unterstützung sofort verfügbar ist. Es ist keine zusätzliche Konfiguration erforderlich, um GPUs für den Kubernetes-Scheduler verfügbar zu machen.
+  **[AL2023 Accelerated AMI](https://aws.amazon.com/blogs/containers/amazon-eks-optimized-amazon-linux-2023-accelerated-amis-now-available/)****: Dieses AMI enthält den NVIDIA-GPU-Treiber, aber das [NVIDIA Kubernetes Device Plugin](https://github.com/NVIDIA/k8s-device-plugin) ist nicht vorinstalliert.** Sie müssen das Geräte-Plugin separat installieren und konfigurieren, in der Regel über ein. DaemonSet Beachten Sie, dass, wenn Sie eksctl verwenden, um Ihren Cluster zu erstellen und einen GPU-Instanztyp (z. B.`g5.xlarge`) in Ihrem angeben ClusterConfig, `eksctl` automatisch das entsprechende AMI ausgewählt und das NVIDIA Kubernetes Device Plugin installiert wird. Weitere Informationen finden Sie unter [GPU-Unterstützung](https://eksctl.io/usage/gpu-support/) in der eksctl-Dokumentation.

Wenn Sie stattdessen die EKS-Beschleunigungs-AMIs und den [NVIDIA-GPU-Operator zur Verwaltung von Komponenten wie dem NVIDIA](https://github.com/NVIDIA/gpu-operator) Kubernetes-Geräte-Plug-In verwenden möchten, 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](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/getting-started.html#pre-installed-nvidia-gpu-drivers-and-nvidia-container-toolkit) deaktivieren müssen.

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

```
kubectl describe node | grep nvidia.com/gpu
```

Mit diesem Befehl wird geprüft, ob die `nvidia.com/gpu` Ressource über die Kapazität des Knotens verfügt und ob die Ressourcen zugewiesen werden können. Zum Beispiel sollte ein Knoten mit einer GPU angezeigt werden. `nvidia.com/gpu: 1` Weitere Informationen finden Sie im [Kubernetes GPU Scheduling Guide](https://kubernetes.io/docs/tasks/manage-gpus/scheduling-gpus/).

### Verwenden Sie viele verschiedene EC2-Instance-Typen
<a name="_use_many_different_ec2_instance_types"></a>

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](scale-data-plane.md) Abschnitt beschrieben. Diese Empfehlung gilt auch für Instances mit beschleunigter Hardware (z. B. GPUs). Wenn Sie einen Cluster erstellen, der nur einen Instanztyp verwendet, und versuchen, die Anzahl der Knoten über die Kapazität der Region hinaus zu skalieren, wird möglicherweise ein Fehler mit unzureichender Kapazität (ICE) angezeigt, der darauf hinweist, dass keine Instanzen 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 mit dem [EC2 Instance Type Explorer-Tool](https://aws.amazon.com/ec2/instance-explorer/), um eine Liste von Instance-Typen zu erstellen, die Ihren spezifischen Rechenanforderungen entsprechen, und vermeiden Sie, die Art der Instances, die in Ihrem Cluster verwendet werden können, willkürlich einzuschränken.

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

 **Beispiel** Das folgende Beispiel zeigt, wie ein Karpenter in die Lage versetzt werden kann NodePool , G- und P-Instances für mehr als die Generationen 3 bereitzustellen (z. B. p3). Weitere Informationen finden Sie im [Bewährte Methoden für EKS-Skalierbarkeit](scalability.md) 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
<a name="_consider_using_amazon_ec2_spot_instances_for_gpus_with_karpenter"></a>

Mit Amazon EC2 Spot-Instances können Sie ungenutzte EC2-Kapazität in der AWS-Cloud nutzen und sind mit einem discount von bis zu 90% im Vergleich zu den On-Demand Preisen erhältlich. 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](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-spot-instances.html) im Amazon EC2 EC2-Benutzerhandbuch. Amazon EC2 Spot kann eine hervorragende Wahl für fehlertolerante, zustandslose und flexible Workloads (Zeit und Instanztyp) sein. Weitere Informationen darüber, wann Sie Spot-Instances verwenden sollten, finden Sie unter Bewährte Methoden für [EC2-Spot-Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-best-practices.html). Sie können Spot-Instances auch für AI/ML Workloads verwenden, falls dies der Fall ist. Spot-friendly

 **Anwendungsfälle** 

Spot-friendly Bei Workloads kann es sich um Big Data, containerisierte Workloads, statuslose Webserver CI/CD, High Performance Computing (HPC) und Rendering-Workloads handeln. Spot-Instances eignen sich nicht für Workloads, die unflexibel, zustandsbehaftet, fehlerintolerant oder eng zwischen Instanzknoten gekoppelt sind (z. B. Workloads mit parallel Prozessen, die bei der Berechnung stark voneinander abhängen und eine ständige Kommunikation zwischen den Knoten erfordern, wie 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 hinweg) 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 Optimierungsaufträge opportunistisch auszuführen, da Unterbrechungen ohne nennenswerte Verluste toleriert werden können, insbesondere bei Experimenten mit kurzer Dauer.
+  **Datenerweiterung**: Verwenden Sie Spot-Instances, um Aufgaben zur Datenvorverarbeitung und -erweiterung durchzuführen, die bei einer Unterbrechung von Checkpoints aus neu gestartet werden können, was sie ideal für die variable Verfügbarkeit von Spot macht.
+  **Fine-tuning Modelle**: Verwenden Sie Spot-Instances zur Feinabstimmung mit robusten Checkpoint-Mechanismen, um den Vorgang mit dem zuletzt gespeicherten Status fortzusetzen und so die Auswirkungen von Instance-Unterbrechungen zu minimieren.
+  **Batch-Inferenz**: Verwenden Sie Spot-Instances, um große Batch von Offline-Inferenzanfragen nicht in Echtzeit zu verarbeiten, sodass Jobs angehalten und wieder aufgenommen werden können. Dies bietet die beste Abstimmung mit den Kosteneinsparungen von Spot und die Bewältigung potenzieller Unterbrechungen durch Wiederholungen oder Diversifizierung.
+  **Opportunistische Trainingsuntergruppen**: Verwenden Sie Spot-Instances für marginale oder experimentelle Trainingsworkloads (z. B. kleinere Modelle mit 10 Millionen Parametern), bei denen Unterbrechungen akzeptabel sind und Effizienzoptimierungen wie Diversifizierung zwischen Instance-Typen oder Regionen angewendet werden können. Für Schulungen im Produktionsmaßstab ist dies jedoch aufgrund potenzieller Unterbrechungen nicht zu empfehlen.

 **Überlegungen** 

Um Spot-Instances für beschleunigte Workloads auf Amazon EKS zu verwenden, gibt es eine Reihe wichtiger Überlegungen (in keiner bestimmten Reihenfolge):
+  **Verwenden Sie Karpenter, um Spot-Instances mit aktivierter erweiterter Konsolidierung zu verwalten**. Durch Angabe von karpenter. sh/capacity-Geben Sie in Ihrem Karpenter „spot“ ein. Karpenter NodePool stellt Spot-Instances standardmäßig ohne zusätzliche Konfiguration bereit. Um jedoch eine erweiterte Spot-to-Spot Konsolidierung zu ermöglichen, bei der nicht ausgelastete Spot-Knoten durch kostengünstigere Spot-Alternativen ersetzt werden, müssen Sie das Feature-Gate aktivieren, indem Sie --feature-gates SpotToSpotConsolidation =true in den SpotToSpotConsolidation [Controller-Argumenten von Karpenter](https://karpenter.sh/docs/reference/settings/) oder über die Umgebungsvariable FEATURE\_GATES setzen. [Karpenter verwendet die preis-/kapazitätsoptimierte Zuweisungsstrategie für die Bereitstellung von EC2-Instances.](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](https://aws.amazon.com/ec2/instance-explorer/) verwenden, um eine Liste von Instance-Typen zu generieren, die Ihren spezifischen Rechenanforderungen entsprechen.
+  **Stellen Sie sicher, dass Workloads zustandslos, fehlertolerant und flexibel sind**. Workloads müssen zustandslos, fehlertolerant und in Bezug auf ihre Größe flexibel sein. instance/GPU Dies ermöglicht eine reibungslose Wiederaufnahme nach Spot-Unterbrechungen, und die Flexibilität der Instances ermöglicht es Ihnen, möglicherweise länger vor Ort zu bleiben. Aktivieren Sie die [Behandlung von Spot-Unterbrechungen](https://karpenter.sh/docs/concepts/disruption/#interruption) in Karpenter, indem Sie den Helm-Wert settings.interruptionQueue mit dem Namen der AWS SQS-Warteschlange konfigurieren, um Spot-Unterbrechungsereignisse abzufangen. Verwenden Sie beispielsweise bei der Installation über Helm --set „settings.interruptionQueue=$ {CLUSTER\_NAME}“. [Ein Beispiel finden Sie im Handbuch Erste Schritte mit Karpenter.](https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/) Wenn Karpenter ein Spot-Unterbrechungsereignis bemerkt, sperrt, verunreinigt, entleert und beendet es automatisch die Knoten vor dem Unterbrechungsereignis, um die Kündigungsfrist der Pods zu maximieren. Gleichzeitig startet Karpenter sofort einen neuen Knoten, sodass dieser so schnell wie möglich einsatzbereit sein kann.
+  **Vermeiden Sie es, die Auswahl des Instanztyps zu stark einzuschränken**. Sie sollten es so weit wie möglich vermeiden, die Instanztypen einzuschränken. Wenn die Instance-Typen nicht eingeschränkt werden, ist die Wahrscheinlichkeit höher, Spot-Kapazität in großem Umfang mit einer geringeren Häufigkeit von Spot-Instance-Unterbrechungen zu geringeren Kosten zu erwerben. Vermeiden Sie es beispielsweise, sich auf bestimmte Typen zu beschränken (z. B. g5.xlarge). Erwägen Sie die Angabe verschiedener Instanzkategorien und -generationen mithilfe von Schlüsseln wie karpenter.k8s. aws/instance-category 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. Wenn Ihr AI/ML Workload eine bestimmte oder begrenzte Anzahl von Accelerators erfordert, aber zwischen den Regionen flexibel ist, können Sie außerdem Spot Placement Score verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres Workloads zu ermitteln.
+  **Erweitern Sie die NodePool Anforderungen auf eine größere Anzahl ähnlicher EC2-Instance-Familien**. Jeder Spot-Instance-Pool besteht aus einer ungenutzten EC2-Instance-Kapazität für einen bestimmten Instance-Typ in einer bestimmten Availability Zone (AZ). Wenn Karpenter versucht, einen neuen Knoten bereitzustellen, wählt es einen Instance-Typ aus, der den NodePool Anforderungen entspricht. Wenn in keiner AZ ein kompatibler Instance-Typ über Spot-Kapazität verfügt, schlägt die Bereitstellung fehl. Um dieses Problem zu vermeiden, sollten Sie umfassendere Instanzen der G-Serie (Generation 4 oder höher) von NVIDIA in allen Größen und Availability Zones (AZs) zulassen und dabei Hardwareanforderungen wie GPU-Speicher oder Raytracing berücksichtigen. Da es sich bei Instances um unterschiedliche Typen handeln kann, müssen Sie sicherstellen, dass Ihr Workload auf jedem Typ ausgeführt werden kann und dass die Leistung, die Sie erhalten, Ihren Anforderungen entspricht.
+  **Nutzen Sie alle Verfügbarkeitszonen in einer Region**. Die verfügbare Kapazität variiert je nach Availability Zone (AZ). Ein bestimmter Instance-Typ ist in einer AZ möglicherweise nicht verfügbar, in einer anderen jedoch reichlich vorhanden. Jede einzigartige Kombination aus einem Instance-Typ und einer Availability Zone bildet einen separaten Spot-Kapazitätspool. Wenn Sie innerhalb Ihrer NodePool Karpenter-Anforderungen Kapazität für alle AZs in einer Region anfordern, suchen Sie effektiv nach mehr Pools gleichzeitig. Dadurch wird die Anzahl der Spot-Kapazitätspools maximiert und somit die Wahrscheinlichkeit erhöht, Spot-Kapazität zu erwerben. Um dies zu erreichen, lassen Sie in Ihrer NodePool Konfiguration entweder topology.kubernetes weg. io/zone Geben Sie den Schlüssel vollständig ein, damit Karpenter aus allen verfügbaren AZs in der Region auswählen kann, oder führen Sie AZs explizit mit dem Operator: In auf und geben Sie die Werte an (z. B. us-west-2a).
+  **Erwägen Sie, den Spot Placement Score (SPS) zu verwenden, um sich einen Überblick über die Wahrscheinlichkeit zu verschaffen, mit Spot-Instances erfolgreich auf die erforderliche Kapazität zuzugreifen**. [Der Spot Placement Score (SPS)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/work-with-spot-placement-score.html) ist ein Tool, das eine Bewertung liefert, anhand derer Sie beurteilen können, wie wahrscheinlich es ist, dass eine Spot-Anfrage erfolgreich ist. Wenn Sie SPS verwenden, geben Sie zunächst Ihre Rechenanforderungen für Ihre Spot-Instances an, und dann gibt Amazon EC2 die zehn wichtigsten Regionen oder Availability Zones (AZs) zurück, in denen Ihre Spot-Anfrage wahrscheinlich erfolgreich sein wird. Regionen und Availability Zones werden auf einer Skala von 1 bis 10 bewertet. Eine Punktzahl von 10 bedeutet, dass Ihre Spot-Anfrage mit hoher Wahrscheinlichkeit erfolgreich sein wird, aber nicht garantiert werden kann. Ein Ergebnis von 1 zeigt an, dass Ihre Spot-Anforderung sehr wahrscheinlich nicht erfolgreich sein wird. Dasselbe Ergebnis kann für verschiedene Regionen oder Availability Zones zurückgegeben werden. Weitere Informationen finden Sie unter [Anleitung zur Erstellung eines Spot Placement Score Tracker-Dashboards auf AWS](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/work-with-spot-placement-score.html). Da die Spot-Kapazität ständig schwankt, hilft Ihnen SPS dabei, herauszufinden, welche Kombination von 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 eine bestimmte oder eine begrenzte Anzahl von Accelerators erfordert, aber zwischen den Regionen flexibel ist, können Sie den Spot-Platzierungswert verwenden, um vor dem Start dynamisch die optimale Region für die Bereitstellung Ihres Workloads zu ermitteln. Damit Sie automatisch ermitteln können, wie wahrscheinlich es ist, Spot-Kapazität zu erwerben, stellen wir Ihnen eine Anleitung zur Erstellung eines SPS-Tracker-Dashboards zur Verfügung. Diese Lösung überwacht die SPS-Scores im Laufe der Zeit mithilfe einer YAML-Konfiguration für unterschiedliche Setups (z. B. Instanzanforderungen einschließlich GPUs), speichert Metriken 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 zu gewährleisten, einschließlich der Berücksichtigung der Verwendung anderer AWS-Regionen. Weitere Informationen finden Sie unter [So funktioniert der Spot Placement Score](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/how-sps-works.html).
+  **Gehen Sie sorgsam mit Spot-Unterbrechungen** um und testen Sie. Bei einem Pod mit einer Kündigungsfrist von mehr als zwei Minuten wird der alte Knoten unterbrochen, bevor diese Pods neu geplant werden, was sich auf die Verfügbarkeit der Workloads auswirken kann. Berücksichtigen Sie bei der Entwicklung Ihrer Anwendungen die zweiminütige Spot-Unterbrechungsbenachrichtigung, implementieren Sie Checkpointing in lang laufenden Anwendungen (z. B. Speichern des Fortschritts in einem persistenten Speicher wie Amazon S3), um nach Unterbrechungen wieder fortzufahren, 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 and/or PreStop-Lifecycle-Hook-SIGTERM-Signalen innerhalb Ihrer Anwendung, um Aktivitäten wie Säuberung, Statusspeicherung und Verbindungsabbruch ordnungsgemäß herunterzufahren. Bei Echtzeit-Workloads, bei denen die Skalierungszeit wichtig ist und die Workloads länger als zwei Minuten dauern, bis die Anwendung für den Datenverkehr bereit ist, sollten Sie erwägen, die Startzeiten von Containern und das Laden von ML-Modellen durch Überprüfung [Speicher](aiml-storage.md) und [Skalierung und Leistung von Anwendungen](aiml-performance.md) Best Practices zu optimieren. Verwenden Sie zum Testen eines Ersatzknotens den [AWS Fault Injection Service](https://aws.amazon.com/fis/) (FIS), um Spot-Unterbrechungen zu simulieren.

Zusätzlich zu diesen zentralen Best Practices für Spot sollten Sie diese Faktoren bei der Verwaltung von GPU-Workloads auf Amazon EKS berücksichtigen. Im Gegensatz zu CPU-based Workloads reagieren GPU-Workloads besonders empfindlich auf Hardwaredetails wie GPU-Fähigkeiten und verfügbaren GPU-Speicher. GPU-Workloads können durch die Instance-Typen, die sie verwenden können, eingeschränkt werden, sodass im Vergleich zu CPUs weniger Optionen verfügbar sind. Prüfen Sie zunächst, ob Ihr Workload instanzflexibel ist. Wenn Sie nicht wissen, wie viele Instance-Typen Ihr Workload verwenden kann, testen Sie sie einzeln, um Kompatibilität und Funktionalität sicherzustellen. Identifizieren Sie, wie flexibel Sie sein können, um so viel wie möglich zu diversifizieren, und stellen Sie gleichzeitig sicher, dass die Diversifizierung den Workload am Laufen hält, und verstehen Sie alle Auswirkungen auf die Leistung (z. B. auf den Durchsatz oder die Fertigstellungszeit). Beachten Sie bei der Diversifizierung Ihrer Workloads Folgendes:
+  **Überprüfen Sie die Kompatibilität von CUDA und Framework**. Ihre GPU-Workloads sind möglicherweise für bestimmte Hardware und GPU-Typen (z. B. V100 in p3 gegenüber A100 in p4) optimiert oder für bestimmte CUDA-Versionen für Bibliotheken wie geschrieben. Überprüfen Sie daher unbedingt die TensorFlow Kompatibilität Ihrer Workloads. Diese Kompatibilität ist entscheidend, um Laufzeitfehler, Abstürze und Ausfälle bei der GPU-Beschleunigung zu verhindern (z. B. nicht übereinstimmende CUDA-Versionen mit Frameworks, die Ausführung verhindern TensorFlow können) PyTorch oder um Hardwarefunktionen wie Präzision nutzen zu können. FP16/INT8 
+  **GPU-Speicher**. Stellen Sie sicher, dass Sie die Speicheranforderungen Ihrer Modelle evaluieren und die Speichernutzung Ihres Modells während der Laufzeit mithilfe von Tools wie dem [DCGM-Exporter](https://docs.nvidia.com/datacenter/dcgm/latest/gpu-telemetry/dcgm-exporter.html) profilieren. Geben Sie in bekannten Labels wie karpenter.k8s den für den Instance-Typ mindestens erforderlichen GPU-Speicher an. aws/instance-GPU-Speicher. GPU-VRAM variiert je nach Instance-Typ (z. B. hat NVIDIA T4 16 GB, A10G hat 24 GB, V100 hat 16-32 GB), und ML-Modelle (z. B. Large Language Models) können den verfügbaren Speicher überschreiten, was zu Out-of-Memory-Fehlern (OOM) oder Abstürzen führen kann. Bei Spot-Instances in EKS kann dies die Diversifizierung einschränken. Sie können beispielsweise keine Typen mit niedrigerem VRAM verwenden, wenn Ihr Modell nicht passt. Dies kann den Zugriff auf Kapazitätspools einschränken und das Risiko von Unterbrechungen erhöhen. Beachten Sie, dass dies bei Inferenz mit einem einzelnen GPU und einem einzelnen Knoten (z. B. mehrere Pods, die auf demselben Knoten geplant sind, um dessen GPU-Ressourcen zu nutzen) die Diversifizierung einschränken kann, da Sie nur Instance-Typen mit ausreichend VRAM in Ihre Spot-Konfiguration aufnehmen können.
+  **Floating-point Präzision** und Leistung. Nicht alle Nvidia-GPU-Architekturen haben dieselbe Gleitkomma-Präzision (z. B. FP16/INT8). Bewerten Sie die Leistung und die Gleitkomma-Präzision der Kerntypen (CUDA/Tensor/RT), die für Ihre Workloads erforderlich sind. Der Betrieb auf einer kostengünstigeren, weniger leistungsfähigen GPU bedeutet nicht, dass sie besser ist. Daher sollten Sie die Leistung anhand der innerhalb eines bestimmten Zeitrahmens abgeschlossenen Arbeit bewerten, um die Auswirkungen der Diversifizierung zu verstehen.

 **Szenario: Diversifizierung für Inferenz-Workloads in Echtzeit** 

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

 **Beispiel** 

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

### Implementieren Sie Checkpointing für lang andauernde Trainingsjobs
<a name="_implement_checkpointing_for_long_running_training_jobs"></a>

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

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

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

 **Anwendungsfälle** 

Checkpointing ist in bestimmten Szenarien besonders nützlich, um ein Gleichgewicht zwischen Fehlertoleranz und Leistungsaufwand zu finden. Erwägen Sie die Verwendung von Checkpointing in den folgenden Fällen:
+  **Die Auftragsdauer überschreitet einige Stunden**: Für Trainingsjobs mit langer Laufzeit (z. B. > 1-2 Stunden für kleine Modelle oder days/weeks für große Basismodelle mit Milliarden von Parametern), bei denen der Verlust von Fortschritten aufgrund von Unterbrechungen kostspielig ist. Kürzere Aufträge rechtfertigen möglicherweise nicht den Mehraufwand. I/O 
+  **Für Spot-Instances oder Hardwarefehler**: In Umgebungen, die anfällig für Unterbrechungen sind, wie EC2 Spot (2 Minuten im Voraus) oder Hardwarefehler (z. B. GPU-Speicherfehler), ermöglicht Checkpointing eine schnelle Wiederaufnahme, sodass Spot für Kosteneinsparungen bei fehlertoleranten Workloads rentabel ist.
+  **Verteiltes Training im großen Maßstab**: Für Setups mit hundreds/thousands mehreren Beschleunigern (z. B. >100 GPUs), bei denen die mittlere Zeit zwischen Ausfällen linear mit der Skalierung abnimmt. Wird aus Gründen der model/data Parallelität verwendet, um den gleichzeitigen Zugriff auf Checkpoints zu handhaben und vollständige Neustarts zu vermeiden.
+  **Large-scale Modelle mit hohem Ressourcenbedarf**: Bei LLM-Schulungen im Petabyte-Bereich, bei denen Ausfälle aufgrund der Clustergröße unvermeidlich sind, optimieren mehrstufige Ansätze (schnell lokal alle 5—30 Minuten bei Transienten, dauerhaft stündlich bei größeren Ausfällen) die Wiederherstellungszeit im Verhältnis zur Effizienz.

### Verwenden Sie ML-Kapazitätsblöcke für die Kapazitätssicherung von P- und Trainium-Instances
<a name="_use_ml_capacity_blocks_for_capacity_assurance_of_p_and_trainium_instances"></a>

 Mit [Kapazitätsblöcken für ML](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-blocks.html) können Sie sehr gefragte GPU-Instances, insbesondere P-Instances (z. B. p6-b200, p5, p5e, p5en, p4d, p4de) und Trainium-Instances (z. B. trn1, trn2), reservieren, um entweder fast sofort oder zu einem future Zeitpunkt zu starten, um Ihre kurzfristigen Machine-Learning-Workloads (ML) zu unterstützen. Diese Reservierungen sind ideal, um die Kapazität für rechenintensive Aufgaben wie Modelltraining und Feinabstimmung sicherzustellen. 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 Capacity Blocks for ML](https://aws.amazon.com/ec2/capacityblocks/pricing/).

Um GPUs für AI/ML Workloads auf Amazon EKS für eine vorhersehbare Kapazitätssicherung zu reservieren, empfehlen wir, ML-Kapazitätsblöcke für kurzfristige Zwecke oder [Kapazitätsreservierungen (ODCRs) für die allgemeine On-Demand Kapazitätssicherung](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-reservations.html) zu nutzen.
+ Mit ODCRs können Sie EC2-Instance-Kapazität (z. B. GPU-Instances wie g5 oder p5) in einer bestimmten Availability Zone für einen bestimmten Zeitraum reservieren und so die Verfügbarkeit auch bei hoher Nachfrage sicherstellen. 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 ungenutzt ist. [In EKS werden ODCRs von Knotentypen wie [Karpenter](https://karpenter.sh/) 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 Feld so, dass es verwendet wird. NodeClass `capacityReservationSelectorTerms` [Weitere Informationen finden Sie in der Karpenter Dokumentation. NodePools ](https://karpenter.sh/docs/concepts/nodeclasses/#speccapacityreservationselectorterms)
+ Kapazitätsblöcke sind ein spezieller Reservierungsmechanismus für GPU- (z. B. p5, p4d) oder Trainium-Instances (trn1, trn2), der für kurzfristige ML-Workloads wie Modelltraining, Feinabstimmung oder Experimente konzipiert wurde. Sie reservieren Kapazität für einen bestimmten Zeitraum (in der Regel 24 Stunden bis 182 Tage), der an einem future Datum beginnt, und zahlen nur für die reservierte Zeit. Sie sind im Voraus bezahlt, erfordern eine vorausschauende Planung des Kapazitätsbedarfs und unterstützen keine automatische Skalierung. Sie befinden sich jedoch in EC2 für Netzwerke mit niedriger Latenz. UltraClusters Sie berechnen nur für den reservierten Zeitraum. Weitere Informationen [finden Sie unter Suchen und Kaufen von Kapazitätsblöcken](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/capacity-blocks-purchase.html) oder richten Sie zunächst verwaltete Knotengruppen mit Kapazitätsblöcken ein. Folgen Sie dabei den Anweisungen unter [Erstellen einer verwalteten Knotengruppe mit Kapazitätsblöcken für ML](https://docs.aws.amazon.com/eks/latest/userguide/capacity-blocks-mng.html).

Reservieren Sie Kapazität über die AWS-Managementkonsole und konfigurieren Sie Ihre Knoten für die Verwendung von ML-Kapazitätsblöcken. Planen Sie Reservierungen auf der Grundlage von Workload-Zeitplänen und testen Sie sie in einem Staging-Cluster. Weitere Informationen finden Sie in der [Dokumentation zu Kapazitätsblöcken](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-blocks.html).

### On-DemandErwägen Sie Amazon EC2 Spot oder On-Demand Capacity Reservations (ODCRs) für G Amazon EC2 EC2-Instances
<a name="_consider_on_demand_amazon_ec2_spot_or_on_demand_capacity_reservations_odcrs_for_g_amazon_ec2_instances"></a>

Für G Amazon EC2-Instances sollten Sie die verschiedenen Kaufoptionen von On-Demand Amazon EC2-Spot-Instances und On-Demand Kapazitätsreservierungen in Betracht ziehen. Mit [ODCRs](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-reservations.html) können Sie EC2-Instance-Kapazität in einer bestimmten Availability Zone für einen bestimmten Zeitraum reservieren und so die Verfügbarkeit auch bei hoher Nachfrage sicherstellen. 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, einschließlich G-Instances, verwendet werden. Dadurch eignen sie sich für Workloads, die unterschiedliche GPU-Fähigkeiten erfordern, wie Inferenz oder Grafik. Bei der Verwendung von Amazon EC2 Spot-Instances ist die Möglichkeit, zwischen verschiedenen Instance-Typen, Größen und Verfügbarkeitszonen zu variieren, entscheidend, um länger vor Ort bleiben zu können.

ODCRs haben keine langfristige Bindung, aber Sie zahlen den On-Demand Tarif für die reservierte Kapazität, unabhängig davon, ob sie genutzt oder ungenutzt genutzt ist. ODCRs können für den sofortigen Einsatz erstellt oder für einen future Zeitpunkt geplant werden, was Flexibilität bei der Kapazitätsplanung bietet. [In Amazon EKS werden ODCRs von Knotentypen wie [Karpenter](https://karpenter.sh/) 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 Feld so, dass es verwendet wird. NodeClass `capacityReservationSelectorTerms` [Weitere Informationen finden Sie in der Karpenter Dokumentation. NodePools ](https://karpenter.sh/docs/concepts/nodepools/) Weitere Informationen zum Erstellen von ODCRs, einschließlich CLI-Befehlen, finden Sie unter [On-Demand Capacity Reservation Getting Started](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-capacity-reservations-getting-started.html).

### Ziehen Sie andere beschleunigte Instance-Typen und -Größen in Betracht
<a name="_consider_other_accelerated_instance_types_and_sizes"></a>

Die Auswahl der geeigneten beschleunigten Instance und Größe ist entscheidend für die Optimierung von Leistung und Kosten Ihrer ML-Workloads auf Amazon EKS. Beispielsweise verfügen verschiedene GPU-Instance-Familien über unterschiedliche Leistungen und Funktionen wie GPU-Speicher. **Um Ihnen bei der Auswahl der Option mit dem besten Preis-Leistungs-Verhältnis zu helfen, sehen Sie sich die verfügbaren GPU-Instances auf der Seite [EC2-Instance-Typen](https://aws.amazon.com/ec2/instance-types/) unter Accelerated Computing an.** Bewerten 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-Instanztyps und der richtigen Größe können Sie eine bessere Ressourcennutzung und Kosteneffizienz in Ihren EKS-Clustern erreichen.

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

```
kubectl exec nvidia-device-plugin-daemonset-xxxxx \
  -n kube-system -- nvidia-smi \
  --query-gpu=index,power.draw,power.limit,temperature.gpu,utilization.gpu,utilization.memory,memory.free,memory.used \
  --format=csv -l 5
```
+ Wenn der `utilization.memory` Wert nahe bei 100% liegt, sind Ihr (e) Code (s) wahrscheinlich speichergebunden. Dies bedeutet, dass die GPU (Speicher) voll ausgelastet ist, könnte aber darauf hindeuten, dass weitere Leistungsoptimierungen untersucht werden sollten.
+ Wenn der nahe bei 100% `utilization.gpu` liegt, bedeutet dies nicht unbedingt, dass die GPU voll ausgelastet ist. Eine bessere Metrik, die man sich ansehen sollte, ist das Verhältnis von `power.draw` zu`power.limit`. Wenn dieses Verhältnis 100% oder mehr beträgt, nutzen Ihre Codes die Rechenkapazität der GPU vollständig aus.
+ Die `-l 5` Flagge besagt, dass die Metriken alle 5 Sekunden ausgegeben werden sollen. Im Fall eines einzelnen GPU-Instanztyps wird das Indexabfrageflag nicht benötigt.

Weitere Informationen finden Sie unter [GPU-Instances](https://docs.aws.amazon.com/dlami/latest/devguide/gpu.html) in der AWS-Dokumentation.

### Optimieren Sie die GPU-Ressourcenzuweisung mit Time-Slicing MIG und fraktionierter GPU-Zuweisung
<a name="_optimize_gpu_resource_allocation_with_time_slicing_mig_and_fractional_gpu_allocation"></a>

Statische Ressourcenbeschränkungen in Kubernetes (z. B. CPU-, Arbeitsspeicher- und GPU-Anzahl) können zu einer Überbereitstellung oder Unterauslastung führen, insbesondere bei dynamischen Workloads wie Inferenz. AI/ML Die Auswahl der richtigen GPU ist wichtig. Bei Workloads mit geringem Volumen oder hoher Auslastung ermöglicht Time-Slicing, dass sich mehrere Workloads eine einzelne GPU teilen, indem sie ihre Rechenressourcen gemeinsam nutzen, was potenziell die Effizienz verbessert und Verschwendung reduziert. Die gemeinsame Nutzung der GPU kann über verschiedene Optionen erreicht werden:
+  **Nutzen Sie die Knotenauswahl und die Knotenaffinität, um die Planung zu beeinflussen**: Stellen Sie sicher, dass die bereitgestellten Knoten und Pods auf den für die Arbeitslast geeigneten GPUs eingeplant werden (z. B. `karpenter.k8s.aws/instance-gpu-name: "a100"`
+  **Time-Slicing**: Plant Workloads so, dass sie die Rechenressourcen einer GPU im Laufe der Zeit gemeinsam nutzen, sodass eine gleichzeitige Ausführung ohne physische Partitionierung möglich ist. Dies ist ideal für Workloads mit variablem Rechenbedarf, aber möglicherweise mangelt es an Speicherisolierung.
+  **Multi-Instance GPU (MIG)**: MIG ermöglicht die Partitionierung einer einzelnen NVIDIA-GPU in mehrere isolierte Instanzen und wird von NVIDIA Ampere- (z. B. A100-GPU), NVIDIA Hopper (z. B. H100-GPU) und NVIDIA Blackwell-GPUs (z. B. Blackwell-GPUs) unterstützt. Jede MIG-Instanz erhält dedizierte Rechen- und Speicherressourcen und ermöglicht so die gemeinsame Nutzung von Ressourcen in Umgebungen mit mehreren Mandanten oder Workloads, für die Ressourcengarantien erforderlich sind. Dadurch können Sie die GPU-Ressourcennutzung optimieren, einschließlich Szenarien wie der Bereitstellung mehrerer Modelle mit unterschiedlichen Batchgrößen durch Timeslicing.
+  **Teilweise GPU-Zuweisung**: Nutzt softwarebasiertes Scheduling, um Teile der Rechenleistung oder des Speichers einer GPU Workloads zuzuweisen, was Flexibilität für dynamische Workloads bietet. Der [NVIDIA KAI Scheduler](https://github.com/NVIDIA/KAI-Scheduler), Teil der Run:ai Plattform, ermöglicht dies, indem er es Pods ermöglicht, fraktionierte GPU-Ressourcen anzufordern.

Um diese Funktionen in EKS zu aktivieren, können Sie das NVIDIA Device Plugin bereitstellen, das GPUs als planbare Ressourcen verfügbar macht und Time-Slicing und MIG unterstützt. Weitere Informationen finden Sie unter [Time-Slicing GPUs in Kubernetes und GPU-Sharing](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html) [auf Amazon EKS mit NVIDIA Timeslicing](https://aws.amazon.com/blogs/containers/gpu-sharing-on-amazon-eks-with-nvidia-time-slicing-and-accelerated-ec2-instances/) und beschleunigten EC2-Instances.

 **Beispiel** 

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

```
apiVersion: v1
kind: ConfigMap
metadata:
  name: nvidia-device-plugin-config
  namespace: kube-system
data:
  config.yaml: |
    version: v1
    sharing:
      timeSlicing:
        resources:
        - name: nvidia.com/gpu
          replicas: 4  # Allow 4 pods to share each GPU
```

 **Beispiel** 

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

```
apiVersion: v1
kind: Pod
metadata:
  name: fractional-gpu-pod-example
  annotations:
    gpu-fraction: "0.5"  # Annotation for 50% GPU
  labels:
    runai/queue: "default"  # Required queue assignment
spec:
  containers:
  - name: ml-workload
    image: nvcr.io/nvidia/pytorch:25.04-py3
    resources:
      limits:
        nvidia.com/gpu: 1
  nodeSelector:
    nvidia.com/gpu: "true"
  schedulerName: kai-scheduler
```

## Knotenausfallsicherheit und Verwaltung von Schulungsaufträgen
<a name="_node_resiliency_and_training_job_management"></a>

### Implementieren Sie Node Health Checks mit automatisierter Wiederherstellung
<a name="_implement_node_health_checks_with_automated_recovery"></a>

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

**Um die Widerstandsfähigkeit gegen Hardwarefehler zu erhöhen, wie z. B. GPU-Ausfälle in EKS-Clustern, auf denen GPU-Workloads ausgeführt werden, empfehlen wir, entweder den **EKS Node Monitoring Agent** mit Auto Repair oder Amazon zu nutzen. SageMaker HyperPod** Der EKS Node Monitoring Agent with Auto Repair bietet Funktionen wie die Überwachung des Knotenzustands und die automatische Reparatur mithilfe von Kubernetes-Standardmechanismen, SageMaker HyperPod bietet gezielte Resilienz und zusätzliche Funktionen, die speziell für groß angelegte ML-Trainings entwickelt wurden, wie z. B. eingehende Gesundheitschecks und automatische Wiederaufnahme von Jobs.
+ Der [EKS Node Monitoring Agent](https://docs.aws.amazon.com/eks/latest/userguide/node-health.html) mit Node Auto Repair überwacht kontinuierlich den Zustand der Knoten NodeConditions, liest Protokolle und wendet Standardbedingungen wie `Ready` und spezifische Bedingungen für beschleunigte Hardware an, um Probleme wie GPU- oder Netzwerkausfälle zu identifizieren. Wenn ein Knoten als fehlerhaft eingestuft wird, sperrt Node Auto Repair ihn ab und ersetzt ihn durch einen neuen Knoten. Die Neuplanung von Pods und der Neustart von Jobs basieren auf den Standardmechanismen von Kubernetes und der Neustartrichtlinie des Jobs.
+ Der Agent für [SageMaker HyperPod](https://catalog.workshops.aws/sagemaker-hyperpod-eks/en-US)eingehende Integritätsprüfungen und Zustandsüberwachung überwacht kontinuierlich den Integritätsstatus der GPU und der Instanzen. Trainium-based Er ist auf AI/ML Workloads zugeschnitten und verwendet Labels (z. B. Node-Health-Status) zur Verwaltung des Knotenzustands. Wenn ein Knoten als fehlerhaft eingestuft wird, wird der automatische Austausch der fehlerhaften HyperPod Hardware, wie z. B. GPUs, ausgelöst. Es erkennt standardmäßig netzwerkbedingte Ausfälle für EFA durch seine grundlegenden Integritätsprüfungen und unterstützt die automatische Wiederaufnahme unterbrochener Trainingsjobs, sodass Jobs ab dem letzten Checkpoint fortgesetzt werden können, wodurch Unterbrechungen bei umfangreichen ML-Aufgaben minimiert werden.

Stellen Sie sowohl für EKS Node Monitoring Agent mit Auto Repair als auch für SageMaker HyperPod Cluster, die EFA verwenden, zur Überwachung von EFA-specific Metriken wie RDMA-Fehlern (Remote Direct Memory Access) und Paketverlusten sicher, dass der [AWS EFA-Treiber installiert](https://docs.aws.amazon.com/eks/latest/userguide/node-efa.html) ist. Darüber hinaus empfehlen wir den Einsatz von [CloudWatch Observability Add-on](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-EKS-addon.html) oder die Verwendung von Tools wie DCGM Exporter mit Prometheus und Grafana, um EFA, GPU und damit spezifische Metriken im Zusammenhang mit seinen Funktionen zu überwachen. SageMaker HyperPod

### Deaktivieren Sie Karpenter Consolidation für unterbrechungssensitive Workloads
<a name="_disable_karpenter_consolidation_for_interruption_sensitive_workloads"></a>

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

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

```
disruption:
  consolidationPolicy: WhenEmpty
  consolidateAfter: 60m
```

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

### Verwenden Sie TTL, um Kubernetes-Jobs SecondsAfterFinished zu automatisieren Clean-Up
<a name="_use_ttlsecondsafterfinished_to_auto_clean_up_kubernetes_jobs"></a>

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

### Low-Priority Job Preemption konfigurieren für Higher-Priority Jobs/workloads
<a name="_configure_low_priority_job_preemption_for_higher_priority_jobsworkloads"></a>

Für AI/ML Workloads mit gemischter Priorität auf Amazon EKS können Sie das Preemption von Jobs mit niedriger Priorität konfigurieren, um sicherzustellen, dass Aufgaben mit höherer Priorität (z. B. Echtzeit-Inferenz) umgehend Ressourcen erhalten. Ohne Präemption können Workloads mit niedriger Priorität wie Batch-Prozesse (z. B. Batch-Inferenz, Datenverarbeitung), Nicht-Batch-Dienste (z. B. Hintergrundaufgaben, Cron-Jobs) oder Jobs (z. B. Webdienste) kritische Pods verzögern, indem sie Knoten belegen. CPU/memory-intensive Mit Preemption kann Kubernetes Pods mit niedriger Priorität entfernen, wenn Pods mit hoher Priorität Ressourcen benötigen, wodurch eine effiziente Ressourcenzuweisung auf Knoten mit GPUs, CPUs oder Arbeitsspeicher gewährleistet wird. Wir empfehlen die Verwendung von Kubernetes, um Prioritäten zuzuweisen und das Verhalten bei Räumungen 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 [Dokumentation zu Kubernetes Priority and Preemption](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/).

## Skalierung und Leistung von Anwendungen
<a name="_application_scaling_and_performance"></a>

### Passen Sie die Rechenkapazität für ML-Workloads mit Karpenter oder Static Nodes an
<a name="_tailor_compute_capacity_for_ml_workloads_with_karpenter_or_static_nodes"></a>

Um kosteneffiziente und reaktionsschnelle Rechenkapazitäten für maschinelles Lernen (ML) -Workflows auf Amazon EKS sicherzustellen, empfehlen wir, Ihre Node-Bereitstellungsstrategie an die Merkmale und Kostenverpflichtungen Ihres Workloads anzupassen. Im Folgenden sind zwei Ansätze aufgeführt, die Sie in Betracht ziehen sollten: Just-in-Time-Skalierung mit [Karpenter](https://karpenter.sh/docs/) und statische Knotengruppen für reservierte Kapazität.
+  **Just-in-time Datenebenen-Skalierer wie Karpenter**: Für dynamische ML-Workflows mit variablen Rechenanforderungen (z. B. GPU-based Inferenz gefolgt von CPU-based Plotten) empfehlen wir die Verwendung von Just-in-Time-Datenebenen-Skalierern wie Karpenter.
+  **Verwenden Sie statische Knotengruppen für vorhersehbare Workloads: Bei vorhersehbaren, stetigen ML-Workloads** oder bei der Verwendung von Reserved Instances können [verwaltete EKS-Knotengruppen](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) dazu beitragen, dass die reservierte Kapazität vollständig bereitgestellt und genutzt wird, wodurch die Einsparungen maximiert werden. Dieser Ansatz ist ideal für bestimmte Instance-Typen, die über RIs oder ODCRs festgeschrieben werden.

 **Beispiel** 

Dies ist ein Beispiel für einen vielseitigen Karpenter [NodePool](https://karpenter.sh/docs/concepts/nodepools/), der das Starten von `g` Amazon EC2 EC2-Instances ermöglicht, bei denen die Instance-Generierung mehr als drei beträgt.

```
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: gpu-inference
spec:
  template:
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand"]
        - key: karpenter.k8s.aws/instance-category
          operator: In
          values: ["g"]
        - key: karpenter.k8s.aws/instance-generation
          operator: Gt
          values: ["3"]
        - key: kubernetes.io/arch
          operator: In
          values: ["amd64"]
      taints:
        - key: nvidia.com/gpu
          effect: NoSchedule
  limits:
    cpu: "1000"
    memory: "4000Gi"
    nvidia.com/gpu: "10"  *# Limit the total number of GPUs to 10 for the NodePool*
  disruption:
    consolidationPolicy: WhenEmpty
    consolidateAfter: 60m
    expireAfter: 720h
```

 **Beispiel** 

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

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: ml-cluster
  region: us-west-2
managedNodeGroups:
  - name: gpu-node-group
    instanceType: p4d.24xlarge
    minSize: 2
    maxSize: 2
    desiredCapacity: 2
    taints:
      - key: nvidia.com/gpu
        effect: NoSchedule
```

### Verwenden Sie Taints und Toleranzen, um zu verhindern, dass nicht beschleunigte Workloads auf beschleunigten Instances geplant werden
<a name="_use_taints_and_tolerations_to_prevent_non_accelerated_workloads_from_being_scheduled_on_accelerated_instances"></a>

Die Planung nicht beschleunigter Workloads auf GPU-Ressourcen ist nicht recheneffizient. Wir empfehlen, Taints und Toleration zu verwenden, um sicherzustellen, dass Pods für nicht beschleunigte Workloads nicht auf ungeeigneten Knoten geplant werden. [Weitere Informationen finden Sie in der Kubernetes-Dokumentation.](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)

### Skalieren Sie basierend auf der Modellleistung
<a name="_scale_based_on_model_performance"></a>

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

## Dynamische Ressourcenzuweisung für erweitertes GPU-Management
<a name="aiml-dra"></a>

 Die [dynamische Ressourcenzuweisung (DRA)](https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/#enabling-dynamic-resource-allocation) stellt einen grundlegenden Fortschritt im Kubernetes-GPU-Ressourcenmanagement dar. DRA geht über die Beschränkungen herkömmlicher Geräte-Plug-ins hinaus und ermöglicht ausgeklügelte GPU-Sharing, Topologieerkennung und knotenübergreifende Ressourcenkoordination. DRA ist in Amazon EKS [Version 1.33](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions-standard.html#kubernetes-1-33) verfügbar und adressiert kritische Herausforderungen bei AI/ML Workloads, indem es Folgendes bietet:
+ Fine-grained GPU-Zuweisung
+ Erweiterte Sharing-Mechanismen wie Multi-Process Service (MPS) und Multi-Instance GPU (MIG)
+ Support 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, selbst wenn sie nur einen Bruchteil der Ressourcen benötigen. DRA transformiert dieses Modell, indem es eine strukturierte, deklarative Zuweisung einführt, die dem Kubernetes-Scheduler einen vollständigen Überblick über Hardwaremerkmale und Workload-Anforderungen bietet. Dies ermöglicht intelligente Platzierungsentscheidungen und eine effiziente gemeinsame Nutzung von Ressourcen.

### Vorteile der Verwendung von DRA anstelle des NVIDIA-Geräte-Plugins
<a name="_advantages_of_using_dra_instead_of_nvidia_device_plugin"></a>

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

 **Einschränkungen des NVIDIA-Geräte-Plug-ins** 
+  **Statische Konfiguration:** Konfigurationen zur gemeinsamen Nutzung von GPUs (Time-Slicing-Replikate und MPS-Einstellungen) erfordern eine clusterweite Vorkonfiguration. `ConfigMaps` Dies macht es schwierig, unterschiedliche Sharing-Strategien für unterschiedliche Workloads bereitzustellen.
+  **Eingeschränkte detaillierte Auswahl:** Das Geräte-Plug-In macht zwar GPU-Merkmale anhand von Knotenbezeichnungen verfügbar, Workloads können jedoch nicht dynamisch bestimmte GPU-Konfigurationen (Speichergröße und Rechenkapazität) als Teil der Planungsentscheidung anfordern.
+  **Keine knotenübergreifende Ressourcenkoordination:** Es ist nicht möglich, verteilte GPU-Ressourcen über mehrere Knoten zu verwalten oder komplexe Topologieanforderungen wie NVLink-Domänen für Systeme wie NVIDIA 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 handhaben.
+  **Komplexität der Konfiguration: Die** Einrichtung verschiedener Strategien zur gemeinsamen Nutzung erfordert mehrere `ConfigMaps` und sorgfältige Knotenkennzeichnungen, was zu betrieblicher Komplexität führt.

 **Lösungen mit DRA** 
+  **Dynamische Ressourcenauswahl:** Mit DRA können Workloads detaillierte Anforderungen (GPU-Speicher, Treiberversionen und spezifische Attribute) zum Zeitpunkt der Anfrage angeben. `resourceclaims` Dies ermöglicht einen flexibleren Ressourcenabgleich.
+  **Topologiebewusstsein:** Durch strukturierte Parameter und Geräteauswahlen bewältigt DRA komplexe Anforderungen wie knotenübergreifende GPU-Kommunikation und speicherkohärente Verbindungen.
+  **Cross-node Ressourcenmanagement:** `computeDomains` ermöglicht die Koordination verteilter GPU-Ressourcen auf mehrere Knoten, 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, sodass eine feinkörnige Steuerung pro Workload anstelle von clusterweiten Einstellungen möglich ist.
+  **Verbesserte Scheduler-Integration:** DRA stellt dem Scheduler detaillierte Geräteinformationen zur Verfügung und ermöglicht intelligentere Platzierungsentscheidungen auf der Grundlage der Hardwaretopologie und der Ressourceneigenschaften.

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

### Von DRA unterstützte Instanzen und ihre Funktionen
<a name="_instances_supported_by_dra_and_their_features"></a>

Die DRA-Unterstützung variiert je nach Amazon EC2 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 | Modelltraining für die Stiftung | 
| 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 einzigen GPU.
+  **Internode Memory Exchange (IMEX)**: Memory-coherent Kommunikation zwischen Knoten für GB200. UltraServers

### Weitere Ressourcen
<a name="_additional_resources"></a>

Weitere Informationen zu Kubernetes DRA- und NVIDIA DRA-Treibern finden Sie in den folgenden Ressourcen unter: GitHub
+ [Dynamische Ressourcenzuweisung in Kubernetes](https://github.com/kubernetes/dynamic-resource-allocation) 
+  [Vorschlag zur Erweiterung von Kubernetes für DRA](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3063-dynamic-resource-allocation) 
+  [NVIDIA DRA-Treiber für GPUs](https://github.com/NVIDIA/k8s-dra-driver-gpu) 
+  [NVIDIA DRA-Beispiele und Schnellstart](https://github.com/NVIDIA/k8s-dra-driver-gpu/tree/main/demo/specs/quickstart) 

### Richten Sie eine dynamische Ressourcenzuweisung für erweitertes GPU-Management ein
<a name="aiml-dra-setup"></a>

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

#### Voraussetzungen
<a name="aiml-dra-prereqs"></a>

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

##### Cluster-Konfiguration
<a name="aiml-dra-configuration"></a>
+ Amazon EKS-Cluster mit laufender 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)](https://github.com/kubernetes-sigs/karpenter/issues/1231)
+ NVIDIA-Worker-Knoten GPU-enabled mit entsprechenden Instance-Typen

##### Erforderliche Komponenten
<a name="aiml-dra-components"></a>
+ NVIDIA-Geräte-Plug-in-Version `0.17.1` oder höher
+ NVIDIA DRA-Treiberversion `25.3.0` oder höher

#### Schritt 1: Erstellen Sie mithilfe von eksctl einen Cluster mit einer DRA-enabled Knotengruppe
<a name="aiml-dra-create-cluster"></a>

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

1. Erstellen Sie den Cluster:

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

#### Schritt 2: Stellen Sie das NVIDIA-Geräte-Plugin bereit
<a name="aiml-dra-nvidia-plugin"></a>

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

1. 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
   ```

1. 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 das Helm-Diagramm für den NVIDIA-DRA-Treiber bereit
<a name="aiml-dra-helm-chart"></a>

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

1. Fügen Sie das NVIDIA NGC-Helm-Repository hinzu:

   ```
   helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
   helm repo update
   ```

1. 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
<a name="aiml-dra-verify"></a>

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

1. Überprüfen Sie die verfügbaren Geräteklassen:

   ```
   kubectl get deviceclasses
   ```

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

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

   Wenn eine neu erstellte G6-GPU-Instance Ihrem Amazon EKS-Cluster mit aktiviertem DRA beitritt, werden die folgenden Aktionen ausgeführt:
   + Der NVIDIA DRA-Treiber erkennt automatisch die A10G-GPU und erstellt zwei `resourceslices` auf diesem Knoten.
   + Der `gpu.nvidia.com` Slice registriert das physische A10G-GPU-Gerät mit seinen Spezifikationen (Speicher, Rechenkapazität und mehr).
   + Da A10G die MIG-Partitionierung nicht unterstützt, erstellt der `compute-domain.nvidia.com` Slice eine einzelne Rechendomäne, die den gesamten Rechenkontext der GPU darstellt.
   + Diese `resourceslices` werden dann auf dem Kubernetes-API-Server veröffentlicht, sodass die GPU-Ressourcen für die Planung zur Verfügung stehen. `resourceclaims`

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

     Wenn Sie den folgenden Befehl ausführen:

     ```
     kubectl get resourceslices
     ```

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

     ```
     NAME                                                          NODE                             DRIVER                       POOL                             AGE
     ip-100-64-129-47.ec2.internal-compute-domain.nvidia.com-rwsts ip-100-64-129-47.ec2.internal    compute-domain.nvidia.com    ip-100-64-129-47.ec2.internal    35m
     ip-100-64-129-47.ec2.internal-gpu.nvidia.com-6kndg            ip-100-64-129-47.ec2.internal    gpu.nvidia.com               ip-100-64-129-47.ec2.internal    35m
     ```

Fahren Sie fort mit [Planen Sie einen einfachen GPU-Workload mithilfe der dynamischen Ressourcenzuweisung](#aiml-dra-workload).

### Planen Sie einen einfachen GPU-Workload mithilfe der dynamischen Ressourcenzuweisung
<a name="aiml-dra-workload"></a>

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

1. Erstellen Sie eine Grundlage `ResourceClaimTemplate` für die GPU-Zuweisung mit einer Datei mit dem Namen`basic-gpu-claim-template.yaml`:

   ```
   ---
   apiVersion: v1
   kind: Namespace
   metadata:
     name: gpu-test1
   
   ---
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     namespace: gpu-test1
     name: single-gpu
   spec:
     spec:
       devices:
         requests:
         - name: gpu
           deviceClassName: gpu.nvidia.com
   ```

1. Wenden Sie die Vorlage an:

   ```
   kubectl apply -f basic-gpu-claim-template.yaml
   ```

1. Überprüfen Sie den Status:

   ```
   kubectl get resourceclaimtemplates -n gpu-test1
   ```

   Das Folgende ist eine Beispielausgabe:

   ```
   NAME         AGE
   single-gpu   9m16s
   ```

1. Erstellen Sie einen Pod, der den verwendet, `ResourceClaimTemplate` mit einer Datei namens`basic-gpu-pod.yaml`:

   ```
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     namespace: gpu-test1
     name: gpu-pod
     labels:
       app: pod
   spec:
     containers:
     - name: ctr0
       image: ubuntu:22.04
       command: ["bash", "-c"]
       args: ["nvidia-smi -L; trap 'exit 0' TERM; sleep 9999 & wait"]
       resources:
         claims:
         - name: gpu0
     resourceClaims:
     - name: gpu0
       resourceClaimTemplateName: single-gpu
     nodeSelector:
       NodeGroupType: gpu-dra
       nvidia.com/gpu.present: "true"
     tolerations:
     - key: "nvidia.com/gpu"
       operator: "Exists"
       effect: "NoSchedule"
   ```

1. Wenden Sie den Pod an und überwachen Sie ihn:

   ```
   kubectl apply -f basic-gpu-pod.yaml
   ```

1. Überprüfen Sie den Pod-Status:

   ```
   kubectl get pod -n gpu-test1
   ```

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

   ```
   NAME      READY   STATUS    RESTARTS   AGE
   gpu-pod   1/1     Running   0          13m
   ```

1. Überprüfen Sie den `ResourceClaim` Status:

   ```
   kubectl get resourceclaims -n gpu-test1
   ```

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

   ```
   NAME                 STATE                AGE
   gpu-pod-gpu0-l76cg   allocated,reserved   9m6s
   ```

1. Sehen Sie sich die Pod-Logs an, um GPU-Informationen zu sehen:

   ```
   kubectl logs gpu-pod -n gpu-test1
   ```

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

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

Weitere fortgeschrittene Techniken [Techniken zur GPU-Optimierung mit dynamischer Ressourcenzuweisung](#aiml-dra-optimization) zur GPU-Optimierung mithilfe von DRA finden Sie weiter.

### Techniken zur GPU-Optimierung mit dynamischer Ressourcenzuweisung
<a name="aiml-dra-optimization"></a>

Moderne GPU-Workloads erfordern ein ausgeklügeltes Ressourcenmanagement, um eine optimale Nutzung und Kosteneffizienz zu erreichen. DRA ermöglicht mehrere fortschrittliche Optimierungstechniken, die auf unterschiedliche Anwendungsfälle und Hardwarefunktionen zugeschnitten sind:
+  **Time-slicing**ermöglicht es mehreren Workloads, GPU-Rechenressourcen im Laufe der Zeit gemeinsam zu nutzen, was es ideal für Inferenz-Workloads mit sporadischer GPU-Nutzung macht. Ein Beispiel finden Sie unter [Optimieren Sie GPU-Workloads mit Time-Slicing](#aiml-dra-timeslicing).
+  **Multi-Process Service (MPS)** ermöglicht die gleichzeitige Ausführung mehrerer CUDA-Prozesse auf einer einzigen GPU und bietet dabei eine bessere Isolierung als Time-Slicing. Ein Beispiel finden Sie unter [Optimieren Sie GPU-Workloads mit MPS](#aiml-dra-mps).
+  **Multi-Instance GPU (MIG)** ermöglicht Partitionierung auf Hardwareebene und erstellt isolierte GPU-Instanzen mit dedizierten Rechen- und Speicherressourcen. Ein Beispiel finden Sie unter [Optimieren Sie GPU-Workloads mit GPU Multi-Instance](#aiml-dra-mig).
+  **Internode Memory Exchange (IMEX)** ermöglicht eine speicherkohärente Kommunikation zwischen Knoten für verteiltes Training auf NVIDIA GB200-Systemen. Ein Beispiel finden Sie unter [Optimieren Sie GPU-Workloads mit IMEX mithilfe von GB200 P6e-Instances](#aiml-dra-imex).

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

#### Optimieren Sie GPU-Workloads mit Time-Slicing
<a name="aiml-dra-timeslicing"></a>

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

Führen Sie die folgenden Schritte aus.

1. Definieren Sie a `ResourceClaimTemplate` für Timeslicing mit einer Datei mit dem Namen: `timeslicing-claim-template.yaml`

   ```
   ---
   apiVersion: v1
   kind: Namespace
   metadata:
     name: timeslicing-gpu
   
   ---
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     name: timeslicing-gpu-template
     namespace: timeslicing-gpu
   spec:
     spec:
       devices:
         requests:
         - name: shared-gpu
           deviceClassName: gpu.nvidia.com
         config:
         - requests: ["shared-gpu"]
           opaque:
             driver: gpu.nvidia.com
             parameters:
               apiVersion: resource.nvidia.com/v1beta1
               kind: GpuConfig
               sharing:
                 strategy: TimeSlicing
   ```

1. 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
   ```

1. Wenden Sie die Vorlage und den Pod an:

   ```
   kubectl apply -f timeslicing-claim-template.yaml
   kubectl apply -f timeslicing-pod.yaml
   ```

1. Ressourcenansprüche überwachen:

   ```
   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**: Startet sofort

Zweiter Pod (`training-pod-2`)
+  **Bundesland**: `pending` 
+  **Das heißt**: Ich warte darauf, dass DRA Time-Slicing auf derselben GPU konfiguriert
+  **Pod-Status**: Wartet darauf, geplant zu werden
+ Der Status wird von bis `pending` `allocated,reserved` zu wechseln `running` 

#### Optimieren Sie GPU-Workloads mit MPS
<a name="aiml-dra-mps"></a>

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

Führen Sie die folgenden Schritte aus.

1. Definieren Sie a `ResourceClaimTemplate` für MPS mit einer Datei namens`mps-claim-template.yaml`:

   ```
   ---
   apiVersion: v1
   kind: Namespace
   metadata:
     name: mps-gpu
   
   ---
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     name: mps-gpu-template
     namespace: mps-gpu
   spec:
     spec:
       devices:
         requests:
         - name: shared-gpu
           deviceClassName: gpu.nvidia.com
         config:
         - requests: ["shared-gpu"]
           opaque:
             driver: gpu.nvidia.com
             parameters:
               apiVersion: resource.nvidia.com/v1beta1
               kind: GpuConfig
               sharing:
                 strategy: MPS
   ```

1. Definieren Sie einen Pod mithilfe von MPS mit einer Datei namens`mps-pod.yaml`:

   ```
   ---
   # Single Pod with Multiple Containers sharing GPU via MPS
   apiVersion: v1
   kind: Pod
   metadata:
     name: mps-multi-container-pod
     namespace: mps-gpu
     labels:
       app: mps-demo
   spec:
     restartPolicy: Never
     containers:
     # Container 1 - Inference workload
     - name: inference-container
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["python", "-c"]
       args:
       - |
         import torch
         import torch.nn as nn
         import time
         import os
   
         print(f"=== INFERENCE CONTAINER STARTING ===")
         print(f"Process ID: {os.getpid()}")
         print(f"GPU available: {torch.cuda.is_available()}")
         print(f"GPU count: {torch.cuda.device_count()}")
   
         if torch.cuda.is_available():
             device = torch.cuda.current_device()
             print(f"Current GPU: {torch.cuda.get_device_name(device)}")
             print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB")
   
             # Create inference model
             model = nn.Sequential(
                 nn.Linear(1000, 500),
                 nn.ReLU(),
                 nn.Linear(500, 100)
             ).cuda()
   
             # Run inference
             for i in range(1, 999999):
                 with torch.no_grad():
                     x = torch.randn(128, 1000).cuda()
                     output = model(x)
                     result = torch.sum(output)
                     print(f"Inference Container PID {os.getpid()}: Batch {i}, Result: {result.item():.2f} at {time.strftime('%H:%M:%S')}")
                 time.sleep(2)
         else:
             print("No GPU available!")
             time.sleep(60)
       resources:
         claims:
         - name: shared-gpu-claim
           request: shared-gpu
   
     # Container 2 - Training workload
     - name: training-container
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["python", "-c"]
       args:
       - |
         import torch
         import torch.nn as nn
         import time
         import os
   
         print(f"=== TRAINING CONTAINER STARTING ===")
         print(f"Process ID: {os.getpid()}")
         print(f"GPU available: {torch.cuda.is_available()}")
         print(f"GPU count: {torch.cuda.device_count()}")
   
         if torch.cuda.is_available():
             device = torch.cuda.current_device()
             print(f"Current GPU: {torch.cuda.get_device_name(device)}")
             print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1024**3:.1f} GB")
   
             # Create training model
             model = nn.Sequential(
                 nn.Linear(2000, 1000),
                 nn.ReLU(),
                 nn.Linear(1000, 500),
                 nn.ReLU(),
                 nn.Linear(500, 10)
             ).cuda()
   
             criterion = nn.MSELoss()
             optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
   
             # Run training
             for epoch in range(1, 999999):
                 x = torch.randn(64, 2000).cuda()
                 target = torch.randn(64, 10).cuda()
   
                 optimizer.zero_grad()
                 output = model(x)
                 loss = criterion(output, target)
                 loss.backward()
                 optimizer.step()
   
                 print(f"Training Container PID {os.getpid()}: Epoch {epoch}, Loss: {loss.item():.4f} at {time.strftime('%H:%M:%S')}")
                 time.sleep(3)
         else:
             print("No GPU available!")
             time.sleep(60)
       resources:
         claims:
         - name: shared-gpu-claim
           request: shared-gpu
   
     resourceClaims:
     - name: shared-gpu-claim
       resourceClaimTemplateName: mps-gpu-template
   
     nodeSelector:
       NodeGroupType: "gpu-dra"
       nvidia.com/gpu.present: "true"
     tolerations:
     - key: nvidia.com/gpu
       operator: Exists
       effect: NoSchedule
   ```

1. Wenden Sie die Vorlage an und erstellen Sie mehrere MPS-Pods:

   ```
   kubectl apply -f mps-claim-template.yaml
   kubectl apply -f mps-pod.yaml
   ```

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

Jeder Container erhält seinen eigenen isolierten GPU-Speicherplatz und eigene Rechenressourcen, wobei der MPS-Daemon den Zugriff auf die zugrunde liegende Hardware koordiniert. Sie können überprüfen, ob dies funktioniert, indem Sie wie folgt vorgehen:
+ Überprüfung`nvidia-smi`, wodurch beide Container als M\+C (`MPS + Compute`) -Prozesse angezeigt werden, die sich dasselbe GPU-Gerät teilen.
+ Überwachung der Logs aus beiden Containern, wobei verschachtelte Zeitstempel angezeigt werden, die die gleichzeitige Ausführung belegen.

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

##### Behälter 1: `inference-container`
<a name="_container1_inference_container"></a>

```
root@mps-multi-container-pod:/workspace# nvidia-smi
Wed Jul 16 21:09:30 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.158.01             Driver Version: 570.158.01     CUDA Version: 12.9     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA L4                      On  |   00000000:35:00.0 Off |                    0 |
| N/A   48C    P0             28W /   72W |     597MiB /  23034MiB |      0%   E. Process |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A               1    M+C   python                                  246MiB |
+-----------------------------------------------------------------------------------------+
```

##### Behälter 2: `training-container`
<a name="_container2_training_container"></a>

```
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
<a name="aiml-dra-mig"></a>

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

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

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

##### Schritt 1: Stellen Sie den NVIDIA GPU Operator bereit
<a name="_step_1_deploy_nvidia_gpu_operator"></a>

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

   ```
   helm repo add nvidia https://nvidia.github.io/gpu-operator
   helm repo update
   ```

1. 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
   ```

1. Installieren Sie GPU Operator mithilfe der `gpu-operator-values.yaml` folgenden Datei:

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

   Dieses Helm-Diagramm stellt die folgenden Komponenten und mehrere MIG-Profile bereit:
   + Geräte-Plugin (GPU-Ressourcenplanung)
   + DCGM Exporter (GPU-Metriken und Überwachung)
   + Erkennung von Knotenmerkmalen (NFD — Hardwarekennzeichnung)
   + Erkennung von GPU-Features (GFD — GPU-specific Kennzeichnung)
   + MIG Manager (Multi-instance GPU-Partitionierung)
   + Container-Toolkit (GPU-Container-Laufzeit)
   + Operator Controller (Lebenszyklusmanagement)

1. Ü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
   ```

1. 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.

1. Melden Sie sich bei der `p4de` Instanz an.

1. Führen Sie den folgenden Befehl aus:

   ```
   nvidia-smi -L
   ```

   Sie sollten die folgende Beispielausgabe sehen:

   ```
   [root@ip-100-64-173-145 bin]# nvidia-smi -L
   GPU 0: NVIDIA A100-SXM4-80GB (UUID: GPU-ab52e33c-be48-38f2-119e-b62b9935925a)
     MIG 3g.40gb     Device  0: (UUID: MIG-da972af8-a20a-5f51-849f-bc0439f7970e)
     MIG 2g.20gb     Device  1: (UUID: MIG-7f9768b7-11a6-5de9-a8aa-e9c424400da4)
     MIG 1g.10gb     Device  2: (UUID: MIG-498adad6-6cf7-53af-9d1a-10cfd1fa53b2)
     MIG 1g.10gb     Device  3: (UUID: MIG-3f55ef65-1991-571a-ac50-0dbf50d80c5a)
   GPU 1: NVIDIA A100-SXM4-80GB (UUID: GPU-0eabeccc-7498-c282-0ac7-d3c09f6af0c8)
     MIG 3g.40gb     Device  0: (UUID: MIG-80543849-ea3b-595b-b162-847568fe6e0e)
     MIG 2g.20gb     Device  1: (UUID: MIG-3af1958f-fac4-59f1-8477-9f8d08c55029)
     MIG 1g.10gb     Device  2: (UUID: MIG-401088d2-716f-527b-a970-b1fc7a4ac6b2)
     MIG 1g.10gb     Device  3: (UUID: MIG-8c56c75e-5141-501c-8f43-8cf22f422569)
   GPU 2: NVIDIA A100-SXM4-80GB (UUID: GPU-1c7a1289-243f-7872-a35c-1d2d8af22dd0)
     MIG 3g.40gb     Device  0: (UUID: MIG-e9b44486-09fc-591a-b904-0d378caf2276)
     MIG 2g.20gb     Device  1: (UUID: MIG-ded93941-9f64-56a3-a9b1-a129c6edf6e4)
     MIG 1g.10gb     Device  2: (UUID: MIG-6c317d83-a078-5c25-9fa3-c8308b379aa1)
     MIG 1g.10gb     Device  3: (UUID: MIG-2b070d39-d4e9-5b11-bda6-e903372e3d08)
   GPU 3: NVIDIA A100-SXM4-80GB (UUID: GPU-9a6250e2-5c59-10b7-2da8-b61d8a937233)
     MIG 3g.40gb     Device  0: (UUID: MIG-20e3cd87-7a57-5f1b-82e7-97b14ab1a5aa)
     MIG 2g.20gb     Device  1: (UUID: MIG-04430354-1575-5b42-95f4-bda6901f1ace)
     MIG 1g.10gb     Device  2: (UUID: MIG-d62ec8b6-e097-5e99-a60c-abf8eb906f91)
     MIG 1g.10gb     Device  3: (UUID: MIG-fce20069-2baa-5dd4-988a-cead08348ada)
   GPU 4: NVIDIA A100-SXM4-80GB (UUID: GPU-5d09daf0-c2eb-75fd-3919-7ad8fafa5f86)
   GPU 5: NVIDIA A100-SXM4-80GB (UUID: GPU-99194e04-ab2a-b519-4793-81cb2e8e9179)
   GPU 6: NVIDIA A100-SXM4-80GB (UUID: GPU-c1a1910f-465a-e16f-5af1-c6aafe499cd6)
   GPU 7: NVIDIA A100-SXM4-80GB (UUID: GPU-c2cfafbc-fd6e-2679-e955-2a9e09377f78)
   ```

NVIDIA GPU Operator hat das `p4de-half-balanced` MIG-Profil erfolgreich auf Ihre P4DE-Instanz angewendet und dabei wie konfiguriert GPU-Partitionen auf Hardwareebene erstellt. So funktioniert die Partitionierung:

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

```
p4de-half-balanced:
  - devices: [0, 1, 2, 3]        # First 4 GPUs: MIG enabled
    mig-enabled: true
    mig-devices:
      "1g.10gb": 2               # 2x small instances (10GB each)
      "2g.20gb": 1               # 1x medium instance (20GB)
      "3g.40gb": 1               # 1x large instance (40GB)
  - devices: [4, 5, 6, 7]        # Last 4 GPUs: Full GPUs
    mig-enabled: false
```

Aus Ihrer `nvidia-smi -L` Ausgabe hat der GPU-Operator Folgendes erstellt:
+ MIG-enabled GPUs (0-3): Hardware partitioniert
  + GPU 0: NVIDIA A100-SXM4-80GB
    + MIG 3G.40 GB Gerät 0 — Große Arbeitslasten (40 GB Speicher, 42 SMs)
    + MIG 2G.20 GB Gerät 1 — Mittlere Arbeitslasten (20 GB Speicher, 28 SMs)
    + MIG 1g.10gb Gerät 2 — Kleine Workloads (10 GB Speicher, 14 SMs)
    + MIG 1G.10GB Gerät 3 — Kleine Workloads (10 GB Speicher, 14 SMs)
  + GPU 1: NVIDIA A100-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 — Gleiches 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.10 GB, 2G.20 GB, 3G.40 GB) und stellt sie über die Geräteklasse als planbare Ressourcen zur Verfügung. `mig.nvidia.com`

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

##### Schritt 2: Testen Sie die MIG-Ressourcenzuweisung
<a name="_step_2_test_mig_resource_allocation"></a>

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

1. Erstellen, um `mig-claim-template.yaml` die MIG einzuschließen: `resourceclaimtemplates`

   ```
   apiVersion: v1
   kind: Namespace
   metadata:
     name: mig-gpu
   
   ---
   # Template for 3g.40gb MIG instance (Large training)
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     name: mig-large-template
     namespace: mig-gpu
   spec:
     spec:
       devices:
         requests:
         - name: mig-large
           deviceClassName: mig.nvidia.com
           selectors:
           - cel:
               expression: |
                 device.attributes['gpu.nvidia.com'].profile == '3g.40gb'
   
   ---
   # Template for 2g.20gb MIG instance (Medium training)
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     name: mig-medium-template
     namespace: mig-gpu
   spec:
     spec:
       devices:
         requests:
         - name: mig-medium
           deviceClassName: mig.nvidia.com
           selectors:
           - cel:
               expression: |
                 device.attributes['gpu.nvidia.com'].profile == '2g.20gb'
   
   ---
   # Template for 1g.10gb MIG instance (Small inference)
   apiVersion: resource.k8s.io/v1beta1
   kind: ResourceClaimTemplate
   metadata:
     name: mig-small-template
     namespace: mig-gpu
   spec:
     spec:
       devices:
         requests:
         - name: mig-small
           deviceClassName: mig.nvidia.com
           selectors:
           - cel:
               expression: |
                 device.attributes['gpu.nvidia.com'].profile == '1g.10gb'
   ```

1. Wenden Sie die drei Vorlagen an:

   ```
   kubectl apply -f mig-claim-template.yaml
   ```

1. 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
   ```

1. Erstellen Sie`mig-pod.yaml`, um mehrere Jobs zu planen und diese Vorteile zu nutzen`resourceclaimtemplates`:

   ```
   ---
   # ConfigMap containing Python scripts for MIG pods
   apiVersion: v1
   kind: ConfigMap
   metadata:
     name: mig-scripts-configmap
     namespace: mig-gpu
   data:
     large-training-script.py: |
       import torch
       import torch.nn as nn
       import torch.optim as optim
       import time
       import os
   
       print(f"=== LARGE TRAINING POD (3g.40gb) ===")
       print(f"Process ID: {os.getpid()}")
       print(f"GPU available: {torch.cuda.is_available()}")
       print(f"GPU count: {torch.cuda.device_count()}")
   
       if torch.cuda.is_available():
           device = torch.cuda.current_device()
           print(f"Using GPU: {torch.cuda.get_device_name(device)}")
           print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB")
   
           # Large model for 3g.40gb instance
           model = nn.Sequential(
               nn.Linear(2048, 1024),
               nn.ReLU(),
               nn.Linear(1024, 512),
               nn.ReLU(),
               nn.Linear(512, 256),
               nn.ReLU(),
               nn.Linear(256, 10)
           ).cuda()
   
           optimizer = optim.Adam(model.parameters())
           criterion = nn.CrossEntropyLoss()
   
           print(f"Model parameters: {sum(p.numel() for p in model.parameters())}")
   
           # Training loop
           for epoch in range(100):
               # Large batch for 3g.40gb
               x = torch.randn(256, 2048).cuda()
               y = torch.randint(0, 10, (256,)).cuda()
   
               optimizer.zero_grad()
               output = model(x)
               loss = criterion(output, y)
               loss.backward()
               optimizer.step()
   
               if epoch % 10 == 0:
                   print(f"Large Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB")
               time.sleep(3)
   
           print("Large training completed on 3g.40gb MIG instance")
   
     medium-training-script.py: |
       import torch
       import torch.nn as nn
       import torch.optim as optim
       import time
       import os
   
       print(f"=== MEDIUM TRAINING POD (2g.20gb) ===")
       print(f"Process ID: {os.getpid()}")
       print(f"GPU available: {torch.cuda.is_available()}")
       print(f"GPU count: {torch.cuda.device_count()}")
   
       if torch.cuda.is_available():
           device = torch.cuda.current_device()
           print(f"Using GPU: {torch.cuda.get_device_name(device)}")
           print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB")
   
           # Medium model for 2g.20gb instance
           model = nn.Sequential(
               nn.Linear(1024, 512),
               nn.ReLU(),
               nn.Linear(512, 256),
               nn.ReLU(),
               nn.Linear(256, 10)
           ).cuda()
   
           optimizer = optim.Adam(model.parameters())
           criterion = nn.CrossEntropyLoss()
   
           print(f"Model parameters: {sum(p.numel() for p in model.parameters())}")
   
           # Training loop
           for epoch in range(100):
               # Medium batch for 2g.20gb
               x = torch.randn(128, 1024).cuda()
               y = torch.randint(0, 10, (128,)).cuda()
   
               optimizer.zero_grad()
               output = model(x)
               loss = criterion(output, y)
               loss.backward()
               optimizer.step()
   
               if epoch % 10 == 0:
                   print(f"Medium Training - Epoch {epoch}, Loss: {loss.item():.4f}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB")
               time.sleep(4)
   
           print("Medium training completed on 2g.20gb MIG instance")
   
     small-inference-script.py: |
       import torch
       import torch.nn as nn
       import time
       import os
   
       print(f"=== SMALL INFERENCE POD (1g.10gb) ===")
       print(f"Process ID: {os.getpid()}")
       print(f"GPU available: {torch.cuda.is_available()}")
       print(f"GPU count: {torch.cuda.device_count()}")
   
       if torch.cuda.is_available():
           device = torch.cuda.current_device()
           print(f"Using GPU: {torch.cuda.get_device_name(device)}")
           print(f"GPU Memory: {torch.cuda.get_device_properties(device).total_memory / 1e9:.1f} GB")
   
           # Small model for 1g.10gb instance
           model = nn.Sequential(
               nn.Linear(512, 256),
               nn.ReLU(),
               nn.Linear(256, 10)
           ).cuda()
   
           print(f"Model parameters: {sum(p.numel() for p in model.parameters())}")
   
           # Inference loop
           for i in range(200):
               with torch.no_grad():
                   # Small batch for 1g.10gb
                   x = torch.randn(32, 512).cuda()
                   output = model(x)
                   prediction = torch.argmax(output, dim=1)
   
                   if i % 20 == 0:
                       print(f"Small Inference - Batch {i}, Predictions: {prediction[:5].tolist()}, GPU Memory: {torch.cuda.memory_allocated()/1e9:.2f}GB")
               time.sleep(2)
   
           print("Small inference completed on 1g.10gb MIG instance")
   
   ---
   # Pod 1: Large training workload (3g.40gb)
   apiVersion: v1
   kind: Pod
   metadata:
     name: mig-large-training-pod
     namespace: mig-gpu
     labels:
       app: mig-large-training
       workload-type: training
   spec:
     restartPolicy: Never
     containers:
     - name: large-training-container
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["python", "/scripts/large-training-script.py"]
       volumeMounts:
       - name: script-volume
         mountPath: /scripts
         readOnly: true
       resources:
         claims:
         - name: mig-large-claim
     resourceClaims:
     - name: mig-large-claim
       resourceClaimTemplateName: mig-large-template
     nodeSelector:
       node.kubernetes.io/instance-type: p4de.24xlarge
       nvidia.com/gpu.present: "true"
     tolerations:
     - key: nvidia.com/gpu
       operator: Exists
       effect: NoSchedule
     volumes:
     - name: script-volume
       configMap:
         name: mig-scripts-configmap
         defaultMode: 0755
   
   ---
   # Pod 2: Medium training workload (2g.20gb) - can run on SAME GPU as Pod 1
   apiVersion: v1
   kind: Pod
   metadata:
     name: mig-medium-training-pod
     namespace: mig-gpu
     labels:
       app: mig-medium-training
       workload-type: training
   spec:
     restartPolicy: Never
     containers:
     - name: medium-training-container
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["python", "/scripts/medium-training-script.py"]
       volumeMounts:
       - name: script-volume
         mountPath: /scripts
         readOnly: true
       resources:
         claims:
         - name: mig-medium-claim
     resourceClaims:
     - name: mig-medium-claim
       resourceClaimTemplateName: mig-medium-template
     nodeSelector:
       node.kubernetes.io/instance-type: p4de.24xlarge
       nvidia.com/gpu.present: "true"
     tolerations:
     - key: nvidia.com/gpu
       operator: Exists
       effect: NoSchedule
     volumes:
     - name: script-volume
       configMap:
         name: mig-scripts-configmap
         defaultMode: 0755
   
   ---
   # Pod 3: Small inference workload (1g.10gb) - can run on SAME GPU as Pod 1 & 2
   apiVersion: v1
   kind: Pod
   metadata:
     name: mig-small-inference-pod
     namespace: mig-gpu
     labels:
       app: mig-small-inference
       workload-type: inference
   spec:
     restartPolicy: Never
     containers:
     - name: small-inference-container
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["python", "/scripts/small-inference-script.py"]
       volumeMounts:
       - name: script-volume
         mountPath: /scripts
         readOnly: true
       resources:
         claims:
         - name: mig-small-claim
     resourceClaims:
     - name: mig-small-claim
       resourceClaimTemplateName: mig-small-template
     nodeSelector:
       node.kubernetes.io/instance-type: p4de.24xlarge
       nvidia.com/gpu.present: "true"
     tolerations:
     - key: nvidia.com/gpu
       operator: Exists
       effect: NoSchedule
     volumes:
     - name: script-volume
       configMap:
         name: mig-scripts-configmap
         defaultMode: 0755
   ```

1. Wenden Sie diese Spezifikation an, die drei Pods bereitstellen sollte:

   ```
   kubctl apply -f mig-pod.yaml
   ```

   Diese Pods sollten vom DRA-Treiber geplant werden.

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

   ```
   I0717 21:50:22.925811 1 driver.go:87] NodePrepareResource is called: number of claims: 1
   I0717 21:50:22.932499 1 driver.go:129] Returning newly prepared devices for claim '933e9c72-6fd6-49c5-933c-a896407dc6d1': [&Device{RequestNames:[mig-large],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-0-mig-9-4-4,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-0-mig-9-4-4**],}]
   I0717 21:50:23.186472 1 driver.go:87] NodePrepareResource is called: number of claims: 1
   I0717 21:50:23.191226 1 driver.go:129] Returning newly prepared devices for claim '61e5ddd2-8c2e-4c19-93ae-d317fecb44a4': [&Device{RequestNames:[mig-medium],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-2-mig-14-0-2,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-2-mig-14-0-2**],}]
   I0717 21:50:23.450024 1 driver.go:87] NodePrepareResource is called: number of claims: 1
   I0717 21:50:23.455991 1 driver.go:129] Returning newly prepared devices for claim '1eda9b2c-2ea6-401e-96d0-90e9b3c111b5': [&Device{RequestNames:[mig-small],PoolName:ip-100-64-173-145.ec2.internal,DeviceName:gpu-1-mig-19-2-1,CDIDeviceIDs:[k8s.gpu.nvidia.com/device=**gpu-1-mig-19-2-1**],}]
   ```

1. Überprüfen Sie den Pod-Status`resourceclaims`, 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, `allocated,reserved` wurden alle Pods vom DRA-Treiber von „Ausstehend“ zu „Ausstehend“ verschoben.

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

   ```
   root@ip-100-64-173-145 bin]# nvidia-smi
   +-----------------------------------------------------------------------------------------+
   | NVIDIA-SMI 570.158.01 Driver Version: 570.158.01 CUDA Version: 12.8 |
   |-----------------------------------------+------------------------+----------------------+
   | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
   | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
   | | | MIG M. |
   |=========================================+========================+======================|
   | 0 NVIDIA A100-SXM4-80GB On | 00000000:10:1C.0 Off | On |
   | N/A 63C P0 127W / 400W | 569MiB / 81920MiB | N/A Default |
   | | | Enabled |
   +-----------------------------------------+------------------------+----------------------+
   | 1 NVIDIA A100-SXM4-80GB On | 00000000:10:1D.0 Off | On |
   | N/A 56C P0 121W / 400W | 374MiB / 81920MiB | N/A Default |
   | | | Enabled |
   +-----------------------------------------+------------------------+----------------------+
   | 2 NVIDIA A100-SXM4-80GB On | 00000000:20:1C.0 Off | On |
   | N/A 63C P0 128W / 400W | 467MiB / 81920MiB | N/A Default |
   | | | Enabled |
   +-----------------------------------------+------------------------+----------------------+
   | 3 NVIDIA A100-SXM4-80GB On | 00000000:20:1D.0 Off | On |
   | N/A 57C P0 118W / 400W | 249MiB / 81920MiB | N/A Default |
   | | | Enabled |
   +-----------------------------------------+------------------------+----------------------+
   | 4 NVIDIA A100-SXM4-80GB On | 00000000:90:1C.0 Off | 0 |
   | N/A 51C P0 77W / 400W | 0MiB / 81920MiB | 0% Default |
   | | | Disabled |
   +-----------------------------------------+------------------------+----------------------+
   | 5 NVIDIA A100-SXM4-80GB On | 00000000:90:1D.0 Off | 0 |
   | N/A 46C P0 69W / 400W | 0MiB / 81920MiB | 0% Default |
   | | | Disabled |
   +-----------------------------------------+------------------------+----------------------+
   | 6 NVIDIA A100-SXM4-80GB On | 00000000:A0:1C.0 Off | 0 |
   | N/A 52C P0 74W / 400W | 0MiB / 81920MiB | 0% Default |
   | | | Disabled |
   +-----------------------------------------+------------------------+----------------------+
   | 7 NVIDIA A100-SXM4-80GB On | 00000000:A0:1D.0 Off | 0 |
   | N/A 47C P0 72W / 400W | 0MiB / 81920MiB | 0% Default |
   | | | Disabled |
   +-----------------------------------------+------------------------+----------------------+
   
   
   +-----------------------------------------------------------------------------------------+
   | MIG devices: |
   +------------------+----------------------------------+-----------+-----------------------+
   | GPU GI CI MIG | Memory-Usage | Vol| Shared |
   | ID ID Dev | BAR1-Usage | SM Unc| CE ENC DEC OFA JPG |
   | | | ECC| |
   |==================+==================================+===========+=======================|
   | 0 2 0 0 | 428MiB / 40192MiB | 42 0 | 3 0 2 0 0 |
   | | 2MiB / 32767MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 0 3 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 |
   | | 0MiB / 16383MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 0 9 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 0 10 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 1 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 |
   | | 0MiB / 32767MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 1 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 |
   | | 0MiB / 16383MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 1 13 0 2 | 161MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 2MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 1 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 2 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 |
   | | 0MiB / 32767MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 2 5 0 1 | 289MiB / 19968MiB | 28 0 | 2 0 1 0 0 |
   | | 2MiB / 16383MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 2 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 2 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 3 1 0 0 | 107MiB / 40192MiB | 42 0 | 3 0 2 0 0 |
   | | 0MiB / 32767MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 3 5 0 1 | 71MiB / 19968MiB | 28 0 | 2 0 1 0 0 |
   | | 0MiB / 16383MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 3 13 0 2 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   | 3 14 0 3 | 36MiB / 9728MiB | 14 0 | 1 0 0 0 0 |
   | | 0MiB / 8191MiB | | |
   +------------------+----------------------------------+-----------+-----------------------+
   
   
   +-----------------------------------------------------------------------------------------+
   | Processes: |
   | GPU GI CI PID Type Process name GPU Memory |
   | ID ID Usage |
   |=========================================================================================|
   **| 0 2 0 64080 C python 312MiB |
   | 1 13 0 64085 C python 118MiB |
   | 2 5 0 64073 C python 210MiB |**
   +-----------------------------------------------------------------------------------------+
   ```

#### Optimieren Sie GPU-Workloads mit IMEX mithilfe von GB200 P6e-Instances
<a name="aiml-dra-imex"></a>

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

Führen Sie die folgenden Schritte aus.

1. Definieren Sie ein `ComputeDomain` für ein Training mit mehreren Knoten mit einer Datei namens`imex-compute-domain.yaml`:

   ```
   apiVersion: resource.nvidia.com/v1beta1
   kind: ComputeDomain
   metadata:
     name: distributed-training-domain
     namespace: default
   spec:
     numNodes: 2
     channel:
       resourceClaimTemplate:
         name: imex-channel-template
   ```

1. Definieren Sie einen Pod mithilfe von IMEX-Kanälen mit einer Datei namens: `imex-pod.yaml`

   ```
   apiVersion: v1
   kind: Pod
   metadata:
     name: imex-distributed-training
     namespace: default
     labels:
       app: imex-training
   spec:
     affinity:
       nodeAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
           nodeSelectorTerms:
           - matchExpressions:
             - key: nvidia.com/gpu.clique
               operator: Exists
     containers:
     - name: distributed-training
       image: nvcr.io/nvidia/pytorch:25.04-py3
       command: ["bash", "-c"]
       args:
       - |
         echo "=== IMEX Channel Verification ==="
         ls -la /dev/nvidia-caps-imex-channels/
         echo ""
   
         echo "=== GPU Information ==="
         nvidia-smi
         echo ""
   
         echo "=== NCCL Test (if available) ==="
         python -c "
         import torch
         import torch.distributed as dist
         import os
   
         print(f'CUDA available: {torch.cuda.is_available()}')
         print(f'CUDA device count: {torch.cuda.device_count()}')
   
         if torch.cuda.is_available():
             for i in range(torch.cuda.device_count()):
                 print(f'GPU {i}: {torch.cuda.get_device_name(i)}')
   
         # Check for IMEX environment variables
         imex_vars = [k for k in os.environ.keys() if 'IMEX' in k or 'NVLINK' in k]
         if imex_vars:
             print('IMEX Environment Variables:')
             for var in imex_vars:
                 print(f'  {var}={os.environ[var]}')
   
         print('IMEX channel verification completed')
         "
   
         # Keep container running for inspection
         sleep 3600
       resources:
         claims:
         - name: imex-channel-0
         - name: imex-channel-1
     resourceClaims:
     - name: imex-channel-0
       resourceClaimTemplateName: imex-channel-template
     - name: imex-channel-1
       resourceClaimTemplateName: imex-channel-template
     tolerations:
     - key: nvidia.com/gpu
       operator: Exists
       effect: NoSchedule
   ```
**Anmerkung**  
Dies erfordert P6e GB200-Instanzen.

1. Stellen Sie IMEX bereit, indem Sie die folgenden Vorlagen anwenden: `ComputeDomain`

   ```
   kubectl apply -f imex-claim-template.yaml
   kubectl apply -f imex-compute-domain.yaml
   kubectl apply -f imex-pod.yaml
   ```

1. Überprüfen Sie den `ComputeDomain` Status.

   ```
   kubectl get computedomain distributed-training-domain
   ```

1. Überwachen Sie die Bereitstellung des IMEX-Daemons.

   ```
   kubectl get pods -n nvidia-dra-driver -l resource.nvidia.com/computeDomain
   ```

1. Überprüfen Sie die IMEX-Kanäle im Pod:

   ```
   kubectl exec imex-distributed-training -- ls -la /dev/nvidia-caps-imex-channels/
   ```

1. Sehen Sie sich die Pod-Logs an:

   ```
   kubectl logs imex-distributed-training
   ```

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

   ```
   === IMEX Channel Verification ===
   total 0
   drwxr-xr-x. 2 root root 80 Jul 8 10:45 .
   drwxr-xr-x. 6 root root 380 Jul 8 10:45 ..
   crw-rw-rw-. 1 root root 241, 0 Jul 8 10:45 channel0
   crw-rw-rw-. 1 root root 241, 1 Jul 8 10:45 channel1
   ```

Weitere Informationen finden Sie im [NVIDIA-Beispiel](https://github.com/NVIDIA/k8s-dra-driver-gpu/discussions/249) unter GitHub.