Ejecutar una carga de trabajo por lotes pequeña con TPUs y VMs de inicio flexible

En esta guía se explica cómo optimizar el aprovisionamiento de TPUs para cargas de trabajo de entrenamiento a mediana y pequeña escala mediante el uso de máquinas virtuales de inicio flexible. Las VMs de inicio flexible se crean mediante la opción de consumo inicio flexible. En esta guía, usarás VMs de inicio flexible para desplegar una carga de trabajo que consta de un grupo de nodos de segmento de TPU.

Esta guía está dirigida a ingenieros de aprendizaje automático, administradores y operadores de plataformas, y especialistas en datos e IA que estén interesados en usar las funciones de orquestación de contenedores de Kubernetes para ejecutar cargas de trabajo por lotes. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Google Cloud

Precios de flex-start

Se recomienda el inicio flexible si tu carga de trabajo requiere recursos aprovisionados dinámicamente según sea necesario, durante un máximo de siete días con reservas a corto plazo, sin una gestión de cuotas compleja y con un acceso rentable. La función de inicio flexible se basa en Dynamic Workload Scheduler y se factura según los precios de Dynamic Workload Scheduler:

  • Descuento de hasta el 53 % en vCPUs, GPUs y TPUs.
  • Pagas a medida que lo usas.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la CLI de gcloud, obtén la versión más reciente ejecutando el comando gcloud components update. Es posible que las versiones anteriores de la interfaz de línea de comandos de gcloud no admitan la ejecución de los comandos de este documento.

Crear un grupo de nodos con flex-start

Si usas un clúster en el modo Autopilot, sáltate esta sección y ve a la sección Ejecutar una carga de trabajo por lotes.

Para crear un grupo de nodos con flex-start habilitado en un clúster Standard, usa la CLI de gcloud.

Crear un grupo de nodos de segmento de TPU de un solo host

Puedes crear un grupo de nodos de segmento de TPU de un solo host con inicio flexible:

  1. Crea un grupo de nodos con inicio flexible:

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --node-locations=NODE_ZONES \
        --machine-type=MACHINE_TYPE \
        --reservation-affinity=none \
        --enable-autoscaling \
        --flex-start \
        --num-nodes 0 \
        --min-nodes=0 \
        --max-nodes=1
    

    Haz los cambios siguientes:

    • NODE_POOL_NAME: el nombre que elijas para tu grupo de nodos.
    • CLUSTER_NAME: el nombre del clúster.
    • CONTROL_PLANE_LOCATION: la región de computación del plano de control del clúster.
    • NODE_ZONES: lista separada por comas de una o varias zonas en las que GKE crea el grupo de nodos.
    • MACHINE_TYPE: el tipo de máquina que se va a usar en los nodos. Para obtener más información sobre los tipos de máquinas compatibles con las TPU, consulta la tabla de la sección Elegir la versión de TPU.

      Por ejemplo, el comando de creación del grupo de nodos puede incluir los siguientes parámetros:

      ...
      --machine-type=ct6e-standard-4t \
      --tpu-topology=4x4 \
      --enable-autoscaling \
      --num-nodes=0 \
      --max-nodes=4 \
      

      Este comando asigna el valor --max-nodes al campo 4 porque una topología 4x4 consta de 16 chips y cada VM ct6e-standard-4t tiene 4 chips.

      El autoescalador de clústeres aumenta el número de nodos hasta el número que requiere tu carga de trabajo. Una vez que se haya completado la carga de trabajo, el autoescalador de clúster se reducirá a cero nodos.

    • --reservation-affinity=none: flex-start no usa ni requiere reservas.

Crear un grupo de nodos de un slice de TPU de varios hosts

Los pasos para crear un grupo de nodos de un slice de TPU de varios hosts varían en función de si usas Ironwood (TPU7x) o una versión anterior de TPU.

Ironwood (TPU7x)

Puedes crear un grupo de nodos de slice de TPU multihost en la versión Ironwood (TPU7x) mediante Google Cloud CLI o Terraform:

gcloud

