Déployer des TPU Multislice dans GKE


Cette page explique comment déployer des charges de travail dans Google Kubernetes Engine (GKE) à l'aide de la configuration Cloud TPU Multislice pour un entraînement économique et à grande échelle.

Ce tutoriel s'adresse aux ingénieurs en machine learning (ML), aux administrateurs et aux opérateurs de plate-forme qui souhaitent utiliser l'orchestration de conteneurs Kubernetes pour gérer des charges de travail d'entraînement, de réglage et d'inférence à grande échelle à l'aide de TPU. Pour en savoir plus sur les rôles courants et les exemples de tâches référencés dans le contenu Google Cloud , consultez la section Rôles utilisateur et tâches courantes de l'utilisateur dans GKE Enterprise.

Avant de configurer Multislice dans GKE, assurez-vous de connaître les concepts suivants :

  1. Présentation de Cloud TPU
  2. Architecture du système Cloud TPU
  3. À propos des TPU dans GKE

Qu'est-ce que TPU Multislice ?

TPU Multislice est l'organisation architecturale de VM dans une tranche TPU où deux tranches Cloud TPU ou plus communiquent sur le réseau de centre de données. Multislice permet un entraînement full stack à grande échelle et économique, avec un scaling presque linéaire jusqu'à plusieurs dizaines de milliers de puces TPU. Dans une configuration Multislice, GKE déploie une charge de travail Multislice sur plusieurs tranches de TPU. La communication entre les puces TPU d'une tranche s'effectue via des interconnexions entre puces (ICI). La communication entre les tranches s'effectue via le DCN.

Nous vous recommandons d'utiliser Multislice si votre job est trop grand pour tenir sur une seule tranche de TPU.

Disponibilité de Multislice dans GKE

  • La version standard est compatible avec Multislice dans les versions 1.27.4-gke.900 et ultérieures.
  • Autopilot est compatible avec Multislice dans les versions 1.29.2-gke.1521000 et ultérieures.
  • Multislice est compatible avec les frameworks JAX et PyTorch. La version minimale de JAX compatible est la version 2.1.
  • Multislice n'est compatible qu'avec les pools de nœuds de tranches TPU multi-hôtes. Par exemple, vous ne pouvez pas utiliser Multislice avec ct4p-hightpu-4t avec une topologie 2x2x1 ou ct5lp-hightpu-4t avec une topologie 2x2, car il s'agit de pools de nœuds de tranche de pod TPU à hôte unique.
  • Multislice n'est compatible qu'avec l'entraînement synchrone multicontrôleur.
  • Les charges de travail Multislice ne peuvent s'exécuter que sur des tranches de TPU partageant le même type, la même taille et la même topologie de TPU.
  • Multislice n'est pas compatible avec TPU v3.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.

Exécuter une charge de travail sur Multislice

Cette section explique comment exécuter une charge de travail sur un Multislice. Si vous utilisez le mode GKE Autopilot, passez à la section Exécuter une charge de travail Multislice. Les clusters Autopilot qui exécutent la version 1.29.2-gke.1521000 ou une version ultérieure activent les TPU par défaut.

Préparer un pool de nœuds en mode Standard

Cette section couvre les étapes suivantes :

  1. Créer trois pools de nœuds de tranche TPU multi-hôtes.
  2. Vérifier l'état du pool de nœuds

Créer le pool de nœuds de tranche TPU

Vous pouvez créer plusieurs pools de nœuds de tranche TPU multi-hôtes. Pour les besoins de ce guide, créez trois pools de nœuds de tranche TPU multi-hôtes pour exécuter une charge de travail Multislice. Vous pouvez créer un pool de nœuds tranche de TPU multi-hôte à l'aide de Google Cloud CLI, de Terraform ou de la console Google Cloud .

gcloud

gcloud container node-pools create POOL_NAME \
    --location=LOCATION \
    --cluster=CLUSTER_NAME \
    --node-locations=NODE_ZONES \
    --machine-type=MACHINE_TYPE \
    --tpu-topology=TPU_TOPOLOGY \
    [--num-nodes=NUM_NODES] \
    [--spot \]
    [--flex-start \]
    [--enable-autoscaling \
      --max-nodes MAX_NODES]
    [--reservation-affinity=specific \
    --reservation=RESERVATION_NAME] \
    [--node-labels cloud.google.com/gke-nodepool-group-name=COLLECTION_NAME,cloud.google.com/gke-workload-type=HIGH_AVAILABILITY]
    [--placement-type=COMPACT]

