Reinforcement Learning-Training mit mehreren Hosts für Gemma 4 26B auf TPU v6e ausführen

In dieser Anleitung erfahren Sie, wie Sie mit MaxText und Cluster Toolkit ein Multi-Host-Training für Reinforcement Learning (RL) auf einem Tensor Processing Unit (TPU)-Cluster (v6e-64) durchführen. Mit Cluster Toolkit führen Sie eine Multi-Host-Trainingsarbeitslast aus und exportieren die Ergebnisse zur Bereitstellung wieder in das Hugging Face-Format.

Ziele

  • Cluster Toolkit und seine Abhängigkeiten installieren
  • MaxText und seine Abhängigkeiten installieren
  • Cluster Toolkit-Cluster bereitstellen
  • Hugging Face-Modell in das MaxText-Format konvertieren
  • RL-Trainingsarbeitslast auf dem TPU v6e-Cluster ausführen
  • Das feinabgestimmte Modell zur Bereitstellung wieder in das Hugging Face-Format konvertieren

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Verwenden Sie den Preisrechner.

Neuen Google Cloud Nutzern vonsteht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

Für diese Anleitung benötigen Sie ein Hugging Face-Zugriffstoken. Sie können sich kostenlos bei Hugging Face registrieren. Nachdem Sie ein Konto haben, erstellen Sie ein Zugriffstoken:

  1. Klicken Sie auf der Seite Welcome to Hugging Face (Willkommen bei Hugging Face) auf Ihren Kontoavatar und wählen Sie Access tokens (Zugriffstokens) aus.
  2. Klicken Sie auf der Seite Access tokens (Zugriffstokens) auf Create new token (Neues Token erstellen).
  3. Wählen Sie den Tokentyp Read (Lesen) aus und geben Sie einen Namen für Ihr Token ein.
  4. Ihr Zugriffstoken wird angezeigt. Speichern Sie das Token an einem sicheren Ort.
  • Akzeptieren Sie auf der Hugging Face-Website die Lizenz vereinbarung für das Modell, das Sie trainieren möchten. In dieser Anleitung wird das Modell gemma4-26b verwendet.

Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Ausführen dieser Anleitung benötigen:

Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Umgebungsvariablen einrichten

Richten Sie die Umgebungsvariablen ein:

export PROJECT="YOUR_PROJECT_ID"
export REGION="YOUR_REGION"
export ZONE="YOUR_ZONE"
export CLUSTER_NAME="YOUR_CLUSTER_NAME"
export REPOSITORY_NAME="YOUR_REPOSITORY_NAME"
export GCS_BUCKET="YOUR_BUCKET_NAME"
export CLOUD_IMAGE_NAME="${REGION}-docker.pkg.dev/${PROJECT}/${REPOSITORY_NAME}/maxtext_base:latest"
export COMPUTE_TYPE="ct6e-standard-4t"
export TPU_TYPE="v6e-64"
export TOPOLOGY="8x8"
export CLUSTER_NODEPOOL_COUNT=1
export PW_CPU_MACHINE_TYPE="c4d-standard-96"
export RESERVATION="YOUR_RESERVATION_NAME"
export MODEL_NAME="gemma4-26b"
export HF_TOKEN="YOUR_HF_TOKEN"

Ersetzen Sie Folgendes:

  • YOUR_PROJECT_ID: die ID Ihres Google Cloud Projekts.
  • YOUR_REGION: die Region, in der Sie Ihren Cluster bereitstellen möchten.
  • YOUR_ZONE: die Zone, in der Sie Ihren Cluster bereitstellen möchten.
  • YOUR_CLUSTER_NAME: der Name Ihres Google Kubernetes Engine Clusters.
  • YOUR_REPOSITORY_NAME: der Name des Artifact Registry Repositorys für Ihre MaxText-Images.
  • YOUR_BUCKET_NAME: ein global eindeutiger Name für einen Cloud Storage-Bucket.
  • YOUR_RESERVATION_NAME: der Name Ihrer Reservierung.
  • YOUR_HF_TOKEN: Ihr Hugging Face-Zugriffstoken.

Cluster Toolkit-Abhängigkeiten installieren

Wenn Sie diese Anleitung auf einem Linux- oder macOS-Client oder einer Linux- oder macOS-Workstation ausführen möchten, folgen Sie der entsprechenden Anleitung unter Abhängigkeiten installieren in der Cluster Toolkit-Dokumentation.

Wenn Sie Cloud Shell verwenden, können Sie diesen Abschnitt überspringen.

Cluster Toolkit installieren

Installieren Sie das vorgefertigte Bundle für Cluster Toolkit gemäß der Anleitung unter Cluster Toolkit installieren.

MaxText-Container-Image vorbereiten

