Ejecuta una pequeña carga de trabajo por lotes con TPU y VMs de inicio flexible

En esta guía, se muestra cómo optimizar el aprovisionamiento de TPU para cargas de trabajo de entrenamiento a pequeña y mediana escala con VMs de inicio flexible. Las VMs de inicio flexible se crean con la opción de consumo flex-start. En esta guía, usarás VMs con inicio flexible para implementar una carga de trabajo que consta de un grupo de nodos de porción de TPU.

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

Precios de inicio flexible

Se recomienda el inicio flexible si tu carga de trabajo requiere recursos aprovisionados de forma dinámica según sea necesario, durante un máximo de siete días con reservas a corto plazo, sin administración compleja de cuotas y con acceso rentable. El inicio flexible cuenta con la tecnología del programador dinámico de cargas de trabajo y se factura con los precios del programador dinámico de cargas de trabajo:

  • Descuento (hasta un 53%) en CPU virtuales, GPU y TPU
  • Pagas por lo que usas.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta el comando gcloud components update para obtener la versión más reciente. Es posible que las versiones anteriores de gcloud CLI no admitan la ejecución de los comandos que se describen en este documento.
  • Verifica que tengas un clúster de Autopilot o un clúster estándar que ejecute la versión 1.33.0-gke.1712000 o posterior.
  • Verifica que conozcas las limitaciones de flex-start.
  • Cuando uses un clúster estándar, verifica que mantengas al menos un grupo de nodos sin el inicio flexible habilitado para que el clúster funcione correctamente.
  • Verifica que tengas cuota para las TPUs interrumpibles en las ubicaciones de tus nodos.

Crea un grupo de nodos con inicio flexible

Si usas un clúster en modo Autopilot, omite esta sección y ve a la sección Ejecuta una carga de trabajo por lotes.

Para crear un grupo de nodos con el inicio flexible habilitado en un clúster estándar existente, usa gcloud CLI.

Crea un grupo de nodos de porción de TPU de host único

Puedes crear un grupo de nodos de porción de TPU de host único con inicio flexible:

  1. Crea un grupo de nodos con flex-start:

    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
    

    Reemplaza lo siguiente:

    • NODE_POOL_NAME: es el nombre que eliges para el grupo de nodos.
    • CLUSTER_NAME: el nombre del clúster
    • CONTROL_PLANE_LOCATION: Es la región de procesamiento del plano de control del clúster.
    • NODE_ZONES: La lista separada por comas de una o más zonas en las que GKE crea el grupo de nodos.
    • MACHINE_TYPE: Es el tipo de máquina que se usará para los nodos. Para obtener más información sobre los tipos de máquinas compatibles con TPU, usa la tabla en Elige 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 establece el campo --max-nodes en 4 porque una topología 4x4 consta de 16 chips y cada VM ct6e-standard-4t tiene 4 chips.

      El escalador automático del clúster se ajusta verticalmente a la cantidad de nodos que requiere tu carga de trabajo. Una vez que se completa tu carga de trabajo, el escalador automático de clústeres reduce la escala a cero nodos.

    • --reservation-affinity=none: El inicio flexible no usa ni requiere reservas.

Crea un grupo de nodos de porción de TPU de varios hosts

Los pasos para crear un grupo de nodos de porción de TPU de varios hosts difieren según si usas Ironwood (TPU7x) o una versión anterior de la TPU.

Ironwood (TPU7x)

Puedes crear un grupo de nodos de porción de TPU de varios hosts en la versión Ironwood (TPU7x) con Google Cloud CLI o Terraform:

gcloud

