Présentation des TPU dans GKE

Les clients Google Kubernetes Engine (GKE) peuvent désormais créer des pools de nœuds Kubernetes contenant des tranches TPU v4 et v5e. Pour en savoir plus sur les TPU, consultez la page Architecture du système.

Lorsque vous travaillez avec GKE, vous devez d'abord créer un cluster GKE. Vous ajoutez ensuite des pools de nœuds à votre cluster. Les pools de nœuds GKE sont des ensembles de VM partageant les mêmes attributs. Pour les charges de travail TPU, les pools de nœuds sont constitués de VM TPU.

Types de pools de nœuds

GKE est compatible avec deux types de pools de nœuds TPU:

Pool de nœuds des tranches TPU multi-hôtes

Un pool de nœuds de tranches TPU à hôtes multiples est un pool de nœuds contenant au moins deux VM TPU interconnectées. Un appareil TPU est connecté à chaque VM. Les TPU d'une tranche à hôtes multiples sont connectés via une interconnexion à haut débit (ICI). Une fois qu'un pool de nœuds de tranches multi-hôtes est créé, vous ne pouvez plus y ajouter de nœuds. Par exemple, vous ne pouvez pas créer un pool de nœuds v4-32, puis ajouter ultérieurement un nœud Kubernetes supplémentaire (VM TPU) au pool de nœuds. Pour ajouter une tranche TPU supplémentaire à un cluster GKE, vous devez créer un pool de nœuds.

Les hôtes d'un pool de nœuds de tranches TPU multi-hôtes sont traités comme une seule unité atomique. Si GKE ne parvient pas à déployer un nœud de la tranche, aucun nœud de la tranche ne sera déployé.

Si un nœud d'une tranche TPU à hôtes multiples doit être réparé, GKE arrête toutes les VM TPU de la tranche, forçant ainsi l'éviction de tous les pods Kubernetes de la charge de travail. Une fois que toutes les VM TPU de la tranche sont opérationnelles, les pods Kubernetes peuvent être programmés sur les VM TPU de la nouvelle tranche.

Le schéma suivant montre un exemple de tranche de TPU à plusieurs hôtes v5litepod-16 (v5e). Cette tranche comporte quatre VM TPU. Chaque VM TPU comporte quatre puces TPU v5e connectées par des interconnexions à haut débit (ICI), et chaque puce TPU v5e possède un TensorCore.

Schéma des tranches de TPU multi-hôte

Le schéma suivant montre un cluster GKE contenant une tranche de TPU v5litepod-16 (v5e) (topologie: 4x4) et une tranche TPU v5litepod-8 (v5e) (topologie: 2x4):

Schéma du pod TPU v5e

Pour obtenir un exemple d'exécution d'une charge de travail sur une tranche de TPU multi-hôtes, consultez la section Exécuter votre charge de travail sur des TPU.

Pools de nœuds de tranches TPU à hôte unique

Une tranche à hôte unique est un pool de nœuds qui contient une ou plusieurs VM TPU indépendantes. Un appareil TPU est connecté à chaque VM. Bien que les VM d'un pool de nœuds de tranches à hôte unique puissent communiquer sur le réseau de centre de données (DCN), les TPU associés aux VM ne sont pas interconnectés.

Le schéma suivant montre un exemple de tranche TPU à hôte unique avec sept machines v4-8:

Schéma du pool de nœuds de tranches à hôte unique

Pour obtenir un exemple d'exécution d'une charge de travail sur une tranche TPU à hôte unique, consultez la section Exécuter votre charge de travail sur des TPU.

Types de machines TPU pour les pools de nœuds GKE

Avant de créer des pools de nœuds, vous devez choisir la version de TPU et la taille de la tranche TPU requise par votre charge de travail. Le TPU v4 est compatible avec GKE Standard 1.26.1-gke.1500 et versions ultérieures, v5e dans GKE Standard 1.27.2-gke.2100 et versions ultérieures, et v5p dans GKE Standard 1.28.3-gke.1024000 et versions ultérieures.

Les TPU v4, v5e et v5p sont compatibles avec GKE Autopilot 1.29.2-gke.1521000 et versions ultérieures.

Pour en savoir plus sur les caractéristiques matérielles des différentes versions de TPU, consultez la section Architecture du système. Lors de la création d'un pool de nœuds TPU, sélectionnez une taille de tranche TPU (topologie TPU) en fonction de la taille de votre modèle et de la quantité de mémoire requise. Le type de machine que vous spécifiez lors de la création de vos pools de nœuds dépend de la version et de la taille de vos tranches.

V5E

Voici les topologies et types de machines TPU v5e compatibles avec les cas d'utilisation d'entraînement et d'inférence:

Type de machine Topology Nombre de puces TPU Nombre de VM Cas d'utilisation recommandé
ct5lp-hightpu-1t 1x1 1 1 Entraînement, inférence à hôte unique
ct5lp-hightpu-4t 2x2 4 1 Entraînement, inférence à hôte unique
ct5lp-hightpu-8t 2x4 8 1 Entraînement, inférence à hôte unique
ct5lp-hightpu-4t 2x4 8 2 Entraînement, inférence multi-hôte
ct5lp-hightpu-4t 4x4 16 4 Entraînement à grande échelle, inférence sur plusieurs hôtes
ct5lp-hightpu-4t 4x8 32 8 Entraînement à grande échelle, inférence sur plusieurs hôtes
ct5lp-hightpu-4t 8x8 64 16 Entraînement à grande échelle, inférence sur plusieurs hôtes
ct5lp-hightpu-4t 8x16 128 32 Entraînement à grande échelle, inférence sur plusieurs hôtes
ct5lp-hightpu-4t 16x16 256 64 Entraînement à grande échelle, inférence sur plusieurs hôtes

Cloud TPU v5e est un produit combiné d'entraînement et d'inférence. Les jobs d'entraînement sont optimisés pour le débit et la disponibilité, tandis que les jobs d'inférence sont optimisés pour la latence. Pour en savoir plus, consultez les pages Types d'accélérateurs d'entraînement v5e et Types d'accélérateurs d'inférence v5e.

Les machines TPU v5e sont disponibles dans us-west4-a, us-east5-b et us-east1-c. Les clusters GKE Standard doivent exécuter le plan de contrôle version 1.27.2-gke.2100 ou ultérieure. GKE Autopilot doit exécuter le plan de contrôle 1.29.2-gke.1521000 ou une version ultérieure. Pour en savoir plus sur la version v5e, consultez la page Entraînement Cloud TPU v5e.