Remplacez les éléments suivants :

  • POOL_NAME : nom du nouveau pool de nœuds.
  • LOCATION: nom de la zone basé sur la version de TPU que vous souhaitez utiliser. Pour identifier un emplacement disponible, consultez la section Disponibilité des TPU dans GKE.
  • CLUSTER_NAME : nom du cluster.
  • NODE_ZONES : liste d'une ou de plusieurs zones, séparées par une virgule, dans lesquelles GKE crée le pool de nœuds.
  • MACHINE_TYPE : type de machine à utiliser pour les nœuds. Pour en savoir plus sur les types de machines disponibles, consultez la section Choisir la version de TPU.
  • TPU_TOPOLOGY : Topologie physique de la tranche de TPU. Le format de la topologie dépend de la version du TPU. Pour en savoir plus sur les topologies TPU, consultez le tableau de la section Choisir une topologie.

    Pour en savoir plus, consultez la section Topologie.

Vous pouvez également utiliser les options suivantes :

  • NUM_NODES : Nombre de nœuds dans le pool de nœuds. Doit être égal à zéro ou au produit des valeurs définies dans TPU_TOPOLOGY ({A}x{B}x{C}) divisé par le nombre de puces dans chaque VM. Pour les TPU multi-hôtes v4 et v5e, le nombre de puces dans chaque VM est de quatre. Par conséquent, si votre TPU_TOPOLOGY est 2x4x4 (TPU v4 avec quatre puces dans chaque VM), la valeur de NUM_NODES est 32/4, ce qui correspond à 8. Si vous omettez cet indicateur, le nombre de nœuds est calculé et défini par défaut en fonction de la topologie et du type de machine.
  • RESERVATION_NAME : nom de la réservation utilisée par GKE lors de la création du pool de nœuds. Si vous omettez cette option, GKE utilise les pools de nœuds de tranche TPU disponibles. Pour en savoir plus sur les réservations TPU, consultez la page Réservations TPU.
  • --spot : définit le pool de nœuds de sorte qu'il utilise des VM Spot pour les nœuds de tranche TPU. Ce paramètre ne peut pas être modifié après la création du pool de nœuds. Pour en savoir plus, consultez la page VM Spot.
  • --flex-start: définit le pool de nœuds de sorte qu'il utilise le mode de provisionnement démarrage flexible.
  • --enable-autoscaling : Ajouter un pool de nœuds avec l'autoscaling activé. Lorsque GKE met à l'échelle un pool de nœuds de tranche TPU multi-hôte, il effectue un scaling de façon atomique du pool de nœuds de zéro à la taille maximale.

    • MAX_NODES : taille maximale du pool de nœuds. L'option --max-nodes est obligatoire si --enable-autoscaling est fourni. Elle doit être égale au produit des valeurs définies dans TPU_TOPOLOGY ({A}x{B}x{C}) divisée par le nombre de puces dans pour chaque VM.
  • --node-label=cloud.google.com/gke-nodepool-group-name=COLLECTION_NAME, cloud.google.com/gke-workload-type=HIGH_AVAILABILITY: indique à GKE que le pool de nœuds de tranche TPU multi-hôte est une collection. Utilisez cette option si les conditions suivantes s'appliquent:

    • Le pool de nœuds exécute les charges de travail d'inférence dans le nouveau pool de nœuds.
    • Le pool de nœuds utilise TPU Trillium.
    • Les VM Spot ne sont pas compatibles avec la planification de la collecte.

    Pour en savoir plus sur la gestion de la planification de la collecte, consultez Gérer la planification de la collecte dans les tranches TPU multi-hôtes.

  • --placement-type=COMPACT: Créer un pool de nœuds avec l'emplacement compact activé. Cette option doit être utilisée avec l'indicateur --tpu-topology. Pour en savoir plus, consultez les pages Créer une stratégie d'emplacement compact et Topologie TPU.

