TPUs mit dynamischem Slicing in GKE konfigurieren

In diesem Dokument wird erläutert, wie Sie dynamisches Slicing in Google Kubernetes Engine (GKE) verwenden. Mit Dynamic Slicing können Sie bereitgestellte TPU-Unterblöcke in verschiedenen Topologien konfigurieren. Diese Funktion macht es weniger erforderlich, Knotenpools neu zu erstellen, verbessert die Fehlertoleranz durch automatische Wiederherstellung bei einem Fehler und optimiert die Ressourcennutzung.

Dieses Dokument richtet sich an KI-/ML-Entwickler und Plattformadministratoren, die die TPU-Auslastung optimieren, die Bereitstellungszeit verkürzen und die Fehlertoleranz für umfangreiche Trainings- und Inferenzarbeitslasten verbessern möchten.

Bevor Sie dieses Dokument lesen, sollten Sie mit Folgendem vertraut sein:

Was ist dynamisches Slicing?

Dynamisches Slicing bietet Flexibilität bei der Verwaltung der Cloud TPU-Kapazität, da Sie die TPU-Bereitstellung entkoppeln können. Das dynamische Aufteilen umfasst die folgenden Schritte:

  1. Sie stellen Ressourcen als kleinere Einheiten bereit, die als Unterblöcke bezeichnet werden. Ein Unterblock ist die grundlegende logische Baueinheit der Ironwood-Kapazität (TPU7x). Für Ironwood (TPU7x) stellt sie eine Gruppe von 16 TPU-VMs mit einer 4x4x4-Topologie miteinander verbundener TPU-Chips dar. Im Kontext des TPU-Modus „Alle Kapazitäten“ und des dynamischen Slicing wird ein Knotenpool direkt einem Unterblock zugeordnet.
  2. Beim dynamischen Slicing werden diese Unterblöcke dann zu größeren Slices zusammengefügt.

Vorteile des dynamischen Aufteilens

Dynamisches Aufteilen bietet folgende Vorteile:

  • Bereitstellungszeit verkürzen: Die individuelle Bereitstellung von Unterblöcken führt zu einer insgesamt schnelleren Bereitstellung, da die Auswirkungen eines einzelnen Fehlers minimiert werden.
  • Zeit für die Wiederherstellung verkürzen: Wenn ein TPU-Chip ausfällt, ist die kleinste Einheit, die ausfällt, ein Subblock. Durch dynamisches Slicing werden fehlerhafte Unterblöcke isoliert, sodass Arbeitslasten schneller auf fehlerfreien Unterblöcken neu geplant werden können, als wenn ein großer Slice neu bereitgestellt werden muss.
  • Kapazität neu gestalten: Wenn Sie unterschiedliche Anforderungen an die Arbeitslast haben, müssen Sie Knotengruppen für Topologieänderungen nicht löschen und neu erstellen. Ohne dynamisches Slicing wäre das erforderlich. Stattdessen können Sie die bereitgestellten Knotenpools dynamisch neu konfigurieren, um den angegebenen Formen zu entsprechen.

Wichtige Elemente des dynamischen Aufteilens

Beim dynamischen Aufteilen werden die folgenden wichtigen Konzepte eingeführt:

  • Inkrementelle Bereitstellung von Knotenpools:Beim dynamischen Slicing wird die inkrementelle Bereitstellung verwendet, ein fehlertolerantes Bereitstellungsmodell für Knotenpools. Bei diesem Modell wird Ihre gesamte TPU-Kapazität in Knotenpools mit einer Gruppe von 16 TPU-VMs umgewandelt.
  • Slice-Controller:Ein Kubernetes-Controller für benutzerdefinierte Ressourcen, der in der GKE-Steuerungsebene ausgeführt wird und das dynamische Slicing verwaltet. Der Slice-Controller verwaltet den Lebenszyklus einer benutzerdefinierten Slice-Ressource, die einen dynamischen Slice darstellt. Der Slice-Controller ist für das Erstellen, kontinuierliche Überwachen und Löschen des Slice zuständig. Wenn Sie einen Scheduler verwenden, wird das Erstellen und Löschen der benutzerdefinierten Slice-Ressource vom Scheduler gesteuert.
  • Benutzerdefinierte Slice-Ressource: Diese Subblöcke werden basierend auf der angeforderten TPU-Topologie dynamisch zusammengefügt. Dieser Prozess basiert auf der dynamischen Neukonfiguration des OCS-Netzwerks, um die TPU-Knotenpools zu verbinden. So wird eine optimierte Leistung erzielt. Sie können den Fortschritt oder den Zustand der dynamischen Segmentbildung prüfen, indem Sie die Statusfelder der benutzerdefinierten Slice-Ressource untersuchen.