Comparaison des types de machines :

Type de machine ct5lp-hightpu-1t ct5lp-hightpu-4t ct5lp-hightpu-8t
Nombre de puces v5e 1 4 8
Nombre de vCPU 24 112 224
Mémoire RAM (Go) 48 192 384
Nombre de nœuds NUMA 1 1 2
Probabilité de préemption Élevée Moyenne Faible

Pour libérer de l'espace pour les VM dotées de plus de puces, le programmeur GKE peut préempter et replanifier les VM ayant moins de puces. Les VM à 8 puces ont donc plus de chances de préempter les VM à 1 et 4 puces.

v4 et v5p

Voici les types de machines TPU v4 et v5p:

Type de machine Nombre de processeurs virtuels Mémoire (Go) Nombre de nœuds NUMA
ct4p-hightpu-4t 240 407 2
ct5p-hightpu-4t 208 448 2

Lorsque vous créez une tranche TPU v4, utilisez le type de machine ct4p-hightpu-4t, qui possède un hôte et quatre puces. Pour en savoir plus, consultez les pages Topologies v4 et Architecture du système TPU. Les types de machines de tranches TPU v4 sont disponibles dans us-central2-b. Vos clusters GKE Standard doivent exécuter le plan de contrôle 1.26.1-gke.1500 ou une version ultérieure. Les clusters GKE Autopilot doivent exécuter le plan de contrôle 1.29.2-gke.1521000 ou une version ultérieure.

Lors de la création d'une tranche TPU v5p, utilisez le type de machine ct5p-hightpu-4t, qui possède un hôte et quatre puces. Les types de machines des tranches TPU v5p sont disponibles dans us-west4-a et us-east5-a. Les clusters GKE Standard doivent exécuter le plan de contrôle 1.28.3-gke.1024000 ou une version ultérieure. GKE Autopilot doit exécuter 1.29.2-gke.1521000 ou une version ultérieure. Pour en savoir plus sur v5p, consultez la présentation de l'entraînement v5p.

Limites et problèmes connus

  • Nombre maximal de pods Kubernetes: vous pouvez exécuter un maximum de 256 pods Kubernetes dans une seule VM TPU.
  • Réservations spécifiques uniquement: lorsque vous utilisez des TPU dans GKE, SPECIFIC est la seule valeur acceptée pour l'option --reservation-affinity de la commande gcloud container node-pools create.
  • Seule la variante de VM Spot des TPU préemptifs est compatible : les VM Spot sont semblables aux VM préemptives et sont soumises aux mêmes limites de disponibilité, mais leur durée maximale n'est pas de 24 heures.
  • Aucune compatibilité avec la répartition des coûts: la répartition des coûts GKE et la mesure de l'utilisation n'incluent aucune donnée sur l'utilisation ou les coûts des TPU.
  • L'autoscaler peut calculer la capacité: l'autoscaler de cluster peut calculer la capacité de manière incorrecte pour les nouveaux nœuds contenant des VM TPU avant que ces nœuds ne soient disponibles. L'autoscaler de cluster peut ensuite effectuer un scaling à la hausse supplémentaire et, par conséquent, créer plus de nœuds que nécessaire. L'autoscaler de cluster réduit la capacité des nœuds supplémentaires qui ne sont plus nécessaires après une opération de scaling à la baisse standard.
  • L'autoscaler annule le scaling à la hausse: l'autoscaler de cluster annule le scaling à la hausse des pools de nœuds TPU qui restent en attente pendant plus de 10 heures. L'autoscaler de cluster relancera ces opérations de scaling à la hausse ultérieurement. Ce comportement peut réduire l'obtention de TPU pour les clients qui n'utilisent pas de réservations.
  • La rejet peut empêcher le scaling à la baisse: les charges de travail non-TPU qui ont une tolérance pour le rejet TPU peuvent empêcher le scaling à la baisse du pool de nœuds si elles sont recréées lors du drainage du pool de nœuds TPU.

Assurez-vous que les quotas TPU et GKE sont suffisants

Vous devrez peut-être augmenter certains quotas liés à GKE dans les régions où vos ressources sont créées.

Les quotas suivants ont des valeurs par défaut que vous devrez probablement augmenter:

  • Quota de disques persistants SSD (Go): le disque de démarrage de chaque nœud Kubernetes nécessite 100 Go par défaut. Par conséquent, ce quota doit être au moins égal à (nombre maximal de nœuds GKE que vous prévoyez de créer) x 100 Go.
  • Quota d'adresses IP en cours d'utilisation: chaque nœud Kubernetes utilise une adresse IP. Par conséquent, ce quota doit être au moins égal au nombre maximal de nœuds GKE que vous prévoyez de créer.

Pour demander une augmentation du quota, consultez la section Demander un quota supérieur. Pour en savoir plus sur les types de quotas TPU, consultez la section Quotas TPU.

L'approbation de vos demandes d'augmentation de quota peut prendre quelques jours. Si vous rencontrez des difficultés pour faire approuver vos demandes d'augmentation de quota dans un délai de quelques jours, contactez l'équipe chargée de votre compte Google.

Migrer votre réservation TPU

Si vous ne prévoyez pas d'utiliser une réservation TPU existante avec des TPU dans GKE, ignorez cette section et passez à la section Créer un cluster Google Kubernetes Engine.

Pour utiliser des TPU réservés avec GKE, vous devez d'abord migrer votre réservation TPU vers un nouveau système de réservation basé sur Compute Engine.

Il y a plusieurs points importants à connaître sur cette migration:

  • La capacité TPU migrée vers le nouveau système de réservation basé sur Compute Engine ne peut pas être utilisée avec l'API Queued Resource de Cloud TPU. Si vous avez l'intention d'utiliser des ressources en file d'attente TPU avec votre réservation, vous devez migrer une partie de votre réservation TPU vers le nouveau système de réservation basé sur Compute Engine.
  • Aucune charge de travail ne peut s'exécuter activement sur les TPU lorsqu'elles sont migrées vers le nouveau système de réservation basé sur Compute Engine.
  • Sélectionnez une heure pour effectuer la migration et planifiez la migration avec l'équipe chargée de votre compte Google Cloud. La période de migration doit se situer pendant les heures de bureau (du lundi au vendredi, de 9h à 17h, heure du Pacifique).

Créer un cluster Google Kubernetes Engine

Consultez la page Créer un cluster dans la documentation Google Kubernetes Engine.

Créer un pool de nœuds TPU

Consultez la page Créer un pool de nœuds dans la documentation Google Kubernetes Engine.

Exécuter sans le mode privilégié