Terraform

  1. Assurez-vous d'utiliser la version 4.84.0 ou ultérieure du fournisseur google.
  2. Ajoutez le bloc suivant à votre configuration Terraform :

    resource "google_container_node_pool" "NODE_POOL_RESOURCE_NAME" {
      provider           = google
      project            = PROJECT_ID
      cluster            = CLUSTER_NAME
      name               = POOL_NAME
      location           = CLUSTER_LOCATION
      node_locations     = [NODE_ZONES]
      initial_node_count = NUM_NODES
    
      autoscaling {
        max_node_count = MAX_NODES
        location_policy      = "ANY"
      }
      node_config {
        machine_type = MACHINE_TYPE
        reservation_affinity {
          consume_reservation_type = "SPECIFIC_RESERVATION"
          key = "compute.googleapis.com/reservation-name"
          values = [RESERVATION_LABEL_VALUES]
        }
        spot = true
        flex_start = false
      }
    
      placement_policy {
        type = "COMPACT"
        tpu_topology = TPU_TOPOLOGY
      }
    }
    

    Remplacez les éléments suivants :

    • NODE_POOL_RESOURCE_NAME : nom de la ressource de pool de nœuds dans le modèle Terraform.
    • PROJECT_ID : ID de votre projet
    • CLUSTER_NAME : nom du cluster existant auquel ajouter le pool de nœuds.
    • POOL_NAME : nom du pool de nœuds à créer
    • CLUSTER_LOCATION : emplacement de calcul du cluster. Nous vous recommandons de disposer d'un cluster régional pour améliorer la fiabilité du plan de contrôle Kubernetes. Vous pouvez également utiliser un cluster zonal. Pour en savoir plus, consultez la section Sélectionner une version et une topologie de TPU.
    • NODE_ZONES : liste d'une ou de plusieurs zones, séparées par une virgule, dans lesquelles GKE crée le pool de nœuds.
    • NUM_NODES : Nombre de nœuds dans le pool de nœuds. Doit être égal à zéro ou au produit du nombre de puces TPU divisé par quatre, car dans les tranches de TPU à hôtes multiples, chaque nœud de tranche TPU comporte quatre puces. Par exemple, si TPU_TOPOLOGY est défini sur 4x8, il y a 32 puces, ce qui signifie que NUM_NODES doit être égal à 8. Pour en savoir plus sur les topologies TPU, consultez le tableau de la section Choisir la version de TPU.
    • TPU_TOPOLOGY : indique la topologie physique souhaitée pour la tranche de TPU. Le format de la topologie dépend de la version de TPU que vous utilisez. Pour en savoir plus sur les topologies TPU, consultez le tableau de la section Choisir une topologie.

    Vous pouvez également utiliser les variables suivantes :

    • RESERVATION_NAME : si vous utilisez la réservation TPU, il s'agit de la liste des libellés des ressources de réservation à utiliser lors de la création du pool de nœuds. Pour en savoir plus sur la spécification de RESERVATION_LABEL_VALUES dans le champ reservation_affinity, consultez la page Fournisseur Terraform.
    • autoscaling : Ajouter un pool de nœuds avec l'autoscaling activé. Lorsque GKE met à l'échelle un pool de nœuds de tranche TPU multi-hôte, il effectue un scaling de façon atomique du pool de nœuds de zéro à la taille maximale.
      • MAX_NODES : taille maximale du pool de nœuds. Elle doit être égale au produit des valeurs définies dans TPU_TOPOLOGY ({A}x{B}x{C}) divisée par le nombre de puces dans chaque VM.
    • spot : permet au pool de nœuds d'utiliser des VM Spot pour les nœuds de tranche TPU. Ce paramètre ne peut pas être modifié après la création du pool de nœuds. Pour en savoir plus, consultez la page VM Spot.
    • flex_start: définit le pool de nœuds de sorte qu'il utilise le mode de provisionnement démarrage flexible. Ne peut pas être défini sur true si spot est activé.

Console