Voraussetzungen

Damit Sie dynamisches Slicing in GKE verwenden können, müssen die folgenden Anforderungen erfüllt sein:

  • Verwenden Sie einen Standardcluster in Version 1.35.0-gke.274500 oder höher im Rapid Channel.
  • Verwenden Sie die Ironwood-Version (TPU7x).
  • Verwenden Sie das Container-Optimized OS-Image für Ihre Knoten.
  • Wenn Sie die inkrementelle Bereitstellung verwenden möchten, müssen Sie Reservierungen im Modus „Alle Kapazitäten“ verwenden. Der Kapazitätsmodus ist eine Funktion, die von TPU Cluster Director aktiviert wird.

Hinweise

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diesen Task verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem Befehl gcloud components update ab. In früheren gcloud CLI-Versionen werden die Befehle in diesem Dokument möglicherweise nicht unterstützt.

Beschränkungen

  • Für einen einzelnen Slice müssen Unterblöcke innerhalb desselben TPU-Blocks unter einer Reservierung verwendet werden. Wenn Sie Unterblöcke über TPU-Blöcke hinweg verwenden möchten, nutzen Sie TPU-Multislices.
  • Dynamisches Aufteilen wird für Topologien mit weniger als 4x4x4 nicht unterstützt.

Dynamisches Slicing in GKE mit Kueue verwenden

In diesem Abschnitt wird der Workflow für die Verwendung von dynamischem Slicing in GKE beschrieben.

  1. Topologie und Systemzustand von Reservierungen im Modus „Alle Kapazitäten“ ansehen
  2. Slice-Controller in Ihrem Cluster aktivieren
  3. TPU-Knotenpools erstellen
  4. Kueue so konfigurieren, dass eine benutzerdefinierte Slice-Ressource erstellt wird
  5. Arbeitslasten mit dynamischem Slicing mit Kueue ausführen
  6. Führen Sie eine Bereinigung durch.

Slice-Controller aktivieren

Wenn Sie dynamisches Slicing verwenden möchten, aktivieren Sie den Slice-Controller in Ihrem Cluster.

  1. Cluster aktualisieren:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --enable-slice-controller
    

    Ersetzen Sie Folgendes:

  2. Rufen Sie Anmeldedaten ab, damit Sie mit kubectl-Befehlen mit Ihrem Cluster kommunizieren können:

    gcloud config set container/cluster CLUSTER_NAME
    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    
  3. Prüfen Sie in der Ausgabe des folgenden Befehls, ob der Wert slices.accelerator.gke.io vorhanden ist:

    kubectl get crd slices.accelerator.gke.io
    

    Die Ausgabe sieht etwa so aus:

    slices.accelerator.gke.io                2026-01-09T23:58:02Z
    

Knotenpools mit inkrementeller Bereitstellung erstellen

In diesem Abschnitt wird beschrieben, wie Sie die TPU-Knotenpools mit inkrementeller Bereitstellung erstellen. GKE konvertiert Ihre gesamte TPU-Kapazität in Knotenpools mit einer 16-Knoten-Gruppe von TPU-VMs oder Unterblöcken. GKE stellt diese Knotenpools auch dann bereit, wenn nicht alle 16 fehlerfreien VMs gefunden werden können. Dazu werden Knoten auf fehlerfreien Teilen des Hostcomputers platziert und fehlerhafte Maschinen inkrementell bereitgestellt, während sie repariert werden.

Sie können festlegen, dass Ihr Knotenpool zu einer der folgenden Gruppen gehört:

  • Ein bestimmter TPU-Block, der in Reservierungen im Modus „Alle Kapazitäten“ verfügbar ist. Durch die Blockausrichtung kann GKE den Knotenpool in einem beliebigen verfügbaren Unterblock innerhalb des angegebenen Blocks erstellen.
  • Ein bestimmter Unterblock oder eine bestimmte Gruppe von 16 TPU-VMs für eine detailliertere Steuerung.

Arbeitslastrichtlinie erstellen

Wenn Sie einen TPU-Slice-Knotenpool mit Ironwood (TPU7x) erstellen möchten, müssen Sie zuerst eine Arbeitslastrichtlinie erstellen, bei der das Feld accelerator-topology-mode auf provision_only festgelegt ist. Diese Einstellung löst den inkrementellen Bereitstellungsprozess aus.

Arbeitslastrichtlinie erstellen:

