Execute uma carga de trabalho de lote pequena com TPUs e VMs de início flexível

Este guia mostra como otimizar o aprovisionamento de TPUs para cargas de trabalho de preparação de escala média e pequena usando VMs de início flexível. As VMs de início flexível são criadas através da opção de consumo flex-start. Neste guia, vai usar VMs de início flexível para implementar uma carga de trabalho que consiste num conjunto de nós de uma fatia de TPU.

Este guia destina-se a engenheiros de aprendizagem automática (ML), administradores e operadores de plataformas, e a especialistas de dados e IA interessados em usar capacidades de orquestração de contentores do Kubernetes para executar cargas de trabalho em lote. Para mais informações sobre as funções comuns e exemplos de tarefas que referimos no Google Cloud conteúdo, consulte Funções e tarefas comuns de utilizadores do GKE.

Preços de início flexível

Recomendamos o início flexível se a sua carga de trabalho exigir recursos aprovisionados dinamicamente conforme necessário, durante um máximo de sete dias com reservas de curto prazo, sem gestão de quotas complexa e com acesso económico. O início flexível é alimentado pelo programador de carga de trabalho dinâmico e é faturado através dos preços do programador de carga de trabalho dinâmico:

  • Com desconto (até 53%) para vCPUs, GPUs e TPUs.
  • Paga à medida que usa.

Antes de começar

Antes de começar, certifique-se de que realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ative a API Google Kubernetes Engine
  • Se quiser usar a CLI gcloud para esta tarefa, instale-a e, em seguida, inicialize a CLI gcloud. Se instalou anteriormente a CLI gcloud, execute o comando gcloud components update para obter a versão mais recente. As versões anteriores da CLI gcloud podem não suportar a execução dos comandos neste documento.

Crie um node pool com início flexível

Se usar um cluster no modo de piloto automático, ignore esta secção e aceda à secção Execute uma carga de trabalho em lote.

Para criar um node pool com o início flexível ativado num cluster padrão existente, use a CLI gcloud.

Crie um node pool de fatia de TPU de anfitrião único

Pode criar um node pool de fatia de TPU de host único com início flexível:

  1. Crie um node pool com início flexível:

    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
    

    Substitua o seguinte:

    • NODE_POOL_NAME: o nome que escolher para o seu node pool.
    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: a região de computação para o plano de controlo do cluster.
    • NODE_ZONES: a lista separada por vírgulas de uma ou mais zonas onde o GKE cria o conjunto de nós.
    • MACHINE_TYPE: o tipo de máquina a usar para os nós. Para mais informações sobre os tipos de máquinas compatíveis com a TPU, use a tabela em Escolha a versão da TPU.

      Por exemplo, o comando de criação do conjunto de nós pode incluir os seguintes parâmetros:

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

      Este comando define o campo --max-nodes como 4 porque uma topologia 4x4 consiste em 16 chips e cada VM ct6e-standard-4t tem 4 chips.

      O redimensionador automático de clusters é dimensionado até ao número de nós que a sua carga de trabalho requer. Depois de a carga de trabalho ser concluída, o escalador automático do cluster é reduzido para zero nós.

    • --reservation-affinity=none: o início flexível não usa nem requer reservas.

Crie um node pool de fatia de TPU com vários anfitriões

Os passos para criar um conjunto de nós de fatia de TPU com vários anfitriões variam consoante use o Ironwood (TPU7x) ou uma versão anterior da TPU.

Ironwood (TPU7x)

Pode criar um nó de segmento de TPU com vários anfitriões na versão Ironwood (TPU7x) através da Google Cloud CLI ou do Terraform:

gcloud

