Présentation de Trillium (v6e)

v6e est utilisé pour désigner Trillium dans cette documentation, l'API TPU et les journaux. v6e représente la 6e génération de TPU de Google.

Avec 256 puces par pod, l'architecture v6e présente de nombreuses similitudes avec la version v5e. Ce système est optimisé pour l'entraînement, l'ajustement et la diffusion des transformateurs, du texte en image et des réseaux de neurones convolutifs (CNN).

Pour en savoir plus sur l'architecture et les configurations du système v6e, consultez la page TPU v6e.

Ce document d'introduction se concentre sur les processus d'entraînement et de diffusion des modèles à l'aide des frameworks JAX, PyTorch ou TensorFlow. Avec chaque framework, vous pouvez provisionner des TPU à l'aide de ressources mises en file d'attente ou de GKE. La configuration de GKE peut être effectuée à l'aide de XPK ou de commandes GKE.

Procédure générale pour entraîner ou diffuser un modèle à l'aide de la version v6e

  1. Préparer un Google Cloud projet
  2. Capacité sécurisée
  3. Provisionner l'environnement Cloud TPU
  4. Exécuter une charge de travail d'entraînement ou d'inférence de modèle

Préparer un projet Google Cloud

Avant de pouvoir utiliser Cloud TPU, vous devez:

  • Créer un Google Cloud compte et un projet avec la facturation activée
  • Installer les composants alpha de la Google Cloud CLI
  • Activer l'API Cloud TPU
  • Créer un agent de service Cloud TPU
  • Créer un compte de service Cloud TPU et accorder des autorisations

Pour en savoir plus, consultez Configurer l'environnement Cloud TPU.

Sécuriser la capacité

Contactez l'assistanceGoogle Cloud pour demander un quota Cloud TPU v6e et répondre à vos questions sur la capacité.

Provisionner l'environnement Cloud TPU

Les Cloud TPU v6e peuvent être provisionnés et gérés avec GKE, avec GKE et XPK (un outil de ligne de commande wrapper sur GKE), ou en tant que ressources mises en file d'attente.

Prérequis

  • Vérifiez que votre projet dispose d'un quota TPUS_PER_TPU_FAMILY suffisant, qui spécifie le nombre maximal de chips auxquels vous pouvez accéder dans votre projet Google Cloud.
  • La version v6e a été testée avec la configuration suivante :
    • Python 3.10 ou version ultérieure
    • Versions logicielles nocturnes :
      • JAX par nuit : 0.4.32.dev20240912
      • LibTPU 0.1.dev20240912+nightly nocturne
    • Versions logicielles stables :
      • JAX + JAX Lib de la version 0.4.37
  • Vérifiez que votre projet dispose d'un quota suffisant pour:

    • Quota de VM Cloud TPU
    • Quota d'adresses IP
    • Quota Hyperdisk équilibré

  • Si vous utilisez GKE avec XPK, consultez la section Autorisations de la console Cloud sur le compte utilisateur ou de service pour connaître les autorisations requises pour exécuter XPK.

Créez des variables d'environnement

Dans Cloud Shell, créez les variables d'environnement suivantes:

export NODE_ID=your-tpu-name
export PROJECT_ID=your-project-id
export ACCELERATOR_TYPE=v6e-16
export ZONE=us-east1-d
export RUNTIME_VERSION=v2-alpha-tpuv6e
export SERVICE_ACCOUNT=your-service-account
export QUEUED_RESOURCE_ID=your-queued-resource-id
export VALID_DURATION=your-duration 

# Additional environment variable needed for Multislice:
export NUM_SLICES=number-of-slices

# Use a custom network for better performance as well as to avoid having the default network becoming overloaded.

export NETWORK_NAME=${PROJECT_ID}-mtu9k
export NETWORK_FW_NAME=${NETWORK_NAME}-fw

Description des options de commande

Variable Description
NODE_ID ID attribué par l'utilisateur du Cloud TPU créé lors de l'allocation de la demande de ressources en file d'attente.
PROJECT_ID Google Cloud nom du projet. Utilisez un projet existant ou créez-en un. Pour en savoir plus, consultez Configurer votre projet Google Cloud .
ZONE Pour connaître les zones compatibles, consultez le document Régions et zones Cloud TPU.
ACCELERATOR_TYPE Consultez la section Types d'accélérateurs.
RUNTIME_VERSION v2-alpha-tpuv6e
SERVICE_ACCOUNT Il s'agit de l'adresse e-mail de votre compte de service, que vous pouvez trouver dans Google Cloud Console -> IAM -> Comptes de service.

Par exemple : tpu-service-account@your-project-ID.iam.gserviceaccount.com.com

NUM_SLICES Nombre de tranches à créer (nécessaire pour Multislice uniquement).
QUEUED_RESOURCE_ID ID de texte attribué par l'utilisateur à la requête de ressource mise en file d'attente.
VALID_DURATION Durée de validité de la requête de ressource mise en file d'attente.
NETWORK_NAME Nom d'un réseau secondaire à utiliser.
NETWORK_FW_NAME Nom d'un pare-feu réseau secondaire à utiliser.

Optimiser les performances du réseau

Pour des performances optimales,utilisez un réseau avec une MTU (unité de transmission maximale) de 8 896.

Par défaut, un cloud privé virtuel (VPC) ne fournit qu'une MTU de 1 460 octets,ce qui offre des performances réseau non optimales. Vous pouvez définir la MTU d'un réseau VPC sur n'importe quelle valeur comprise entre 1 300 octets et 8 896 octets (inclus). Les tailles de MTU personnalisées les plus courantes sont de 1 500 octets (Ethernet standard) ou de 8 896 octets (le maximum possible). Pour en savoir plus, consultez la section Tailles de MTU valides pour le réseau VPC.

Pour en savoir plus sur la modification du paramètre MTU d'un réseau existant ou par défaut, consultez la page Modifier le paramètre de MTU d'un réseau VPC.

L'exemple suivant crée un réseau avec 8 896 MTU.

export RESOURCE_NAME=your-resource-name
export NETWORK_NAME=${RESOURCE_NAME}-privatenetwork
export NETWORK_FW_NAME=${RESOURCE_NAME}-privatefirewall
gcloud compute networks create ${NETWORK_NAME} --mtu=8896 --project=${PROJECT_ID} \
 --subnet-mode=auto --bgp-routing-mode=regional
gcloud compute firewall-rules create ${NETWORK_FW_NAME} --network=${NETWORK_NAME} \
 --allow tcp,icmp,udp --project=${PROJECT_ID}

Utilisation de plusieurs cartes d'interface réseau (option pour Multislice)

Les variables d'environnement suivantes sont nécessaires pour un sous-réseau secondaire lorsque vous utilisez un environnement multicouche.

export NETWORK_NAME_2=${RESOURCE_NAME}
export SUBNET_NAME_2=${RESOURCE_NAME}
export FIREWALL_RULE_NAME=${RESOURCE_NAME}
export ROUTER_NAME=${RESOURCE_NAME}-network-2
export NAT_CONFIG=${RESOURCE_NAME}-natconfig-2
export REGION=your-region

Utilisez les commandes suivantes pour créer un routage IP personnalisé pour le réseau et le sous-réseau.

gcloud compute networks create ${NETWORK_NAME_2} --mtu=8896 \
   --bgp-routing-mode=regional --subnet-mode=custom --project=${PROJECT_ID}
gcloud compute networks subnets create ${SUBNET_NAME_2} \
   --network=${NETWORK_NAME_2} \
   --range=10.10.0.0/18 --region=${REGION} \
   --project=${PROJECT_ID}

gcloud compute firewall-rules create ${FIREWALL_RULE_NAME} \
   --network=${NETWORK_NAME_2} --allow tcp,icmp,udp \
   --source-ranges 10.10.0.0/18 --project=${PROJECT_ID}

gcloud compute routers create ${ROUTER_NAME} \
  --project=${PROJECT_ID} \
  --network=${NETWORK_NAME_2} \
  --region=${REGION}