gcloud compute resource-policies create workload-policy WORKLOAD_POLICY_NAME \
        --project=PROJECT_ID \
        --region=REGION  \
        --type=HIGH_THROUGHPUT \
        --accelerator-topology=4x4x4 \
        --accelerator-topology-mode=provision_only

Ersetzen Sie Folgendes:

  • WORKLOAD_POLICY_NAME: ein Name für Ihre Arbeitslastrichtlinie.
  • PROJECT_ID: Projekt-ID in Google Cloud .
  • REGION: die Region für die Arbeitslastrichtlinie.

Führen Sie in diesem Befehl folgende Schritte aus::

  • Legen Sie das Feld accelerator-topology immer auf 4x4x4 fest, damit es der Gesamtzahl der Chips in einem einzelnen Unterblock entspricht.
  • Legen Sie das Feld accelerator-topology-mode immer auf provision_only fest, damit der inkrementelle Bereitstellungsprozess ausgelöst wird. Wenn das Feld provision_only festgelegt ist, werden im Knotenpool TPU-Knoten bereitgestellt, ohne ICI- oder OCS-Verbindungen zu erstellen.
können Sie die Liste der Arbeitslastrichtlinien aufrufen.

Knotenpool auf einen Block oder Unterblock ausrichten

Sie können bestimmte Unterblöcke oder Blöcke in Ihrer Reservierung im Modus „Alle Kapazitäten“ targetieren.

  • Auf einen Block ausrichten:Jeder Knotenpool verwendet Kapazität aus einem bestimmten Block. GKE platziert den Knotenpool in einem verfügbaren Unterblock in diesem Block. Sie müssen so viele Knotenpools erstellen, wie es Unterblöcke im Block gibt, den Sie verwenden möchten.
  • Auf einen Unterblock ausrichten:Jeder Knotenpool wird einem bestimmten verfügbaren Unterblock zugeordnet. Wenn Sie die Ausrichtung auf Unterblöcke verwenden, erstellt GKE den Knotenpool, wenn mindestens eine VM fehlerfrei ist. Durch die inkrementelle Bereitstellung wird sichergestellt, dass alle Knoten innerhalb des angegebenen Unterblocks platziert werden.

Blockieren

  1. Wenn Sie den Namen des Blocks in einer Reservierung und die Anzahl der verfügbaren Unterblöcke im Block abrufen möchten, führen Sie die folgenden Schritte im Dokument Topologie und Status von Reservierungen im Modus „Alle Kapazitäten“ ansehen aus:

    1. Ermitteln Sie den Namen des Blocks, indem Sie alle Reservierungsblöcke auflisten und den Wert im Feld name: kopieren. Dieser Wert ist der Name des Blocks oder BLOCK_NAME in diesem Dokument.

    2. Ermitteln Sie, wie viele Knotenpools erstellt werden sollen, indem Sie einen Reservierungsblock beschreiben und den Wert im Feld reservationSubBlockCount ermitteln. Dieser Wert gibt die Anzahl der verfügbaren Unterblöcke an. Der Wert reservationSubBlockCount: 4 gibt beispielsweise an, dass für den Block vier Unterblöcke verfügbar sind und Sie vier separate Knotenpools erstellen müssen.

  2. Reservierungspfad festlegen:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME"
    

    Ersetzen Sie Folgendes:

    • RESERVATION_NAME: Der Name Ihrer TPU-Reservierung.
    • BLOCK_NAME: der Name des Blocks.
  3. Erstellen Sie für jeden im vorherigen Schritt ermittelten Unterblock einen Knotenpool. Wenn die Anzahl beispielsweise 4 ist, führen Sie diesen Befehl viermal aus. Verwenden Sie für jeden Knotenpool einen eindeutigen Namen.

    gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --node-locations=ZONE \
          --machine-type=tpu7x-standard-4t \
          --num-nodes=16 \
          --placement-policy=WORKLOAD_POLICY_NAME \
          --reservation-affinity=specific \
          --reservation=${RESERVATION_PATH}
    

    Ersetzen Sie Folgendes:

    • NODE_POOL_NAME ist der Name des neuen Knotenpools.
    • CLUSTER_NAME: der Name Ihres GKE-Clusters.
    • WORKLOAD_POLICY_NAME: der Name der von Ihnen erstellten Workload-Richtlinie.
    • ZONE: die Zone für den Knotenpool, z. B. us-central1-a.