Para criar um node pool de fatia de TPU com vários anfitriões com o Ironwood (TPU7x), tem de criar primeiro uma política de carga de trabalho.

  1. Crie uma política de carga de trabalho:

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

    Substitua o seguinte:

    • WORKLOAD_POLICY_NAME: um nome para a sua política de carga de trabalho.
    • TPU_TOPOLOGY: a topologia Ironwood da TPU (TPU7x). Por exemplo, 2x2x2. Para ver todas as topologias do Ironwood (TPU7x) suportadas, consulte a secção de topologia.
    • PROJECT_ID: o ID do seu Google Cloud projeto.
    • REGION: a região da política de carga de trabalho. Uma política de carga de trabalho é um recurso regional e pode ser reutilizada em pools de nós que partilham a mesma topologia.
  2. Crie o node pool com a política de workload:

    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
    

    Substitua o seguinte:

    • NODE_POOL_NAME: o nome do novo grupo de nós.
    • WORKLOAD_POLICY: o nome da política de carga de trabalho que criou.
    • MAX_NODES: o tamanho máximo do node pool. A flag --max-nodes é obrigatória se --enable-autoscaling for fornecido e tem de ser igual ao produto dos valores definidos em TPU_TOPOLOGY ({A}x{B}x{C}) dividido pelo número de chips em cada MV. Por exemplo, se TPU_TOPOLOGY for 2x2x2, o produto é 8. Uma vez que cada MV em tpu7x-standard-4t tem 4 chips, o número de nós é 2.

    Este comando cria um conjunto de nós denominado NODE_POOL_NAME com as seguintes caraterísticas:

    • --machine-type=tpu7x-standard-4t especifica o tipo de máquina Ironwood (TPU7x)
    • --flex-start permite o início flexível.

Terraform

  1. Certifique-se de que usa a versão 4.84.0 ou posterior do fornecedor google.
  2. Crie uma política de carga de trabalho:

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

    Substitua o seguinte:

    • WORKLOAD_POLICY_NAME: um nome para a política de carga de trabalho.
    • CLUSTER_LOCATION: calcular a localização do cluster. Recomendamos que tenha um cluster regional para uma maior fiabilidade do plano de controlo do Kubernetes. Também pode usar um cluster zonal. Para mais informações, consulte o artigo Selecione uma versão e uma topologia da TPU.
    • TPU_TOPOLOGY: a topologia Ironwood da TPU (TPU7x). Por exemplo, 2x2x2. Para ver todas as topologias do Ironwood (TPU7x) suportadas, consulte o artigo Planeie TPUs.

    Para mais informações sobre a referência google_compute_resource_policy, consulte o fornecedor do Terraform.

  3. Na configuração do Terraform, adicione o seguinte bloco:

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

    Substitua o seguinte:

    • NODE_POOL_RESOURCE_NAME: o nome do recurso do conjunto de nós no modelo do Terraform.
    • PROJECT_ID: o ID do projeto.
    • CLUSTER_NAME: o nome do cluster existente ao qual adicionar o conjunto de nós.
    • POOL_NAME: o nome do node pool a criar.
    • NODE_ZONES: a lista separada por vírgulas de uma ou mais zonas onde o GKE cria o conjunto de nós.
    • NUM_NODES: o número de nós no node pool. Tem de ser zero ou o produto do número de chips da TPU dividido por quatro, porque nas fatias de TPU com vários anfitriões, cada nó da fatia de TPU tem quatro chips. Por exemplo, se TPU_TOPOLOGY for 4x8, existem 32 chips, o que significa que NUM_NODES tem de ser 8. Para saber mais sobre as topologias de TPU, use a tabela em Escolha a versão do TPU.
    • TPU_TOPOLOGY: isto indica a topologia física selecionada para a fatia da TPU. O formato da topologia depende da versão da TPU que está a usar. Para saber mais sobre as topologias de TPUs, use a tabela em Escolha uma topologia.

    Opcionalmente, também pode usar as seguintes variáveis:

    • RESERVATION_NAME: se usar uma reserva de TPU, forneça uma lista de etiquetas de recursos de reserva a usar quando criar o conjunto de nós. Para saber como preencher o campo RESERVATION_LABEL_VALUES no campo reservation_affinity, consulte o artigo Fornecedor do Terraform.
    • autoscaling: crie um node pool com o dimensionamento automático ativado. Quando o GKE dimensiona um conjunto de nós de fatia de TPU com vários anfitriões, dimensiona atomicamente o conjunto de nós de zero para o tamanho máximo.
      • MAX_NODES: o tamanho máximo do node pool. O valor tem de ser igual ao produto dos valores definidos em TPU_TOPOLOGY ({A}x{B}x{C}) dividido pelo número de chips em cada MV. Por exemplo, se TPU_TOPOLOGY for 2x2x2, o produto é 8. Uma vez que cada MV em tpu7x-standard-4t tem 4 chips, o número de nós é 2.
    • spot: o node pool que vai usar VMs do Spot para os nós da fatia de TPU. Não é possível alterar esta definição após a criação do conjunto de nós. Para mais informações, consulte VMs de spot.
    • flex_start: o conjunto de nós que vai usar a opção de consumo flex-start. Não é possível definir esta definição como true se spot estiver ativado.