Para crear un grupo de nodos de un segmento de TPU de varios hosts con Ironwood (TPU7x), primero debes crear una política de carga de trabajo.

  1. Crea una política de cargas de trabajo:

    gcloud compute resource-policies create workload-policy WORKLOAD_POLICY_NAME \
        --type=HIGH_THROUGHPUT \
        --accelerator-topology=TPU_TOPOLOGY \
        --project=PROJECT_ID \
        --region=REGION
    

    Haz los cambios siguientes:

    • WORKLOAD_POLICY_NAME: un nombre para tu política de carga de trabajo.
    • TPU_TOPOLOGY: la topología de la TPU Ironwood (TPU7x). Por ejemplo, 2x2x2. Para ver todas las topologías de Ironwood (TPU7x) admitidas, consulta la sección de topología.
    • PROJECT_ID: tu ID de proyecto Google Cloud .
    • REGION: la región de la política de cargas de trabajo. Una política de carga de trabajo es un recurso regional y se puede reutilizar en grupos de nodos que compartan la misma topología.
  2. Crea el grupo de nodos con la política de carga de trabajo:

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=us-central1 \
        --node-locations=us-central1-c \
        --machine-type=tpu7x-standard-4t \
        --reservation-affinity=none \
        --enable-autoscaling \
        --num-nodes=0 --min-nodes=0 --max-nodes=MAX_NODES \
        --flex-start \
        --placement-policy=WORKLOAD_POLICY
    

    Haz los cambios siguientes:

    • NODE_POOL_NAME: el nombre del nuevo grupo de nodos.
    • WORKLOAD_POLICY: el nombre de la política de carga de trabajo que has creado.
    • MAX_NODES: tamaño máximo del grupo de nodos. La marca --max-nodes es obligatoria si se proporciona --enable-autoscaling y debe ser igual al producto de los valores definidos en TPU_TOPOLOGY ({A}x{B}x{C}) dividido entre el número de chips de cada máquina virtual. Por ejemplo, si TPU_TOPOLOGY es 2x2x2, el producto es 8. Como cada VM de tpu7x-standard-4t tiene 4 chips, el número de nodos es 2.

    Este comando crea un grupo de nodos llamado NODE_POOL_NAME con las siguientes características:

    • --machine-type=tpu7x-standard-4t especifica el tipo de máquina Ironwood (TPU7x).
    • --flex-start habilita inicio flexible.

Terraform

  1. Asegúrate de usar la versión 4.84.0 o una posterior del proveedor google.
  2. Crea una política de cargas de trabajo:

    resource "google_compute_resource_policy" {
      name   = "WORKLOAD_POLICY_NAME"
      region = CLUSTER_LOCATION
      workload_policy {
        type = "HIGH_THROUGHPUT"
        accelerator_topology = "TPU_TOPOLOGY"
      }
    }
    

    Haz los cambios siguientes:

    • WORKLOAD_POLICY_NAME: un nombre para tu política de carga de trabajo.
    • CLUSTER_LOCATION: ubicación de cálculo del clúster. Te recomendamos que tengas un clúster regional para aumentar la fiabilidad del plano de control de Kubernetes. También puedes usar un clúster zonal. Para obtener más información, consulta Seleccionar una versión y una topología de TPU.
    • TPU_TOPOLOGY: la topología de la TPU Ironwood (TPU7x). Por ejemplo, 2x2x2. Para ver todas las topologías de Ironwood (TPU7x) compatibles, consulta Planificar TPUs.

    Para obtener más información sobre la referencia de google_compute_resource_policy, consulta Proveedor de Terraform.

  3. En tu configuración de Terraform, añade el siguiente bloque:

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

    Haz los cambios siguientes:

    • NODE_POOL_RESOURCE_NAME: el nombre del recurso de grupo de nodos en la plantilla de Terraform.
    • PROJECT_ID: tu ID de proyecto.
    • CLUSTER_NAME: el nombre del clúster al que quieres añadir el grupo de nodos.
    • POOL_NAME: el nombre del grupo de nodos que se va a crear.
    • NODE_ZONES: lista separada por comas de una o varias zonas en las que GKE crea el grupo de nodos.
    • NUM_NODES: número de nodos del grupo de nodos. Debe ser cero o el producto del número de chips de TPU dividido entre cuatro, ya que en las porciones de TPU de varios hosts, cada nodo de la porción de TPU tiene cuatro chips. Por ejemplo, si TPU_TOPOLOGY es 4x8, hay 32 chips, lo que significa que NUM_NODES debe ser 8. Para obtener más información sobre las topologías de TPU, consulta la tabla de la sección Elegir la versión de TPU.
    • TPU_TOPOLOGY: indica la topología física seleccionada del segmento de TPU. El formato de la topología depende de la versión de TPU que estés usando. Para obtener más información sobre las topologías de TPU, consulta la tabla de la sección Elegir una topología.

    También puedes usar las siguientes variables:

    • RESERVATION_NAME: si usas una reserva de TPU, proporciona una lista de etiquetas de recursos de reserva que se usarán al crear el grupo de nodos. Para obtener más información sobre cómo rellenar el campo RESERVATION_LABEL_VALUES en reservation_affinity, consulta Proveedor de Terraform.
    • autoscaling: crea un grupo de nodos con el autoescalado habilitado. Cuando GKE escala un grupo de nodos de un segmento de TPU multihost, escala el grupo de nodos de forma atómica de cero al tamaño máximo.
      • MAX_NODES: tamaño máximo del grupo de nodos. El valor debe ser igual al producto de los valores definidos en TPU_TOPOLOGY ({A}x{B}x{C}) dividido por el número de chips de cada máquina virtual. Por ejemplo, si TPU_TOPOLOGY es 2x2x2, el producto es 8. Como cada VM de tpu7x-standard-4t tiene 4 chips, el número de nodos es 2.
    • spot: el grupo de nodos que usará Spot VMs para los nodos de la porción de TPU. Este ajuste no se puede cambiar después de crear el grupo de nodos. Para obtener más información, consulta Máquinas virtuales de acceso puntual.
    • flex_start: el grupo de nodos que usará la opción de consumo flex-start. Este ajuste no se puede definir en true si spot está habilitado.