gcloud compute routers nats create ${NAT_CONFIG} \
  --router=${ROUTER_NAME} \
  --region=${REGION} \
  --auto-allocate-nat-external-ips \
  --nat-all-subnet-ip-ranges \
  --project=${PROJECT_ID} \
  --enable-logging

Une fois que vous avez créé une tranche multiréseau, vous pouvez vérifier que les deux cartes d'interface réseau (NIC) sont utilisées en configurant un cluster XPK et en ajoutant l'option --command ifconfig à la commande de création de charge de travail XPK.

Utilisez la commande xpk workload suivante pour afficher la sortie de la commande ifconfig dans les journaux de la console Google Cloud et vérifier que eth0 et eth1 ont mtu=8896.

python3 xpk.py workload create \
   --cluster CLUSTER_NAME \
   {--base-docker-image maxtext_base_image | --docker-image your-cloud-image-name} \
   --workload=${USER}-xpk-${ACCELERATOR_TYPE}-${NUM_SLICES} \
   --tpu-type=${ACCELERATOR_TYPE} \
   --num-slices=${NUM_SLICES}  \
   --on-demand \
   --zone=${ZONE} \
   --project=${PROJECT_ID} \
   --command "ifconfig"

Si vous souhaitez activer les journaux de débogage ou utiliser Vertex AI TensorBoard, ajoutez les arguments facultatifs suivants à la commande:

    --enable-debug-logs \
    --use-vertex-tensorboard

Vérifiez que les interfaces eth0 et eth1 ont une valeur mtu de 8 896. Pour vérifier que la multi-NIC s'exécute, ajoutez l'indicateur --command ifconfig à la commande de création de la charge de travail XPK. Vérifiez la sortie de cette charge de travail xpk dans les journaux de la console Google Cloud et vérifiez que eth0 et eth1 ont mtu=8896.

Améliorer les paramètres TCP

Si vous avez créé vos Cloud TPU à l'aide de l'interface de ressources en file d'attente, vous pouvez exécuter la commande suivante pour améliorer les performances du réseau en augmentant les limites de tampon de réception TCP.

gcloud alpha compute tpus queued-resources ssh "${QUEUED_RESOURCE_ID}" \
  --project "${PROJECT}" \
  --zone "${ZONE}" \
  --node=all \
  --command='sudo sh -c "echo \"4096 41943040 314572800\" > /proc/sys/net/ipv4/tcp_rmem"' \
  --worker=all

Provisionner avec des ressources en file d'attente

Vous pouvez créer un Cloud TPU v6e à l'aide de ressources mises en file d'attente. Les ressources mises en file d'attente vous permettent de recevoir de la capacité une fois qu'elle est disponible. Vous pouvez spécifier une heure de début et de fin facultative pour le traitement de la demande. Pour en savoir plus, consultez la section Gérer les ressources en file d'attente.

Provisionner des Cloud TPU v6e avec GKE ou XPK

Si vous utilisez des commandes GKE avec la version v6e, vous pouvez utiliser des commandes Kubernetes ou XPK pour provisionner des Cloud TPU et entraîner ou diffuser des modèles. Consultez Planifier des Cloud TPU dans GKE pour découvrir comment planifier vos configurations Cloud TPU dans les clusters GKE. Les sections suivantes fournissent des commandes permettant de créer un cluster XPK avec prise en charge d'une seule carte réseau et de plusieurs cartes réseau.

Créer un cluster XPK compatible avec une seule carte réseau

export CLUSTER_NAME=xpk-cluster-name
export ZONE=us-east1-d
export PROJECT_ID=your-project-id
export TPU_TYPE=v6e-256
export NUM_SLICES=2

export NETWORK_NAME=${CLUSTER_NAME}-mtu9k
export NETWORK_FW_NAME=${NETWORK_NAME}-fw
gcloud compute networks create ${NETWORK_NAME} \
   --mtu=8896 \
   --project=${PROJECT_ID} \
   --subnet-mode=auto \
   --bgp-routing-mode=regional
gcloud compute firewall-rules create ${NETWORK_FW_NAME} \
   --network=${NETWORK_NAME} \
   --allow tcp,icmp,udp \
   --project=${PROJECT_ID}
export CLUSTER_ARGUMENTS="--network=${NETWORK_NAME} --subnetwork=${NETWORK_NAME}"
python3 xpk.py cluster create --cluster=${CLUSTER_NAME} \
   --cluster-cpu-machine-type=n1-standard-8 \
   --num-slices=${NUM_SLICES} \
   --tpu-type=${TPU_TYPE} \
   --zone=${ZONE}  \
   --project=${PROJECT_ID} \
   --on-demand \
   --custom-cluster-arguments="${CLUSTER_ARGUMENTS}"  \
   --create-vertex-tensorboard

Description des options de commande

Variable Description
CLUSTER_NAME Nom attribué par l'utilisateur au cluster XPK.
PROJECT_ID Google Cloud nom du projet. Utilisez un projet existant ou créez-en un. Pour en savoir plus, consultez Configurer votre projet Google Cloud .
ZONE Pour connaître les zones compatibles, consultez le document Régions et zones Cloud TPU.
TPU_TYPE Consultez la section Types d'accélérateurs.
NUM_SLICES Nombre de tranches que vous souhaitez créer
CLUSTER_ARGUMENTS Réseau et sous-réseau à utiliser.

Par exemple : --network=${NETWORK_NAME} --subnetwork=${NETWORK_NAME}

NUM_SLICES Nombre de secteurs à créer.
NETWORK_NAME Nom d'un réseau secondaire à utiliser.
NETWORK_FW_NAME Nom d'un pare-feu réseau secondaire à utiliser.

Créer un cluster XPK compatible avec plusieurs cartes d'interface réseau

export CLUSTER_NAME=xpk-cluster-name
export ZONE=us-east1-d
export PROJECT_ID=your-project-id
export TPU_TYPE=v6e-256
export NUM_SLICES=2

export NETWORK_NAME_1=${CLUSTER_NAME}-mtu9k-1-${ZONE}
export SUBNET_NAME_1=${CLUSTER_NAME}-privatesubnet-1-${ZONE}
export NETWORK_FW_NAME_1=${NETWORK_NAME_1}-fw-1-${ZONE}
export FIREWALL_RULE_NAME=${CLUSTER_NAME}-privatefirewall-1-${ZONE}
export ROUTER_NAME=${CLUSTER_NAME}-network-1-${ZONE}
export NAT_CONFIG=${CLUSTER_NAME}-natconfig-1-${ZONE}
gcloud compute networks create ${NETWORK_NAME_1} \
   --mtu=8896 \
   --bgp-routing-mode=regional \
   --subnet-mode=custom \
   --project=${PROJECT_ID}
gcloud compute networks subnets create ${SUBNET_NAME_1} \
   --network=${NETWORK_NAME_1} \
   --range=10.11.0.0/18 \
   --region=${REGION} \
   --project=${PROJECT_ID}
gcloud compute firewall-rules create ${FIREWALL_RULE_NAME} \
   --network=${NETWORK_NAME_1} \
   --allow tcp,icmp,udp \
   --project=${PROJECT_ID}
gcloud compute routers create ${ROUTER_NAME} \
    --project=${PROJECT_ID} \
    --network=${NETWORK_NAME_1} \
    --region=${REGION}
gcloud compute routers nats create ${NAT_CONFIG} \
    --router=${ROUTER_NAME} \
    --region=${REGION} \
    --auto-allocate-nat-external-ips \
    --nat-all-subnet-ip-ranges \
    --project=${PROJECT_ID} \
    --enable-logging
# Secondary subnet for multi-nic experience.
# Need custom IP routing to be different from the first network's subnet.

export NETWORK_NAME_2=${CLUSTER_NAME}-privatenetwork-2-${ZONE}
export SUBNET_NAME_2=${CLUSTER_NAME}-privatesubnet-2-${ZONE}
export FIREWALL_RULE_NAME=${CLUSTER_NAME}-privatefirewall-2-${ZONE}
export ROUTER_NAME=${CLUSTER_NAME}-network-2-${ZONE}
export NAT_CONFIG=${CLUSTER_NAME}-natconfig-2-${ZONE}
gcloud compute networks create ${NETWORK_NAME_2} \
   --mtu=8896 \
   --bgp-routing-mode=regional \
   --subnet-mode=custom \
   --project=${PROJECT_ID}