Führen Sie die folgenden Schritte aus, um Ihr MaxText-Container-Image vorzubereiten und die erforderlichen Abhängigkeiten zu installieren:

  1. Erstellen Sie einen Cloud Storage-Bucket:

    gcloud storage buckets create gs://$GCS_BUCKET --project=$PROJECT --location=$REGION || true
  2. Erstellen Sie ein Artifact Registry-Repository.

    gcloud artifacts repositories create ${REPOSITORY_NAME} \
        --repository-format=docker \
        --location=$REGION \
        --project=$PROJECT \
        --description="Docker repository for MaxText images in $REGION" || true
  3. Erstellen Sie im Stammverzeichnis Ihres Repositorys eine Datei mit dem Namen cloudbuild.yaml und dem folgenden Inhalt:

    steps:
      - name: 'gcr.io/cloud-builders/docker'
        entrypoint: 'bash'
        args:
          - '-c'
          - |
            set -euo pipefail
    
            # 0. Install prerequisites (if needed)
            apt-get update && apt-get install -y curl || apk add curl || true
    
            # 1. Install uv
            curl -LsSf https://astral.sh/uv/install.sh | sh
            source $$HOME/.local/bin/env
    
            # 2. Setup Python environment and install MaxText runner
            uv venv --python 3.12 --seed maxtext_venv
            source maxtext_venv/bin/activate
            uv pip install maxtext[runner]==0.2.4 --resolution=lowest
    
            # 3. Build the Docker image (Cloud Build has Docker pre-configured)
            build_maxtext_docker_image WORKFLOW=post-training
    
            # 4. Tag the image properly
            docker tag maxtext_base_image ${_CLOUD_IMAGE_NAME}
    
    # Cloud Build automatically pushes images listed here
    images:
      - '${_CLOUD_IMAGE_NAME}'
    
    options:
      machineType: 'E2_HIGHCPU_32'
  4. Erstellen Sie mit Cloud Build Ihr MaxText-Docker-Image:

    gcloud builds submit . \
        --project=$PROJECT \
        --region=$REGION \
        --substitutions=_CLOUD_IMAGE_NAME="${CLOUD_IMAGE_NAME}"

Cluster Toolkit-Cluster erstellen

Führen Sie die folgenden Schritte aus, um einen Cluster Toolkit-Cluster mit 64 v6e-TPU-Chips zu erstellen und bereitzustellen:

  1. Erstellen Sie eine benutzerdefinierte IAM-Rolle (Identity and Access Management) mit dem Namen gke.gcsfuse.profileUser:

    # The GKE TPU v6e blueprint uses GCS Fuse CSI Storage Profiles which requires a custom IAM role.
    # If this role is not already created in your project, you must create it before deploying.
    gcloud iam roles create gke.gcsfuse.profileUser \
      --project=${PROJECT} \
      --title="GKE GCSFuse Profile User" \
      --description="Allows scanning GCS buckets for objects, retrieving bucket metadata, and creating Anywhere Caches." \
      --permissions="storage.objects.list,storage.buckets.get,storage.anywhereCaches.create,storage.anywhereCaches.get,storage.anywhereCaches.list,storage.anywhereCaches.update"
  2. Erstellen Sie einen Cloud Storage-Bucket:

    gcloud storage buckets create gs://$GCS_BUCKET --project=$PROJECT --location=$REGION || true
  3. Standardmäßig hat das Dienstkonto Ihres Cluster-Knotenpools nicht die erforderlichen Berechtigungen, um in Ihren Cloud Storage-Bucket zu schreiben. Damit das Knotenpool-Dienstkonto in Ihren Cloud Storage-Bucket schreiben kann, müssen Sie ihm die Rolle Storage Admin zuweisen. Bearbeiten Sie dazu die Datei gke-tpu-v6e-advanced.yaml und aktualisieren Sie das service-account Modul mit dem Namen node_pool_service_account:

    - id: node_pool_service_account
      source: modules/project/service-account
      settings:
        name: gke-np-sa
        project_roles:
        - logging.logWriter
        - monitoring.metricWriter
        - monitoring.viewer
        - stackdriver.resourceMetadata.writer
        - storage.admin            # Change from storage.objectViewer
        - artifactregistry.reader
  4. Wenden Sie benutzerdefinierte Einstellungen auf den Block gke-tpu-v6e-cluster an, um die Standardeinstellungen für IPv6 und Maschinentyp zu überschreiben:

    - id: gke-tpu-v6e-cluster
      source: modules/scheduler/gke-cluster
      use: [gke-tpu-v6e-net-0, workload_service_account]
      settings:
        enable_private_ipv6_google_access: false
        system_node_pool_disk_size_gb: $(vars.system_node_pool_disk_size_gb)
        system_node_pool_taints: []
        enable_private_endpoint: false # Allows access from authorized public IPs
        enable_pathways_for_tpus: $(vars.enable_pathways_for_tpus)
        enable_dataplane_v2: true
        configure_workload_identity_sa: true
  5. Stellen Sie Ihren Cluster Toolkit-Cluster mit dem Blueprint gke-tpu-v6e-advanced.yaml bereit und übergeben Sie die erforderlichen Variablen mit dem Flag --vars:

    ./gcluster deploy examples/gke-tpu-v6e/gke-tpu-v6e-advanced.yaml \
        --vars "project_id=${PROJECT},deployment_name=${CLUSTER_NAME},region=${REGION},zone=${ZONE},num_slices=${CLUSTER_NODEPOOL_COUNT},tpu_topology=${TOPOLOGY},authorized_cidr=0.0.0.0/0,reservation=${RESERVATION:-}" \
        -l IGNORE --auto-approve -w