Pour créer un pool de nœuds à l'aide de TPU, exécutez la commande suivante :

  1. Accédez à la page Google Kubernetes Engine dans la console Google Cloud .

    Accéder à Google Kubernetes Engine

  2. Dans la liste des clusters, cliquez sur le nom du cluster que vous souhaitez modifier.

  3. Cliquez sur Ajouter un pool de nœuds.

  4. Dans la section Détails du pool de nœuds, cochez la case Spécifier les emplacements de nœud.

  5. Sélectionnez le nom de la zone en fonction de la version de TPU que vous souhaitez utiliser. Pour identifier un emplacement disponible, consultez la section Disponibilité des TPU dans GKE.

  6. Dans le volet de navigation, cliquez sur Nœuds.

  7. Dans la section Configuration de la machine, sélectionnez TPU.

  8. Dans le menu déroulant Série, sélectionnez l'une des options suivantes :

    • CT3P: pour les TPU v3.
    • CT4P : pour les TPU v4.
    • CT5LP : pour les TPU v5e
  9. Dans le menu déroulant Type de machine, sélectionnez le nom de la machine à utiliser pour les nœuds. Utilisez le tableau Choisir la version de TPU pour apprendre à définir le type de machine et la topologie TPU qui créent un pool de nœuds de tranche TPU multi-hôtes.

  10. Dans le menu déroulant Topologie TPU, sélectionnez la topologie physique de la tranche de TPU.

  11. Dans la boîte de dialogue Modifications requises, cliquez sur Apporter des modifications.

  12. Assurez-vous d'avoir défini le champ Type de disque de démarrage sur Disque persistant standard ou Disque persistant SSD.

  13. Vous pouvez éventuellement cocher la case Activer les nœuds sur les VM Spot afin d'utiliser des VM Spot pour les nœuds du pool de nœuds.

  14. Cliquez sur Créer.

Vérifier l'état du pool de nœuds

  1. Obtenez des identifiants afin de pouvoir utiliser kubectl pour accéder au cluster :

    gcloud container clusters get-credentials CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION
    

    Remplacez les éléments suivants :

    • CLUSTER_NAME : nom du cluster.
    • PROJECT_ID : ID de votre projet
    • CONTROL_PLANE_LOCATION: emplacement Compute Engine du plan de contrôle de votre cluster. Indiquez une région pour les clusters régionaux ou une zone pour les clusters zonaux.
  2. Utilisez kubectl dans Cloud Shell pour afficher vos nœuds de tranche TPU :

    kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=ACCELERATOR_TYPE \
       -l cloud.google.com/gke-tpu-topology=TPU_TOPOLOGY
    

    Remplacez les éléments suivants :

    • TPU_ACCELERATOR: type d'accélérateur TPU que vous avez utilisé lors de la création des pools de nœuds. Par exemple, tpu-v4-podslice ou tpu-v5-lite-podslice.
    • TPU_TOPOLOGY : Topologie physique de la tranche de TPU.

    Le résultat ressemble à ce qui suit :

     NAME                                    STATUS   ROLES    AGE    VERSION
     gke-tpu-20ee2cce-5tv6                   Ready    <none>   34h     v1.28.1-gke.1066000
    

Exécuter une charge de travail Multislice

Dans cette section, vous exécutez une charge de travail JAX qui affiche le nombre global de puces TPU dans la tranche TPU, puis se ferme.