gcloud compute networks subnets create ${SUBNET_NAME_2} \
   --network=${NETWORK_NAME_2} \
   --range=10.10.0.0/18 \
   --region=${REGION} \
   --project=${PROJECT_ID}
gcloud compute firewall-rules create ${FIREWALL_RULE_NAME} \
   --network=${NETWORK_NAME_2} \
   --allow tcp,icmp,udp \
   --project=${PROJECT_ID}
gcloud compute routers create ${ROUTER_NAME} \
     --project=${PROJECT_ID} \
     --network=${NETWORK_NAME_2} \
     --region=${REGION}
gcloud compute routers nats create ${NAT_CONFIG} \
     --router=${ROUTER_NAME} \
     --region=${REGION} \
     --auto-allocate-nat-external-ips \
     --nat-all-subnet-ip-ranges \
     --project=${PROJECT_ID} \
     --enable-logging
export CLUSTER_ARGUMENTS="--enable-dataplane-v2 --enable-ip-alias --enable-multi-networking
--network=${NETWORK_NAME_1} --subnetwork=${SUBNET_NAME_1}"

export NODE_POOL_ARGUMENTS="--additional-node-network
network=${NETWORK_NAME_2},subnetwork=${SUBNET_NAME_2}"
python3 ~/xpk/xpk.py cluster create \
    --cluster=${CLUSTER_NAME} \
    --num-slices=${NUM_SLICES} \
    --tpu-type=${TPU_TYPE} \
    --zone=${ZONE}  \
    --project=${PROJECT_ID} \
    --on-demand \
    --custom-cluster-arguments="${CLUSTER_ARGUMENTS}" \
    --custom-nodepool-arguments="${NODE_POOL_ARGUMENTS}" \
    --create-vertex-tensorboard

Description des options de commande

Variable Description
CLUSTER_NAME Nom attribué par l'utilisateur au cluster XPK.
PROJECT_ID Google Cloud nom du projet. Utilisez un projet existant ou créez-en un. Pour en savoir plus, consultez Configurer votre projet Google Cloud .
ZONE Pour connaître les zones compatibles, consultez le document Régions et zones Cloud TPU.
TPU_TYPE Consultez la section Types d'accélérateurs.
NUM_SLICES Nombre de tranches que vous souhaitez créer
CLUSTER_ARGUMENTS Réseau et sous-réseau à utiliser.

Par exemple : --enable-dataplane-v2 --enable-ip-alias --enable-multi-networking --network=${NETWORK_NAME_1} --subnetwork=${SUBNET_NAME_1}

NODE_POOL_ARGUMENTS Réseau de nœuds supplémentaire à utiliser.

Par exemple : --additional-node-network network=${NETWORK_NAME_2},subnetwork=${SUBNET_NAME_2}

NUM_SLICES Nombre de tranches à créer (nécessaire pour Multislice uniquement).
NETWORK_NAME Nom d'un réseau secondaire à utiliser.
NETWORK_FW_NAME Nom d'un pare-feu réseau secondaire à utiliser.

Configuration du framework

Cette section décrit le processus de configuration général pour l'entraînement de modèles de ML à l'aide des frameworks JAX, PyTorch ou TensorFlow. Si vous utilisez GKE, vous pouvez utiliser XPK ou des commandes Kubernetes pour configurer le framework.

Configuration pour JAX

Cette section fournit des instructions de configuration pour exécuter des charges de travail JAX sur GKE, avec ou sans XPK, ainsi que pour utiliser des ressources en file d'attente.

Configurer JAX avec GKE

Tranche unique sur un seul hôte

L'exemple suivant configure un pool de nœuds à hôte unique 2x2 à l'aide d'un fichier YAML Kubernetes.

apiVersion: v1
kind: Pod
metadata:
  name: tpu-pod-jax-v6e-a
spec:
  restartPolicy: Never
  nodeSelector:
    cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
    cloud.google.com/gke-tpu-topology: 2x2
  containers:
  - name: tpu-job
    image: python:3.10
    securityContext:
      privileged: true
    command:
    - bash
    - -c
    - |
      pip install -U --pre jax jaxlib libtpu-nightly requests -f https://storage.googleapis.com/jax-releases/jax_nightly_releases.html -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
      JAX_PLATFORMS=tpu,cpu ENABLE_PJRT_COMPATIBILITY=true python3 -c 'import jax; print("Total TPU chips:", jax.device_count())'
    resources:
      requests:
        google.com/tpu: 4
      limits:
        google.com/tpu: 4

Une fois l'opération terminée, le message suivant doit s'afficher dans le journal GKE:

Total TPU chips: 4

Tranche unique sur plusieurs hôtes

L'exemple suivant configure un pool de nœuds multi-hôtes 4x4 à l'aide d'un fichier YAML Kubernetes.

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None
  selector:
    job-name: tpu-available-chips
---
apiVersion: batch/v1
kind: Job
metadata:
  name: tpu-available-chips
spec:
  backoffLimit: 0
  completions: 4
  parallelism: 4
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc
      restartPolicy: Never
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
        cloud.google.com/gke-tpu-topology: 4x4
      containers:
      - name: tpu-job
        image: python:3.10
        ports:
        - containerPort: 8471 # Default port using which TPU VMs communicate
        - containerPort: 8431 # Port to export TPU runtime metrics, if supported.
        securityContext:
          privileged: true
        command:
        - bash
        - -c
        - |
          pip install -U --pre jax jaxlib libtpu-nightly requests -f https://storage.googleapis.com/jax-releases/jax_nightly_releases.html -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
          JAX_PLATFORMS=tpu,cpu ENABLE_PJRT_COMPATIBILITY=true python -c 'import jax; print("Total TPU chips:", jax.device_count())'
        resources:
          requests:
            google.com/tpu: 4
          limits:
            google.com/tpu: 4

Une fois l'opération terminée, le message suivant doit s'afficher dans le journal GKE:

Total TPU chips: 16

Multislice sur multi-hôte

L'exemple suivant configure deux pools de nœuds multi-hôtes 4x4 à l'aide d'un fichier YAML Kubernetes.

Vous devez d'abord installer JobSet v0.2.3 ou une version ultérieure.

apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
  name: multislice-job
  annotations:
    alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool
spec:
  failurePolicy:
    maxRestarts: 4
  replicatedJobs:
    - name: slice
      replicas: 2
      template:
        spec:
          parallelism: 4
          completions: 4
          backoffLimit: 0
          template:
            spec:
              hostNetwork: true
              dnsPolicy: ClusterFirstWithHostNet
              nodeSelector:
                cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
                cloud.google.com/gke-tpu-topology: 4x4
              hostNetwork: true
              containers:
              - name: jax-tpu
                image: python:3.10
                ports:
                - containerPort: 8471
                - containerPort: 8080
                - containerPort: 8431
                securityContext:
                  privileged: true
                command:
                - bash
                - -c
                - |
                  pip install -U --pre jax jaxlib libtpu-nightly requests -f https://storage.googleapis.com/jax-releases/jax_nightly_releases.html -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                  JAX_PLATFORMS=tpu,cpu ENABLE_PJRT_COMPATIBILITY=true python -c 'import jax; print("Total TPU chips:", jax.device_count())'
                resources:
                  limits:
                   google.com/tpu: 4
                  requests:
                   google.com/tpu: 4

Une fois l'opération terminée, le message suivant doit s'afficher dans le journal GKE:

Total TPU chips: 32

Pour en savoir plus, consultez la section Exécuter une charge de travail multicouche dans la documentation de GKE.

Pour améliorer les performances, activez hostNetwork.

Multi-NIC

Pour profiter de la multi-NIC dans GKE, le fichier manifeste du pod Kubernetes doit comporter des annotations supplémentaires. Voici un exemple de fichier manifeste de charge de travail multi-NIC non TPU.