Si vous souhaitez réduire le champ d'application des autorisations sur votre conteneur, consultez la section Mode privilège TPU.

Exécuter des charges de travail dans des pools de nœuds TPU

Consultez la page Exécuter vos charges de travail GKE sur des TPU dans la documentation Google Kubernetes Engine.

Sélecteurs de nœuds

Pour que Kubernetes puisse planifier votre charge de travail sur des nœuds contenant des VM TPU, vous devez spécifier deux sélecteurs pour chaque nœud dans votre fichier manifeste Google Kubernetes Engine:

  • Définissez cloud.google.com/gke-accelerator-type sur tpu-v5-lite-podslice ou tpu-v4-podslice.
  • Définissez cloud.google.com/gke-tpu-topology sur la topologie TPU du nœud.

Les sections Charges de travail d'entraînement et Charges de travail d'inférence contiennent des exemples de fichiers manifestes qui illustrent l'utilisation de ces sélecteurs de nœuds.

Considérations sur la planification des charges de travail

Les TPU présentent des caractéristiques uniques qui nécessitent une planification et une gestion spéciales des charges de travail dans Kubernetes. Pour en savoir plus, consultez la section Considérations relatives à la planification des charges de travail dans la documentation GKE.

Réparation des nœuds

Si un nœud d'un pool de nœuds de tranches TPU multi-hôtes n'est pas opérationnel, GKE recrée l'intégralité du pool de nœuds. Pour en savoir plus, consultez la section Réparation automatique des nœuds dans la documentation GKE.

Tranches multiples : aller au-delà d'une seule tranche

Vous pouvez agréger des tranches plus petites dans une multitranche pour gérer les charges de travail d'entraînement plus importantes. Pour en savoir plus, consultez la page Cloud TPU multi-tranche.

Tutoriels sur les charges de travail d'entraînement

Ces tutoriels se concentrent sur les charges de travail d'entraînement sur une tranche TPU à hôtes multiples (par exemple, quatre machines v5e). Elles couvrent les modèles suivants:

  • Modèles FLAX Hugging Face: Train Diffusion sur Pokémon
  • PyTorch/XLA: GPT2 sur WikiText

Télécharger les ressources du tutoriel

Téléchargez les scripts Python du tutoriel et les spécifications YAML pour chaque modèle pré-entraîné à l'aide de la commande suivante:

git clone https://github.com/GoogleCloudPlatform/ai-on-gke.git

Créer un cluster et s'y connecter

Créez un cluster GKE régional afin que le plan de contrôle Kubernetes soit répliqué dans trois zones, offrant ainsi une plus grande disponibilité. Créez votre cluster dans us-west4, us-east1 ou us-central2 selon la version de TPU que vous utilisez. Pour en savoir plus sur les TPU et les zones, consultez la page Régions et zones de Cloud TPU.

La commande suivante crée un cluster régional GKE abonné au version disponible rapide avec un pool de nœuds contenant initialement un nœud par zone. La commande active également les fonctionnalités du pilote CSI Workload Identity et Cloud Storage FUSE sur votre cluster, car les exemples de charges de travail d'inférence présentés dans ce guide utilisent des buckets Cloud Storage pour stocker des modèles pré-entraînés.

gcloud container clusters create cluster-name \
  --region your-region \
  --release-channel rapid \
  --num-nodes=1 \
  --workload-pool=project-id.svc.id.goog \
  --addons GcsFuseCsiDriver

Pour activer les fonctionnalités des pilotes CSI Workload Identity et Cloud Storage FUSE pour les clusters existants, exécutez la commande suivante:

gcloud container clusters update cluster-name \
  --region your-region \
  --update-addons GcsFuseCsiDriver=ENABLED \
  --workload-pool=project-id.svc.id.goog

Les exemples de charges de travail sont configurés avec les hypothèses suivantes:

  • le pool de nœuds utilise tpu-topology=4x4 avec quatre nœuds
  • le pool de nœuds utilise machine-type ct5lp-hightpu-4t

Exécutez la commande suivante pour vous connecter au cluster que vous venez de créer:

gcloud container clusters get-credentials cluster-name \
--location=cluster-region

Modèles FLAX Hugging Face: Train Diffusion sur Pokémon

Cet exemple entraîne le modèle de diffusion stable à partir de HuggingFace à l'aide de l'ensemble de données Pokémon.

Le modèle Stable Diffusion est un modèle texte-image latent qui génère des images photoréalistes à partir de n'importe quelle entrée de texte. Pour en savoir plus sur Stable Diffusion, consultez les pages suivantes:

Créer une image Docker

Le Dockerfile se trouve dans le dossier ai-on-gke/tutorials-and-examples/tpu-examples/training/diffusion/.

Avant d'exécuter la commande suivante, assurez-vous que votre compte dispose des autorisations appropriées pour que Docker puisse transférer vers le dépôt.

Créez et transférez l'image Docker:

cd ai-on-gke/tutorials-and-examples/tpu-examples/training/diffusion/
docker build -t gcr.io/project-id/diffusion:latest .
docker push gcr.io/project-id/diffusion:latest

Déployer la charge de travail

Créez un fichier avec le contenu suivant et nommez-le tpu_job_diffusion.yaml. Remplissez le champ "Image" avec l'image que vous venez de créer.

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None
  selector:
    job-name: tpu-job-diffusion
---
apiVersion: batch/v1
kind: Job
metadata:
  name: tpu-job-diffusion
spec:
  backoffLimit: 0
  # Completions and parallelism should be the number of chips divided by 4.
  # (e.g. 4 for a v5litepod-16)
  completions: 4
  parallelism: 4
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc
      restartPolicy: Never
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
        cloud.google.com/gke-tpu-topology: 4x4
      containers:
      - name: tpu-job-diffusion
        image: gcr.io/${project-id}/diffusion:latest
        ports:
        - containerPort: 8471 # Default port using which TPU VMs communicate
        - containerPort: 8431 # Port to export TPU usage metrics, if supported
        command:
        - bash
        - -c
        - |
          cd examples/text_to_image
          python3 train_text_to_image_flax.py --pretrained_model_name_or_path=duongna/stable-diffusion-v1-4-flax --dataset_name=lambdalabs/pokemon-blip-captions --resolution=128 --center_crop --random_flip --train_batch_size=4 --mixed_precision=fp16 --max_train_steps=1500 --learning_rate=1e-05 --max_grad_norm=1 --output_dir=sd-pokemon-model
        resources:
          requests:
            google.com/tpu: 4
          limits:
            google.com/tpu: 4