Unterblock

  1. Führen Sie die folgenden Schritte im Dokument Topologie und Integritätsstatus von Reservierungen im Modus „Alle Kapazitäten“ ansehen aus, um den Namen des Blocks und die IDs der verfügbaren Unterblöcke abzurufen:

    1. Um den Namen des Blocks zu ermitteln, listen Sie alle Reservierungsblöcke auf und kopieren Sie den Wert im Feld name:. Dieser Wert ist der Name des Blocks oder der BLOCK_NAME in diesem Dokument.

    2. Um den Namen der Unterblöcke zu ermitteln, listen Sie alle Unterblöcke eines Blocks auf und kopieren Sie den Wert im Feld name: für jeden Eintrag unter reservationSubBlocks. Dieser Wert ist der Name des Unterblocks oder SUBBLOCK_NAME in diesem Dokument.

  2. Reservierungspfad festlegen:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME/reservationSubBlocks/SUBBLOCK_NAME"
    

    Ersetzen Sie Folgendes:

    • RESERVATION_NAME: Der Name Ihrer TPU-Reservierung.
    • BLOCK_NAME: der Name des Blocks.
    • SUBBLOCK_NAME: der Name des Unterblocks.
  3. Knotenpool erstellen:

    gcloud container node-pools create NODE_POOL_NAME \
            --project=PROJECT_ID \
            --cluster=CLUSTER_NAME \
            --node-locations=ZONE \
            --machine-type=tpu7x-standard-4t \
            --num-nodes=16 \
            --placement-policy=WORKLOAD_POLICY_NAME \
            --reservation-affinity=specific \
            --reservation=${RESERVATION_PATH}
    

    Ersetzen Sie Folgendes:

    • NODE_POOL_NAME: ein eindeutiger Name für Ihren neuen Knotenpool, z. B. sub-block-pool-1.
    • PROJECT_ID: Projekt-ID in Google Cloud .
    • CLUSTER_NAME: Name Ihres GKE-Clusters.
    • ZONE: Die Zone für den Knotenpool, z. B. us-central2-b.
    • WORKLOAD_POLICY_NAME: der Name der von Ihnen erstellten Arbeitslastrichtlinie.

In dieser Phase werden die Knoten erstellt, ihre Inter-Chip Interconnect-Verbindungen (ICI) sind jedoch noch nicht aktiv. Daher können Sie Arbeitslasten nicht direkt in diesen Knotenpools ausführen.

Damit alle erforderlichen ICI-Links zum Erstellen des Slices und zum Planen von Arbeitslasten verwendet werden können, erstellen Sie einen dynamischen Slice mit einer der folgenden Methoden:

  • Erstellen Sie eine benutzerdefinierte Slice-Ressource. Anstelle von Pods verwenden Sie eine benutzerdefinierte Slice-Ressource, um die angegebene Topologie zu definieren, die vom Slice-Controller aktiviert wird.
  • GKE-Arbeitslasten mit Kueue und TAS planen. Kueue übernimmt automatisch das Erstellen und Löschen von benutzerdefinierten Slice-Ressourcen. Von Kueue erstellte benutzerdefinierte Slice-Ressourcen sollten nicht manuell geändert werden.

Dynamischen Slice mit Kueue und TAS erstellen

In diesem Abschnitt planen Sie GKE-Arbeitslasten mit Kueue und TAS.