apiVersion: v1
kind: Pod
metadata:
  name: sample-netdevice-pod-1
  annotations:
    networking.gke.io/default-interface: 'eth0'
    networking.gke.io/interfaces: |
      [
        {"interfaceName":"eth0","network":"default"},
        {"interfaceName":"eth1","network":"netdevice-network"}
      ]
spec:
  containers:
  - name: sample-netdevice-pod
    image: busybox
    command: ["sleep", "infinity"]
    ports:
    - containerPort: 80
  restartPolicy: Always
  tolerations:
  - key: "google.com/tpu"
    operator: "Exists"
    effect: "NoSchedule"

Si vous utilisez la commande exec pour vous connecter au pod Kubernetes, vous devriez voir la carte réseau supplémentaire à l'aide du code suivant.

$ k exec --stdin --tty sample-netdevice-pod-1 -- /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1460 qdisc noqueue
    link/ether da:be:12:67:d2:25 brd ff:ff:ff:ff:ff:ff
    inet 10.124.2.6/24 brd 10.124.2.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc mq qlen 1000
    link/ether 42:01:ac:18:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.24.0.4/32 scope global eth1
       valid_lft forever preferred_lft forever

Configurer JAX à l'aide de GKE avec XPK

Pour configurer JAX à l'aide de GKE et XPK, consultez le README xpk.

Pour configurer et exécuter XPK avec MaxText, consultez Exécuter MaxText.

Configurer JAX à l'aide de ressources en file d'attente

Installez JAX sur toutes les VM Cloud TPU de votre ou vos tranches simultanément à l'aide de la commande gcloud alpha compute tpus tpu-vm ssh. Pour Multislice, ajoutez l'indicateur --node=all.

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project ${PROJECT_ID} \
 --zone ${ZONE} --worker=all \
 --command='pip install -U --pre jax jaxlib libtpu-nightly requests -f https://storage.googleapis.com/jax-releases/jax_nightly_releases.html -f https://storage.googleapis.com/jax-releases/libtpu_releases.html'

Vous pouvez exécuter la commande suivante pour vérifier le nombre de cœurs Cloud TPU disponibles dans votre tranche et pour vérifier que tout est correctement installé:

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project ${PROJECT_ID} \
   --zone ${ZONE} --worker=all  \
   --command='python3 -c "import jax; print(jax.device_count(), jax.local_device_count())"'

Le résultat ressemble à ce qui suit lors de l'exécution sur une tranche v6e-16:

SSH: Attempting to connect to worker 0...
SSH: Attempting to connect to worker 1...
SSH: Attempting to connect to worker 2...
SSH: Attempting to connect to worker 3...
16 4
16 4
16 4
16 4

jax.device_count() indique le nombre total de chips dans la tranche donnée. jax.local_device_count() indique le nombre de puces accessibles par une seule VM dans cette tranche.

gcloud alpha compute tpus queued-resources ssh ${QUEUED_RESOURCE_ID} \
   --project=${PROJECT_ID} --zone=${ZONE} --worker=all  \
   --command='git clone -b mlperf4.1 https://github.com/google/maxdiffusion.git &&
   cd maxdiffusion && git checkout 975fdb7dbddaa9a53ad72a421cdb487dcdc491a3 &&
   && pip install -r requirements.txt  && pip install . '

Résoudre les problèmes de configuration de JAX

En règle générale, nous vous recommandons d'activer la journalisation détaillée dans le fichier manifeste de votre charge de travail GKE. Fournissez ensuite les journaux à l'assistance GKE.

TPU_MIN_LOG_LEVEL=0 TF_CPP_MIN_LOG_LEVEL=0 TPU_STDERR_LOG_LEVEL=0

Messages d'erreur

no endpoints available for service 'jobset-webhook-service'

Cette erreur signifie que le jobset n'a pas été installé correctement. Vérifiez si les pods Kubernetes de déploiement jobset-controller-manager sont en cours d'exécution. Pour en savoir plus, consultez la documentation de dépannage JobSet.

TPU initialization failed: Failed to connect

Assurez-vous que votre nœud GKE utilise la version 1.30.4-gke.1348000 ou une version ultérieure (GKE 1.31 n'est pas compatible).

Configuration pour PyTorch

Cette section explique comment commencer à utiliser PJRT sur la version v6e avec PyTorch/XLA. La version recommandée est Python 3.10.

Configurer PyTorch à l'aide de GKE avec XPK

Vous pouvez utiliser le conteneur Docker suivant avec XPK, qui contient déjà les dépendances PyTorch:

us-central1-docker.pkg.dev/tpu-pytorch-releases/docker/xla:nightly_3.10_tpuvm_20241028

Pour créer une charge de travail XPK, utilisez la commande suivante:

python3 xpk.py workload create \
    --cluster ${CLUSTER_NAME} \
    {--docker-image | --base-docker-image} us-central1-docker.pkg.dev/tpu-pytorch-releases/docker/xla:nightly_3.10_tpuvm_20241028 \
    --workload ${USER} -xpk-${ACCELERATOR_TYPE} -${NUM_SLICES} \
    --tpu-type=${ACCELERATOR_TYPE} \
    --num-slices=${NUM_SLICES}  \
    --on-demand \
    --zone ${ZONE} \
    --project ${PROJECT_ID} \
    --enable-debug-logs \
    --command 'python3 -c "import torch; import torch_xla; import torch_xla.runtime as xr; print(xr.global_runtime_device_count())"'

L'utilisation de --base-docker-image crée une nouvelle image Docker avec le répertoire de travail actuel intégré au nouveau Docker.

Configurer PyTorch à l'aide de ressources en file d'attente

Suivez ces étapes pour installer PyTorch à l'aide de ressources mises en file d'attente et exécuter un petit script sur la version 6e.

Installer des dépendances à l'aide de SSH pour accéder aux VM

Utilisez la commande suivante pour installer les dépendances sur toutes les VM Cloud TPU. Pour Multislice, ajoutez l'indicateur --worker=all:

gcloud compute tpus tpu-vm ssh ${TPU_NAME} \
    --project=${PROJECT_ID} \
    --zone=${ZONE} \
    --worker=all \
    --command='sudo apt install -y libopenblas-base pip3 && \
               pip install torch~=2.6.0 "torch_xla[tpu]~=2.6.0" -f https://storage.googleapis.com/libtpu-releases/index.html -f https://storage.googleapis.com/libtpu-wheels/index.html'

Améliorer les performances des modèles avec des allocations importantes et fréquentes

Pour les modèles comportant des allocations fréquentes et importantes, l'utilisation de la fonction tcmalloc améliore considérablement les performances par rapport à l'implémentation de la fonction malloc par défaut. Par conséquent, la fonction malloc par défaut utilisée sur la VM Cloud TPU est tcmalloc. Toutefois, en fonction de votre charge de travail (par exemple, avec DLRM, qui dispose d'allocations très importantes pour ses tables d'imbrication), la fonction tcmalloc peut entraîner un ralentissement. Dans ce cas, vous pouvez essayer de ne pas définir la variable suivante à l'aide de la fonction malloc par défaut:

unset LD_PRELOAD

Utiliser un script Python pour effectuer un calcul sur une VM v6e

Utilisez la commande suivante pour exécuter un script qui crée deux tenseurs, les additionne et affiche le résultat.

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} \
   --project ${PROJECT_ID} \
   --zone ${ZONE} --worker all --command='
   unset LD_PRELOAD
   python3 -c "import torch; import torch_xla; import torch_xla.core.xla_model as xm; print(xm.xla_device()); dev = xm.xla_device(); t1 = torch.randn(3,3,device=dev); t2 = torch.randn(3,3,device=dev); print(t1 + t2)"
'

Un résultat semblable à celui-ci doit s'afficher :

SSH: Attempting to connect to worker 0...
WARNING:root:libtpu.so and TPU device found. Setting PJRT_DEVICE=TPU.
xla:0
tensor([[ 0.3355, -1.4628, -3.2610],
        [-1.4656,  0.3196, -2.8766],
        [ 0.8668, -1.5060,  0.7125]], device='xla:0')

