Soluciona problemas de TPU en GKE


En esta página, se muestra cómo resolver problemas relacionados con las TPU en Google Kubernetes Engine (GKE).

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.

Cuota insuficiente para satisfacer la solicitud TPU

Un error similar a Insufficient quota to satisfy the request indica que tu proyecto de Google Cloud tiene una cuota insuficiente para satisfacer la solicitud.

Para resolver este problema, verifica el límite de cuota y el uso actual de tu proyecto. Si es necesario, solicita un aumento de tu cuota de TPU.

Verifica el límite de cuota y el uso actual

Si deseas verificar el límite y el uso actual de la cuota de la API de Compute Engine para las TPUs, sigue estos pasos:

  1. Dirígete a la página Cuotas en la consola de Google Cloud.

    Ir a Cuotas

  2. En la casilla Filtro, haz lo siguiente:

    1. Selecciona la propiedad Servicio, ingresa API de Compute Engine y presiona Intro.

    2. Selecciona la propiedad Tipo y elige Cuota.

    3. Selecciona la propiedad Dimensiones (p. ej., ubicaciones) y, luego, ingresa region: seguido del nombre de la región en la que planeas crear TPUs en GKE. Por ejemplo, ingresa region:us-west4 si planeas crear nodos de porción TPU en la zona us-west4-a. La cuota de TPU es regional, por lo que todas las zonas dentro de la misma región consumen la misma cuota de TPU.

Si ninguna cuota coincide con el filtro que ingresaste, no se le otorgó ninguna de las cuotas especificadas para la región deseada al proyecto y debes solicitar un aumento de la cuota de TPU.

Se produjo un error cuando se habilitaba el aprovisionamiento automático de nodos en un grupo de nodos de porción TPU

El siguiente error ocurre cuando habilitas el aprovisionamiento automático de nodos en un clúster de GKE que no admite TPU.

El mensaje de error es similar al siguiente:

ERROR: (gcloud.container.clusters.create) ResponseError: code=400,
  message=Invalid resource: tpu-v4-podslice.

Para resolver este problema, actualiza tu clúster de GKE a la versión 1.27.6 o posterior.

GKE no aprovisiona de forma automática los nodos de porción TPU

En las siguientes secciones, se describen los casos en los que GKE no aprovisiona de forma automática los nodos de porción TPU y cómo solucionarlos.

Limita la configuración incorrecta

GKE no aprovisiona de forma automática los nodos de porción TPU si los límites de aprovisionamiento automático que definiste para un clúster son demasiado bajos. Puedes observar los siguientes errores en esas situaciones:

  • Si existe un grupo de nodos de porción TPU, pero GKE no puede escalar verticalmente los nodos debido a incumplimiento de los límites de los recursos, puedes ver el siguiente mensaje de error cuando ejecutas el comando 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
    

    Además, en esta situación, puedes ver mensajes de advertencia similares a los siguientes en la consola de Google Cloud:

    "Your cluster has one or more unschedulable Pods"
    
  • Cuando GKE intenta aprovisionar de forma automática un grupo de nodos de porción TPU que exceda los límites de recursos, los registros de visibilidad del escalador automático de clústeres mostrarán el siguiente mensaje de error:

    messageId: "no.scale.up.nap.pod.zonal.resources.exceeded"
    

    Además, en esta situación, puedes ver mensajes de advertencia similares a los siguientes en la consola de 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"
    

Para resolver estos problemas, aumenta la cantidad máxima de chips TPU, núcleos de CPU y memoria en el clúster.