JobSet- und Kueue-Ressourcen für dynamisches Slicing installieren

  1. JobSet installieren:

    helm install jobset oci://registry.k8s.io/jobset/charts/jobset \
            --version 0.10.1 \
            --namespace jobset-system \
            --create-namespace \
            --set controller.resources.requests.cpu=4 \
            --set controller.resources.requests.memory=16Gi
    
  2. Installieren Sie Kueue:

    helm install kueue oci://registry.k8s.io/kueue/charts/kueue \
            --version 0.16.1 \
            --namespace kueue-system \
            --create-namespace \
            --wait \
            --set controllerManager.replicas=3 \
            --set controllerManager.manager.resources.requests.cpu=16 \
            --set controllerManager.manager.resources.requests.memory=64Gi
    
  3. Installieren Sie den Kueue-Slice-Controller:

    kubectl apply -f https://gist.githubusercontent.com/mwysokin/cd90010d0d375b3bf57c536905692547/raw/506c36dd070f4ac222ba8a5e58ba28bbfcfa8ed3/kueue-slice-controller-v0.8.0-130.yaml
    
  4. Speichern Sie zum Konfigurieren von Kueue für dynamisches Slicing das folgende Manifest als dynamic-slice-topology.yaml:

    apiVersion: kueue.x-k8s.io/v1beta1
    kind: Topology
    metadata:
      name: superslice-topology
    spec:
      levels:
      # Label to identify the physical block a sub-block belongs to.
      # Only sub-blocks from the same block can form a slice.
      - nodeLabel: cloud.google.com/gce-topology-block
      # Label to identify individual TPU sub-blocks (4x4x4 topology).
      - nodeLabel: cloud.google.com/gke-tpu-partition-4x4x4-id
      # Standard Kubernetes label for individual nodes.
      # Required to assign Pods to specific VMs.
      - nodeLabel: kubernetes.io/hostname
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: ResourceFlavor
    metadata:
      name: superslice-rf
    spec:
      nodeLabels:
        cloud.google.com/gke-tpu-accelerator: tpu7x
      topologyName: superslice-topology
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: AdmissionCheck
    metadata:
      name: superslice-ac
    spec:
      controllerName: accelerator.gke.io/slice
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: ClusterQueue
    metadata:
      name: cq
    spec:
      namespaceSelector: {}
      admissionChecks:
      - superslice-ac
      resourceGroups:
      - coveredResources:
        - google.com/tpu
        flavors:
        - name: superslice-rf
          resources:
          - name: google.com/tpu
            nominalQuota: "999999"  # modeling unlimited quota
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: LocalQueue
    metadata:
      name: lq
      namespace: default
    spec:
      clusterQueue: cq
    
  5. Wenden Sie das dynamic-slice-topology.yaml-Manifest an:

    kubectl apply -f dynamic-slice-topology.yaml
    

    In diesem Manifest konfigurieren Sie Kueue für das dynamische Aufteilen in Scheiben, indem Sie die folgenden Ressourcen definieren:

    • Dynamische Slice-Topologie für Ironwood (TPU7x) (superslice-topology): Die Topologie definiert die Ebenen, die Kueue bei der Planung von Arbeitslasten mit dynamischem Slicing berücksichtigt. Folgende Ebenen sind verfügbar:
      • cloud.google.com/gce-topology-block-Label: Diese Ebene ist erforderlich, um zu verstehen, welche Unterblöcke zu welchen Blöcken gehören, da nur Unterblöcke aus demselben Block einen Slice bilden können.
      • Label cloud.google.com/gke-tpu-partition-4x4x4-id: Diese Ebene stellt einzelne Ironwood-Unterblöcke (TPU7x) mit 4x4x4-Topologie dar.
      • Label kubernetes.io/hostname: Diese Ebene ist erforderlich, um Pods bestimmten VMs zuzuweisen und ihre Labels und Taints zu beobachten.
    • Ironwood (TPU7x) SuperSlice ResourceFlavor (superslice-rf): Der ResourceFlavor für Ironwood-Unterblöcke (TPU7x) enthält das Label cloud.google.com/gke-tpu-accelerator: tpu7x, um Knoten mit Ironwood-Maschinen (TPU7x) abzugleichen.
    • SuperSlice AdmissionCheck (superslice-ac): Dieser AdmissionCheck weist Kueue an, eine Arbeitslast erst dann zu planen, wenn der GKE-Slice-Controller bestätigt, dass der Slice aktiv geworden ist. Die Zulassungsprüfung wird zuerst definiert und dann der ClusterQueue hinzugefügt, der dynamische Slicing-Arbeitslasten verarbeitet.
    • ClusterQueue (cq) und LocalQueue (lq): Mit diesen Feldern werden google.com/tpu-Ressourcen verwaltet. Die cq ClusterQueue umfasst die superslice-ac-Aufnahmeüberprüfung. Die nominalQuota für google.com/tpu kann auf zwei Arten konfiguriert werden:
      • Spezifisches Kontingent: Legen Sie nominalQuota so fest, dass es der vorhandenen Kapazität für die faire Nutzung und die Kontingentverwaltung entspricht.
      • Unbegrenztes Kontingent: Setzen Sie nominalQuota auf einen sehr hohen Wert wie "999999", um ein unbegrenztes Kontingent zu modellieren. Um sich auf TAS und dynamisches Slicing zu konzentrieren, wird mit dieser Konfiguration die Kontingentverwaltungsfunktion von Kueue umgangen.

Auswahl der Unterblock-Systemdiagnose definieren

Neben dem Standardstatus für Knoten und der Bereitschaft stellt GKE den spezifischen Status jedes Unterblocks über das Label cloud.google.com/gke-tpu-partition-4x4x4-state bereit. Mit diesem Label kann GKE Faktoren berücksichtigen, die die Slice-Bildung beeinflussen, z. B. den Status von TPU-Links.