Configuration pour TensorFlow

Vous pouvez réinitialiser l'environnement d'exécution Cloud TPU avec la version TensorFlow compatible avec la version 6e en exécutant les commandes suivantes:

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project ${PROJECT_ID} \
    --zone  ${ZONE} --worker=all --command="sudo sed -i 's/TF_DOCKER_URL=.*/TF_DOCKER_URL=gcr.io\/cloud-tpu-v2-images\/grpc_tpu_worker:v6e\"/' /etc/systemd/system/tpu-runtime.service"
gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME}  --project ${PROJECT_ID} \
    --zone ${ZONE} --worker=all --command='sudo systemctl daemon-reload && sudo systemctl restart tpu-runtime'

Utilisez SSH pour accéder à worker-0:

$ gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project ${PROJECT_ID} \
     --zone ${ZONE}

Installez TensorFlow sur worker-0:

sudo apt install -y libopenblas-base
pip install cloud-tpu-client
pip install https://storage.googleapis.com/tensorflow-public-build-artifacts/prod/tensorflow/official/release/nightly/linux_x86_tpu/wheel_py310/749/20240915-062017/github/tensorflow/build_output/tf_nightly_tpu-2.18.0.dev20240915-cp310
pip install cloud-tpu-client

pip install https://storage.googleapis.com/tensorflow-public-build-artifacts/prod/tensorflow/official/release/nightly/linux_x86_tpu/wheel_py310/749/20240915-062017/github/tensorflow/build_output/tf_nightly_tpu-2.18.0.dev20240915-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl \
-f https://storage.googleapis.com/libtpu-tf-releases/index.html --force

Exportez la variable d'environnement TPU_NAME:

export TPU_NAME=v6e-16

Vous pouvez exécuter le script Python suivant pour vérifier le nombre de cœurs Cloud TPU disponibles dans votre tranche et pour vérifier que tout est correctement installé:

import TensorFlow as tf
print("TensorFlow version " + tf.__version__)

@tf.function
  def add_fn(x,y):
  z = x + y
  return z

  cluster_resolver = tf.distribute.cluster_resolver.TPUClusterResolver()
  tf.config.experimental_connect_to_cluster(cluster_resolver)
  tf.tpu.experimental.initialize_tpu_system(cluster_resolver)
  strategy = tf.distribute.TPUStrategy(cluster_resolver)

  x = tf.constant(1.)
  y = tf.constant(1.)
  z = strategy.run(add_fn, args=(x,y))
  print(z)

Le résultat ressemble à ce qui suit lors de l'exécution sur une tranche v6e-16:

PerReplica:{
  0: tf.Tensor(2.0, shape=(), dtype=float32),
  1: tf.Tensor(2.0, shape=(), dtype=float32),
  2: tf.Tensor(2.0, shape=(), dtype=float32),
  3: tf.Tensor(2.0, shape=(), dtype=float32),
  4: tf.Tensor(2.0, shape=(), dtype=float32),
  5: tf.Tensor(2.0, shape=(), dtype=float32),
  6: tf.Tensor(2.0, shape=(), dtype=float32),
  7: tf.Tensor(2.0, shape=(), dtype=float32)
}

v6e avec SkyPilot

Vous pouvez utiliser Cloud TPU v6e avec SkyPilot. Pour ajouter des informations sur l'emplacement et les tarifs liés à la v6e à SkyPilot, procédez comme suit :

  1. Ajoutez ce qui suit à la fin du fichier ~/.sky/catalogs/v5/gcp/vms.csv:

    ,,,tpu-v6e-1,1,tpu-v6e-1,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-1,1,tpu-v6e-1,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-1,1,tpu-v6e-1,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-4,1,tpu-v6e-4,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-4,1,tpu-v6e-4,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-4,1,tpu-v6e-4,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-8,1,tpu-v6e-8,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-8,1,tpu-v6e-8,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-8,1,tpu-v6e-8,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-16,1,tpu-v6e-16,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-16,1,tpu-v6e-16,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-16,1,tpu-v6e-16,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-32,1,tpu-v6e-32,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-32,1,tpu-v6e-32,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-32,1,tpu-v6e-32,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-64,1,tpu-v6e-64,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-64,1,tpu-v6e-64,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-64,1,tpu-v6e-64,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-128,1,tpu-v6e-128,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-128,1,tpu-v6e-128,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-128,1,tpu-v6e-128,us-east5,us-east5-b,0,0
    ,,,tpu-v6e-256,1,tpu-v6e-256,us-south1,us-south1-a,0,0
    ,,,tpu-v6e-256,1,tpu-v6e-256,europe-west4,europe-west4-a,0,0
    ,,,tpu-v6e-256,1,tpu-v6e-256,us-east5,us-east5-b,0,0
    
  2. Spécifiez les ressources suivantes dans un fichier YAML:

    # tpu_v6.yaml
    resources:
      accelerators: tpu-v6e-16 # Fill in the accelerator type you want to use
      accelerator_args:
        runtime_version: v2-alpha-tpuv6e # Official suggested runtime
    
  3. Lancez un cluster avec Cloud TPU v6e:

       sky launch tpu_v6.yaml -c tpu_v6
    
  4. Connectez-vous au Cloud TPU v6e à l'aide de SSH: ssh tpu_v6

Tutoriels sur l'inférence

Les tutoriels suivants montrent comment exécuter une inférence sur Cloud TPU v6e:

Exemples d'entraînement

Les sections suivantes fournissent des exemples d'entraînement des modèles MaxText, MaxDiffusion et PyTorch sur Cloud TPU v6e.

Entraînement MaxText et MaxDiffusion sur une VM Cloud TPU v6e

Les sections suivantes couvrent le cycle de vie de l'entraînement des modèles MaxText et MaxDiffusion.

En général, les étapes de haut niveau sont les suivantes:

  1. Créez l'image de base de la charge de travail.
  2. Exécutez votre charge de travail à l'aide de XPK.
    1. Créez la commande d'entraînement pour la charge de travail.
    2. Déployez la charge de travail.
  3. Suivez la charge de travail et affichez les métriques.
  4. Supprimez la charge de travail XPK si elle n'est pas nécessaire.
  5. Supprimez le cluster XPK lorsqu'il n'est plus nécessaire.

Créer une image de base

Installez MaxText ou MaxDiffusion, puis créez l'image Docker:

  1. Clonez le dépôt que vous souhaitez utiliser et accédez au répertoire du dépôt:

    MaxText:

    git clone https://github.com/google/maxtext.git && cd maxtext
    

    MaxDiffusion:

    git clone https://github.com/google/maxdiffusion.git && cd maxdiffusion
    
  2. Configurez Docker pour qu'il utilise la Google Cloud CLI:

    gcloud auth configure-docker
    
  3. Créez l'image Docker à l'aide de la commande suivante ou à l'aide de la pile stable JAX. Pour en savoir plus sur la pile stable JAX, consultez Créer une image Docker avec la pile stable JAX.

    bash docker_build_dependency_image.sh MODE=stable JAX_VERSION=0.4.35
    
  4. Si vous lancez la charge de travail à partir d'une machine sur laquelle l'image n'est pas compilée localement, importez-la:

    bash docker_upload_runner.sh CLOUD_IMAGE_NAME=${USER}_runner
    