Otras versiones de TPU

Puedes crear un grupo de nodos de slice de TPU multihost en las versiones v3, v4, v5p, v5e y Trillium (v6e) mediante la CLI de Google Cloud, Terraform o la Google Cloud consola.

gcloud

  gcloud container node-pools create NODE_POOL_NAME \
      --cluster=CLUSTER_NAME \
      --location=CONTROL_PLANE_LOCATION \
      --node-locations=NODE_ZONES \
      --machine-type=MACHINE_TYPE \
      --tpu-topology=TPU_TOPOLOGY \
      --reservation-affinity=none \
      --enable-autoscaling \
      --num-nodes=0 --min-nodes=0 --max-nodes=MAX_NODES \
      --flex-start

Haz los cambios siguientes:

  • NODE_POOL_NAME: el nombre del nuevo grupo de nodos.
  • CLUSTER_NAME: el nombre del clúster.
  • CONTROL_PLANE_LOCATION: el nombre de la zona en función de la versión de TPU que quieras usar. Para identificar una ubicación disponible, consulta Disponibilidad de las TPUs en GKE.
  • NODE_ZONES: lista separada por comas de una o varias zonas en las que GKE crea el grupo de nodos.
  • MACHINE_TYPE: el tipo de máquina que se va a usar en los nodos. Para obtener más información sobre los tipos de máquinas compatibles con TPU, consulta la tabla de la sección Elegir la versión de TPU.
  • TPU_TOPOLOGY: la topología de la TPU. Por ejemplo, 2x2x2. Para ver todas las topologías de TPU admitidas, consulta la sección de topología.
  • MAX_NODES: tamaño máximo del grupo de nodos. La marca --max-nodes es obligatoria si se proporciona --enable-autoscaling y debe ser igual al producto de los valores definidos en TPU_TOPOLOGY ({A}x{B}x{C}) dividido entre el número de chips de cada máquina virtual.

    Este comando crea un grupo de nodos llamado NODE_POOL_NAME con flex-start habilitado.