Pour exécuter une charge de travail JAX, procédez comme suit :

  1. Créez le fichier manifeste tpu-multislice.yaml suivant :

    Autopilot

    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: NUM_SLICES
          template:
            spec:
              parallelism: NUM_NODES
              completions: NUM_NODES
              backoffLimit: 0
              template:
                spec:
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: ACCELERATOR_TYPE
                    cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
                  containers:
                  - name: jax-tpu
                    image: python:3.10
                    ports:
                    - containerPort: 8471
                    - containerPort: 8080
                    - containerPort: 8431
                    command:
                    - bash
                    - -c
                    - |
                      pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                      python -c 'import jax; print("Global device count:", jax.device_count())'
                      sleep 60
                    resources:
                     limits:
                        google.com/tpu: NUM_CHIPS
    

    Standard

    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: NUM_SLICES
          template:
            spec:
              parallelism: NUM_NODES
              completions: NUM_NODES
              backoffLimit: 0
              template:
                spec:
                  hostNetwork: true
                  dnsPolicy: ClusterFirstWithHostNet
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: ACCELERATOR_TYPE
                    cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
                  containers:
                  - name: jax-tpu
                    image: python:3.10
                    ports:
                    - containerPort: 8471
                    - containerPort: 8080
                    - containerPort: 8431
                    securityContext:
                      privileged: true
                    command:
                    - bash
                    - -c
                    - |
                      pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                      python -c 'import jax; print("Global device count:", jax.device_count())'
                      sleep 60
                    resources:
                      limits:
                       google.com/tpu: NUM_CHIPS
    

    Remplacez les éléments suivants :

    • NUM_SLICES: nombre de pools de nœuds de tranche TPU. Dans ce cas, NUM_SLICES est égal à 3.
    • ACCELERATOR_TYPE: type d'accélérateur TPU que vous avez utilisé lors de la création des pools de nœuds. (par exemple, tpu-v4-podslice ou tpu-v5-lite-podslice).
    • TPU_TOPOLOGY : Topologie physique de la tranche de TPU. Par exemple, 4x4x4 ou 2x2 selon la version du TPU.
    • NUM_NODES : Nombre de nœuds dans le pool de nœuds. Doit être égal à zéro ou au produit des valeurs définies dans TPU_TOPOLOGY ({A}x{B}x{C}) divisé par le nombre de puces TPU dans chaque VM.  : pour les TPU multi-hôtes v4, le nombre de puces TPU dans chaque VM est de quatre. Pour les TPU multi-hôtes v5e, le nombre de puces TPU dans chaque VM est de un, quatre ou huit. Par conséquent, si votre TPU_TOPOLOGY est 2x4x4 (TPU v4 avec quatre puces TPU dans chaque VM), la valeur de NUM_NODES est 32/4, ce qui correspond à 8.
    • NUM_CHIPS : pour les TPU multi-hôtes v4, le nombre de puces TPU dans chaque VM est de quatre. Pour les TPU multi-hôtes v5e, le nombre de puces TPU dans chaque VM est de un, quatre ou huit. Pour en savoir plus, consultez la section puces TPU sur la VM dans une tranche TPU.

    Dans le fichier manifeste :

    • JobSet est un service headless portant le même nom que le nom JobSet. Dans le cas présent, il s'agit de multislice-job.
    • L'annotation alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool configure l'affinité des pods pour s'assurer que tous les pods sont programmés sur la même tranche.
    • La valeur maxRestarts: 4 indique le nombre maximal de redémarrages de GKE sur une ressource JobSet en cas d'échec d'un job enfant. Si le redémarrage de JobSet atteint la valeur maximale définie, la ressource JobSet est marquée comme ayant échoué.
    • Les champs parallelism et completions correspondent au nombre de nœuds dans chaque pool de nœuds.
    • Le paramètre backoff est égal à 0, car Multislice n'accepte que l'entraînement synchrone multicontrôleurs. Doit être défini sur 0. Faire échouer le job en cas de défaillance d'un pod.
    • Les valeurs de la section d'affinité permettent de s'assurer qu'une seule charge de travail TPU Multislice s'exécute dans un groupe de segments multiples.
    • containerPort: 8080 est le port du coordinateur MXLA.
    • containerPort: 8431 est le port permettant d'exporter les métriques d'utilisation du TPU.
    • L'élément securityContext: privileged: true indique que le mode privilégié est activé pour les nœuds pour l'accès aux TPU. Les nœuds de GKE version 1.28 ou ultérieure n'ont pas besoin d'activer le mode privilégié pour accéder aux TPU. Pour en savoir plus, consultez la page Exécuter des conteneurs sans mode privilégié.
  2. Appliquez le fichier manifeste :

    kubectl apply -f tpu-multislice.yaml
    
  3. Confirmez que la charge de travail est acceptée :

    kubectl get jobsets
    

    Le résultat ressemble à ce qui suit :

    NAME            RESTARTS   COMPLETED   AGE
    multislice-job                         3s
    
  4. Surveillez l'état des pods provisionnés :

    kubectl get pods
    

    Le résultat ressemble à ce qui suit :

     NAME                                READY   STATUS      RESTARTS   AGE
     multislice-job-slice-0-0-wzq9t      0/1     Completed   0          2m31s
     multislice-job-slice-0-1-zf4dp      0/1     Completed   0          2m30s
     multislice-job-slice-1-0-hbfn5      0/1     Completed   0          2m31s
     multislice-job-slice-1-1-45fgl      0/1     Completed   0          2m30s
     multislice-job-slice-2-0-wjbp4      0/1     Completed   0          2m30s
     multislice-job-slice-2-1-lwnvs      0/1     Completed   0          2m30s
    

    JobSet multislice-job planifie, crée, puis exécute les pods jusqu'à la fin. Les noms des pods sont au format <jobsetName>-<jobName>-<jobReplicaIndex>-<randomSuffix>. Le préfixe jobsetName détermine le JobJob auquel appartient le pod.

  5. (Facultatif) Supprimez la charge de travail JAX :

    kubectl delete -f tpu-multislice.yaml
    