Exécuter votre charge de travail à l'aide de XPK

  1. Définissez les variables d'environnement suivantes si vous n'utilisez pas les valeurs par défaut définies par MaxText ou MaxDiffusion:

    export BASE_OUTPUT_DIR=gs://YOUR_BUCKET
    export PER_DEVICE_BATCH_SIZE=2
    export NUM_STEPS=30
    export MAX_TARGET_LENGTH=8192
  2. Créez le script de votre modèle. Ce script sera copié en tant que commande d'entraînement à une étape ultérieure.

    N'exécutez pas encore le script du modèle.

    MaxText

    MaxText est un LLM Open Source hautes performances et hautement évolutif, écrit en Python et JAX purs, et ciblant les Google Cloud TPU et GPU pour l'entraînement et l'inférence.

    JAX_PLATFORMS=tpu,cpu \
    ENABLE_PJRT_COMPATIBILITY=true \
    TPU_SLICE_BUILDER_DUMP_CHIP_FORCE=true \
    TPU_SLICE_BUILDER_DUMP_ICI=true && \
    python /deps/MaxText/train.py /deps/MaxText/configs/base.yml \
            base_output_directory=${BASE_OUTPUT_DIR} \
            dataset_type=synthetic \
            per_device_batch_size=${PER_DEVICE_BATCH_SIZE} \
            enable_checkpointing=false \
            gcs_metrics=true \
            profiler=xplane \
            skip_first_n_steps_for_profiler=5 \
            steps=${NUM_STEPS}  # attention='dot_product'"
    

    Gemma2

    Gemma est une famille de LLM à poids ouverts développés par Google DeepMind, basés sur la recherche et la technologie Gemini.

    python3 MaxText/train.py MaxText/configs/base.yml \
        model_name=gemma2-27b \
        run_name=gemma2-27b-run \
        base_output_directory=${BASE_OUTPUT_DIR} \
        max_target_length=${MAX_TARGET_LENGTH} \
        per_device_batch_size=${PER_DEVICE_BATCH_SIZE} \
        steps=${NUM_STEPS} \
        enable_checkpointing=false \
        use_iota_embed=true \
        gcs_metrics=true \
        dataset_type=synthetic \
        profiler=xplane \
        attention=flash
    

    Mixtral 8x7b

    Mixtral est un modèle d'IA de pointe développé par Mistral AI, qui utilise une architecture MoE (Mixture of Experts) sporadique.

    python3 MaxText/train.py MaxText/configs/base.yml \
        base_output_directory=${BASE_OUTPUT_DIR} \
        per_device_batch_size=${PER_DEVICE_BATCH_SIZE} \
        model_name=mixtral-8x7b \
        steps=${NUM_STEPS} \
        max_target_length=${MAX_TARGET_LENGTH} \
        tokenizer_path=assets/tokenizer.mistral-v1 \
        attention=flash \
        dtype=bfloat16 \
        dataset_type=synthetic \
        profiler=xplane
    

    Llama3-8b

    Llama est une famille de LLM à pondération ouverte développée par Meta.

    python3 MaxText/train.py MaxText/configs/base.yml \
        model_name=llama3-8b \
        base_output_directory=${BASE_OUTPUT_DIR} \
        dataset_type=synthetic \
        tokenizer_path=assets/tokenizer_llama3.tiktoken \
        per_device_batch_size=${PER_DEVICE_BATCH_SIZE} # set to 4 \
        gcs_metrics=true \
        profiler=xplane \
        skip_first_n_steps_for_profiler=5 \
        steps=${NUM_STEPS} \
        max_target_length=${MAX_TARGET_LENGTH} \
        attention=flash
    

    MaxDiffusion

    MaxDiffusion est un ensemble d'implémentations de référence de divers modèles de diffusion latente écrits en Python pur et en JAX, qui s'exécutent sur des appareils XLA, y compris des Cloud TPU et des GPU. Stable Diffusion est un modèle de texte vers image latent qui génère des images photoréalistes à partir de n'importe quelle entrée textuelle.

    Vous devez installer une branche Git spécifique pour exécuter MaxDiffusion, comme indiqué dans la commande git checkout suivante.

    git clone https://github.com/google/maxdiffusion.git
    && cd maxdiffusion
    && git checkout e712c9fc4cca764b0930067b6e33daae2433abf0
    && pip install -r requirements.txt
    && pip install .
    

    Script d'entraînement:

        cd maxdiffusion && OUT_DIR=${BASE_OUTPUT_DIR} \
        python src/maxdiffusion/train_sdxl.py \
        src/maxdiffusion/configs/base_xl.yml \
        revision=refs/pr/95 \
        activations_dtype=bfloat16 \
        weights_dtype=bfloat16 \
        resolution=1024 \
        per_device_batch_size=1 \
        output_dir=${OUT_DIR}  \
        jax_cache_dir=${OUT_DIR}/cache_dir/ \
        max_train_steps=200 \
        attention=flash run_name=sdxl-ddp-v6e
        
  3. Exportez les variables suivantes:

    export CLUSTER_NAME=CLUSTER_NAME
    export ACCELERATOR_TYPE=ACCELERATOR_TYPE
    export NUM_SLICES=NUM_SLICES
    export YOUR_MODEL_SCRIPT=YOUR_MODEL_SCRIPT

    Descriptions des variables d'environnement

    Variable Description
    CLUSTER_NAME Nom de votre cluster XPK.
    ACCELERATOR_TYPE Consultez la section Types d'accélérateurs.
    NUM_SLICES Nombre de tranches TPU.
    YOUR_MODEL_SCRIPT Script du modèle à exécuter en tant que commande d'entraînement.
  4. Exécutez le modèle à l'aide du script que vous avez créé à l'étape précédente. Vous devez spécifier l'option --base-docker-image pour utiliser l'image de base MaxText ou l'option --docker-image et l'image que vous souhaitez utiliser.

    Facultatif: vous pouvez activer la journalisation de débogage en incluant l'option --enable-debug-logs. Pour en savoir plus, consultez Déboguer JAX sur MaxText.

    Facultatif: vous pouvez créer un Vertex AI Experiment pour importer des données dans Vertex AI TensorBoard en incluant l'indicateur --use-vertex-tensorboard. Pour en savoir plus, consultez Surveiller JAX sur MaxText à l'aide de Vertex AI.

    python3 xpk.py workload create \
        --cluster ${CLUSTER_NAME} \
        {--base-docker-image maxtext_base_image|--docker-image ${CLOUD_IMAGE_NAME}} \
        --workload=${USER}-xpk-${ACCELERATOR_TYPE}-${NUM_SLICES} \
        --tpu-type=${ACCELERATOR_TYPE} \
        --num-slices=${NUM_SLICES}  \
        --on-demand \
        --zone=${ZONE} \
        --project=${PROJECT_ID} \
        [--enable-debug-logs] \
        [--use-vertex-tensorboard] \
        --command=${YOUR_MODEL_SCRIPT}

    Le résultat inclut un lien permettant de suivre votre charge de travail. Ouvrez le lien, puis cliquez sur l'onglet Journaux pour suivre votre charge de travail en temps réel.

Déboguer JAX sur MaxText

Utilisez des commandes XPK supplémentaires pour diagnostiquer pourquoi le cluster ou la charge de travail ne s'exécute pas.

Surveiller JAX sur MaxText à l'aide de Vertex AI

Afficher les données scalaires et de profil via TensorBoard géré par Vertex AI.

  1. Augmentez le nombre de requêtes de gestion des ressources (CRUD) pour la zone que vous utilisez de 600 à 5 000. Cela peut ne pas poser de problème pour les petites charges de travail utilisant moins de 16 VM.
  2. Installez des dépendances telles que cloud-accelerator-diagnostics pour Vertex AI:

    # xpk dependencies will install cloud-accelerator-diagnostics for Vertex AI
    cd ~/xpk
    pip install .
  3. Créez votre cluster XPK à l'aide de l'option --create-vertex-tensorboard, comme décrit dans Créer Vertex AI TensorBoard. Vous pouvez également exécuter cette commande sur des clusters existants.

  4. Créez votre test Vertex AI lorsque vous exécutez votre charge de travail XPK à l'aide de l'indicateur --use-vertex-tensorboard et de l'indicateur --experiment-name facultatif. Pour obtenir la liste complète des étapes, consultez Créer un test Vertex AI pour importer des données dans Vertex AI TensorBoard.

Les journaux incluent un lien vers un Vertex AI TensorBoard, semblable à celui-ci:

View your TensorBoard at https://us-central1.tensorboard.googleusercontent.com/experiment/project_id+locations+us-central1+tensorboards+hash+experiments+name

Vous pouvez également trouver le lien Vertex AI TensorBoard dans la console Google Cloud. Accédez à Vertex AI Experiments (Tests Vertex AI) dans la console Google Cloud. Sélectionnez la région appropriée dans le menu déroulant.