Sie können den Wert des Labels cloud.google.com/gke-tpu-partition-4x4x4-state so definieren:

  • HEALTHY: Die Infrastruktur ist fehlerfrei.
  • DEGRADED: Die Infrastruktur des Unterblocks ist in einem schlechten Zustand, z. B. aufgrund einer Verschlechterung der OCS-Verbindung. Der Unterblock kann weiterhin einen Slice bilden, aber die Gesamtleistung ist möglicherweise geringer als bei fehlerfreien Unterblöcken. Wenn Sie eine potenziell geringere Leistung in Kauf nehmen können, können Sie Ihre Arbeitslast so konfigurieren, dass DEGRADED-Unterblöcke verwendet werden. Verwenden Sie dazu die Knotenaffinität, wie in Beispiel 3 gezeigt.
  • UNHEALTHY: Der Unterblock ist fehlerhaft und kann keinen Slice bilden.

Der Kueue Slice Controller-Webhook prüft, ob eine Arbeitslast eine bestimmte Anforderung für den Status eines Unterblocks enthält. Wenn keine Präferenz angegeben ist, fügt der Webhook eine Standardknotenaffinität ein.

Das Verhalten ist wie folgt:

  • Wenn ein nodeSelector- oder nodeAffinity-Element vorhanden ist, das auf das Label cloud.google.com/gke-tpu-partition-4x4x4-state ausgerichtet ist, bleibt es unverändert.
  • Wenn keine solche Labelkonfiguration vorhanden ist, fügt der Webhook die folgende Standardknotenaffinität ein, um sicherzustellen, dass nur verfügbare Unterblöcke verwendet werden:

    nodeSelector:
      cloud.google.com/gke-tpu-partition-4x4x4-state: "HEALTHY"
    

Im folgenden Abschnitt finden Sie Beispiele, in denen das Label cloud.google.com/gke-tpu-partition-4x4x4-state konfiguriert ist, um die verschiedenen Konfigurationen für den Gesundheitszustand von Unterblöcken anzugeben.

Testarbeitslasten mit dynamischem Slicing mit Kueue ausführen

In diesem Abschnitt wird beschrieben, wie Sie Arbeitslasten mit Kueue und TAS auf dynamischen Slices bereitstellen. Es enthält drei Beispiele, die zeigen, wie Sie eine dynamische Slice-Arbeitslast und eine Arbeitslast mit mehreren Slices erstellen. Die Arbeitslasten werden als JobSets eingereicht.

Beispiel 1: Eine einzelne Arbeitslast verwendet einen einzelnen dynamischen Slice

Im folgenden Beispiel wird beschrieben, wie Sie einen Arbeitslast mithilfe eines Slice mit einer 4x12x16-Topologie erstellen, der aus 12 Unterblöcken besteht. Die Anzahl der Pods wurde so berechnet: (4 * 12 * 16) / 4 Chips pro Knoten = 192 Pods.

  1. Speichern Sie das folgende Manifest als big-super-slice.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: big-super-slice
      labels:
        kueue.x-k8s.io/queue-name: lq
      annotations:
    spec:
      replicatedJobs:
        - name: job-jax
          replicas: 1
          template:
            spec:
              parallelism: 192  # pods per slice calculation: 4*12*16 / 4 = 192
              completions: 192
              backoffLimit: 10
              template:
                metadata:
                  annotations:
                    cloud.google.com/gke-tpu-slice-topology: 4x12x16
                spec:
                  tolerations:
                    - key: "google.com/tpu"
                      operator: "Equal"
                      value: "present"
                      effect: "NoSchedule"
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: tpu7x
                    cloud.google.com/gke-tpu-partition-4x4x4-state: "HEALTHY"
                  containers:
                    - name: jax
                      image: python:latest
                      command:
                        - bash
                        - -c
                        - |
                          printenv
                          pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                          python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())'
                      resources:
                        limits:
                          google.com/tpu: 4
                  restartPolicy: Never
    

    In diesem Manifest geben die folgenden Annotationen an, wie Kueue die Slice-Merkmale und -Topologie konfigurieren soll:

    • cloud.google.com/gke-tpu-slice-topology: gibt "4x12x16" als dynamische Slice-Topologie an. Für die tpu7x-Beschleunigertopologie gelten die folgenden Regeln:
      • Die Mindesttopologie ist 4x4x4.
      • Die Topologie muss ein dreidimensionaler String im Format AxBxC sein. Beispiel: 4x8x8.
      • Jede Dimension (A, B und C) muss ein Vielfaches von vier sein.
      • Die Dimensionen müssen in nicht absteigender Reihenfolge sortiert sein: A <= B <= C. 4x8x4 ist beispielsweise ungültig und sollte 4x4x8 lauten.
      • Das Produkt der Abmessungen (ABC) darf 9.216 nicht überschreiten.
      • Die größten unterstützten Slice-Topologien können bis zu 32 Unterblöcke enthalten. Beispielsweise liegen 8x16x16 mit 32 Unterblöcken, 8x12x20 mit 30 Unterblöcken oder 12x12x12 mit 27 Unterblöcken innerhalb der zulässigen Grenzwerte.
    • cloud.google.com/gke-tpu-accelerator: tpu7x: Plant Pods auf VMs, auf denen Ironwood (TPU7x) ausgeführt wird.
    • kueue.x-k8s.io/queue-name: Weist das JobSet einer Kueue LocalQueue zu.
  2. Wenden Sie das big-super-slice.yaml-Manifest an:

    kubectl apply -f big-super-slice.yaml
    

    Nachdem Sie das Manifest angewendet haben, erstellt Kueue einen JobSet mit dem Namen big-super-slice. Kueue versucht dann, ein einzelnes dynamisches Slice mit einer 4x12x16-Topologie zu erstellen. Nachdem das Slice aktiv ist, lässt Kueue die Arbeitslast zu und die 192 Pods werden auf den Knoten geplant, um das dynamische Slice zu bilden, auf dem Ihre Arbeitslasten ausgeführt werden.

