In dieser Anleitung erfahren Sie, wie Sie verteilte PyTorch-Arbeitslasten ausführen und ein Gemma 4-Modell auf Cloud TPU-Slices mit mehreren Hosts in Google Kubernetes Engine (GKE) optimieren. Dazu verwenden Sie Ray Core, Ray Train, PyTorch Fully Sharded Data Parallel (FSDP2) und TorchTPU.
Diese Anleitung richtet sich an Entwickler für maschinelles Lernen (ML), Plattformadministratoren und -operatoren sowie Daten- und KI-Spezialisten, die verteilte PyTorch-Trainingsarbeitslasten auf TPU-Slices mit mehreren Hosts in Kubernetes orchestrieren möchten. Weitere Informationen zu gängigen Rollen und Beispielaufgaben, auf die wir in Google Cloud -Inhalten verweisen, finden Sie unter Häufig verwendete GKE-Nutzerrollen und -Aufgaben.
Bevor Sie mit dieser Anleitung beginnen, sollten Sie mit Folgendem vertraut sein:
Hintergrund
In diesem Abschnitt werden die in dieser Anleitung verwendeten Schlüsseltechnologien beschrieben.
TPUs
Tensor Processing Units (TPUs) sind von Google speziell entwickelte Beschleuniger für Arbeitslasten des maschinellen Lernens. Diese Anleitung unterstützt sowohl TPU Trillium (v6e) als auch Ironwood (TPU7x). In einem TPU-Slice mit mehreren Hosts kommunizieren mehrere TPU-Hosts direkt über ein Hochgeschwindigkeits-ICI-Netzwerk (Inter-Chip Interconnect). Dadurch werden der aggregierte High Bandwidth Memory (HBM) und die kollektive Kommunikation mit niedriger Latenz bereitgestellt, die zum Trainieren von Modellen erforderlich sind, die die Speicherkapazität eines einzelnen Chips oder TPU-Hosts überschreiten.
TorchTPU
TorchTPU ist ein Open-Source-PyTorch-Backend für Cloud TPU, das in Zusammenarbeit von Google und Meta entwickelt wurde. Mit TorchTPU können Sie vorhandene PyTorch-Modelle mit minimalen Codeänderungen auf TPU-Hardware ausführen und Trainings- und Inferenzarbeitslasten über den XLA-Compiler (Accelerated Linear Algebra) von einem einzelnen Chip auf TPU-Pods mit mehreren Slices skalieren. TorchTPU verwendet ein Ausführungsmodell mit einem Prozess pro Gerät über das TPU-ICI-Netzwerk und unterstützt Standard-PyTorch-APIs, einschließlich sofortiger Ausführung, torch.compile, torch.distributed, DeviceMesh, DTensor und Fully Sharded Data Parallel (FSDP2).
KubeRay und Ray auf TPUs
KubeRay ist ein Kubernetes-Operator zum Bereitstellen und Verwalten von Ray-Anwendungen. Wenn Sie das Ray on GKE-Add-on aktivieren, werden der verwaltete KubeRay-Operator und der KubeRay-TPU-Webhook bereitgestellt. Wenn KubeRay Worker-Pods erstellt, die google.com/tpu-Ressourcen anfordern, konfiguriert der Webhook automatisch die Pod-Hostnamen, den monitorlosen Dienst und die TPU-Umgebungsvariablen, die für die Koordination mehrerer Hosts erforderlich sind.
Ray erkennt die TPU-Topologie auf jedem Knoten beim Start und plant verteilte Arbeitslasten über TPU-Slices hinweg. Sie können verteilte TorchTPU-Arbeitslasten auf zwei Ebenen orchestrieren:
- Ray Core bietet topologiebewusste Platzierungsgruppen und Akteurplanung für benutzerdefinierte verteilte Ausführungsschleifen, z. B. tensorparallele Berechnungen oder Pipelines für bestärkendes Lernen (Reinforcement Learning, RL).
- Ray Train bietet verwaltetes verteiltes datenparalleles und modellparalleles Training, einschließlich PyTorch Distributed Data Parallel (DDP), PyTorch FSDP2 und JAX Single Program, Multiple Data (SPMD), mit integrierter Prüfpunkterstellung und automatischer Fehlerbehebung.
Ziele
In dieser Anleitung wird Folgendes beschrieben:
- Erstellen Sie einen GKE-Cluster im Autopilot- oder Standardmodus auf TPU Trillium (v6e) oder Ironwood (TPU7x).
- Erstellen Sie ein Container-Image, das Ray- und Hugging Face-Trainingsbibliotheken über das TorchTPU-Basis-Image legt.
- Stellen Sie eine benutzerdefinierte RayCluster-Ressource bereit, um die Head- und TPU-Worker-Knoten bereitzustellen.
- Verteilte tensorparallele Berechnungen mit PyTorch
DeviceMeshundDTensorauf einem TPU-Slice mit Ray Core ausführen. - Feinabstimmung eines Gemma 4-Modells mit PyTorch FSDP2 über ein Multi-Host-TPU-Slice mit Ray Train.
Kosten
In dieser Anleitung verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in dieser Anleitung beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Hinweis
Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:
- Aktivieren Sie die Artifact Registry API, die Cloud Storage API und die Google Kubernetes Engine API. APIs aktivieren
- Wenn Sie die Google Cloud CLI für diese Aufgabe 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 updateab. Ältere gcloud CLI-Versionen unterstützen möglicherweise nicht die Ausführung der Befehle in diesem Dokument.
- Prüfen Sie, ob Ihr Projekt über ein ausreichendes Kontingent für TPU Trillium (v6e)- oder Ironwood (TPU7x)-Kapazität in der ausgewählten Zone verfügt. Weitere Informationen finden Sie unter Cloud TPU-Kontingente.
- Prüfen Sie, ob Ihr Konto die folgenden IAM-Rollen hat:
- Kubernetes Engine-Administrator (
roles/container.admin) - Artifact Registry-Administrator (
roles/artifactregistry.admin) - Storage-Administrator (
roles/storage.admin)
- Kubernetes Engine-Administrator (
Umgebung vorbereiten
In dieser Anleitung verwenden Sie Cloud Shell zum Verwalten von Ressourcen, die in Google Cloudgehostet werden. Die Software, die Sie für diese Anleitung benötigen, ist in Cloud Shell vorinstalliert, einschließlich kubectl, docker, python3 und der gcloud-Befehlszeile.
So richten Sie Ihre Umgebung mit Cloud Shell ein:
Starten Sie in der Google Cloud -Console eine Cloud Shell-Sitzung. Klicken Sie dazu in der Google Cloud -Console auf
Cloud Shell aktivieren. Dadurch wird im unteren Bereich der Google Cloud Console eine Sitzung gestartet.
Klonen Sie das Repository
kubernetes-engine-samplesund wechseln Sie in das Beispielverzeichnis für diese Anleitung:git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples/ai-ml/gke-ray/raytrain/torchtpuErstellen und aktivieren Sie eine lokale virtuelle Python-Umgebung mit installierter Ray-Befehlszeile:
python3 -m venv ~/ray-env source ~/ray-env/bin/activate pip install "ray[default]==2.58.0"Wenn Sie die Gemma 4-Modellgewichtungen herunterladen möchten, müssen Sie die Google-Lizenzvereinbarung auf Hugging Face akzeptieren:
- Rufen Sie die Gemma 4-Modellseite auf Hugging Face auf.
- Melden Sie sich an und akzeptieren Sie die Lizenzbedingungen, indem Sie auf Agree and access repository klicken.
- Generieren Sie in den Einstellungen Ihres Hugging Face-Kontos ein Nutzerzugriffstoken mit
Read-Berechtigungen.
Legen Sie die Umgebungsvariablen für Ihr Google Cloud -Projekt, Ihren Cluster, Ihren Cloud Storage-Bucket und Ihr Hugging Face-Token fest:
export PROJECT_ID=PROJECT_ID export CLUSTER_NAME=CLUSTER_NAME export REGION=REGION export ZONE=ZONE export ARTIFACT_REGISTRY=ARTIFACT_REGISTRY export BUCKET_NAME=BUCKET_NAME export HF_TOKEN=HF_TOKEN export IMAGE_URI=${REGION}-docker.pkg.dev/${PROJECT_ID}/${ARTIFACT_REGISTRY}/ray-torchtpu:latest gcloud config set project ${PROJECT_ID}Ersetzen Sie Folgendes:
PROJECT_ID: Projekt-ID in Google Cloud .CLUSTER_NAME: der Name Ihres GKE-Cluster, z. B.ray-torchtpu-cluster.REGION: Die Region, in der sich Ihr Artifact Registry-Repository, Ihr Cloud Storage-Bucket und Ihre TPU-Kapazität befinden.ZONE: die Zone, in der Ihre TPU-Kapazität verfügbar ist. Informationen zu den verfügbaren Regionen und Zonen nach TPU-Version finden Sie unter TPU-Regionen und -Zonen.ARTIFACT_REGISTRY: der Name Ihres Artifact Registry-Docker-Repositorys, z. B.ray-torchtpu.BUCKET_NAME: der Name Ihres Cloud Storage-Bucket zum Speichern von Ray Train-Prüfpunkten, z. B.PROJECT_ID-ray-torchtpu.HF_TOKEN: Ihr Hugging Face-Zugriffstoken.
GKE-Cluster erstellen
Sie können verteilte TorchTPU-Trainingsarbeitslasten in einem GKE Autopilot- oder Standardcluster mit aktiviertem verwalteten Ray-Operator-Add-on ausführen.
Erstellen Sie Ihren GKE-Cluster und konfigurieren Sie die Anmeldedaten für das
kubectl-Befehlszeilentool:Autopilot
Erstellen Sie einen regionalen GKE Autopilot-Cluster mit aktiviertem Ray-Operator-Add-on:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --region=${REGION} \ --cluster-version=1.36 \ --enable-ray-operatorWenn Sie die benutzerdefinierte RayCluster-Ressource in einem späteren Schritt bereitstellen, stellt GKE Autopilot automatisch den CPU-Head-Knoten und das Multi-Host-TPU-Slice bereit, die Ihren Pod-Ressourcenanfragen und Knotenselektoren entsprechen.
Konfigurieren Sie das
kubectl-Befehlszeilentool für die Kommunikation mit Ihrem Cluster:gcloud container clusters get-credentials ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --region=${REGION}
Standard
Erstellen Sie einen zonalen GKE Standard-Cluster mit einem CPU-Knotenpool zum Hosten des Ray-Head-Pods, Image-Streaming, GKE Dataplane V2 und Workload Identity-Föderation für GKE aktiviert:
gcloud container clusters create ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --zone=${ZONE} \ --cluster-version=1.36 \ --machine-type=n2-standard-8 \ --num-nodes=1 \ --addons=RayOperator \ --enable-image-streaming \ --enable-dataplane-v2 \ --workload-pool=${PROJECT_ID}.svc.id.googKonfigurieren Sie das
kubectl-Befehlszeilentool für die Kommunikation mit Ihrem Cluster:gcloud container clusters get-credentials ${CLUSTER_NAME} \ --project=${PROJECT_ID} \ --zone=${ZONE}Erstellen Sie einen TPU-Slice-Knotenpool mit mehreren Hosts und 16 Geräten mit einer
4x4-Topologie auf vier Hosts auf TPU Trillium (v6e) oder einer2x2x2-Topologie auf zwei Hosts auf Ironwood (TPU7x):Trillium (v6e)
gcloud container node-pools create tpu-multi-host-pool \ --project=${PROJECT_ID} \ --cluster=${CLUSTER_NAME} \ --zone=${ZONE} \ --machine-type=ct6e-standard-4t \ --tpu-topology=4x4 \ --num-nodes=4Ironwood (TPU7x)
gcloud container node-pools create tpu-multi-host-pool \ --project=${PROJECT_ID} \ --cluster=${CLUSTER_NAME} \ --zone=${ZONE} \ --machine-type=tpu7x-standard-4t \ --tpu-topology=2x2x2 \ --num-nodes=2
Erstellen Sie einen Cloud Storage-Bucket, um freigegebene Ray Train-Prüfpunkte auf den TPU-Knoten mit mehreren Hosts zu speichern, und gewähren Sie der Kubernetes-ServiceAccount-Ressource
defaultZugriff auf den Bucket:gcloud storage buckets create gs://${BUCKET_NAME} --location=${REGION} PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") gcloud storage buckets add-iam-policy-binding gs://${BUCKET_NAME} \ --member="principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/default/sa/default" \ --role="roles/storage.objectAdmin"Erstellen Sie ein Kubernetes-Secret mit Ihrem Hugging Face-Zugriffstoken, damit Ray-Pods die geschützten Gemma 4-Gewichtungen herunterladen können:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=${HF_TOKEN}
Container-Image erstellen
Erstellen Sie ein Container-Image, das Ray und die Hugging Face-Trainingsbibliotheken zusätzlich zum vordefinierten TorchTPU-Basis-Image installiert, das TorchTPU und die libtpu-Bibliothek enthält.
Erstellen Sie ein Artifact Registry-Docker-Repository und konfigurieren Sie die Docker-Authentifizierung:
gcloud artifacts repositories create ${ARTIFACT_REGISTRY} \ --repository-format=docker \ --location=${REGION} gcloud auth configure-docker ${REGION}-docker.pkg.dev,us-docker.pkg.devPrüfen Sie die
Dockerfileim Beispielverzeichnis:Für das Single-Slice-Training mit der Ray-Klasse
TorchTrainerund die Planung pro Chiplet auf Ironwood (TPU7x) ist Ray Version 2.58.0 oder höher erforderlich. Für die Feinabstimmung von Gemma 4 ist dietransformers-Bibliothek Version 5.5.0 oder höher erforderlich.Erstellen Sie das Image und übertragen Sie es per Push in die Artifact Registry:
docker build -t ${IMAGE_URI} . docker push ${IMAGE_URI}
Benutzerdefinierte RayCluster-Ressource bereitstellen
Stellen Sie eine benutzerdefinierte RayCluster-Ressource bereit, die einen CPU-Head-Pod, ein In-Memory-/dev/shm-Volume für den Ray-Objektspeicher mit gemeinsamem Arbeitsspeicher und eine Multi-Host-TPU-Worker-Gruppe bereitstellt.
Sehen Sie sich das RayCluster-Manifest für Ihre TPU-Version im Beispiel-Repository an:
Trillium (v6e)
Ironwood (TPU7x)
Auf Ironwood (TPU7x) enthält jeder physische Chip zwei Chiplets, was acht logische TPU-Kerne pro Host mit vier Chips ergibt. Im Manifest wird der Wert des Felds
TPUim Abschnittresourcesauf"8"festgelegt. Außerdem wird die UmgebungsvariableRAY_TPU_RESOURCE_PER_CHIPauf"2"gesetzt, um acht logischeTPU-Ressourcen pro Host anzukündigen und zu planen.Wenden Sie das Manifest an, um die benutzerdefinierte RayCluster-Ressource zu erstellen:
Trillium (v6e)
envsubst < ray-cluster.tpu-v6e-multihost.yaml | kubectl apply -f -Ironwood (TPU7x)
envsubst < ray-cluster.tpu-v7x-multihost.yaml | kubectl apply -f -Warten Sie, bis der RayCluster-Head-Pod und alle TPU-Worker-Pods den Status
Runningerreicht haben:kubectl get pods -l ray.io/cluster=ray-torchtpu-clusterDie Ausgabe sieht etwa so aus:
Trillium (v6e)
NAME READY STATUS RESTARTS AGE ray-torchtpu-cluster-head-pdpk6 1/1 Running 0 2m30s ray-torchtpu-cluster-v6e-16-worker-brwpc 1/1 Running 0 2m30s ray-torchtpu-cluster-v6e-16-worker-dx4w7 1/1 Running 0 2m30s ray-torchtpu-cluster-v6e-16-worker-h4d4w 1/1 Running 0 2m30s ray-torchtpu-cluster-v6e-16-worker-t2g24 1/1 Running 0 2m30sIronwood (TPU7x)
NAME READY STATUS RESTARTS AGE ray-torchtpu-cluster-head-k9x2m 1/1 Running 0 2m30s ray-torchtpu-cluster-tpu7x-16-worker-7cwpq 1/1 Running 0 2m30s ray-torchtpu-cluster-tpu7x-16-worker-m98r9 1/1 Running 0 2m30sPrüfen Sie die Umgebungsvariablen auf einem der Worker-Pods, um zu bestätigen, dass der KubeRay-TPU-Webhook die TPU-Koordinations- und TorchTPU-Topologievariablen für mehrere Hosts eingefügt hat:
kubectl get pods -l ray.io/node-type=worker \ -o=jsonpath='{range .items[0].spec.containers[0].env[*]}{.name}={.value}{"\n"}{end}' \ | grep -E "TPU_WORKER_ID|TPU_WORKER_HOSTNAMES|TPU_NAME|TORCH_TPU_TOPOLOGY|TORCH_TPU_SLICEBUILDER_ADDRESSES"Die Ausgabe sieht etwa so aus:
Trillium (v6e)
TPU_WORKER_HOSTNAMES=v6e-16-0-0.ray-torchtpu-cluster-headless,v6e-16-0-1.ray-torchtpu-cluster-headless,v6e-16-0-2.ray-torchtpu-cluster-headless,v6e-16-0-3.ray-torchtpu-cluster-headless TORCH_TPU_TOPOLOGY=4,4,1 TORCH_TPU_SLICEBUILDER_ADDRESSES=v6e-16-0-0.ray-torchtpu-cluster-headless:8471,v6e-16-0-0.ray-torchtpu-cluster-headless:8472,v6e-16-0-0.ray-torchtpu-cluster-headless:8473,v6e-16-0-0.ray-torchtpu-cluster-headless:8474,v6e-16-0-1.ray-torchtpu-cluster-headless:8471,v6e-16-0-1.ray-torchtpu-cluster-headless:8472,v6e-16-0-1.ray-torchtpu-cluster-headless:8473,v6e-16-0-1.ray-torchtpu-cluster-headless:8474,v6e-16-0-2.ray-torchtpu-cluster-headless:8471,v6e-16-0-2.ray-torchtpu-cluster-headless:8472,v6e-16-0-2.ray-torchtpu-cluster-headless:8473,v6e-16-0-2.ray-torchtpu-cluster-headless:8474,v6e-16-0-3.ray-torchtpu-cluster-headless:8471,v6e-16-0-3.ray-torchtpu-cluster-headless:8472,v6e-16-0-3.ray-torchtpu-cluster-headless:8473,v6e-16-0-3.ray-torchtpu-cluster-headless:8474 TPU_WORKER_ID=3 TPU_NAME=v6e-16-0Ironwood (TPU7x)
TPU_WORKER_HOSTNAMES=tpu7x-16-0-0.ray-torchtpu-cluster-headless,tpu7x-16-0-1.ray-torchtpu-cluster-headless TORCH_TPU_TOPOLOGY=2,2,2,2 TORCH_TPU_SLICEBUILDER_ADDRESSES=tpu7x-16-0-0.ray-torchtpu-cluster-headless:8471,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8472,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8473,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8474,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8475,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8476,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8477,tpu7x-16-0-0.ray-torchtpu-cluster-headless:8478,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8471,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8472,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8473,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8474,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8475,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8476,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8477,tpu7x-16-0-1.ray-torchtpu-cluster-headless:8478 TPU_WORKER_ID=1 TPU_NAME=tpu7x-16-0Richten Sie eine Portweiterleitungssitzung zum Ray-Head-Dienst ein:
kubectl port-forward svc/ray-torchtpu-cluster-head-svc 8265:8265 >/dev/null 2>&1 &Sie können die TPU-Worker-Knoten und ihre automatisch erkannten
ray.io/tpu-*-Labels auf dem Tab Cluster des Ray-Dashboards prüfen.
Verteilte Tensor-Parallelität mit Ray Core ausführen
Ray Core bietet die Funktion slice_placement_group im Modul ray.util.tpu, um ein intaktes TPU-Slice mit mehreren Hosts zu reservieren, und die Klasse PlacementGroupSchedulingStrategy, um einen Ray-Akteur pro logischem TPU-Gerät im Slice zu planen.
Sehen Sie sich das Script
ray_core_collectives.pyim Beispiel-Repository an:Das Script führt die verteilte Tensor-Parallelität auf dem TPU-Slice in drei Schritten aus:
- Die Funktion
slice_placement_groupreserviert ein TPU-Slice mit 16 Geräten und plant einenTorchTPUSliceWorker-Actor auf jedem TPU-Gerät. - Jeder Akteur berechnet seinen globalen Rang aus seinem Hostindex und seiner lokalen Geräte-ID und initialisiert dann die Prozessgruppe
tpu_dist. - Die Funktionen
init_device_meshundparallelize_moduleteilen die Feedforward-Ebenen auf alle 16 TPU-Geräte auf, vergleichen die Ausgabe mit einer CPU-Referenz auf einem einzelnen Gerät und führen einall_reduce-Kollektiv über ICI aus.
- Die Funktion
Senden Sie den Ray Core-Job für Ihre TPU-Version:
Trillium (v6e)
ray job submit \ --address http://localhost:8265 \ --working-dir . \ --runtime-env-json '{"excludes": ["ray-env", ".git", "*.whl"]}' \ -- python3 ray_core_collectives.py --topology=4x4 --accelerator-type=TPU-V6EIronwood (TPU7x)
ray job submit \ --address http://localhost:8265 \ --working-dir . \ --runtime-env-json '{"excludes": ["ray-env", ".git", "*.whl"]}' \ -- python3 ray_core_collectives.py --topology=2x2x2 --accelerator-type=TPU-V7XDie Ausgabe sieht etwa so aus:
Trillium (v6e)
Rank 0 (worker_id=0, local_rank=0, ip=10.72.3.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 1 (worker_id=0, local_rank=1, ip=10.72.3.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 2 (worker_id=0, local_rank=2, ip=10.72.3.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 3 (worker_id=0, local_rank=3, ip=10.72.3.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 4 (worker_id=1, local_rank=0, ip=10.72.14.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 5 (worker_id=1, local_rank=1, ip=10.72.14.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 6 (worker_id=1, local_rank=2, ip=10.72.14.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 7 (worker_id=1, local_rank=3, ip=10.72.14.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 8 (worker_id=2, local_rank=0, ip=10.72.7.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 9 (worker_id=2, local_rank=1, ip=10.72.7.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 10 (worker_id=2, local_rank=2, ip=10.72.7.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 11 (worker_id=2, local_rank=3, ip=10.72.7.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 12 (worker_id=3, local_rank=0, ip=10.72.6.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 13 (worker_id=3, local_rank=1, ip=10.72.6.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 14 (worker_id=3, local_rank=2, ip=10.72.6.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 15 (worker_id=3, local_rank=3, ip=10.72.6.20): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] All 16 TorchTPU ranks verified DTensor TP parity (max_abs_diff=0.002470) and all_reduce sum = 136.0 ------------------------------------------ Job 'raysubmit_HFTkKrjSnfza3ZFD' succeeded ------------------------------------------Ironwood (TPU7x)
Rank 0 (worker_id=0, local_rank=0, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 1 (worker_id=0, local_rank=1, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 2 (worker_id=0, local_rank=2, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 3 (worker_id=0, local_rank=3, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 4 (worker_id=0, local_rank=4, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 5 (worker_id=0, local_rank=5, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 6 (worker_id=0, local_rank=6, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 7 (worker_id=0, local_rank=7, ip=172.16.14.6): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 8 (worker_id=1, local_rank=0, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 9 (worker_id=1, local_rank=1, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 10 (worker_id=1, local_rank=2, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 11 (worker_id=1, local_rank=3, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 12 (worker_id=1, local_rank=4, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 13 (worker_id=1, local_rank=5, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 14 (worker_id=1, local_rank=6, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] Rank 15 (worker_id=1, local_rank=7, ip=172.16.15.7): all_reduce_sum=[136.0, 136.0, 136.0, 136.0] All 16 TorchTPU ranks verified DTensor TP parity (max_abs_diff=0.002470) and all_reduce sum = 136.0 ------------------------------------------ Job 'raysubmit_MrJbAe3hvARBcBN2' succeeded ------------------------------------------
Gemma 4-Modell mit Ray Train und PyTorch FSDP2 optimieren
Die Ray Train-Klasse TorchTrainer automatisiert die TPU-Slice-Reservierung, die Worker-Platzierung und die torch.distributed-Initialisierung über ein TPU-Slice mit mehreren Hosts.
Sehen Sie sich das Script
ray_train_llm_finetune.pyim Beispiel-Repository an, mit dem das Modellgoogle/gemma-4-E2B-itanhand des Anweisungs-Datasetsdatabricks/databricks-dolly-15koptimiert wird:Das Script konfiguriert die Klasse
TorchTrainermit den folgenden Komponenten:- Die Klasse
ScalingConfigkonfiguriert die verteilte Worker-Topologie für den Trainingsjob. Wenn Sie die Parameteruse_tpu=True,num_workers=16,topologyundaccelerator_typefestlegen, wird ein TPU-Slice mit 16 Geräten reserviert und ein Worker pro TPU-Kern geplant. - Die Klasse
TorchConfigkonfiguriert die Prozessgruppetorch.distributedauf den Workern. Wenn Sie den Parameterbackend="tpu_dist"festlegen, werden alle 16 Worker über das TPU-ICI-Netzwerk verbunden, bevor die Funktiontrain_funcausgeführt wird. - Die Funktion
create_dataloaderlädt das Anweisungs-Dataset herunter und tokenisiert es, fasst die Token-Sequenzen mit einem PyTorch-DataLoader-Objekt zusammen und ruft die Funktionray.train.torch.prepare_data_loaderauf, damit jeder Worker ein disjunktes Shard jedes globalen Batches auf seinem zugewiesenen TPU-Gerät erhält. - Die Funktion
train_funclädt das Modell mit der Genauigkeitbfloat16und ruft die PyTorch FSDP2-Funktionfully_shardfür jeden Feedforward-Block und das Stammmodell auf, um Parameter, Gradienten und Optimierungszustände auf alle 16 TPU-Kerne zu verteilen. - Die Klasse
Checkpointund die Funktionray.train.reporterfassen am Ende jeder Epoche das vollständige Modellstatus-Dictionary auf Rang 0 und laden den Prüfpunkt in Ihren Cloud Storage-Bucket hoch.
- Die Klasse
Senden Sie den
TorchTrainer-FSDP2-Feinabstimmungsjob für Ihre TPU-Version:Trillium (v6e)
ray job submit \ --address http://localhost:8265 \ --working-dir . \ --runtime-env-json '{"excludes": ["ray-env", ".git", "*.whl"]}' \ -- python3 ray_train_llm_finetune.py \ --topology=4x4 \ --accelerator-type=TPU-V6E \ --storage-path=gs://${BUCKET_NAME}/ray_train_torchtpuIronwood (TPU7x)
ray job submit \ --address http://localhost:8265 \ --working-dir . \ --runtime-env-json '{"excludes": ["ray-env", ".git", "*.whl"]}' \ -- python3 ray_train_llm_finetune.py \ --topology=2x2x2 \ --accelerator-type=TPU-V7X \ --storage-path=gs://${BUCKET_NAME}/ray_train_torchtpuDie Ausgabe sieht etwa so aus:
Trillium (v6e)
Starting Ray Train FSDP2 SFT job: model=google/gemma-4-E2B-it, topology=4x4, accelerator_type=TPU-V6E, num_workers=16 (TrainController pid=5407) Attempting to start training worker group of size 16 with the following resources: [{'TPU': 1, 'accelerator_type:TPU-V6E': 0.001}] * 16 (RayTrainWorker pid=19733, ip=10.72.3.20) Setting up process group for: env:// [rank=0, world_size=16] (RayTrainWorker pid=19733, ip=10.72.3.20) Epoch 1/3 | loss=3.1402 | epoch_time=28.17s | tokens/s=18613.5 (RayTrainWorker pid=19733, ip=10.72.3.20) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791864427/checkpoint_2026-10-13_04-08-10.762175) (RayTrainWorker pid=19733, ip=10.72.3.20) Epoch 2/3 | loss=2.3318 | epoch_time=26.07s | tokens/s=20112.8 (RayTrainWorker pid=19733, ip=10.72.3.20) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791864427/checkpoint_2026-10-13_04-10-02.548088) (RayTrainWorker pid=19733, ip=10.72.3.20) Epoch 3/3 | loss=2.2050 | epoch_time=25.52s | tokens/s=20545.2 (RayTrainWorker pid=19733, ip=10.72.3.20) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791864427/checkpoint_2026-10-13_04-11-48.701853) Training completed! Final metrics: {'epoch': 3, 'loss': 2.205, 'epoch_time_s': 25.52, 'tokens_per_s': 20545.2} Saved checkpoint: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791864427/checkpoint_2026-10-13_04-11-48.701853) ------------------------------------------ Job 'raysubmit_zbm4pnFZitA1YECA' succeeded ------------------------------------------Ironwood (TPU7x)
Starting Ray Train FSDP2 SFT job: model=google/gemma-4-E2B-it, topology=2x2x2, accelerator_type=TPU-V7X, num_workers=16 (TrainController pid=1162) Attempting to start training worker group of size 16 with the following resources: [{'TPU': 1, 'accelerator_type:TPU-V7X': 0.001}] * 16 (RayTrainWorker pid=257, ip=172.16.26.6) Setting up process group for: env:// [rank=0, world_size=16] (RayTrainWorker pid=257, ip=172.16.26.6) Epoch 1/3 | loss=3.1407 | epoch_time=26.28s | tokens/s=19953.3 (RayTrainWorker pid=257, ip=172.16.26.6) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791867004/checkpoint_2026-10-13_04-52-00.026930) (RayTrainWorker pid=257, ip=172.16.26.6) Epoch 2/3 | loss=2.3235 | epoch_time=16.68s | tokens/s=31429.9 (RayTrainWorker pid=257, ip=172.16.26.6) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791867004/checkpoint_2026-10-13_04-53-33.533341) (RayTrainWorker pid=257, ip=172.16.26.6) Epoch 3/3 | loss=2.1964 | epoch_time=16.98s | tokens/s=30884.6 (RayTrainWorker pid=257, ip=172.16.26.6) Checkpoint successfully created at: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791867004/checkpoint_2026-10-13_04-55-01.508219) Training completed! Final metrics: {'epoch': 3, 'loss': 2.1964, 'epoch_time_s': 16.98, 'tokens_per_s': 30884.6} Saved checkpoint: Checkpoint(filesystem=gcs, path=my-project-ray-torchtpu/ray_train_torchtpu/torchtpu_gemma4_fsdp2_sft_1791867004/checkpoint_2026-10-13_04-55-01.508219) ------------------------------------------ Job 'raysubmit_zSNnCXhHkwKiSmJh' succeeded ------------------------------------------Die Trainingsausgabe sieht so aus:
- Epoche 1 umfasst die anfängliche XLA-Grafikkompilierung. In den Epochen 2 und 3 werden die im Cache gespeicherten ausführbaren Dateien aus
/dev/shm/torch_tpu_cachewiederverwendet. Dabei werden über 20.000 Tokens pro Sekunde auf TPU Trillium (v6e) und 31.000 Tokens pro Sekunde auf Ironwood (TPU7x) erreicht. - Der globale Kreuzentropieverlust, der über alle 16 FSDP2-Worker-Ränge synchronisiert wird, sinkt von 3,14 in Epoche 1 auf 2,20 in Epoche 3 über die drei Feinabstimmungsepochen im
databricks/databricks-dolly-15k-Anweisungs-Dataset. - Am Ende jeder Epoche erfasst Rang 0 das vollständige Modellstatus-Dictionary und lädt den Prüfpunkt in Ihren Cloud Storage-Bucket hoch. Dabei wird der Prüfpunkt mit dem geringsten Verlust beibehalten, wie im
CheckpointConfig(num_to_keep=1, checkpoint_score_attribute="loss", checkpoint_score_order="min")-Objekt konfiguriert.
- Epoche 1 umfasst die anfängliche XLA-Grafikkompilierung. In den Epochen 2 und 3 werden die im Cache gespeicherten ausführbaren Dateien aus
Arbeitslastleistung beobachten
Informationen zum Überwachen der TPU-TensorCore-Auslastung, der HBM-Nutzung und der Ray-Cluster-Messwerte in Cloud Monitoring finden Sie unter Logs und Messwerte für Ray-Cluster in GKE erfassen und ansehen und TPU-Messwerte im Ray-Dashboard ansehen.
Auf das Ray-Dashboard zugreifen
So prüfen Sie den Status Ihrer Ray-Akteure, Platzierungsgruppen und Trainingsjobs im integrierten Ray-Dashboard:
Wenn die Portweiterleitung zum Ray-Head-Dienst noch nicht ausgeführt wird, starten Sie sie im Hintergrund:
kubectl port-forward svc/ray-torchtpu-cluster-head-svc 8265:8265 >/dev/null 2>&1 &Klicken Sie in Cloud Shell auf
Webvorschau und wählen Sie Vorschau auf Port 8265 aus oder öffnen Sie
http://localhost:8265in Ihrem lokalen Browser.Klicken Sie auf die Tabs Jobs, Cluster und Messwerte, um Worker-Logs, den Status der Platzierungsgruppe, TPU-Knotenlabels und das Diagramm TPU-Auslastung nach Knoten zu prüfen.
Bereinigen
Damit Ihrem Google Cloud Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie die benutzerdefinierte RayCluster-Ressource, den GKE-Cluster, den Cloud Storage-Bucket und das Artifact Registry-Repository:
Beenden Sie den Portweiterleitungsprozess im Hintergrund und löschen Sie die benutzerdefinierte RayCluster-Ressource und das Kubernetes-Secret:
pkill -f "kubectl port-forward" || true kubectl delete raycluster ray-torchtpu-cluster kubectl delete secret hf-secret --ignore-not-foundLöschen Sie den GKE-Cluster:
Autopilot
gcloud container clusters delete ${CLUSTER_NAME} \ --region=${REGION}Standard
gcloud container clusters delete ${CLUSTER_NAME} \ --zone=${ZONE}Löschen Sie den Cloud Storage-Bucket und seinen Prüfpunktinhalt:
gcloud storage rm --recursive gs://${BUCKET_NAME}Löschen Sie das Artifact Registry-Repository:
gcloud artifacts repositories delete ${ARTIFACT_REGISTRY} \ --location=${REGION}
Nächste Schritte
- Weitere Informationen zu PyTorch auf Cloud TPU
- TorchTPU-Dokumentation lesen
- LLMs auf TPUs mit mehreren Hosts mit Ray und TorchTPU bereitstellen
- KI-Training auf TPUs mit DWS und Kueue optimieren
- TPUs in GKE
- Ray Train-Dokumentation lesen