Outras versões do TPU

Pode criar um nó de segmento de TPU multi-anfitrião na versão v3, v4, v5p, v5e e Trillium (v6e) através da CLI Google Cloud, do Terraform ou da 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

Substitua o seguinte:

  • NODE_POOL_NAME: o nome do novo grupo de nós.
  • CLUSTER_NAME: o nome do cluster.
  • CONTROL_PLANE_LOCATION: o nome da zona com base na versão da TPU que quer usar. Para identificar uma localização disponível, consulte o artigo Disponibilidade de TPUs no GKE.
  • NODE_ZONES: a lista separada por vírgulas de uma ou mais zonas onde o GKE cria o conjunto de nós.
  • MACHINE_TYPE: o tipo de máquina a usar para os nós. Para mais informações sobre os tipos de máquinas compatíveis com a TPU, use a tabela em Escolha a versão da TPU.
  • TPU_TOPOLOGY: a topologia da TPU. Por exemplo, 2x2x2. Para ver todas as topologias de TPUs suportadas, consulte a secção de topologia.
  • MAX_NODES: o tamanho máximo do node pool. A flag --max-nodes é obrigatória se --enable-autoscaling for fornecido e tem de ser igual ao produto dos valores definidos em TPU_TOPOLOGY ({A}x{B}x{C}) dividido pelo número de chips em cada MV.

    Este comando cria um node pool denominado NODE_POOL_NAME com o início flexível ativado.

Terraform

  1. Certifique-se de que usa a versão 4.84.0 ou posterior do fornecedor google.
  2. Adicione o seguinte bloco à configuração do 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
      }
    }
    

    Substitua o seguinte:

    • NODE_POOL_RESOURCE_NAME: o nome do recurso do conjunto de nós no modelo do Terraform.
    • PROJECT_ID: o ID do projeto.
    • CLUSTER_NAME: o nome do cluster existente ao qual adicionar o conjunto de nós.
    • POOL_NAME: o nome do node pool a criar.
    • CLUSTER_LOCATION: calcular a localização do cluster. Recomendamos que tenha um cluster regional para uma maior fiabilidade do plano de controlo do Kubernetes. Também pode usar um cluster zonal. Para saber mais, consulte o artigo Selecione uma versão e uma topologia da TPU.
    • NODE_ZONES: a lista separada por vírgulas de uma ou mais zonas onde o GKE cria o conjunto de nós.
    • NUM_NODES: o número de nós no node pool. Tem de ser zero ou o produto do número de chips de TPU dividido por quatro, porque nas fatias de TPU com vários anfitriões, cada nó de fatia de TPU tem 4 chips. Por exemplo, se TPU_TOPOLOGY for 4x8, existem 32 chips, o que significa que NUM_NODES tem de ser 8. Para saber mais sobre as topologias de TPU, use a tabela em Escolha a versão do TPU.
    • TPU_TOPOLOGY: isto indica a topologia física da fatia da TPU. O formato da topologia depende da versão da TPU que está a usar. Para saber mais sobre as topologias de TPUs, use a tabela em Escolha uma topologia.

    Opcionalmente, também pode usar as seguintes variáveis:

    • RESERVATION_NAME: se usar a reserva de TPU, esta é a lista de etiquetas dos recursos de reserva a usar quando criar o conjunto de nós. Para saber como preencher o campo RESERVATION_LABEL_VALUES no campo reservation_affinity, consulte o fornecedor do Terraform.
    • autoscaling: crie um node pool com o dimensionamento automático ativado. Quando o GKE dimensiona um conjunto de nós de fatia de TPU com vários anfitriões, dimensiona atomicamente o conjunto de nós de zero para o tamanho máximo.
      • MAX_NODES: é o tamanho máximo do node pool. Tem de ser igual ao produto dos valores definidos em TPU_TOPOLOGY ({A}x{B}x{C}) dividido pelo número de chips em cada MV).
    • spot: permite que o node pool use VMs do Spot para os nós da fatia de TPU. Não é possível alterar esta opção após a criação do conjunto de nós. Para mais informações, consulte VMs de spot.
    • flex_start: define o conjunto de nós para usar a opção de consumo flex-start. Não é possível definir como true se spot estiver ativado.