Beispiel 2: Arbeitslast mit mehr als einem Replikat

Im folgenden Beispiel wird gezeigt, wie Sie eine Arbeitslast erstellen, die zwei dynamische Slices verwendet, die jeweils aus vier Unterblöcken bestehen.

  1. Speichern Sie das folgende Manifest als two-super-slices.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
    name: two-super-slices
    labels:
        kueue.x-k8s.io/queue-name: lq
    annotations:
    spec:
    replicatedJobs:
        - name: job-jax
        replicas: 2
        template:
            spec:
            parallelism: 64  # Pods per slice calculation: (4*8*8) / 4 = 64
            completions: 64
            backoffLimit: 10
            template:
                metadata:
                annotations:
                    cloud.google.com/gke-tpu-slice-topology: 4x8x8
                spec:
                tolerations:
                    - key: "google.com/tpu"
                    operator: "Equal"
                    value: "present"
                    effect: "NoSchedule"
                nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: tpu7x
                    cloud.google.com/gke-tpu-partition-4x4x4-state: "HEALTHY"
                containers:
                    - name: jax
                    image: python:latest
                    command:
                        - bash
                        - -c
                        - |
                        printenv
                        pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                        python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())'
                    resources:
                        limits:
                        google.com/tpu: 4
                restartPolicy: Never
    
  2. Wenden Sie das two-super-slices.yaml-Manifest an:

    kubectl apply -f two-super-slices.yaml
    

In diesem Manifest legen Sie replicas: 2 im Feld replicatedJobs fest. Nachdem Sie das Manifest angewendet haben, versucht Kueue, zwei separate Slices mit einer 4x8x8-Topologie zu erstellen. Kueue erstellt für jedes in jobset.spec.replicatedJobs[].replicas definierte Replikat ein dynamisches Slice. Wenn n Replikate angegeben sind, erstellt Kueue n dynamische Slices für die Arbeitslast und wartet, bis alle Slices aktiv werden, bevor die Arbeitslast zugelassen wird.

Beispiel 3: Arbeitslast mit einem dynamischen Slice und NodeAffinity

Ab Kueue 0.15 unterstützt Kueue NodeAffinity für die TAS-Knotenauswahl. Mit dieser Funktion können sowohl HEALTHY- als auch DEGRADED-Knoten Teil eines dynamischen Slices sein. Das folgende Beispiel zeigt, wie eine Arbeitslast mit einem einzelnen dynamischen Slice und NodeAffinity konfiguriert wird:

  1. Speichern Sie das folgende Manifest als slice-8x8x8-na.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: slice-8x8x8-na
      labels:
        kueue.x-k8s.io/queue-name: lq
    spec:
      replicatedJobs:
        - name: rj1
          replicas: 1
          template:
            spec:
              parallelism: 128
              completions: 128
              backoffLimit: 10
              template:
                metadata:
                  annotations:
                    cloud.google.com/gke-tpu-slice-topology: 8x8x8
                spec:
                  tolerations:
                    - key: "google.com/tpu"
                      operator: "Equal"
                      value: "present"
                      effect: "NoSchedule"
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: tpu7x
                  affinity:
                    nodeAffinity:
                      requiredDuringSchedulingIgnoredDuringExecution:
                        nodeSelectorTerms:
                          - matchExpressions:
                              - key: cloud.google.com/gke-tpu-partition-4x4x4-state
                                operator: In
                                values:
                                  - "HEALTHY"
                                  - "DEGRADED"
                  containers:
                    - name: jax
                      image: python:latest
                      command:
                        - bash
                        - -c
                        - |
                          printenv
                          pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                          python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())'
                      resources:
                        limits:
                          google.com/tpu: 4
                  restartPolicy: Never
    
  2. Wenden Sie das slice-8x8x8-na.yaml-Manifest an:

    kubectl apply -f slice-8x8x8-na.yaml
    

    Nachdem Sie das Manifest angewendet haben, erstellt Kueue einen JobSet mit dem Namen slice-8x8x8-na. Kueue versucht dann, einen einzelnen dynamischen Slice mit einer 8x8x8-Topologie zu bilden, der aufgrund der angegebenen NodeAffinity sowohl HEALTHY- als auch DEGRADED-Knoten enthalten kann. Nachdem der Slice aktiv ist, lässt Kueue die Arbeitslast zu und die 128 Pods werden auf den Knoten geplant, aus denen der dynamische Slice besteht.