Para completar estos pasos, haz lo siguiente:

  1. Calcula los requisitos de recursos para un recuento y un tipo de máquina de TPU determinados. Ten en cuenta que debes agregar recursos para grupos de nodos que no sean de TPU, como las cargas de trabajo del sistema.
  2. Obtén una descripción de la TPU, la CPU y la memoria disponibles para un tipo de máquina y una zona específicos. Usa la CLI de gcloud:

    gcloud compute machine-types describe MACHINE_TYPE \
        --zone COMPUTE_ZONE
    

    Reemplaza lo siguiente:

    • MACHINE_TYPE: el tipo de máquina que se buscará.
    • COMPUTE_ZONE: el nombre de la zona de procesamiento.

    El resultado incluye una línea descriptiva similar a la siguiente:

      description: 240 vCPUs, 407 GB RAM, 4 Google TPUs
      ```
    
  3. Para calcular la cantidad total de CPU y memoria, multiplica estas cantidades por la cantidad requerida de nodos. Por ejemplo, el tipo de máquina ct4p-hightpu-4t usa 240 núcleos de CPU y 407 GB de RAM con 4 chips TPU. Si suponemos que necesitas 20 chips TPU, que corresponden a cinco nodos, debes definir los siguientes valores:

    • --max-accelerator=type=tpu-v4-podslice,count=20.
    • CPU = 1200 (240 veces 5)
    • memory = 2035 (407 veces 5)

    Debes definir los límites con algún margen para admitir nodos que no sean de TPU, como las cargas de trabajo del sistema.

  4. Actualiza los límites del clúster:

    gcloud container clusters update CLUSTER_NAME \
        --max-accelerator type=TPU_ACCELERATOR \
        count=MAXIMUM_ACCELERATOR \
        --max-cpu=MAXIMUM_CPU \
        --max-memory=MAXIMUM_MEMORY
    

    Reemplaza lo siguiente:

    • CLUSTER_NAME: Es el nombre del clúster.
    • TPU_ACCELERATOR: Es el nombre del acelerador de TPU.
    • MAXIMUM_ACCELERATOR: Es la cantidad máxima de chips TPU en el clúster.
    • MAXIMUM_CPU: Es la cantidad máxima de núcleos en el clúster.
    • MAXIMUM_MEMORY: Es la cantidad máxima de gigabytes de memoria en el clúster.

No todas las instancias en ejecución

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.

Este error puede aparecer cuando se agota el tiempo de espera de la operación de GKE o que la solicitud no se puede completar ni poner en cola para aprovisionar grupos de nodos TPU de host único o de varios hosts. Para mitigar los problemas de capacidad, puedes usar reservas o considerar las VMs Spot.

Configuración incorrecta de la carga de trabajo

Este error se produce debido a una configuración incorrecta de la carga de trabajo. Las siguientes son algunas de las causas más comunes de este error:

  • Las etiquetas cloud.google.com/gke-tpu-accelerator y cloud.google.com/gke-tpu-topology son incorrectas o faltan en la especificación del Pod. GKE no aprovisionará grupos de nodos de porción TPU y el aprovisionamiento automático de nodos no podrá escalar verticalmente el clúster.
  • La especificación del Pod no especifica google.com/tpu en sus requisitos de recursos.

Para solucionar este problema, realiza una de las siguientes acciones:

  1. Verifica que no haya etiquetas no compatibles en el selector de nodos de la carga de trabajo. Por ejemplo, un selector de nodos para la etiqueta cloud.google.com/gke-nodepool evitará que GKE cree grupos de nodos adicionales para tus Pods.
  2. Asegúrate de que las especificaciones de la plantilla de Pod, en las que se ejecuta tu carga de trabajo de TPU, incluyan los siguientes valores:
    • Etiquetas cloud.google.com/gke-tpu-accelerator y cloud.google.com/gke-tpu-topology en su nodeSelector.
    • google.com/tpu en su solicitud.

Para aprender a implementar cargas de trabajo de TPU en GKE, consulta Ejecuta una carga de trabajo que muestre la cantidad de chips TPU disponibles en un grupo de nodos de porción TPU.

Programación de errores cuando se implementan Pods que consumen TPU en GKE

El siguiente problema se produce cuando GKE no puede programar los Pods que solicitan TPU en los nodos de porción TPU. Por ejemplo, esto puede suceder si algunas porciones que no son de TPU ya estaban programados en los nodos TPU.

El mensaje de error, emitido como un evento FailedScheduling en el Pod, es similar al siguiente:

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

Para solucionar este problema, haz lo siguiente:

Verifica que tengas al menos un grupo de nodos de CPU en tu clúster para que los Pods críticos del sistema puedan ejecutarse en los nodos que no son de TPU. Para obtener más información, consulta Implementa un Pod en un grupo de nodos específico.

Soluciona problemas habituales con JobSets en GKE

Para obtener información sobre problemas habituales con JobSet y sugerencias de solución de problemas, consulta la página Solución de problemas de JobSet. En esta página, se abordan problemas habituales, como el error "Webhook no disponible", el trabajo secundario o los Pods que no se crean, y la reanudación de problemas de cargas de trabajo interrumpidas mediante JobSet y Kueue.

No se pudo inicializar la TPU

El siguiente problema se produce cuando GKE no puede aprovisionar cargas de trabajo de TPU nuevas debido a la falta de permisos para acceder a los dispositivos de TPU.

El mensaje de error es similar al siguiente:

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

Para resolver este problema, asegúrate de ejecutar tu contenedor de TPU en modo con privilegios o aumentar ulimit dentro de tu contenedor.

Programación de interbloqueo

La programación de dos o más trabajos puede fallar en un interbloqueo. Por ejemplo, en una situación en la que ocurre todo lo siguiente:

  • Tienes dos trabajos (trabajo A y trabajo B) con reglas de afinidad de Pods. GKE programa las porciones de TPU para ambos trabajos con una topología de TPU de v4-32.
  • Tienes dos porciones de TPU v4-32 en el clúster.
  • Tu clúster tiene una capacidad suficiente para programar ambos trabajos y, en teoría, cada trabajo se puede programar con rapidez en cada porción de TPU.
  • El programador de Kubernetes programa un Pod del trabajo A en una porción y, luego, programa un Pod del trabajo B en la misma porción.

En este caso, dadas las reglas de afinidad de Pods para el trabajo A, el programador intenta programar todos los Pods restantes para el trabajo A y el trabajo B, en una sola porción de TPU cada uno. Como resultado, GKE no podrá programar por completo el trabajo A o el trabajo B. Por lo tanto, el estado de ambos trabajos permanecerá pendiente.

Para resolver este problema, usa la antiafinidad del Pod con cloud.google.com/gke-nodepool como con topologyKey, como se muestra en el siguiente ejemplo:

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

Permiso denegado durante la creación del clúster en us-central2

Si intentas crear un clúster en us-central2 (la única región en la que TPU v4 está disponible), es posible que veas un mensaje de error similar al siguiente:

ERROR: (gcloud.container.clusters.create) ResponseError: code=403,
message=Permission denied on 'locations/us-central2' (or it may not exist).

Este error se debe a que la región us-central2 es privada.

Para resolver este problema, presenta un caso de asistencia o comunícate con el equipo de cuentas para solicitar que us-central2 se muestre en tu proyecto de Google Cloud.

Cuota insuficiente durante la creación del grupo de nodos TPU en us-central2

Si intentas crear un grupo de nodos de porción TPU en us-central2 (la única región en la que TPU v4 está disponible), es posible que debas aumentar las siguientes cuotas relacionadas con GKE cuando crees grupos de nodos TPU v4 por primera vez:

  • Cuota de SSD de Persistent Disk (GB) en us-central2: el disco de arranque de cada nodo de Kubernetes requiere 100 GB de forma predeterminada. Por lo tanto, esta cuota debe establecerse al menos tan alta como el producto de la cantidad máxima de nodos de GKE que esperas crear.us-central2 y 100 GB (maximum_nodes X100 GB ).
  • Cuota de direcciones IP en uso en us-central2: cada nodo de Kubernetes consume una dirección IP. Por lo tanto, esta cuota debe establecerse al menos tan alta como la cantidad máxima de nodos de GKE que esperas crear en us-central2.

Falta la subred durante la creación del clúster de GKE

Si intentas crear un clúster en us-central2 (la única región en la que TPU v4 está disponible), es posible que veas un mensaje de error similar al siguiente:

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>.

Se requiere una subred en tu red de VPC para proporcionar conectividad a los nodos de GKE. Sin embargo, en ciertas regiones, como us-central2, es posible que no se cree una subred predeterminada, incluso cuando usas la red de VPC predeterminada en modo automático (para crear subredes).

Para resolver este problema, asegúrate de haber creado una subred personalizada en la región antes de crear el clúster de GKE. Esta subred no debe superponerse con otras subredes creadas en otras regiones de la misma red de VPC.

Ve registros de TPU de GKE

Para ver todos los registros relacionados con las TPU de una carga de trabajo específica, Cloud Logging ofrece una ubicación centralizada para consultar estos registros cuando el sistema de GKE y el registro de cargas de trabajo están habilitados. En Cloud Logging, los registros se organizan en entradas de registro, y cada entrada de registro individual tiene un formato estructurado. El siguiente es un ejemplo de una entrada de registro de un trabajo de entrenamiento de 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"
}

Cada entrada de registro de los nodos de porción de TPU tiene la etiqueta compute.googleapis.com/resource_name con el valor establecido como el nombre del nodo. Si quieres ver los registros de un nodo en particular y conoces su nombre, puedes filtrar los registros por ese nodo en tu consulta. Por ejemplo, en la siguiente consulta se muestran los registros del nodo TPU gke-tpu-9243ec28-wwf5:

resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" = "gke-tpu-9243ec28-wwf5"

GKE adjunta las etiquetas cloud.google.com/gke-tpu-accelerator y cloud.google.com/gke-tpu-topology a todos los nodos que contienen TPU. Por lo tanto, si no tienes certeza del nombre del nodo o deseas enumerar todos los nodos de porción de TPU, puedes ejecutar el siguiente comando:

kubectl get nodes -l cloud.google.com/gke-tpu-accelerator

Resultado de muestra:

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

Puedes realizar filtros adicionales según las etiquetas de nodo y sus valores. Por ejemplo, con el siguiente comando, se enumeran los nodos TPU con un tipo y una topología específicos:

kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=tpu-v5-lite-podslice,cloud.google.com/gke-tpu-topology=1x1

Para ver todos los registros en los nodos de porción de TPU, puedes usar la consulta que hace coincidir la etiqueta con el sufijo del nodo de porción de TPU. Por ejemplo, usa la siguiente consulta:

resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*"
log_id("stdout")

Para ver los registros asociados con una carga de trabajo de TPU en particular con un trabajo de Kubernetes, puedes filtrar los registros con la etiqueta batch.kubernetes.io/job-name. Por ejemplo, para el trabajo mnist-training-job, puedes ejecutar la siguiente consulta para los registros STDOUT:

resource.type="k8s_container"
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job"
log_id("stdout")

Para ver los registros de una carga de trabajo de TPU con un JobSet de Kubernetes, puedes filtrar los registros con la etiqueta k8s-pod/jobset_sigs_k8s_io/jobset-name. Por ejemplo:

resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"

Para desglosar aún más, puedes filtrar según las otras etiquetas de carga de trabajo. Por ejemplo, para ver los registros de una carga de trabajo de varias porciones del trabajador 0 y la porción 1, puedes filtrar según las etiquetas: job-complete-index y 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"

También puedes filtrar con el patrón de nombre de Pod:

resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>

Por ejemplo, en la siguiente consulta, jobSetName es un trabajo de varias porciones y replicateJobName es una porción. job-index y worker-index son 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"

En otras cargas de trabajo de TPU, como una sola carga de trabajo de Pod de GKE, puedes filtrar los registros por nombres de Pod. Por ejemplo:

resource.type="k8s_container"
resource.labels.pod_name="tpu-job-jax-demo"

Si deseas verificar si el complemento del dispositivo TPU se ejecuta de forma correcta, puedes usar la siguiente consulta para verificar los registros de su contenedor:

resource.type="k8s_container"
labels.k8s-pod/k8s-app="tpu-device-plugin"
resource.labels.namespace_name="kube-system"

Ejecuta la siguiente consulta para verificar los eventos relacionados:

jsonPayload.involvedObject.name=~"tpu-device-plugin.*"
log_id("events")

Para todas las consultas, puedes agregar filtros adicionales, como el nombre del clúster, la ubicación y el ID del proyecto. También puedes combinar condiciones para limitar los resultados. Por ejemplo:

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")

El operador AND es opcional entre las comparaciones y se puede omitir. Para obtener más información sobre el lenguaje de consulta, lee la especificación del lenguaje de consulta de Logging. También puedes leer las consultas de registros relacionadas con Kubernetes para obtener más ejemplos de consultas.

Si prefieres SQL con el Análisis de registros, puedes encontrar ejemplos de consultas en Consulta en SQL con Análisis de registros. Como alternativa, también puedes ejecutar las consultas con Google Cloud CLI en lugar de en el Explorador de registros. Por ejemplo:

gcloud logging read 'resource.type="k8s_container" labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" log_id("stdout")' --limit 10 --format json

¿Qué sigue?

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.