Consola

Para criar um node pool com TPUs:

  1. Aceda à página Google Kubernetes Engine na Google Cloud consola.

    Aceda ao Google Kubernetes Engine

  2. Na lista de clusters, clique no nome do cluster que quer modificar.

  3. Clique em Adicionar conjunto de nós.

  4. Na secção Detalhes do conjunto de nós, selecione a caixa Especificar localizações dos nós.

  5. Selecione o nome da zona com base na versão da TPU que quer usar. Para identificar uma localização disponível, consulte o artigo Disponibilidade de TPUs no GKE.

  6. No painel de navegação, clique em Nodes.

  7. Na secção Configuração da máquina, selecione TPUs.

  8. No menu pendente Série, selecione uma das seguintes opções:

    • CT3: TPU v3, dispositivo de anfitrião único
    • CT3P: TPU v3, fatia de pod multi-host
    • CT4P: TPU v4
    • CT5LP: TPU v5e
    • CT5P: TPU v5p
    • CT6E: TPU Trillium (v6e)
  9. No menu pendente Tipo de máquina, selecione o nome da máquina a usar para os nós. Use a tabela Escolha a versão do TPU para saber como definir o tipo de máquina e a topologia do TPU que criam um conjunto de nós de fatia do TPU com vários anfitriões.

  10. No menu pendente Topologia da TPU, selecione a topologia física para a fatia da TPU.

  11. Na caixa de diálogo Alterações necessárias, clique em Fazer alterações.

  12. Certifique-se de que o Tipo de disco de arranque é um Disco persistente padrão ou um Disco persistente SSD.

  13. Opcionalmente, selecione a caixa de verificação Ativar nós em VMs de capacidade instantânea para usar VMs de capacidade instantânea para os nós no conjunto de nós.

  14. Clique em Criar.

Valide o estado do início flexível no conjunto de nós

Execute o seguinte comando:

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

Se o início flexível estiver ativado no conjunto de nós, o campo flexStart é definido como True.

Execute uma carga de trabalho em lote

Nesta secção, cria um trabalho que agenda um nó da TPU com VMs de início flexível. Um controlador de tarefas no Kubernetes cria um ou mais pods e garante que executam com êxito uma tarefa específica.

  1. Na Google Cloud consola, inicie uma sessão do Cloud Shell clicando em Ícone de ativação do Cloud Shell Ativar Cloud Shell. É aberta uma sessão no painel inferior da consola Google Cloud .

  2. Crie um ficheiro com o nome dws-flex-start.yaml:

    Anfitrião único

    Use o seguinte manifesto para o ficheiro 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
    

    Vários anfitriões

    Use o seguinte manifesto para o ficheiro 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
    

    Substitua o seguinte:

    • ACCELERATOR_TYPE: o tipo de acelerador de TPU que usou quando criou os conjuntos de nós. Por exemplo, tpu-v4-podslice ou tpu-v5-lite-podslice.
    • TPU_TOPOLOGY: a topologia física da fatia de TPU. Por exemplo, o valor pode ser 4x4x4 ou 2x2, consoante a versão da TPU.
    • NUM_CHIPS: o número de chips de TPU em cada VM é um, quatro ou oito. Para saber mais, consulte o artigo Versões da TPU.
  3. Aplique o manifesto dws-flex-start.yaml:

    kubectl apply -f dws-flex-start.yaml
    
  4. Verifique se os trabalhos estão a ser executados no mesmo nó:

    kubectl get pods
    

    O resultado é semelhante ao seguinte:

    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>
    

Limpar

Para evitar incorrer em cobranças na sua Google Cloud conta pelos recursos que usou nesta página, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

Elimine o projeto

  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.

Elimine o recurso individual

  1. Elimine os trabalhos:

    kubectl delete job -l "job-name in (job-1,job-2)"
    
  2. Elimine o node pool:

    gcloud container node-pools delete NODE_POOL_NAME \
          --location CONTROL_PLANE_LOCATION
    
  3. Elimine o cluster:

    gcloud container clusters delete CLUSTER_NAME
    

O que se segue?