Para crear un grupo de nodos de porción de TPU de varios hosts con Ironwood (TPUv7), primero debes crear una política de carga de trabajo.

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

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

    Reemplaza lo siguiente:

    • WORKLOAD_POLICY_NAME: Es un nombre para tu política de carga de trabajo.
    • TPU_TOPOLOGY: Es la topología de la TPU Ironwood (TPU7x). Por ejemplo, 2x2x2 Para ver todas las topologías compatibles con Ironwood (TPU7x), consulta la sección de topología.
    • PROJECT_ID: El ID de tu proyecto Google Cloud .
    • REGION: Es la región de la política de carga de trabajo. Una política de carga de trabajo es un recurso regional y se puede volver a usar en grupos de nodos que comparten la misma topología.
  2. Crea el grupo de nodos con la política de cargas 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
    

    Reemplaza lo siguiente:

    • NODE_POOL_NAME: El nombre del grupo de nodos nuevo.
    • WORKLOAD_POLICY: Es el nombre de la política de cargas de trabajo que creaste.
    • MAX_NODES: el 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}) divididos por la cantidad de chips en cada VM. Por ejemplo, si TPU_TOPOLOGY es 2x2x2, el producto es 8. Dado que cada VM en tpu7x-standard-4t tiene 4 chips, la cantidad 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 el 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 carga de trabajo:

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

    Reemplaza lo siguiente:

    • WORKLOAD_POLICY_NAME: Es un nombre para tu política de carga de trabajo.
    • CLUSTER_LOCATION: la ubicación de procesamiento del clúster. Recomendamos tener un clúster regional para obtener una mayor confiabilidad del plano de control de Kubernetes. También puedes usar un clúster zonal. Para obtener más información, consulta Selecciona una versión y una topología de TPU.
    • TPU_TOPOLOGY: Es la topología de la TPU Ironwood (TPU7x). Por ejemplo, 2x2x2 Para ver todas las topologías compatibles con Ironwood (TPU7x), consulta Planifica las TPU.

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

  3. En la configuración de Terraform, agrega 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
      }
    }
    

    Reemplaza lo siguiente:

    • NODE_POOL_RESOURCE_NAME: El nombre del recurso del grupo de nodos en la plantilla de Terraform.
    • PROJECT_ID: el ID de tu proyecto
    • CLUSTER_NAME: Es el nombre del clúster existente al que se agregará el grupo de nodos.
    • POOL_NAME: el nombre del grupo de nodos que se creará.
    • NODE_ZONES: La lista separada por comas de una o más zonas en las que GKE crea el grupo de nodos.
    • NUM_NODES: Es la cantidad de nodos en el grupo de nodos. Debe ser cero o el producto de la cantidad de chips TPU dividido por cuatro, ya que en las porciones de TPU multihost cada nodo de porción de TPU tiene cuatro chips. Por ejemplo, si TPU_TOPOLOGY es 4x8, entonces hay 32 chips, lo que significa que NUM_NODES debe ser 8. Para obtener más información sobre las topologías de TPU, usa la tabla de Elige la versión de TPU.
    • TPU_TOPOLOGY: Indica la topología física seleccionada para la porción de TPU. El formato de la topología depende de la versión de la TPU que usas. Para obtener más información sobre las topologías de TPU, usa la tabla de Elige una topología.

    De manera opcional, también puedes usar las siguientes variables:

    • RESERVATION_NAME: Si usas una reserva de TPU, proporciona una lista de etiquetas de recursos de reserva para usar cuando crees el grupo de nodos. Para obtener más información sobre cómo completar RESERVATION_LABEL_VALUES en el campo reservation_affinity, consulta Proveedor de Terraform Beta.
    • autoscaling: Crea un grupo de nodos con el ajuste de escala automático habilitado. Cuando GKE escala un grupo de nodos de porción de TPU de varios hosts, escala de forma atómica desde el cero hasta el tamaño máximo.
      • MAX_NODES: Es el 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}) divididos por la cantidad de chips en cada VM. Por ejemplo, si TPU_TOPOLOGY es 2x2x2, el producto es 8. Dado que cada VM en tpu7x-standard-4t tiene 4 chips, la cantidad de nodos es 2.
    • spot: Es el grupo de nodos que usará VMs Spot para los nodos de porción de TPU. Este parámetro de configuración no se puede cambiar después de crear el grupo de nodos. Para obtener más información, consulta VMs Spot.
    • flex_start: Es el grupo de nodos que usará la opción de consumo de flex-start. Este parámetro de configuración no se puede establecer en true si spot está habilitado.

Otras versiones de TPU

Puedes crear un grupo de nodos de porción de TPU de varios hosts en las versiones v3, v4, v5p, v5e y Trillium (v6e) con Google Cloud CLI, Terraform o la consola de Google Cloud .

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

Reemplaza lo siguiente:

  • NODE_POOL_NAME: El nombre del grupo de nodos nuevo.
  • CLUSTER_NAME: el nombre del clúster
  • CONTROL_PLANE_LOCATION: Es el nombre de la zona en función de la versión de TPU que deseas usar. Para identificar una ubicación disponible, consulta Disponibilidad de TPU en GKE.
  • NODE_ZONES: La lista separada por comas de una o más zonas en las que GKE crea el grupo de nodos.
  • MACHINE_TYPE: Es el tipo de máquina que se usará para los nodos. Para obtener más información sobre los tipos de máquinas compatibles con TPU, usa la tabla en Elige la versión de TPU.
  • TPU_TOPOLOGY: Es la topología de la TPU. Por ejemplo, 2x2x2 Para ver todas las topologías de TPU compatibles, consulta la sección de topologías.
  • MAX_NODES: Es el 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}) divididos por la cantidad de chips en cada VM.

    Este comando crea un grupo de nodos llamado NODE_POOL_NAME con la función de inicio flexible habilitada.