Déployez-la ensuite à l'aide de la commande suivante:

kubectl apply -f tpu_job_diffusion.yaml

Effectuer un nettoyage

Une fois l'exécution de votre job terminée, vous pouvez la supprimer à l'aide de la commande suivante:

kubectl delete -f tpu_job_diffusion.yaml

PyTorch/XLA: GPT2 sur WikiText

Ce tutoriel explique comment exécuter GPT2 sur des TPU v5e en utilisant HuggingFace sur PyTorch/XLA avec l'ensemble de données wikitext.

Créer une image Docker

Le Dockerfile se trouve dans le dossier ai-on-gke/tutorials-and-examples/tpu-examples/training/gpt/.

Avant d'exécuter la commande suivante, assurez-vous que votre compte dispose des autorisations appropriées pour que Docker puisse transférer vers le dépôt.

Créez et transférez l'image Docker:

cd ai-on-gke/tutorials-and-examples/tpu-examples/training/gpt/
docker build -t gcr.io/project-id/gpt:latest .
docker push gcr.io/project-id/gpt:latest

Déployer la charge de travail

Copiez le fichier YAML suivant et enregistrez-le dans un fichier nommé tpu_job_gpt.yaml. Remplissez le champ "Image" avec l'image que vous venez de créer.

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None
  selector:
    job-name: tpu-job-gpt
---
apiVersion: batch/v1
kind: Job
metadata:
  name: tpu-job-gpt
spec:
  backoffLimit: 0
  # Completions and parallelism should be the number of chips divided by 4.
  # (for example, 4 for a v5litepod-16)
  completions: 4
  parallelism: 4
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc
      restartPolicy: Never
      volumes:
      # Increase size of tmpfs /dev/shm to avoid OOM.
      - name: shm
        emptyDir:
          medium: Memory
          # consider adding `sizeLimit: XGi` depending on needs
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice
        cloud.google.com/gke-tpu-topology: 4x4
      containers:
      - name: tpu-job-gpt
        image: gcr.io/$(project-id)/gpt:latest
        ports:
        - containerPort: 8479
        - containerPort: 8478
        - containerPort: 8477
        - containerPort: 8476
        - containerPort: 8431 # Port to export TPU usage metrics, if supported.
        env:
        - name: PJRT_DEVICE
          value: 'TPU'
        - name: XLA_USE_BF16
          value: '1'
        command:
        - bash
        - -c
        - |
          numactl --cpunodebind=0 python3 -u examples/pytorch/xla_spawn.py   --num_cores 4 examples/pytorch/language-modeling/run_clm.py    --num_train_epochs 3 --dataset_name wikitext     --dataset_config_name wikitext-2-raw-v1 --per_device_train_batch_size 16    --per_device_eval_batch_size 16 --do_train --do_eval  --output_dir /tmp/test-clm     --overwrite_output_dir --config_name my_config_2.json --cache_dir /tmp --tokenizer_name gpt2  --block_size 1024 --optim adafactor --adafactor true --save_strategy no --logging_strategy no --fsdp "full_shard" --fsdp_config fsdp_config.json
        volumeMounts:
        - mountPath: /dev/shm
          name: shm
        resources:
          requests:
            google.com/tpu: 4
          limits:
            google.com/tpu: 4

Déployez le workflow à l'aide de la commande suivante:

kubectl apply -f tpu_job_gpt.yaml

Effectuer un nettoyage

Une fois l'exécution de votre job terminée, vous pouvez la supprimer à l'aide de la commande suivante:

kubectl delete -f tpu_job_gpt.yaml

Tutoriel: Charges de travail d'inférence à hôte unique

Ce tutoriel explique comment exécuter une charge de travail d'inférence à hôte unique sur des TPU GKE v5e pour des modèles pré-entraînés avec JAX, TensorFlow et PyTorch. De manière générale, vous devez effectuer quatre étapes distinctes sur le cluster GKE:

  1. Créer un bucket Cloud Storage et configurer l'accès à celui-ci Vous stockez le modèle pré-entraîné à l'aide d'un bucket Cloud Storage.

  2. Télécharger un modèle pré-entraîné et le convertir en modèle compatible TPU. Appliquez un pod Kubernetes qui télécharge le modèle pré-entraîné, utilise le convertisseur Cloud TPU et stocke les modèles convertis dans un bucket Cloud Storage à l'aide du pilote CSI Cloud Storage FUSE. Le convertisseur Cloud TPU ne nécessite aucun matériel spécialisé. Ce tutoriel vous explique comment télécharger le modèle et exécuter le convertisseur Cloud TPU dans le pool de nœuds processeur.

  3. Lancer le serveur du modèle converti Appliquez un déploiement qui diffuse le modèle à l'aide d'un framework de serveur reposant sur le volume stocké dans le volume persistant ReadOnlyMany (ROX). Les instances répliquées de déploiement doivent être exécutées dans un pool de nœuds de tranche v5e avec un pod Kubernetes par nœud, et dans un pool de nœuds de tranche v5e avec un pod Kubernetes par nœud.

  4. Déployer un équilibreur de charge pour tester le serveur de modèles Le serveur est exposé à des requêtes externes utilisant le service LoadBalancer. Un script Python est fourni avec un exemple de requête permettant de tester le serveur de modèles.

Le schéma suivant montre comment les requêtes sont acheminées par l'équilibreur de charge.

Schéma illustrant le routage de l'équilibreur de charge

Exemples de déploiement de serveur

Ces exemples de charges de travail sont configurés selon les hypothèses suivantes:

  • Le cluster est exécuté avec un pool de nœuds TPU v5 comportant trois nœuds
  • Le pool de nœuds utilise le type de machine ct5lp-hightpu-1t où :
    • est de type 1 x 1
    • le nombre de puces TPU est de 1

Le fichier manifeste GKE suivant définit un déploiement sur un seul serveur hôte.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: bert-deployment
spec:
  selector:
    matchLabels:
      app: tf-bert-server
  replicas: 3 # number of nodes in node pool
  template:
    metadata:
      annotations:
        gke-gcsfuse/volumes: "true"
      labels:
        app: tf-bert-server
    spec:
      nodeSelector:
        cloud.google.com/gke-tpu-topology: 1x1  # target topology
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice  # target version
      containers:
      - name: serve-bert
        image: us-docker.pkg.dev/cloud-tpu-images/inference/tf-serving-tpu:2.13.0
        env:
        - name: MODEL_NAME
          value: "bert"
        volumeMounts:
        - mountPath: "/models/"
          name: bert-external-storage
        ports:
        - containerPort: 8500
        - containerPort: 8501
        - containerPort: 8431 # Port to export TPU usage metrics, if supported.
        resources:
          requests:
            google.com/tpu: 1 # TPU chip request
          limits:
            google.com/tpu: 1 # TPU chip request
      volumes:
      - name: bert-external-storage
        persistentVolumeClaim:
          claimName: external-storage-pvc