Status des Segments überwachen

Führen Sie den folgenden Befehl aus, um den Status Ihrer dynamischen Slices zu prüfen:

kubectl describe slice SLICE_NAME

Ersetzen Sie SLICE_NAME durch den Namen Ihres Slices. Der Slice-Name wird in der Regel aus dem JobSet-Namen und dem Replikatindex abgeleitet. Im Beispiel 1 hätte ein von Kueue erstellter Slice einen Namen wie default-jobset-big-super-slice-yyyyy-job-jax-0.

Die Ausgabe sieht etwa so aus:

Name:         test-slice
Namespace:
Labels:       <none>
Annotations:  <none>
API Version:  accelerator.gke.io/v1beta1
Kind:         Slice
Metadata:
  Creation Timestamp:  2026-02-12T23:44:28Z
  Finalizers:
    accelerator.gke.io/slice-finalizer
  Generation:        1
  Resource Version:  1770939905695871008
  UID:               6dbbfe14-4486-4462-864d-e078d0ca8b5b
Spec:
  Partition Ids:
    5eae6a4f59d59cf30a9bf49de618eb2b
  Topology:  4x4x4
  Type:      tpu7x
Status:
  Conditions:
    Last Transition Time:  2026-02-12T23:45:05Z
    Message:
    Reason:                ACTIVE
    Status:                True
    Type:                  Ready
    Last Transition Time:  2026-02-12T23:45:05Z
    Message:               NodeLabelingCompleted
    Reason:                NodeLabelIsAdded
    Status:                True
    Type:                  NodeLabeled
Events:                    <none>

Der Slicename entspricht den folgenden Regeln, um die Kompatibilität mit den zugrunde liegenden Compute Engine-Ressourcennamenkonventionen zu gewährleisten:

  • Vorlage: {namespace}-jobset-{jobset.metadata.name}-kueueHash[5-character]-{jobset.spec.replicatedJobs[].name}-sliceIndex.
  • Länge: Der Name hat maximal 54 Zeichen. Der Controller hängt einen Bindestrich und einen 8‑stelligen Cluster-Hash an, um Compute Engine-Ressourcennamen zu erstellen, die ein Limit von 63 Zeichen haben.
  • Format: Der Name entspricht dem regulären Ausdruck ^[a-z]([-a-z0-9]*[a-z0-9])?$. Der Name hat folgende Merkmale:
    • Muss mit einem Kleinbuchstaben beginnen.
    • Darf nur Kleinbuchstaben, Ziffern und Bindestriche (-) enthalten.
    • Endet mit einem Kleinbuchstaben oder einer Ziffer (darf nicht mit einem Bindestrich enden).

Bereinigen

Löschen Sie die Slices, bevor Sie Knotenpools löschen, um unerwartete Kosten zu vermeiden.

  1. Löschen Sie das JobSet. Diese Aktion löst aus, dass Kueue die zugehörigen benutzerdefinierten Slice-Ressourcen löscht.

    kubectl delete jobset JOBSET_NAME
    

    Ersetzen Sie JOBSET_NAME durch den Namen Ihres JobSets, z. B. big-super-slice.

  2. Löschen Sie den TPU-Knotenpool:

    gcloud container node-pools delete NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION
    

(Optional) Dynamisches Slicing mit Ihrem eigenen Scheduler verwenden

In diesem Dokument geht es um die Verwendung von Kueue und TAS. Sie können das dynamische Aufteilen jedoch auch mit einem eigenen benutzerdefinierten Scheduler verwalten. Wenn Sie einen anderen Scheduler verwenden möchten, folgen Sie den Referenzinformationen zur benutzerdefinierten Ressource „Slice“.

Nächste Schritte