Le répertoire TensorBoard est également écrit dans le bucket Cloud Storage que vous avez spécifié avec ${BASE_OUTPUT_DIR}.

Supprimer les charges de travail XPK

Utilisez la commande xpk workload delete pour supprimer une ou plusieurs charges de travail en fonction du préfixe ou de l'état de la tâche. Cette commande peut être utile si vous avez envoyé des charges de travail XPK qui n'ont plus besoin d'être exécutées ou si des tâches sont bloquées dans la file d'attente.

Supprimer le cluster XPK

Utilisez la commande xpk cluster delete pour supprimer un cluster:

python3 xpk.py cluster delete --cluster ${CLUSTER_NAME} \
--zone=${ZONE} --project=${PROJECT_ID}

Entraînement Llama et PyTorch/XLA sur une VM Cloud TPU v6e

Ce tutoriel explique comment entraîner des modèles Llama à l'aide de PyTorch/XLA sur Cloud TPU v6e à l'aide de l'ensemble de données WikiText.

Accéder à Hugging Face et au modèle Llama 3

Vous avez besoin d'un jeton d'accès utilisateur Hugging Face pour suivre ce tutoriel. Pour en savoir plus sur la création et l'utilisation des jetons d'accès utilisateur, consultez la documentation Hugging Face sur les jetons d'accès utilisateur.

Vous devez également disposer d'une autorisation pour accéder au modèle Llama 3 8B sur Hugging Face. Pour y accéder, accédez au modèle Meta-Llama-3-8B sur HuggingFace et demandez l'accès.

Créer une VM Cloud TPU

Créez un Cloud TPU v6e avec huit puces pour exécuter le tutoriel.

  1. Configurez des variables d'environnement :

    export ACCELERATOR_TYPE=v6e-8
    export VERSION=v2-alpha-tpuv6e
    export TPU_NAME=$USER-$ACCELERATOR_TYPE
    export PROJECT_ID=your-project-id
    export ZONE=us-east1-d
  2. Créez une VM Cloud TPU:

    gcloud alpha compute tpus tpu-vm create ${TPU_NAME} --version=${VERSION} \
        --accelerator-type=${ACCELERATOR_TYPE} \
        --zone=${ZONE} \
        --project=${PROJECT_ID}

Installation

Installez le fork pytorch-tpu/transformers des transformers Hugging Face et des dépendances. Ce tutoriel a été testé avec les versions de dépendance suivantes utilisées dans cet exemple:

  • torch: compatible avec la version 2.5.0
  • torch_xla[tpu]: compatible avec la version 2.5.0
  • jax: 0.4.33
  • jaxlib: 0.4.33
gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project=${PROJECT_ID} --zone ${ZONE} \
    --worker=all --command='git clone -b flash_attention https://github.com/pytorch-tpu/transformers.git
    cd transformers
    sudo pip3 install -e .
    pip3 install datasets
    pip3 install evaluate
    pip3 install scikit-learn
    pip3 install accelerate
    pip install torch~=2.6.0 torch_xla[tpu]~=2.6.0 -f https://storage.googleapis.com/libtpu-releases/index.html -f https://storage.googleapis.com/libtpu-wheels/index.html
    pip install jax==0.4.38 jaxlib==0.4.38 -f https://storage.googleapis.com/jax-releases/jax_nightly_releases.html -f https://storage.googleapis.com/jax-releases/jaxlib_nightly_releases.html'

Configurer les configurations de modèle

La commande d'entraînement de la section suivante, Exécuter le modèle, utilise deux fichiers de configuration JSON pour définir les paramètres du modèle et la configuration FSDP (Fully Sharded Data Parallel). Le fractionnement FSDP permet aux poids du modèle de s'adapter à une taille de lot plus importante lors de l'entraînement. Lors de l'entraînement avec des modèles plus petits, il peut suffire d'utiliser le parallélisme des données et de répliquer les poids sur chaque appareil. Pour en savoir plus sur le fractionnement des tenseurs sur plusieurs appareils dans PyTorch/XLA, consultez le guide de l'utilisateur de SPMD PyTorch/XLA.

  1. Créez le fichier de configuration des paramètres du modèle. Voici la configuration des paramètres du modèle pour Llama3-8B. Pour les autres modèles, recherchez la configuration sur Hugging Face. Consultez par exemple la configuration Llama2-7B.

    cat > llama-config.json << EOF
    {
        "architectures": [
            "LlamaForCausalLM"
        ],
        "attention_bias": false,
        "attention_dropout": 0.0,
        "bos_token_id": 128000,
        "eos_token_id": 128001,
        "hidden_act": "silu",
        "hidden_size": 4096,
        "initializer_range": 0.02,
        "intermediate_size": 14336,
        "max_position_embeddings": 8192,
        "model_type": "llama",
        "num_attention_heads": 32,
        "num_hidden_layers": 32,
        "num_key_value_heads": 8,
        "pretraining_tp": 1,
        "rms_norm_eps": 1e-05,
        "rope_scaling": null,
        "rope_theta": 500000.0,
        "tie_word_embeddings": false,
        "torch_dtype": "bfloat16",
        "transformers_version": "4.40.0.dev0",
        "use_cache": false,
        "vocab_size": 128256
    }
    EOF
    
  2. Créez le fichier de configuration FSDP:

    cat > fsdp-config.json << EOF
    {
        "fsdp_transformer_layer_cls_to_wrap": [
            "LlamaDecoderLayer"
        ],
        "xla": true,
        "xla_fsdp_v2": true,
        "xla_fsdp_grad_ckpt": true
    }
    EOF
    

    Pour en savoir plus sur le FSDP, consultez FSDPv2.

  3. Importez les fichiers de configuration dans vos VM Cloud TPU à l'aide de la commande suivante:

    gcloud alpha compute tpus tpu-vm scp llama-config.json fsdp-config.json ${TPU_NAME}:. \
        --worker=all \
        --project=${PROJECT_ID} \
        --zone=${ZONE}

Exécuter le modèle

À l'aide des fichiers de configuration que vous avez créés dans la section précédente, exécutez le script run_clm.py pour entraîner le modèle Llama 3 8B sur l'ensemble de données WikiText. L'exécution du script d'entraînement sur un Cloud TPU v6e-8 prend environ 10 minutes.

  1. Connectez-vous à Hugging Face sur votre Cloud TPU à l'aide de la commande suivante:

    gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project=${PROJECT} \
        --zone ${ZONE} \
        --worker=all \
        --command='
        pip3 install "huggingface_hub[cli]"
        huggingface-cli login --token HUGGING_FACE_TOKEN'
  2. Exécutez l'entraînement du modèle:

    gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --project=${PROJECT} \
        --zone ${ZONE} \
        --worker=all \
        --command='
        export PJRT_DEVICE=TPU
        export XLA_USE_SPMD=1
        export ENABLE_PJRT_COMPATIBILITY=true
            # Optional variables for debugging:
        export XLA_IR_DEBUG=1
        export XLA_HLO_DEBUG=1
        export PROFILE_EPOCH=0
        export PROFILE_STEP=3
        export PROFILE_DURATION_MS=100000
            # Set PROFILE_LOGDIR to a local VM path or gs://my-bucket/profile_path
        export PROFILE_LOGDIR=PROFILE_PATH
        python3 transformers/examples/pytorch/language-modeling/run_clm.py \
        --dataset_name wikitext \
        --dataset_config_name wikitext-2-raw-v1 \
        --per_device_train_batch_size 16 \
        --do_train \
        --output_dir /home/$USER/tmp/test-clm \
        --overwrite_output_dir \
        --config_name /home/$USER/llama-config.json \
        --cache_dir /home/$USER/cache \
        --tokenizer_name meta-llama/Meta-Llama-3-8B \
        --block_size 8192 \
        --optim adafactor \
        --save_strategy no \
        --logging_strategy no \
        --fsdp "full_shard" \
        --fsdp_config /home/$USER/fsdp-config.json \
        --torch_dtype bfloat16 \
        --dataloader_drop_last yes \
        --flash_attention \
        --max_steps 20'

