Cette page explique comment résoudre les problèmes liés aux TPU dans Google Kubernetes Engine (GKE).
Si vous avez besoin d'aide supplémentaire, contactez l'assistance Cloud Customer Care.Quota insuffisant pour répondre à la demande de TPU
Une erreur semblable à Insufficient quota to satisfy the request
indique que votre projet Google Cloud ne dispose pas d'un quota suffisant pour répondre à la requête.
Pour résoudre ce problème, vérifiez la limite de quota et l'utilisation actuelle de votre projet. Si nécessaire, demandez une augmentation de votre quota de TPU.
Vérifier la limite de quota et l'utilisation actuelle
Pour vérifier la limite et l'utilisation actuelle de votre quota d'API Compute Engine pour les TPU, procédez comme suit :
Accédez à la page Quotas de la console Google Cloud.
Dans la zone
Filtre, procédez comme suit :Sélectionnez la propriété Service, saisissez API Compute Engine, puis appuyez sur Entrée.
Sélectionnez la propriété Type et choisissez Quota.
Sélectionnez la propriété Dimensions (par exemple, emplacements) et saisissez
region:
suivi du nom de la région dans laquelle vous prévoyez de créer des TPU dans GKE. Par exemple, saisissezregion:us-west4
si vous envisagez de créer des nœuds de tranche TPU dans la zoneus-west4-a
. Le quota de TPU est régional. Par conséquent, toutes les zones d'une même région consomment le même quota de TPU.
Si aucun quota ne correspond au filtre que vous avez saisi, le projet ne dispose d'aucun quota pour la région souhaitée et vous devez demander une augmentation de quota TPU.
Erreur lors de l'activation du provisionnement automatique des nœuds dans un pool de nœuds de tranche TPU
L'erreur suivante se produit lorsque vous activez le provisionnement automatique des nœuds dans un cluster GKE non compatible avec les TPU.
Le message d'erreur ressemble à ceci :
ERROR: (gcloud.container.clusters.create) ResponseError: code=400,
message=Invalid resource: tpu-v4-podslice.
Pour résoudre ce problème, mettez à niveau votre cluster GKE vers la version 1.27.6 ou ultérieure.
GKE ne provisionne pas automatiquement les nœuds des tranches TPU
Les sections suivantes décrivent les cas où GKE ne provisionne pas automatiquement les nœuds des tranches TPU, et comment les résoudre.
Limiter les erreurs de configuration
GKE ne provisionne pas automatiquement les nœuds des tranches TPU si les limites de provisionnement automatique que vous avez définies pour un cluster sont trop faibles. Vous pouvez rencontrer les erreurs suivantes dans de tels scénarios :
Si un pool de nœuds des tranches TPU existe, mais que GKE ne peut pas effectuer un scaling à la hausse des nœuds en raison des limites de ressources, le message d'erreur suivant peut s'afficher lors de l'exécution de la commande
kubectl get events
:11s Normal NotTriggerScaleUp pod/tpu-workload-65b69f6c95-ccxwz pod didn't trigger scale-up: 1 node(s) didn't match Pod's node affinity/selector, 1 max cluster cpu, memory limit reached
En outre, dans ce scénario, des messages d'avertissement semblables à ceux-ci peuvent s'afficher dans la console Google Cloud :
"Your cluster has one or more unschedulable Pods"
Lorsque GKE tente de provisionner automatiquement un pool de nœuds des tranches TPU dépassant les limites de ressources, les journaux de visibilité de l'autoscaler de cluster affichent le message d'erreur suivant :
messageId: "no.scale.up.nap.pod.zonal.resources.exceeded"
En outre, dans ce scénario, des messages d'avertissement semblables à ceux-ci peuvent s'afficher dans la console Google Cloud :
"Can't scale up because node auto-provisioning can't provision a node pool for the Pod if it would exceed resource limits"
Pour résoudre ces problèmes, augmentez le nombre maximal de puces TPU, de cœurs de processeur et de mémoire dans le cluster.
Pour effectuer cette procédure, procédez comme suit :
- Calculez les besoins en ressources d'un type de machine TPU et d'un nombre donné. Notez que vous devez ajouter des ressources pour les pools de nœuds des tranches non TPU, tels que les charges de travail système.
Obtenez une description du TPU, du processeur et de la mémoire disponibles pour un type de machine et une zone spécifiques. Utiliser la CLI gcloud
gcloud compute machine-types describe MACHINE_TYPE \ --zone COMPUTE_ZONE
Remplacez les éléments suivants :
MACHINE_TYPE
: type de machine à rechercher.COMPUTE_ZONE
: nom de la zone de calcul.
Le résultat inclut une ligne de description semblable à celle-ci :
description: 240 vCPUs, 407 GB RAM, 4 Google TPUs ```
Calculez le nombre total de processeurs et de mémoire en multipliant ces quantités par le nombre de nœuds requis. Par exemple, le type de machine
ct4p-hightpu-4t
utilise 240 cœurs de processeur et 407 Go de RAM avec 4 puces TPU. En supposant que vous ayez besoin de 20 puces TPU, correspondant à cinq nœuds, vous devez définir les valeurs suivantes :--max-accelerator=type=tpu-v4-podslice,count=20
.CPU = 1200
(240 x 5)memory = 2035
(407 x 5)
Vous devez définir des limites avec une certaine marge pour les nœuds des tranches non TPU, tels que les charges de travail système.
Mettez à jour les limites du cluster :
gcloud container clusters update CLUSTER_NAME \ --max-accelerator type=TPU_ACCELERATOR \ count=MAXIMUM_ACCELERATOR \ --max-cpu=MAXIMUM_CPU \ --max-memory=MAXIMUM_MEMORY
Remplacez les éléments suivants :
CLUSTER_NAME
: nom du cluster.TPU_ACCELERATOR
: nom de l'accélérateur TPU.MAXIMUM_ACCELERATOR
: nombre maximal de puces TPU dans le cluster.MAXIMUM_CPU
: nombre maximal de cœurs dans le cluster.MAXIMUM_MEMORY
: quantité maximale de mémoire dans le cluster, en gigaoctets.
Toutes les instances ne sont pas en cours d'exécution
ERROR: nodes cannot be created due to lack of capacity. The missing nodes
will be created asynchronously once capacity is available. You can either
wait for the nodes to be up, or delete the node pool and try re-creating it
again later.
Cette erreur peut s'afficher lorsque l'opération GKE a expiré ou que la requête ne peut pas être traitée et mise en file d'attente pour le provisionnement de pools de nœuds TPU à hôte unique ou multi-hôte. Pour éviter les problèmes de capacité, vous pouvez utiliser des réservations ou envisager des VM Spot.
Mauvaise configuration de la charge de travail
Cette erreur se produit en raison d'une mauvaise configuration de la charge de travail. Voici quelques-unes des causes d'erreur les plus courantes :
- Les libellés
cloud.google.com/gke-tpu-accelerator
etcloud.google.com/gke-tpu-topology
sont incorrects ou manquants dans la spécification de pod. GKE ne provisionne pas de pools de nœuds des tranches TPU et le provisionnement automatique des nœuds ne peut pas effectuer un scaling à la hausse du cluster. - La spécification de pod ne spécifie pas
google.com/tpu
dans ses besoins en ressources.
Pour résoudre ce problème, effectuez l'une des opérations suivantes :
- Vérifiez qu'il n'existe aucun libellé non compatible dans le sélecteur de nœud de votre charge de travail.
Par exemple, un sélecteur de nœuds pour le libellé
cloud.google.com/gke-nodepool
empêche GKE de créer des pools de nœuds supplémentaires pour vos pods. - Assurez-vous que les spécifications du modèle de pod, dans lesquelles la charge de travail de votre TPU s'exécute, incluent les valeurs suivantes :
- Les libellés
cloud.google.com/gke-tpu-accelerator
etcloud.google.com/gke-tpu-topology
dans sonnodeSelector
. google.com/tpu
dans sa requête.
- Les libellés
Pour savoir comment déployer des charges de travail TPU dans GKE, consultez la page Exécuter une charge de travail qui affiche le nombre de puces TPU disponibles dans un pool de nœuds des tranches TPU.
Erreurs de programmation lors du déploiement de pods consommant des TPU dans GKE
Le problème suivant se produit lorsque GKE ne peut pas planifier les pods demandant des TPU sur des nœuds des tranches TPU. Par exemple, cela peut se produire si certaines tranches non TPU ont déjà été programmées sur des nœuds TPU.
Le message d'erreur, émis en tant qu'événement FailedScheduling
sur le pod, se présente comme suit :
Cannot schedule pods: Preemption is not helpful for scheduling.
Error message: 0/2 nodes are available: 2 node(s) had untolerated taint
{google.com/tpu: present}. preemption: 0/2 nodes are available: 2 Preemption is
not helpful for scheduling
Pour résoudre ce problème, procédez comme suit :
Vérifiez que votre cluster comporte au moins un pool de nœuds CPU afin que les pods critiques du système puissent s'exécuter dans les nœuds non TPU. Pour en savoir plus, consultez la page Déployer un pod sur un pool de nœuds spécifique.
Résoudre les problèmes courants liés aux JobSets dans GKE
Pour connaître les problèmes courants liés à JobSet et obtenir des suggestions de dépannage, consultez la page Dépannage JobSet. Cette page traite des problèmes courants tels que l'erreur "Webhook non disponible", les jobs enfants ou les pods qui ne sont pas créés, et le problème de reprise des charges de travail préemptées à l'aide de JobSet et de Kueue.
Échec de l'initialisation du TPU
Le problème suivant se produit lorsque GKE ne peut pas provisionner de nouvelles charges de travail TPU en raison d'un manque d'autorisation d'accès aux appareils TPU.
Le message d'erreur ressemble à ceci :
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
Pour résoudre ce problème, veillez à exécuter votre conteneur TPU en mode privilégié ou à augmenter ulimit
dans votre conteneur.
Planifier un interblocage
La programmation d'au moins deux tâches peut résulter en un interblocage. Par exemple, dans le scénario où tous les événements suivants se produisent :
- Vous avez deux jobs (job A et job B) avec des règles d'affinité de pod.
GKE planifie les tranches de TPU des deux jobs avec une topologie TPU de
v4-32
. - Vous disposez de deux tranches de TPU
v4-32
dans le cluster. - Votre cluster dispose d'une capacité suffisante pour planifier les deux jobs et, en théorie, chaque job peut être rapidement planifié sur chaque tranche de TPU.
- Le programmeur Kubernetes planifie un pod du job A sur une tranche, puis en planifie un autre pour le job B sur la même tranche.
Dans ce cas, en fonction des règles d'affinité de pod du job A, le programmeur tente de planifier tous les pods restants des jobs A et B, chacun sur une seule tranche de TPU. Par conséquent, GKE ne peut pas planifier entièrement le job A ou le job B. L'état des deux jobs reste donc en attente.
Pour résoudre ce problème, utilisez l'anti-affinité de pod avec cloud.google.com/gke-nodepool
comme topologyKey
, comme indiqué 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
Autorisation refusée lors de la création du cluster dans us-central2
Si vous essayez de créer un cluster dans la région us-central2
(seule région où les TPU v4 sont disponibles), vous pouvez rencontrer un message d'erreur semblable à celui-ci :
ERROR: (gcloud.container.clusters.create) ResponseError: code=403,
message=Permission denied on 'locations/us-central2' (or it may not exist).
Cette erreur est due au fait que la région us-central2
est une région privée.
Pour résoudre ce problème, envoyez une demande d'assistance ou contactez l'équipe chargée de votre compte pour demander à ce que la région us-central2
soit rendue visible au sein de votre projet Google Cloud.
Quota insuffisant lors de la création d'un pool de nœuds TPU dans la région us-central2
Si vous essayez de créer un pool de nœuds des tranches TPU dans us-central2
(seule région où les TPU v4 sont disponibles), vous devrez peut-être augmenter les quotas suivants liés à GKE lors de la création initiale des pools de nœuds TPU v4 :
- SSD Persistent Disk (Go) dans la région us-central2 : le disque de démarrage de chaque nœud Kubernetes nécessite 100 Go par défaut. Par conséquent, ce quota doit être défini au moins aussi haut que le produit du nombre maximal de nœuds GKE que vous prévoyez de créer dans
us-central2
et 100 Go (maximum_nodes
X100 GB
). - Quota d'adresses IP en cours d'utilisation dans la région us-central2 : chaque nœud Kubernetes consomme une adresse IP. Par conséquent, ce quota doit être défini au moins aussi haut que le nombre maximal de nœuds GKE que vous prévoyez de créer dans
us-central2
.
Sous-réseau manquant lors de la création du cluster GKE
Si vous essayez de créer un cluster dans la région us-central2
(seule région où les TPU v4 sont disponibles), vous pouvez rencontrer un message d'erreur semblable à celui-ci :
ERROR: (gcloud.container.clusters.create) ResponseError: code=404,
message=Not found: project <PROJECT> does not have an auto-mode subnetwork
for network "default" in region <REGION>.
Vous devez ajouter un sous-réseau dans votre réseau VPC pour fournir la connectivité à vos nœuds GKE. Toutefois, dans certaines régions telles que us-central2
, un sous-réseau par défaut ne peut pas être créé, même lorsque vous utilisez le réseau VPC par défaut en mode automatique (pour la création de sous-réseau).
Pour résoudre ce problème, assurez-vous d'avoir créé un sous-réseau personnalisé dans la région avant de créer votre cluster GKE. Ce sous-réseau ne doit pas chevaucher d'autres sous-réseaux créés dans d'autres régions sur le même réseau VPC.
Afficher les journaux TPU GKE
Pour afficher tous les journaux liés aux TPU pour une charge de travail spécifique, Cloud Logging propose un emplacement centralisé permettant d'interroger ces journaux lorsque la journalisation du système et de la charge de travail GKE est activée. Dans Cloud Logging, les journaux sont organisés en entrées de journal, et chaque entrée de journal a un format structuré. Voici un exemple d'entrée de journal de tâche d'entraînement TPU.
{
insertId: "gvqk7r5qc5hvogif"
labels: {
compute.googleapis.com/resource_name: "gke-tpu-9243ec28-wwf5"
k8s-pod/batch_kubernetes_io/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
k8s-pod/batch_kubernetes_io/job-name: "mnist-training-job"
k8s-pod/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
k8s-pod/job-name: "mnist-training-job"
}
logName: "projects/gke-tpu-demo-project/logs/stdout"
receiveTimestamp: "2024-06-26T05:52:39.652122589Z"
resource: {
labels: {
cluster_name: "tpu-test"
container_name: "tensorflow"
location: "us-central2-b"
namespace_name: "default"
pod_name: "mnist-training-job-l74l8"
project_id: "gke-tpu-demo-project"
}
type: "k8s_container"
}
severity: "INFO"
textPayload: "
1/938 [..............................] - ETA: 13:36 - loss: 2.3238 - accuracy: 0.0469
6/938 [..............................] - ETA: 9s - loss: 2.1227 - accuracy: 0.2995
13/938 [..............................] - ETA: 8s - loss: 1.7952 - accuracy: 0.4760
20/938 [..............................] - ETA: 7s - loss: 1.5536 - accuracy: 0.5539
27/938 [..............................] - ETA: 7s - loss: 1.3590 - accuracy: 0.6071
36/938 [>.............................] - ETA: 6s - loss: 1.1622 - accuracy: 0.6606
44/938 [>.............................] - ETA: 6s - loss: 1.0395 - accuracy: 0.6935
51/938 [>.............................] - ETA: 6s - loss: 0.9590 - accuracy: 0.7160
……
937/938 [============================>.] - ETA: 0s - loss: 0.2184 - accuracy: 0.9349"
timestamp: "2024-06-26T05:52:38.962950115Z"
}
Chaque entrée de journal des nœuds de tranche de TPU porte le libellé compute.googleapis.com/resource_name
avec la valeur définie comme nom de nœud.
Si vous souhaitez afficher les journaux d'un nœud spécifique et que vous connaissez son nom, vous pouvez filtrer les journaux par ce nœud dans votre requête. Par exemple, la requête suivante affiche les journaux du nœud TPU gke-tpu-9243ec28-wwf5
:
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" = "gke-tpu-9243ec28-wwf5"
GKE associe les étiquettes cloud.google.com/gke-tpu-accelerator
et cloud.google.com/gke-tpu-topology
à tous les nœuds contenant des TPU. Par conséquent, si vous ne connaissez pas le nom du nœud ou si vous souhaitez lister tous les nœuds de segment TPU, vous pouvez exécuter la commande suivante :
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator
Exemple de résultat :
NAME STATUS ROLES AGE VERSION
gke-tpu-9243ec28-f2f1 Ready <none> 25m v1.30.1-gke.1156000
gke-tpu-9243ec28-wwf5 Ready <none> 7d22h v1.30.1-gke.1156000
Vous pouvez effectuer un filtrage supplémentaire en fonction des libellés de nœud et de leurs valeurs. Par exemple, la commande suivante liste les nœuds TPU avec un type et une topologie spécifiques :
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=tpu-v5-lite-podslice,cloud.google.com/gke-tpu-topology=1x1
Pour afficher tous les journaux des nœuds de tranches TPU, vous pouvez utiliser la requête qui fait correspondre le libellé au suffixe du nœud de tranche TPU. Par exemple, utilisez la requête suivante :
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*"
log_id("stdout")
Pour afficher les journaux associés à une charge de travail TPU spécifique à l'aide d'une tâche Kubernetes, vous pouvez filtrer les journaux à l'aide du libellé batch.kubernetes.io/job-name
. Par exemple, pour la tâche mnist-training-job
, vous pouvez exécuter la requête suivante pour les journaux STDOUT :
resource.type="k8s_container"
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job"
log_id("stdout")
Pour afficher les journaux d'une charge de travail TPU à l'aide d'un JobSet Kubernetes, vous pouvez filtrer les journaux à l'aide du libellé k8s-pod/jobset_sigs_k8s_io/jobset-name
.
Exemple :
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
Pour aller plus loin, vous pouvez filtrer en fonction des autres libellés de charge de travail.
Par exemple, pour afficher les journaux d'une charge de travail multisegment à partir du nœud de calcul 0 et du segment 1, vous pouvez filtrer en fonction des libellés job-complete-index
et job-index
:
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
labels."k8s-pod/batch_kubernetes_io/job-completion-index"="0"
labels."k8s-pod/jobset_sigs_k8s_io/job-index"="1"
Vous pouvez également filtrer à l'aide du format de nom de pod :
resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>
Par exemple, dans la requête suivante, jobSetName
est un job multi-tranches et replicateJobName
est une tranche. job-index
et worker-index
sont tous deux définis sur 0 :
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
resource.labels.pod_name:"multislice-job-slice-0-0"
Pour les autres charges de travail TPU, comme une charge de travail d'un seul pod GKE, vous pouvez filtrer les journaux par nom de pod. Exemple :
resource.type="k8s_container"
resource.labels.pod_name="tpu-job-jax-demo"
Si vous souhaitez vérifier si le plug-in de l'appareil TPU s'exécute correctement, vous pouvez utiliser la requête suivante pour vérifier ses journaux de conteneur :
resource.type="k8s_container"
labels.k8s-pod/k8s-app="tpu-device-plugin"
resource.labels.namespace_name="kube-system"
Exécutez la requête suivante pour vérifier les événements associés :
jsonPayload.involvedObject.name=~"tpu-device-plugin.*"
log_id("events")
Pour toutes les requêtes, vous pouvez ajouter des filtres supplémentaires, tels que le nom du cluster, l'emplacement et l'ID de projet. Vous pouvez également combiner des conditions pour affiner les résultats. Exemple :
resource.type="k8s_container" AND
resource.labels.project_id="gke-tpu-demo-project" AND
resource.labels.location="us-west1" AND
resource.labels.cluster_name="tpu-demo" AND
resource.labels.namespace_name="default" AND
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" AND
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job" AND
log_id("stdout")
L'opérateur AND
est facultatif entre les comparaisons et peut être omis. Pour en savoir plus sur le langage de requête, consultez la spécification du langage de requête Logging.
Vous pouvez également consulter les requêtes de journaux associées à Kubernetes pour obtenir d'autres exemples de requêtes.
Si vous préférez utiliser SQL avec l'Analyse de journaux, vous trouverez des exemples de requêtes dans Requête SQL avec l'Analyse de journaux. Vous pouvez également exécuter les requêtes à l'aide de Google Cloud CLI plutôt que dans l'explorateur de journaux. Exemple :
gcloud logging read 'resource.type="k8s_container" labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" log_id("stdout")' --limit 10 --format json