Modell in das MaxText-Format konvertieren

Wenn Sie das Modell im MaxText-Format trainieren möchten, müssen Sie es vom Hugging Face-Format in das MaxText-Format konvertieren.

  1. Nachdem Sie Ihren Cluster Toolkit-Cluster erstellt haben, konfigurieren Sie Docker:

    # Configure docker for pulling images
    gcloud auth configure-docker gcr.io --quiet
    gcloud auth configure-docker ${REGION}-docker.pkg.dev --quiet
  2. Konfigurieren Sie Ihr Standardprojekt, Ihren Standardcluster und Ihren Standardstandort, um nachfolgende Befehle zu vereinfachen:

    # Configure gcluster Defaults
    ./gcluster job config set project ${PROJECT}
    ./gcluster job config set cluster ${CLUSTER_NAME}
    ./gcluster job config set location ${REGION}
  3. Konvertieren Sie das Modell vom Hugging Face-Format in das MaxText-Format und speichern Sie es in Ihrem Cloud Storage-Bucket:

    ./gcluster job submit \
      --name="gemma4-hf-to-mt" \
      --cluster="${CLUSTER_NAME}" \
      --project="${PROJECT}" \
      --location="${REGION}" \
      --num-slices=1 \
      --image="${CLOUD_IMAGE_NAME}" \
      --compute-type="${COMPUTE_TYPE}" \
      --topology="${TOPOLOGY}" \
      --await-job-completion \
      --command="[ \"\$JOB_COMPLETION_INDEX\" != \"0\" ] || \
        python3 -m maxtext.checkpoint_conversion.to_maxtext \
        model_name=${MODEL_NAME} \
        hf_access_token=${HF_TOKEN} \
        --hf_model_path='google/gemma-4-26b-a4b-it' \
        base_output_directory=gs://${GCS_BUCKET}/${MODEL_NAME}/max-text-format/ \
        scan_layers=True \
        use_multimodal=False \
        skip_jax_distributed_system=true \
        checkpoint_storage_use_zarr3=0 \
        checkpoint_storage_use_ocdbt=0 \
        hardware=cpu \
        --lazy_load_tensors=True"
  4. Prüfen Sie den Status des Konvertierungsjobs:

    # Use the list command to check status
    ./gcluster job list \
        --cluster ${CLUSTER_NAME} \
        --project ${PROJECT} \
        --location ${REGION}
    
    # Check progress of the job (--main-only targets the coordinator pod (Job Index 0, Pod Index 0) to avoid duplicate logs from other workers)
    ./gcluster job logs gemma4-hf-to-mt --main-only -f \
        --cluster ${CLUSTER_NAME} \
        --project ${PROJECT} \
        --location ${REGION}

Trainingsarbeitslast starten

Nach Abschluss der Konvertierung starten Sie die RL-Trainingsarbeitslast:

./gcluster job submit \
  --name="gemma4-training" \
  --cluster="${CLUSTER_NAME}" \
  --project="${PROJECT}" \
  --location="${REGION}" \
  --num-slices=1 \
  --image="${CLOUD_IMAGE_NAME}" \
  --compute-type="${COMPUTE_TYPE}" \
  --topology="${TOPOLOGY}" \
  --pathways \
  --pathways-gcs-location="gs://${GCS_BUCKET}/pathways/" \
  --env="GRPC_DNS_RESOLVER=native" \
  --pathways-proxy-env="GRPC_DNS_RESOLVER=native" \
  --pathways-server-env="GRPC_DNS_RESOLVER=native" \
  --pathways-worker-env="GRPC_DNS_RESOLVER=native" \
  --command="export VLLM_HOST_IP=\$(hostname -I | awk '{print \$1}'); \
      python3 -c \"import pathlib, tpu_inference.layers.common.fused_moe_gmm as f; p = pathlib.Path(f.__file__); p.write_text(p.read_text().replace('onehot_moe_permute_threshold: int = 0,', 'onehot_moe_permute_threshold: int = 100000,'))\"; \
      JAX_PLATFORMS=proxy,cpu ENABLE_PATHWAYS_PERSISTENCE=1 \
      python3 -m maxtext.trainers.post_train.rl.train_rl \
      run_name=rl \
      base_output_directory=gs://${GCS_BUCKET}/${MODEL_NAME}/trained/ \
      model_name=${MODEL_NAME} \
      scan_layers=False \
      load_parameters_path=gs://${GCS_BUCKET}/${MODEL_NAME}/max-text-format/0/items/ \
      hf_access_token=${HF_TOKEN} \
      num_batches=50 \
      batch_size=8 \
      rollout_tensor_parallelism=2 \
      rollout_expert_parallelism=4 \
      trainer_devices_fraction=0.5 \
      sampler_devices_fraction=0.5 \
      tokenizer_path='google/gemma-4-26b-a4b-it' \
      ici_tensor_parallelism=2 \
      ici_expert_parallelism=4 \
      hbm_utilization_vllm=0.55 \
      remat_policy=full \
      async_scheduling=False \
      allow_split_physical_axes=true \
      ragged_gather_reduce_fallback=True \
      vllm_hf_overrides='{architectures: [\"MaxTextForCausalLM\"]}' \
      vllm_additional_config=\"{'maxtext_config': {'model_name': '${MODEL_NAME}', 'allow_split_physical_axes': 'true', 'use_ragged_sort': 'false', 'ragged_gather_reduce_fallback': 'true', 'prefuse_moe_weights': 'true', 'weight_dtype': 'bfloat16'}}\""

Prüfen Sie den Status des Trainingsjobs:

# Use the list command to check status
./gcluster job list \
    --cluster ${CLUSTER_NAME} \
    --project ${PROJECT} \
    --location ${REGION}

# Check progress of the job (--main-only targets the coordinator pod (Job Index 0, Pod Index 0) to avoid duplicate logs from other workers)
./gcluster job logs gemma4-training --main-only -f \
    --cluster ${CLUSTER_NAME} \
    --project ${PROJECT} \
    --location ${REGION}

Trainiertes Modell wieder in das Hugging Face-Format konvertieren

Nach Abschluss der Trainingsarbeitslast konvertieren Sie das Modell wieder in das Hugging Face-Format:

./gcluster job submit \
  --name="gemma4-mt-to-hf" \
  --cluster="${CLUSTER_NAME}" \
  --project="${PROJECT}" \
  --location="${REGION}" \
  --num-slices=1 \
  --image="${CLOUD_IMAGE_NAME}" \
  --compute-type="${COMPUTE_TYPE}" \
  --topology="${TOPOLOGY}" \
  --await-job-completion \
  --command="[ \"\$JOB_COMPLETION_INDEX\" != \"0\" ] || \
    python3 -m maxtext.checkpoint_conversion.to_huggingface \
      model_name=${MODEL_NAME} \
      hf_access_token=${HF_TOKEN} \
      load_parameters_path=gs://${GCS_BUCKET}/${MODEL_NAME}/trained/rl/checkpoints/actor/50/model_params/ \
      base_output_directory=gs://${GCS_BUCKET}/${MODEL_NAME}/hf-trained/ \
      skip_jax_distributed_system=true \
      hardware=cpu \
      scan_layers=True \
      use_multimodal=False \
      weight_dtype=bfloat16 \
      --override_model_architecture"

Prüfen Sie den Status des Konvertierungsjobs:

# Use the list command to check status
./gcluster job list \
    --cluster ${CLUSTER_NAME} \
    --project ${PROJECT} \
    --location ${REGION}

# Check progress of the job (--main-only targets the coordinator pod (Job Index 0, Pod Index 0) to avoid duplicate logs from other workers)
./gcluster job logs gemma4-mt-to-hf --main-only -f \
    --cluster ${CLUSTER_NAME} \
    --project ${PROJECT} \
    --location ${REGION}

# The trained model is now available in gs://${GCS_BUCKET}/${MODEL_NAME}/hf-trained/

Bereinigen

Löschen Sie die in dieser Anleitung erstellten Ressourcen, um zusätzliche Gebühren zu vermeiden:

./gcluster destroy ${CLUSTER_NAME} --robust
gcloud storage rm -r gs://${GCS_BUCKET}
gcloud artifacts repositories delete ${REPOSITORY_NAME} --location=${REGION} --project=${PROJECT} --quiet

# To delete the local deployment folder
rm -rf .ghpc ${CLUSTER_NAME}

Nächste Schritte