Résoudre les problèmes liés à PyTorch/XLA

Si vous définissez les variables facultatives pour le débogage dans la section précédente, le profil du modèle sera stocké à l'emplacement spécifié par la variable PROFILE_LOGDIR. Vous pouvez extraire le fichier xplane.pb stocké à cet emplacement et utiliser tensorboard pour afficher les profils dans votre navigateur à l'aide des instructions TensorBoard. Si PyTorch/XLA ne fonctionne pas comme prévu, consultez le guide de dépannage, qui contient des suggestions pour déboguer, profiler et optimiser votre modèle.

Entraînement DLRM DCN v2 sur v6e

Ce tutoriel vous explique comment entraîner le modèle DLRM DCN v2 sur Cloud TPU v6e. Vous devez provisionner un TPU v6e avec 64, 128 ou 256 puces.

Si vous exécutez sur un TPU multi-hôte, réinitialisez tpu-runtime avec la version TensorFlow appropriée en exécutant les commandes suivantes. Si vous exécutez sur un TPU à hôte unique, vous n'avez pas besoin d'exécuter les deux commandes suivantes.

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME}  \
    --project ${PROJECT_ID} \
    --zone ${ZONE} \
    --worker=all \
    --command="sudo sed -i 's/TF_DOCKER_URL=.*/TF_DOCKER_URL=gcr.io\/cloud-tpu-v2-images\/grpc_tpu_worker:v6e\"/' /etc/systemd/system/tpu-runtime.service"

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME}  \
    --project ${PROJECT_ID} \
    --zone  ${ZONE} \
    --worker=all \
    --command='sudo systemctl daemon-reload && sudo systemctl restart tpu-runtime'

Se connecter à worker-0 à l'aide de SSH

gcloud alpha compute tpus tpu-vm ssh ${TPU_NAME} --zone ${ZONE} --project ${PROJECT_ID}

Définir le nom du Cloud TPU

export TPU_NAME=your-tpu-name

Exécuter DLRM v2

Copiez l'extrait de code suivant dans un fichier nommé script.sh:

pip install --user setuptools==65.5.0

pip install cloud-tpu-client

pip install gin-config && pip install tensorflow-datasets && pip install tf-keras-nightly --no-deps

pip install https://storage.googleapis.com/tensorflow-public-build-artifacts/prod/tensorflow/official/release/nightly/linux_x86_tpu/wheel_py310/749/20240915-062017/github/tensorflow/build_output/tf_nightly_tpu-2.18.0.dev20240915-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -f https://storage.googleapis.com/libtpu-tf-releases/index.html --force

git clone https://github.com/tensorflow/recommenders.git
git clone https://github.com/tensorflow/models.git

export PYTHONPATH=~/recommenders/:~/models/
export TF_XLA_FLAGS='--tf_mlir_enable_mlir_bridge=true --tf_xla_sparse_core_disable_table_stacking=true --tf_mlir_enable_convert_control_to_data_outputs_pass=true --tf_mlir_enable_merge_control_flow_pass=true'

TF_USE_LEGACY_KERAS=1 TPU_LOAD_LIBRARY=0 python3 ./models/official/recommendation/ranking/train.py  --mode=train     --model_dir=gs://ptxla-debug/tf/sc/dlrm/runs/2/ --params_override="
runtime:
  distribution_strategy: tpu
  mixed_precision_dtype: 'mixed_bfloat16'
task:
  use_synthetic_data: false
  use_tf_record_reader: true
  train_data:
    input_path: 'gs://trillium-datasets/criteo/train/day_*/*'
    global_batch_size: 16384
    use_cached_data: true
  validation_data:
    input_path: 'gs://trillium-datasets/criteo/eval/day_*/*'
    global_batch_size: 16384
    use_cached_data: true
  model:
    num_dense_features: 13
    bottom_mlp: [512, 256, 128]
    embedding_dim: 128
    interaction: 'multi_layer_dcn'
    dcn_num_layers: 3
    dcn_low_rank_dim: 512
    size_threshold: 8000
    top_mlp: [1024, 1024, 512, 256, 1]
    use_multi_hot: true
    concat_dense: false
    dcn_use_bias: true
    vocab_sizes: [40000000,39060,17295,7424,20265,3,7122,1543,63,40000000,3067956,405282,10,2209,11938,155,4,976,14,40000000,40000000,40000000,590152,12973,108,36]
    multi_hot_sizes: [3,2,1,2,6,1,1,1,1,7,3,8,1,6,9,5,1,1,1,12,100,27,10,3,1,1]
    max_ids_per_chip_per_sample: 128
    max_ids_per_table: [280, 128, 64, 272, 432, 624, 64, 104, 368, 352, 288, 328, 304, 576, 336, 368, 312, 392, 408, 552, 2880, 1248, 720, 112, 320, 256]
    max_unique_ids_per_table: [104, 56, 40, 32, 72, 32, 40, 32, 32, 144, 64, 192, 32, 40, 136, 32, 32, 32, 32, 240, 1352, 432, 120, 80, 32, 32]
    use_partial_tpu_embedding: false
    size_threshold: 0
    initialize_tables_on_host: true
trainer:
  train_steps: 10000
  validation_interval: 1000
  validation_steps: 660
  summary_interval: 1000
  steps_per_loop: 1000
  checkpoint_interval: 0
  optimizer_config:
    embedding_optimizer: 'Adagrad'
    dense_optimizer: 'Adagrad'
    lr_config:
      decay_exp: 2
      decay_start_steps: 70000
      decay_steps: 30000
      learning_rate: 0.025
      warmup_steps: 0
    dense_sgd_config:
      decay_exp: 2
      decay_start_steps: 70000
      decay_steps: 30000
      learning_rate: 0.00025
      warmup_steps: 8000
  train_tf_function: true
  train_tf_while_loop: true
  eval_tf_while_loop: true
  use_orbit: true
  pipeline_sparse_and_dense_execution: true"

Si vous exécutez TensorFlow sur GKE, installez le paquet TensorFlow Cloud TPU et libtpu à l'aide de la commande suivante:

pip install https://storage.googleapis.com/tensorflow-public-build-artifacts/prod/tensorflow/official/release/nightly/linux_x86_tpu/wheel_py310/749/20240915-062017/github/tensorflow/build_output/tf_nightly_tpu-2.18.0.dev20240915-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl \
-f https://storage.googleapis.com/libtpu-tf-releases/index.html --force

Définissez les options suivantes, qui sont nécessaires pour exécuter des charges de travail de recommandation (telles que le DCN DLRM):

ENV TF_XLA_FLAGS='--tf_mlir_enable_mlir_bridge=true \
--tf_mlir_enable_tpu_variable_runtime_reformatting_pass=false \
--tf_mlir_enable_convert_control_to_data_outputs_pass=true \
--tf_mlir_enable_merge_control_flow_pass=true --tf_xla_disable_full_embedding_pipelining=true' \
ENV LIBTPU_INIT_ARGS="--xla_sc_splitting_along_feature_dimension=auto \
--copy_with_dynamic_shape_op_output_pjrt_buffer=true"

Exécutez script.sh :

chmod +x script.sh
./script.sh

Résultats du benchmark

La section suivante contient les résultats des analyses comparatives pour le DLRM DCN v2 et MaxDiffusion sur la version 6e.

DLRM DCN v2

Le script d'entraînement DLRM DCN v2 a été exécuté à différentes échelles. Consultez les débits dans le tableau suivant.

v6e-64 v6e-128 v6e-256
Étapes de l'entraînement 7000 7000 7000
Taille du lot global 131072 262144 524288
Débit (exemples/s) 2975334 5111808 10066329

MaxDiffusion

Nous avons exécuté le script d'entraînement de MaxDiffusion sur un v6e-4, un v6e-16 et deux v6e-16. Consultez les débits dans le tableau suivant.

v6e-4 v6e-16 Deux v6e-16
Étapes de l'entraînement 0,069 0.073 0,13
Taille du lot global 8 32 64
Débit (exemples/s) 115,9 438,4 492,3