Configurer des paramètres supplémentaires

Les sections suivantes décrivent les configurations supplémentaires que vous pouvez appliquer à votre objet Multislice.

Améliorer les performances réseau avec hostNetwork

Pour améliorer les performances réseau entre les tranches de TPU, nous vous recommandons d'activer hostNetworking. Utilisez hostNetwork: true dans la spécification de pod pour ignorer toute la pile réseau Kubernetes et laisser vos pods Kubernetes utiliser directement le réseau hôte pour une communication de VM à VM.

Pour activer hostNetworking, ajoutez les deux lignes suivantes à la spécification de votre pod:

hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet

Pour continuer à utiliser podHostnames pour la découverte de nœuds de calcul avec hostNetwork, définissez dnsPolicy: ClusterFirstWithHostNet. Cela est important lorsque vous exécutez des tâches de reprise automatique et que vous devez disposer des mêmes noms pour actualiser les mêmes points de contrôle.

Si vous utilisez TPU Trillium (v6e) et que vos pods utilisent hostNetworking, installez le DaemonSet suivant pour régler /proc/sys/net/ipv4/tcp_rmem sur le nœud.

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/ai-on-gke/51bf3dcab6ff658cf62cc32867f96860bf58dfdc/scripts/network-setup/v6e-increase-rmem.yaml

Améliorer les performances réseau sans hostNetwork sur TPU Trillium

Si vous utilisez TPU Trillium et que vos pods ne peuvent pas utiliser hostNetworking, activez la multiréseaux avec le mode netdevice pour obtenir les meilleures performances réseau. La compatibilité de la carte d'interface réseau en mode netdevice avec le multiréseau transmet directement la carte d'interface réseau de la VM au pod, en contournant Kubernetes et GKE Dataplane V2.

Le type de machine ct6e-standard-4t est pris en charge par deux cartes réseau physiques. Kubernetes nécessite un vNIC qui ne peut pas être transmis aux pods. Par conséquent, chaque nœud doit disposer de trois vNIC pour permettre aux pods d'avoir un accès direct à deux vNIC afin d'obtenir les meilleures performances des deux NIC physiques.

Pour activer le mode netdevice pour ct6e-standard-4t, procédez comme suit:

  1. Créer deux VPC supplémentaires compatibles avec le mode netdevice
  2. Créer un cluster GKE avec des fonctionnalités multiréseaux
  3. Configurez deux réseaux netdevice. Par exemple, vous pouvez utiliser les objets GKENetworkParamSet et Network suivants (SECOND_VPC et THIRD_VPC sont les VPC créés à l'étape précédente):

    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: tpu-second
    spec:
      vpc: SECOND_VPC
      vpcSubnet: SECOND_VPC_SUBNET
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: tpu-third
    spec:
      vpc: THIRD_VPC
      vpcSubnet: SECOND_VPC_SUBNET
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: tpu-second
    spec:
      provider: "GKE"
      type: "Device"
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: tpu-second
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: tpu-third
    spec:
      provider: "GKE"
      type: "Device"
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: tpu-third
    
  4. Connectez vos pods à trois réseaux. Par exemple, vous pouvez utiliser les annotations suivantes dans la spécification de votre pod:

    metadata:
      annotations:
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"tpu-second"},
            {"interfaceName":"eth2","network":"tpu-third"},
          ]
    
  5. Appliquez des sysctls réseau dans le pod, dans le conteneur d'initialisation ou dans le conteneur d'application. Par exemple, vous pouvez ajouter le conteneur d'initialisation suivant à la spécification du pod:

    initContainers:
    - name: "network-optimization-sysctls"
      image: "busybox"
      securityContext:
        privileged: true
      command:
      - bash
      - -c
      - |
        echo 5000 > /proc/sys/net/ipv4/tcp_rto_min_us
        echo 1 > /proc/sys/net/ipv4/tcp_no_metrics_save
        echo 0 > /proc/sys/net/ipv4/tcp_slow_start_after_idle
        echo 131072 > /proc/sys/net/core/optmem_max
        echo "4096 41943040 314572800" > /proc/sys/net/ipv4/tcp_rmem
    