Si vous utilisez un nombre différent de nœuds dans votre pool de nœuds TPU, remplacez le champ replicas par le nombre de nœuds.

Si votre cluster Standard exécute GKE version 1.27 ou antérieure, ajoutez le champ suivant à votre fichier manifeste:

spec:
  securityContext:
    privileged: true

Vous n'avez pas besoin d'exécuter les pods Kubernetes en mode privilégié dans GKE version 1.28 ou ultérieure. Pour en savoir plus, consultez la section Exécuter des conteneurs sans mode privilégié.

Si vous utilisez un autre type de machine:

  • Définissez cloud.google.com/gke-tpu-topology sur la topologie du type de machine que vous utilisez.
  • Définissez les deux champs google.com/tpu sous resources pour qu'il corresponde au nombre de puces pour le type de machine correspondant.

Préparation

Téléchargez les scripts Python du tutoriel et les fichiers manifestes YAML à l'aide de la commande suivante:

git clone https://github.com/GoogleCloudPlatform/ai-on-gke.git

Accédez au répertoire single-host-inference :

cd ai-on-gke/gke-tpu-examples/single-host-inference/

Configurer l'environnement Python

Les scripts Python que vous utilisez dans ce tutoriel nécessitent Python 3.9 ou une version ultérieure. N'oubliez pas d'installer requirements.txt pour chaque tutoriel avant d'exécuter les scripts de test Python.

Si vous n'avez pas la configuration Python appropriée dans votre environnement local, vous pouvez utiliser Cloud Shell pour télécharger et exécuter les scripts Python de ce tutoriel.

Configurer le cluster

  1. Créez un cluster en utilisant le type de machine e2-standard-4.

    gcloud container clusters create cluster-name \
    --region your-region \
    --release-channel rapid \
    --num-nodes=1 \
    --machine-type=e2-standard-4 \
    --workload-pool=project-id.svc.id.goog \
    --addons GcsFuseCsiDriver
    
  2. Créez le pool de nœuds TPU à hôte unique.

Les exemples de charges de travail supposent ce qui suit:

  • Votre cluster s'exécute avec un pool de nœuds TPU v5e comportant trois nœuds.
  • Le pool de nœuds TPU utilise le type de machine ct5lp-hightpu-1t.

Si vous utilisez une configuration de cluster différente de celle décrite précédemment, vous devez modifier le fichier manifeste de déploiement du serveur.

Pour la démonstration JAX Stable Diffusion, vous aurez besoin d'un pool de nœuds de processeur dont le type de machine dispose de plus de 16 Gio de mémoire disponible (par exemple e2-standard-4). Vous pouvez configurer cela dans la commande gcloud container clusters create ou en ajoutant un pool de nœuds supplémentaire au cluster existant à l'aide de la commande suivante:

gcloud beta container node-pools create your-pool-name \
  --zone=your-cluster-zone \
  --cluster=your-cluster-name \
  --machine-type=e2-standard-4 \
  --num-nodes=1

Remplacez les éléments suivants :

  • your-pool-name : nom du pool de nœuds à créer
  • your-cluster-zone: zone dans laquelle votre cluster a été créé.
  • your-cluster-name: nom du cluster dans lequel ajouter le pool de nœuds.
  • your-machine-type: type de machine des nœuds à créer dans le pool de nœuds.

Configurer le stockage du modèle

Il existe plusieurs façons de stocker votre modèle en vue de son inférence. Dans ce tutoriel, nous utiliserons l'approche suivante:

  • Pour convertir le modèle pré-entraîné afin qu'il fonctionne sur des TPU, nous allons utiliser un cloud privé virtuel reposant sur un disque persistant avec un accès ReadWriteMany (RWX).
  • Pour diffuser le modèle sur plusieurs TPU à un seul hôte, nous allons utiliser le même VPC reposant sur le bucket Cloud Storage.

Exécutez la commande suivante pour créer un bucket Cloud Storage.

gcloud storage buckets create gs://your-bucket-name \
  --project=your-bucket-project-id \
  --location=your-bucket-location

Remplacez les éléments suivants :

  • your-bucket-name: nom du bucket Cloud Storage.
  • your-bucket-project-id: ID du projet dans lequel vous avez créé le bucket Cloud Storage.
  • your-bucket-location: emplacement de votre bucket Cloud Storage. Pour améliorer les performances, spécifiez l'emplacement d'exécution de votre cluster GKE.

Suivez les étapes ci-dessous pour autoriser votre cluster GKE à accéder au bucket. Pour simplifier la configuration, les exemples suivants utilisent l'espace de noms par défaut et le compte de service Kubernetes par défaut. Pour en savoir plus, consultez Configurer l'accès aux buckets Cloud Storage à l'aide de GKE Workload Identity.

  1. Créez un compte de service IAM pour votre application ou utilisez un compte de service IAM existant. Vous pouvez utiliser n'importe quel compte de service IAM dans le projet de votre bucket Cloud Storage.

    gcloud iam service-accounts create your-iam-service-acct \
    --project=your-bucket-project-id
    

    Remplacez les éléments suivants :

    • your-iam-service-acct: nom du nouveau compte de service IAM.
    • your-bucket-project-id: ID du projet dans lequel vous avez créé votre compte de service IAM. Le compte de service IAM doit se trouver dans le même projet que votre bucket Cloud Storage.
  2. Assurez-vous que votre compte de service IAM dispose des rôles de stockage dont vous avez besoin.

    gcloud storage buckets add-iam-policy-binding gs://your-bucket-name \
    --member "serviceAccount:your-iam-service-acct@your-bucket-project-id.iam.gserviceaccount.com" \
    --role "roles/storage.objectAdmin"
    

    Remplacez les éléments suivants :

    • your-bucket-name : nom du bucket Cloud Storage.
    • your-iam-service-acct: nom du nouveau compte de service IAM.
    • your-bucket-project-id: ID du projet dans lequel vous avez créé votre compte de service IAM.
  3. Autorisez le compte de service Kubernetes à emprunter l'identité du compte de service IAM en ajoutant une liaison de stratégie IAM entre les deux comptes de service. Cette liaison permet au compte de service Kubernetes d'agir en tant que compte de service IAM.

    gcloud iam service-accounts add-iam-policy-binding your-iam-service-acct@your-bucket-project-id.iam.gserviceaccount.com \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:your-project-id.svc.id.goog[default/default]"
    

    Remplacez les éléments suivants :

    • your-iam-service-acct: nom du nouveau compte de service IAM.
    • your-bucket-project-id: ID du projet dans lequel vous avez créé votre compte de service IAM.
    • your-project-id: ID du projet dans lequel vous avez créé votre cluster GKE. Vos buckets Cloud Storage et votre cluster GKE peuvent se trouver dans le même projet ou dans des projets différents.
  4. Annotez le compte de service Kubernetes avec l'adresse e-mail du compte de service IAM.

    kubectl annotate serviceaccount default \
      --namespace default \
      iam.gke.io/gcp-service-account=your-iam-service-acct@your-bucket-project-id.iam.gserviceaccount.com
    

    Remplacez les éléments suivants :

    • your-iam-service-acct: nom du nouveau compte de service IAM.
    • your-bucket-project-id: ID du projet dans lequel vous avez créé votre compte de service IAM.
  5. Exécutez la commande suivante pour renseigner le nom de votre bucket dans les fichiers YAML de cette démonstration:

    find . -type f -name "*.yaml" | xargs sed -i "s/BUCKET_NAME/your-bucket-name/g"
    

    Remplacez your-bucket-name par le nom de votre bucket Cloud Storage.

  6. Créez le volume persistant et la demande de volume persistant à l'aide de la commande suivante:

    kubectl apply -f pvc-pv.yaml
    