Terraform

  1. Asegúrate de usar la versión 4.84.0 o una posterior del proveedor google.
  2. Añade el siguiente bloque a tu configuración de Terraform:

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

    Haz los cambios siguientes:

    • NODE_POOL_RESOURCE_NAME: el nombre del recurso de grupo de nodos en la plantilla de Terraform.
    • PROJECT_ID: tu ID de proyecto.
    • CLUSTER_NAME: el nombre del clúster al que quieres añadir el grupo de nodos.
    • POOL_NAME: el nombre del grupo de nodos que se va a crear.
    • CLUSTER_LOCATION: calcula la ubicación del clúster. Te recomendamos que tengas un clúster regional para aumentar la fiabilidad del plano de control de Kubernetes. También puedes usar un clúster zonal. Para obtener más información, consulta Seleccionar una versión y una topología de TPU.
    • NODE_ZONES: lista separada por comas de una o varias zonas en las que GKE crea el grupo de nodos.
    • NUM_NODES: número de nodos del grupo de nodos. Debe ser cero o el resultado de dividir el número de chips de TPU entre cuatro, ya que en las porciones de TPU multihost, cada nodo de la porción de TPU tiene cuatro chips. Por ejemplo, si TPU_TOPOLOGY es 4x8, hay 32 chips, lo que significa que NUM_NODES debe ser 8. Para obtener más información sobre las topologías de TPU, consulta la tabla de la sección Elegir la versión de TPU.
    • TPU_TOPOLOGY: indica la topología física del segmento de TPU. El formato de la topología depende de la versión de TPU que estés usando. Para obtener más información sobre las topologías de TPU, consulta la tabla de la sección Elegir una topología.

    También puedes usar las siguientes variables:

    • RESERVATION_NAME: si usas reservas de TPU, esta es la lista de etiquetas de los recursos de reserva que se usarán al crear el grupo de nodos. Para obtener más información sobre cómo rellenar el campo RESERVATION_LABEL_VALUES en reservation_affinity, consulta Proveedor de Terraform.
    • autoscaling: crea un grupo de nodos con el escalado automático habilitado. Cuando GKE escala un grupo de nodos de un segmento de TPU multihost, escala el grupo de nodos de forma atómica de cero al tamaño máximo.
      • MAX_NODES: es el tamaño máximo del pool de nodos. Debe ser igual al producto de los valores definidos en TPU_TOPOLOGY ({A}x{B}x{C}) dividido entre el número de chips de cada máquina virtual.
    • spot: permite que el grupo de nodos use máquinas virtuales de Spot para los nodos de la porción de TPU. No se puede cambiar después de crear el grupo de nodos. Para obtener más información, consulta Máquinas virtuales de acceso puntual.
    • flex_start: define que el grupo de nodos use la opción de consumo inicio flexible. No se puede definir como true si spot está habilitado.

Consola

Para crear un grupo de nodos con TPUs, sigue estos pasos:

  1. Ve a la página Google Kubernetes Engine en la Google Cloud consola.

    Ir a Google Kubernetes Engine

  2. En la lista de clústeres, haga clic en el nombre del clúster que quiera modificar.

  3. Haz clic en Añadir grupo de nodos.

  4. En la sección Detalles del grupo de nodos, marca la casilla Especificar ubicaciones de nodos.

  5. Selecciona el nombre de la zona en función de la versión de TPU que quieras usar. Para identificar una ubicación disponible, consulta Disponibilidad de las TPUs en GKE.

  6. En el panel de navegación, haga clic en Nodos.

  7. En la sección Configuración de la máquina, selecciona TPUs.

  8. En el menú desplegable Serie, selecciona una de las siguientes opciones:

    • CT3 TPU v3, dispositivo de un solo host
    • CT3P: TPU v3, porción de pod multihost
    • CT4P: TPU v4
    • CT5LP: TPU v5e
    • CT5P: TPU v5p
    • CT6E: TPU Trillium (v6e)
  9. En el menú desplegable Tipo de máquina, selecciona el nombre de la máquina que quieras usar para los nodos. Consulta la tabla Elegir la versión de TPU para saber cómo definir el tipo de máquina y la topología de TPU que crean un bloque de nodos de TPU multihost.

  10. En el menú desplegable Topología de TPU, selecciona la topología física del slice de TPU.

  11. En el cuadro de diálogo Cambios necesarios, haga clic en Hacer cambios.

  12. Asegúrate de que el Tipo de disco de arranque sea Disco persistente estándar o Disco persistente SSD.

  13. Si quieres, marca la casilla Habilitar nodos en VMs Spot para usar VMs Spot en los nodos del grupo de nodos.

  14. Haz clic en Crear.

Verificar el estado de inicio flexible en el grupo de nodos

Ejecuta el siguiente comando:

gcloud container node-pools describe NODE_POOL_NAME \
    --cluster CLUSTER_NAME \
    --location CONTROL_PLANE_LOCATION \
    --format="get(config.flexStart)"

Si flex-start está habilitado en el grupo de nodos, el campo flexStart se define como True.

Ejecutar una carga de trabajo por lotes

En esta sección, crearás un trabajo que programará un nodo de TPU con VMs de inicio flexible. Un controlador de trabajo de Kubernetes crea uno o varios pods y se asegura de que ejecuten correctamente una tarea específica.

  1. En la consola deGoogle Cloud , inicia una sesión de Cloud Shell haciendo clic en Icono de activación de Cloud Shell Activar Cloud Shell. Se abrirá una sesión en el panel inferior de la consola Google Cloud .

  2. Crea un archivo llamado dws-flex-start.yaml:

    Un solo host

    Usa el siguiente manifiesto para el archivo dws-flex-start.yaml:

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-1
    spec:
      template:
        spec:
          nodeSelector:
            cloud.google.com/gke-flex-start: "true"
            cloud.google.com/gke-tpu-accelerator: ACCELERATOR_TYPE
            cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
          containers:
          - name: container-1
            image: gcr.io/k8s-staging-perf-tests/sleep:latest
            args: ["3600s"] # Sleep for 1 hour
            resources:
              requests:
                  google.com/tpu: NUM_CHIPS
              limits:
                  google.com/tpu: NUM_CHIPS
          restartPolicy: OnFailure
    

    Varios hosts

    Usa el siguiente manifiesto para el archivo dws-flex-start.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: headless-svc
    spec:
      clusterIP: None
      selector:
        job-name: job-1
    ---
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-1
    spec:
      backoffLimit: 0
      completions: 2
      parallelism: 2
      completionMode: Indexed
      template:
        spec:
          subdomain: headless-svc
          restartPolicy: Never
          nodeSelector:
              cloud.google.com/gke-flex-start: "true"
              cloud.google.com/gke-tpu-accelerator: ACCELERATOR_TYPE
              cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
          containers:
          - name: tpu-job
            image: us-docker.pkg.dev/cloud-tpu-images/jax-ai-image/tpu:latest
            ports:
            - containerPort: 8471 # Default port using which TPU VMs communicate
            - containerPort: 8431 # Port to export TPU runtime metrics, if supported.
            securityContext:
              privileged: true
            command:
            - bash
            - -c
            - |
              python -c 'import jax; print("TPU cores:", jax.device_count())'
            resources:
              requests:
                google.com/tpu: NUM_CHIPS
              limits:
                google.com/tpu: NUM_CHIPS
    

    Haz los cambios siguientes:

    • ACCELERATOR_TYPE: el tipo de acelerador de TPU que has usado al crear los grupos de nodos. Por ejemplo, tpu-v4-podslice o tpu-v5-lite-podslice.
    • TPU_TOPOLOGY: la topología física de la porción de TPU. Por ejemplo, el valor puede ser 4x4x4 o 2x2, según la versión de la TPU.
    • NUM_CHIPS: el número de chips de TPU de cada máquina virtual es uno, cuatro u ocho. Para obtener más información, consulta Versiones de TPU.
  3. Aplica el manifiesto dws-flex-start.yaml:

    kubectl apply -f dws-flex-start.yaml
    
  4. Verifica que los trabajos se estén ejecutando en el mismo nodo:

    kubectl get pods
    

    El resultado debería ser similar al siguiente:

    NAME    READY   STATUS      RESTARTS   AGE   IP       NODE               NOMINATED NODE   READINESS GATES
    job-1   0/1     Completed   0          19m   10.(...) gke-flex-zonal-a2  <none>           <none>
    

Limpieza

Para evitar que se apliquen cargos en tu cuenta Google Cloud por los recursos que has usado en esta página, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

Eliminar el proyecto

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Eliminar el recurso concreto

  1. Elimina los trabajos:

    kubectl delete job -l "job-name in (job-1,job-2)"
    
  2. Elimina el grupo de nodos:

    gcloud container node-pools delete NODE_POOL_NAME \
          --location CONTROL_PLANE_LOCATION
    
  3. Elimina el clúster:

    gcloud container clusters delete CLUSTER_NAME
    

Siguientes pasos