Bonne pratique :

Utilisez les interfaces eth1 et eth2 pour améliorer les performances de mise en réseau plutôt que l'interface eth0. Pour ce faire, ajoutez export LIBTPU_INIT_ARGS="$LIBTPU_INIT_ARGS --megascale_grpc_interface_prefixes=eth1,eth2,lo" à la spécification de la charge de travail.

Activer la journalisation

Les journaux émis par les conteneurs s'exécutant sur des nœuds GKE, y compris les nœuds de tranche TPU, sont visibles dans l'explorateur de journaux, si vous avez activé la journalisation système GKE dans votre cluster.

Vous pouvez afficher vos journaux à partir de GKE à l'aide de l'explorateur de journaux avec le filtre suivant pour afficher les journaux de conteneur de votre charge de travail :

resource.type="k8s_container"
resource.labels.cluster_name=CLUSTER_NAME
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"=JOBSET_NAME

Utilisez le filtre suivant pour les tranches et les nœuds de calcul TPU :

resource.type="k8s_container"
resource.labels.cluster_name=CLUSTER_NAME
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"=JOBSET_NAME
resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>

Pour en savoir plus, consultez Afficher les journaux TPU GKE.

Activer des métriques supplémentaires

En plus des métriques TPU générales, il existe quatre métriques d'exécution TPU multislice spécifiques. Ces métriques sont disponibles dans GKE 1.29.1-gke.1016000 ou version ultérieure. La charge de travail TPU doit utiliser la version JAX 0.4.24

Voici les métriques multislice disponibles :

  • Latences de transfert DCN (réseau de centres de données) : distribution des latences de transfert réseau pour le trafic multislice.
  • Latences collectives : répartition de la latence collective de bout en bout pour le trafic multislice.
  • Latences de transfert hôte à appareil : répartition de la latence de transfert hôte à appareil pour chaque fragment de données pour le trafic multislice.
  • Latences de transfert d'appareil à hôte : répartition de la latence de transfert entre l'appareil et l'hôte, pour chaque fragment de données pour le trafic multislice.

Ces métriques se trouvent dans le schéma du conteneur Kubernetes (k8s_container) :

  • kubernetes.io/container/multislice/network/dcn_transfer_latencies
  • kubernetes.io/container/multislice/network/collective_end_to_end_latencies
  • kubernetes.io/container/multislice/accelerator/host_to_device_transfer_latencies
  • kubernetes.io/container/multislice/accelerator/device_to_host_transfer_latencies

Tranche de pod TPU ou Multislice

Le tableau suivant différencie l'organisation architecturale d'une tranche de TPU et Multislice :

Tranche TPU Multicouche
Interconnectivité La charge de travail s'exécute sur une seule tranche de TPU. Toutes les puces TPU d'une tranche sont connectées à ICI. La charge de travail s'exécute sur plusieurs tranches de TPU. La communication au sein d'une tranche s'effectue via ICI. La communication entre les tranches s'effectue via DCN.
Pools de nœuds compatibles Tranche de TPU à hôte unique et tranche de TPU à multi-hôte Groupes de tranches de TPU multi-hôte
Type de charge de travail recommandé IndexedJob ou JobSet JobSet

Effectuer un nettoyage des ressources

Le moyen le plus simple d'empêcher la facturation est de supprimer le Google Cloud projet que vous avez créé pour ce tutoriel. Vous pouvez également supprimer les différentes ressources.

Supprimer le projet

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

Supprimer des ressources individuelles

Supprimez le cluster GKE :

```sh
gcloud container clusters delete  CLUSTER_NAME \
   --project=PROJECT_ID  \
   --location=CONTROL_PLANE_LOCATION
```

Étapes suivantes