Inférence et inférence de modèle JAX

Installez des dépendances Python pour exécuter les scripts Python du tutoriel qui envoient des requêtes au service de modèle JAX.

pip install -r jax/requirements.txt

Exécutez la démonstration de l'inférence JAX BERT E2E:

Cette démonstration utilise un modèle BERT pré-entraîné de Hugging Face.

Le pod Kubernetes effectue les étapes suivantes:

  1. Il télécharge et utilise le script Python export_bert_model.py issu des exemples de ressources pour télécharger le modèle BERT pré-entraîné dans un répertoire temporaire.
  2. Utilise l'image du convertisseur Cloud TPU pour convertir le modèle pré-entraîné de processeur en TPU et stocke le modèle dans le bucket Cloud Storage que vous avez créé lors de la setup.

Ce pod Kubernetes est configuré pour s'exécuter sur le processeur de pool de nœuds par défaut. Exécutez le pod à l'aide de la commande suivante:

kubectl apply -f jax/bert/install-bert.yaml

Vérifiez que le modèle a été correctement installé à l'aide des éléments suivants:

kubectl get pods install-bert

STATUS peut mettre quelques minutes à lire Completed.

Lancer le serveur de modèles TF pour le modèle

Les exemples de charges de travail présentés dans ce tutoriel supposent ce qui suit:

  • Le cluster est exécuté avec un pool de nœuds TPU v5 comportant trois nœuds
  • Le pool de nœuds utilise le type de machine ct5lp-hightpu-1t qui contient une puce TPU.

Si vous utilisez une configuration de cluster différente de celle décrite précédemment, vous devez modifier le fichier manifeste de déploiement du serveur.

Appliquer le déploiement
kubectl apply -f jax/bert/serve-bert.yaml

Vérifiez que le serveur est en cours d'exécution à l'aide de la commande suivante:

kubectl get deployment bert-deployment

AVAILABLE peut mettre une minute à lire 3.

Appliquer le service d'équilibrage de charge
kubectl apply -f jax/bert/loadbalancer.yaml

Pour vérifier que l'équilibreur de charge est prêt pour le trafic externe, procédez comme suit:

kubectl get svc tf-bert-service

Il peut s'écouler quelques minutes avant que EXTERNAL_IP ne dispose d'une adresse IP.

Envoyer la requête au serveur de modèles

Obtenez une adresse IP externe à partir du service d'équilibrage de charge:

EXTERNAL_IP=$(kubectl get services tf-bert-service --output jsonpath='{.status.loadBalancer.ingress[0].ip}')

Exécutez un script permettant d'envoyer une requête au serveur:

python3 jax/bert/bert_request.py $EXTERNAL_IP

Résultat attendu :

For input "The capital of France is [MASK].", the result is ". the capital of france is paris.."
For input "Hello my name [MASK] Jhon, how can I [MASK] you?", the result is ". hello my name is jhon, how can i help you?."
Effectuer un nettoyage

Pour nettoyer les ressources, exécutez kubectl delete dans l'ordre inverse.

kubectl delete -f jax/bert/loadbalancer.yaml
kubectl delete -f jax/bert/serve-bert.yaml
kubectl delete -f jax/bert/install-bert.yaml

Lancer une démonstration de diffusion E2E Stable Diffusion JAX

Cette démonstration utilise le modèle de diffusion stable pré-entraîné de Hugging Face.

Exporter un modèle enregistré TF2 compatible TPU à partir du modèle Flax Stable Diffusion

L'exportation des modèles de diffusion stables nécessite que le cluster dispose d'un pool de nœuds de processeur dont le type de machine dispose de plus de 16 Go de mémoire disponible, comme décrit dans la section Configurer le cluster.

Le pod Kubernetes exécute les étapes suivantes:

  1. Il télécharge et utilise le script Python export_stable_diffusion_model.py issu des exemples de ressources pour télécharger le modèle de diffusion stable pré-entraîné dans un répertoire temporaire.
  2. Utilise l'image du convertisseur Cloud TPU pour convertir le modèle pré-entraîné de processeur en TPU et stocke le modèle dans le bucket Cloud Storage que vous avez créé lors de la configuration du stockage.

Ce pod Kubernetes est configuré pour s'exécuter sur le pool de nœuds CPU par défaut. Exécutez le pod à l'aide de la commande suivante:

kubectl apply -f jax/stable-diffusion/install-stable-diffusion.yaml

Vérifiez que le modèle a été correctement installé à l'aide des éléments suivants:

kubectl get pods install-stable-diffusion

STATUS peut mettre quelques minutes à lire Completed.

Lancer le conteneur du serveur de modèles TF pour le modèle

Les exemples de charges de travail ont été configurés avec les hypothèses suivantes:

  • Le cluster s'exécute avec un pool de nœuds TPU v5 comportant trois nœuds
  • le pool de nœuds utilise le type de machine ct5lp-hightpu-1t, où :
    • est de type 1 x 1
    • le nombre de puces TPU est de 1