Terraform

  1. Asegúrate de usar la versión 4.84.0 o una posterior del proveedor google.
  2. Agrega el siguiente bloque a la 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
      }
    }
    

    Reemplaza lo siguiente:

    • NODE_POOL_RESOURCE_NAME: El nombre del recurso del grupo de nodos en la plantilla de Terraform.
    • PROJECT_ID: el ID de tu proyecto
    • CLUSTER_NAME: Es el nombre del clúster existente al que se agregará el grupo de nodos.
    • POOL_NAME: el nombre del grupo de nodos que se creará.
    • CLUSTER_LOCATION: Es la ubicación de procesamiento del clúster. Recomendamos tener un clúster regional para obtener una mayor confiabilidad del plano de control de Kubernetes. También puedes usar un clúster zonal. Para obtener más información, consulta Selecciona una versión y una topología de TPU.
    • NODE_ZONES: La lista separada por comas de una o más zonas en las que GKE crea el grupo de nodos.
    • NUM_NODES: Es la cantidad de nodos en el grupo de nodos. Debe ser cero o el producto del número de chips TPU dividido por cuatro, ya que en las porciones de TPU multihost cada nodo de porción de TPU tiene 4 chips. Por ejemplo, si TPU_TOPOLOGY es 4x8, entonces hay 32 chips, lo que significa que NUM_NODES debe ser 8. Para obtener más información sobre las topologías de TPU, usa la tabla de Elige la versión de TPU.
    • TPU_TOPOLOGY: Indica la topología física de la porción de TPU. El formato de la topología depende de la versión de la TPU que usas. Para obtener más información sobre las topologías de TPU, usa la tabla de Elige una topología.

    De manera opcional, también puedes usar las siguientes variables:

    • RESERVATION_NAME: Si usas la reserva de TPU, esta es la lista de etiquetas de los recursos de reserva que se usarán cuando se cree el grupo de nodos. Para obtener más información sobre cómo completar RESERVATION_LABEL_VALUES en el campo reservation_affinity, consulta Proveedor de Terraform Beta.
    • autoscaling: Crea un grupo de nodos con el ajuste de escala automático habilitado. Cuando GKE escala un grupo de nodos de porción de TPU de varios hosts, escala de forma atómica desde el cero hasta el tamaño máximo.
      • MAX_NODES: Es el tamaño máximo del grupo de nodos. Debe ser igual al producto de los valores definidos en TPU_TOPOLOGY ({A}x{B}x{C}) divididos por la cantidad de chips en cada VM.
    • spot: Permite que el grupo de nodos use VMs Spot para los nodos de porción de TPU. Esto no se puede cambiar después de la creación del grupo de nodos. Para obtener más información, consulta VMs Spot.
    • flex_start: Configura el grupo de nodos para usar la opción de consumo flex-start. No se puede establecer en true si spot está habilitado.

Console

Para crear un grupo de nodos con TPUs, haz lo siguiente:

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

    Ir a Google Kubernetes Engine

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

  3. Haz clic en Agregar grupo de nodos.

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

  5. Selecciona el nombre de la zona según la versión de TPU que deseas usar. Para identificar una ubicación disponible, consulta Disponibilidad de TPU en GKE.

  6. Desde el panel de navegación, haz 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 host único
    • CT3P: TPU v3, porción de Pod de varios hosts
    • CT4P: TPU v4
    • CT5LP: TPU v5e
    • CT5P: TPU v5p
    • CT6E: TPU Trillium (v6e)
  9. En el menú desplegable Tipo de máquina, elige el nombre de la máquina que se usará para los nodos. Usa la tabla Elige la versión de TPU para saber cómo definir el tipo de máquina y la topología de TPU que crean un grupo de nodos de porción de TPU de varios hosts.

  10. En el menú desplegable Topología de TPU, elige la topología física para la porción de TPU.

  11. En el diálogo Cambios necesarios, haz 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. De manera opcional, selecciona la casilla de verificación Habilitar nodos en VMs Spot a fin de usar VMs Spot para los nodos en el grupo de nodos.

  14. Haz clic en Crear.

Verifica el estado de flex-start en el grupo de nodos

Ejecuta el comando siguiente:

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

Si el inicio flexible está habilitado en el grupo de nodos, el campo flexStart se establece en True.

Ejecuta una carga de trabajo por lotes

En esta sección, crearás un trabajo que programa un nodo TPU con VMs de inicio flexible. Un controlador de Job en Kubernetes crea uno o más Pods y garantiza que ejecuten correctamente una tarea específica.

  1. En la Google Cloud consola, haz clic en Ícono de activación de Cloud Shell Activar Cloud Shell para iniciar una sesión de Cloud Shell. Se abrirá una sesión en el panel inferior de la consola de Google Cloud .

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

    Único 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
    

    Reemplaza lo siguiente:

    • ACCELERATOR_TYPE: El tipo de acelerador de TPU que usaste cuando creaste los grupos de nodos. Por ejemplo, tpu-v4-podslice o tpu-v5-lite-podslice.
    • TPU_TOPOLOGY: la topología física para la porción de TPU. Por ejemplo, el valor podría ser 4x4x4 o 2x2, según la versión de TPU.
    • NUM_CHIPS: La cantidad de chips TPU en cada VM 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 ejecuten en el mismo nodo:

    kubectl get pods
    

    El resultado es similar a lo 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>
    

Realiza una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en esta página, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

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

Borra el recurso individual

  1. Borra los trabajos:

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

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

    gcloud container clusters delete CLUSTER_NAME
    

¿Qué sigue?