Si vous utilisez une configuration de cluster différente de celle décrite précédemment, vous devez modifier le fichier manifeste de déploiement du serveur.

Appliquez le déploiement:

kubectl apply -f jax/stable-diffusion/serve-stable-diffusion.yaml

Vérifiez que le serveur fonctionne comme prévu:

kubectl get deployment stable-diffusion-deployment

AVAILABLE peut mettre une minute à lire 3.

Appliquez le service d'équilibrage de charge:

kubectl apply -f jax/stable-diffusion/loadbalancer.yaml

Pour vérifier que l'équilibreur de charge est prêt pour le trafic externe, procédez comme suit:

kubectl get svc tf-stable-diffusion-service

Il peut s'écouler quelques minutes avant que EXTERNAL_IP ne dispose d'une adresse IP.

Envoyer la requête au serveur de modèles

Obtenez une adresse IP externe à partir de l'équilibreur de charge:

EXTERNAL_IP=$(kubectl get services tf-stable-diffusion-service --output jsonpath='{.status.loadBalancer.ingress[0].ip}')

Exécuter un script pour envoyer une requête au serveur

python3 jax/stable-diffusion/stable_diffusion_request.py $EXTERNAL_IP

Résultat attendu :

L'invite est Painting of a squirrel skating in New York, et l'image de sortie sera enregistrée sous le nom stable_diffusion_images.jpg dans votre répertoire actuel.

Effectuer un nettoyage

Pour nettoyer les ressources, exécutez kubectl delete dans l'ordre inverse.

kubectl delete -f jax/stable-diffusion/loadbalancer.yaml
kubectl delete -f jax/stable-diffusion/serve-stable-diffusion.yaml
kubectl delete -f jax/stable-diffusion/install-stable-diffusion.yaml

Exécutez la démonstration de l'inférence TensorFlow ResNet-50 E2E:

Installez des dépendances Python pour exécuter les scripts Python du tutoriel qui envoient des requêtes au service de modèle TF.

pip install -r tf/resnet50/requirements.txt
Étape 1: Convertissez le modèle

Appliquez la conversion du modèle:

kubectl apply -f tf/resnet50/model-conversion.yml

Vérifiez que le modèle a été correctement installé à l'aide des éléments suivants:

kubectl get pods resnet-model-conversion

STATUS peut mettre quelques minutes à lire Completed.

Étape 2: Inférer le modèle avec TensorFlow Serving

Appliquez le déploiement d'inférence du modèle:

kubectl apply -f tf/resnet50/deployment.yml

Vérifiez que le serveur fonctionne comme prévu à l'aide de la commande suivante:

kubectl get deployment resnet-deployment

AVAILABLE peut mettre une minute à lire 3.

Appliquez le service d'équilibrage de charge:

kubectl apply -f tf/resnet50/loadbalancer.yml

Pour vérifier que l'équilibreur de charge est prêt pour le trafic externe, procédez comme suit:

kubectl get svc resnet-service

Il peut s'écouler quelques minutes avant que EXTERNAL_IP ne dispose d'une adresse IP.

Étape 3: Envoyer une requête de test au serveur de modèles

Obtenez l'adresse IP externe de l'équilibreur de charge:

EXTERNAL_IP=$(kubectl get services resnet-service --output jsonpath='{.status.loadBalancer.ingress[0].ip}')

Exécutez le script de requête de test (HTTP) pour envoyer la requête au serveur de modèle.

python3 tf/resnet50/request.py --host $EXTERNAL_IP

La réponse doit se présenter sous la forme suivante:

Predict result: ['ImageNet ID: n07753592, Label: banana, Confidence: 0.94921875',
'ImageNet ID: n03532672, Label: hook, Confidence: 0.0223388672', 'ImageNet ID: n07749582,
Label: lemon, Confidence: 0.00512695312
Étape 4: Nettoyage

Pour nettoyer les ressources, exécutez les commandes kubectl delete suivantes:

kubectl delete -f tf/resnet50/loadbalancer.yml
kubectl delete -f tf/resnet50/deployment.yml
kubectl delete -f tf/resnet50/model-conversion.yml

Veillez à supprimer le pool de nœuds et le cluster GKE lorsque vous n'en avez plus besoin.

Inférence et inférence de modèles PyTorch

Installez des dépendances Python pour exécuter les scripts Python du tutoriel qui envoient des requêtes au service de modèle PyTorch:

pip install -r pt/densenet161/requirements.txt

Exécutez la démonstration de l'inférence TorchServe Densenet161 E2E:

  1. Générer une archive de modèle

    1. Appliquer l'archive du modèle:
    kubectl apply -f pt/densenet161/model-archive.yml
    
    1. Vérifiez que le modèle a été correctement installé à l'aide des éléments suivants:
    kubectl get pods densenet161-model-archive
    

    STATUS peut mettre quelques minutes à lire Completed.

  2. Diffuser le modèle avec TorchServe:

    1. Appliquez le déploiement du modèle d'inférence:

      kubectl apply -f pt/densenet161/deployment.yml
      
    2. Vérifiez que le serveur fonctionne comme prévu à l'aide de la commande suivante:

      kubectl get deployment densenet161-deployment
      

      AVAILABLE peut mettre une minute à lire 3.

    3. Appliquez le service d'équilibrage de charge:

      kubectl apply -f pt/densenet161/loadbalancer.yml
      

      Vérifiez que l'équilibreur de charge est prêt pour le trafic externe à l'aide de la commande suivante:

      kubectl get svc densenet161-service
      

      Il peut s'écouler quelques minutes avant que EXTERNAL_IP ne dispose d'une adresse IP.

  3. Envoyez une requête de test au serveur de modèles:

    1. Obtenez l'adresse IP externe de l'équilibreur de charge:

      EXTERNAL_IP=$(kubectl get services densenet161-service --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
      
    2. Exécutez le script de requête de test pour envoyer la requête (HTTP) au serveur de modèle :

      python3 pt/densenet161/request.py --host $EXTERNAL_IP
      

      Vous devriez obtenir une réponse semblable à celle-ci:

      Request successful. Response: {'tabby': 0.47878125309944153, 'lynx': 0.20393909513950348, 'tiger_cat': 0.16572578251361847, 'tiger': 0.061157409101724625, 'Egyptian_cat': 0.04997897148132324
      
  4. Nettoyez les ressources en exécutant les commandes kubectl delete suivantes:

    kubectl delete -f pt/densenet161/loadbalancer.yml
    kubectl delete -f pt/densenet161/deployment.yml
    kubectl delete -f pt/densenet161/model-archive.yml
    

    Veillez à supprimer le pool de nœuds et le cluster GKE lorsque vous n'en avez plus besoin.

Résoudre les problèmes courants

Vous trouverez des informations de dépannage GKE sur la page Résoudre les problèmes liés à TPU dans GKE.

Échec de l'initialisation du TPU

Si vous rencontrez l'erreur suivante, assurez-vous d'exécuter votre conteneur TPU en mode privilégié ou que vous avez augmenté la valeur ulimit dans votre conteneur. Pour en savoir plus, consultez la section Exécuter sans mode privilégié.

TPU platform initialization failed: FAILED_PRECONDITION: Couldn't mmap: Resource
temporarily unavailable.; Unable to create Node RegisterInterface for node 0,
config: device_path:      "/dev/accel0" mode: KERNEL debug_data_directory: ""
dump_anomalies_only: true crash_in_debug_dump: false allow_core_dump: true;
could not create driver instance

Planifier un interblocage

Supposons que vous ayez deux tâches (la tâche A et la tâche B) qui doivent toutes les deux être planifiées sur des tranches de pod TPU ayant une topologie TPU donnée (par exemple, v4-32). Supposons également que vous disposez de deux tranches TPU v4-32 dans le cluster GKE. Nous les appellerons tranche X et tranche Y. Étant donné que votre cluster dispose d'une capacité suffisante pour planifier les deux tâches, en théorie les deux tâches devraient être planifiées rapidement (une tâche sur chacune des deux tranches de TPU v4-32).

Cependant, sans une planification minutieuse, il est possible de rencontrer un interblocage de planification. Supposons que le programmeur Kubernetes planifie un pod Kubernetes de la tâche A sur la tranche X, puis planifie un pod Kubernetes de la tâche B sur la tranche X. Dans ce cas, compte tenu des règles d'affinité de pods Kubernetes pour la tâche A, le programmeur tentera de planifier tous les pods Kubernetes restants pour la tâche A sur la tranche X. Il en va de même pour le job B. Par conséquent, ni la tâche A, ni la tâche B ne peuvent être entièrement planifiées sur une seule tranche. Il en résulte un interblocage de la planification.

Pour éviter tout blocage de la planification, vous pouvez utiliser l'anti-affinité de pod Kubernetes avec cloud.google.com/gke-nodepool comme topologyKey, comme illustré dans l'exemple suivant:

apiVersion: batch/v1
kind: Job
metadata:
 name: pi
spec:
 parallelism: 2
 template:
   metadata:
     labels:
       job: pi
   spec:
     affinity:
       podAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
             matchExpressions:
             - key: job
               operator: In
               values:
               - pi
           topologyKey: cloud.google.com/gke-nodepool
       podAntiAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
             matchExpressions:
             - key: job
               operator: NotIn
               values:
               - pi
           topologyKey: cloud.google.com/gke-nodepool
           namespaceSelector:
             matchExpressions:
             - key: kubernetes.io/metadata.name
               operator: NotIn
               values:
               - kube-system
     containers:
     - name: pi
       image: perl:5.34.0
       command: ["sleep",  "60"]
     restartPolicy: Never
 backoffLimit: 4

Créer des ressources de pool de nœuds TPU avec Terraform

Vous pouvez également utiliser Terraform pour gérer les ressources de votre cluster et de votre pool de nœuds.

Créer un pool de nœuds de tranches TPU multi-hôtes dans un cluster GKE existant

Si vous disposez d'un cluster existant dans lequel vous souhaitez créer un pool de nœuds TPU multi-hôtes, vous pouvez utiliser l'extrait Terraform suivant:

resource "google_container_cluster" "cluster_multi_host" {
  …
  release_channel {
    channel = "RAPID"
  }
  workload_identity_config {
    workload_pool = "my-gke-project.svc.id.goog"
  }
  addons_config {
    gcs_fuse_csi_driver_config {
      enabled = true
    }
  }
}

resource "google_container_node_pool" "multi_host_tpu" {
  provider           = google-beta
  project            = "${project-id}"
  name               = "${node-pool-name}"
  location           = "${location}"
  node_locations     = ["${node-locations}"]
  cluster            = google_container_cluster.cluster_multi_host.name
  initial_node_count = 2

  node_config {
    machine_type = "ct4p-hightpu-4t"
    reservation_affinity {
      consume_reservation_type = "SPECIFIC_RESERVATION"
      key = "compute.googleapis.com/reservation-name"
      values = ["${reservation-name}"]
    }
    workload_metadata_config {
      mode = "GKE_METADATA"
    }
  }

  placement_policy {
    type = "COMPACT"
    tpu_topology = "2x2x2"
  }
}

Remplacez les valeurs suivantes :

  • your-project: projet Google Cloud dans lequel vous exécutez votre charge de travail.
  • your-node-pool: nom du pool de nœuds que vous créez.
  • us-central2: région dans laquelle vous exécutez votre charge de travail.
  • us-central2-b: zone dans laquelle vous exécutez votre charge de travail.
  • your-reservation-name : nom de votre réservation.

Créer un pool de nœuds de tranches TPU à hôte unique dans un cluster GKE existant

Utilisez l'extrait Terraform suivant:

resource "google_container_cluster" "cluster_single_host" {
  …
  cluster_autoscaling {
    autoscaling_profile = "OPTIMIZE_UTILIZATION"
  }
  release_channel {
    channel = "RAPID"
  }
  workload_identity_config {
  workload_pool = "${project-id}.svc.id.goog"
  }
  addons_config {
    gcs_fuse_csi_driver_config {
      enabled = true
    }
  }
}

resource "google_container_node_pool" "single_host_tpu" {
  provider           = google-beta
  project            = "${project-id}"
  name               = "${node-pool-name}"
  location           = "${location}"
  node_locations     = ["${node-locations}"]
  cluster            = google_container_cluster.cluster_single_host.name
  initial_node_count = 0
  autoscaling {
    total_min_node_count = 2
    total_max_node_count = 22
    location_policy      = "ANY"
  }

  node_config {
    machine_type = "ct4p-hightpu-4t"
    workload_metadata_config {
      mode = "GKE_METADATA"
    }
  }
}

Remplacez les valeurs suivantes :

  • your-project: projet Google Cloud dans lequel vous exécutez votre charge de travail.
  • your-node-pool: nom du pool de nœuds que vous créez.
  • us-central2: région dans laquelle vous exécutez votre charge de travail.
  • us-central2-b: zone dans laquelle vous exécutez votre charge de travail.