Criar um cluster do GKE A3 Edge personalizado otimizado para IA

Nesta página, mostramos como criar um cluster do Google Kubernetes Engine (GKE) otimizado para IA que usa máquinas virtuais (VMs) A3 Edge para oferecer suporte às cargas de trabalho de inteligência artificial (IA) e machine learning (ML). As máquinas A3 Edge foram projetadas para permitir que você execute clusters de IA e ML em grande escala usando recursos como posicionamento de carga de trabalho direcionado, posicionamento compacto, controles avançados de manutenção de cluster e TAS. Para mais informações, consulte Visão geral do gerenciamento de clusters.

O GKE oferece uma única plataforma para executar um conjunto diversificado de cargas de trabalho para suas organizações, reduzindo a sobrecarga operacional de gerenciar várias plataformas. É possível executar cargas de trabalho como pré-treinamento distribuído de alta performance, ajuste fino e inferência de modelos, disponibilização de aplicativos e serviços de suporte.

Nesta página, você vai aprender a criar clusters padrão e do Autopilot do Google Kubernetes Engine (GKE) usando GPUDirect-TCPX, gVNIC e várias redes.

Esta página é destinada a engenheiros de machine learning (ML) e administradores de plataforma que facilitam cargas de trabalho de ML. Para saber mais sobre papéis comuns e tarefas de exemplo mencionados no conteúdo do Google Cloud , consulte Tarefas e papéis de usuário comuns do GKE.

Aplicativos de inteligência artificial (IA), ML e computação de alto desempenho (HPC) exigem aceleração poderosa para otimizar o desempenho, reduzindo os tempos de conclusão de jobs. Por exemplo, os modelos de ML que se concentram em IA de conversação e geração de imagens exigem alta escalonabilidade e poder de computação.

Nesta página, presumimos que você conheça as tecnologias de rede, como placas de rede (NICs) e TCP, e as tecnologias de aceleração, como a Biblioteca de Comunicação Coletiva da NVIDIA (NCCL).

Sobre os Google Cloud supercomputadores de GPU

OGoogle Cloud tem supercomputadores otimizados para aceleradores que são desenvolvidos para modelos grandes e escalonáveis. Esses tipos de máquinas com GPU podem ter até 3.600 Gbps de largura de banda de rede.

Sua carga de trabalho do GKE precisa usar todas as GPUs e NICs secundárias disponíveis em um único nó e usar uma parte significativa da largura de banda disponível. A solução descrita neste documento foi projetada para cargas de trabalho que exigem alto desempenho, alta capacidade de processamento e baixa latência.

Recursos e funcionalidades necessários para maximizar a largura de banda

Para maximizar a largura de banda da rede nos nós de supercomputadores da GPU, use os recursos a seguir:

  • Pilha de rede GPUDirect: o A3 Edge oferece suporte a três pilhas de rede para acesso direto à memória (RDMA, na sigla em inglês) personalizado e remoto. As máquinas A3 Edge usam o GPUDirect-TCPX para reduzir a sobrecarga necessária para transferir payloads de pacotes de e para GPUs, o que melhora significativamente a capacidade de processamento em escala em comparação com as GPUs que não usam o GPUDirect.
  • gVNIC: ativa os recursos do GPUDirect, como divisão de cabeçalho de pacote, direcionamento de fluxo e gerenciamento de buffer. A gVNIC é necessária para usar o GPUDirect-TCPX. Para detalhes sobre a gVNIC, consulte Aumentar a velocidade do tráfego de rede para nós da GPU.

Também é necessário ativar e configurar as seguintes capabilities:

  • Várias redes: adicione NICs secundárias à máquina otimizada para aceleradores. Cada placa de rede é associada a uma sub-rede separada na própria VPC para evitar conflitos. Para detalhes sobre o suporte a várias redes, consulte Configurar o suporte a várias redes para pods.
  • Políticas de posicionamento: use uma política de posicionamento de recursos para colocar todos os nós da GPU em uma carga de trabalho específica em servidores fisicamente próximos a fim de minimizar a latência. Para mais detalhes, consulte Definir um posicionamento compacto para nós do GKE.

Descrição do procedimento

Para usar o GPUDirect-TCPX, a gVNIC, várias redes e políticas de colocação compacta juntos, faça o seguinte:

  1. Crie nuvens privadas virtuais (VPC) e sub-redes
  2. Crie o ambiente do GKE
  3. Instalar o binário GPUDirect e o plug-in NCCL
  4. Implantar o plug-in de injeção de dispositivo NRI
  5. Implante uma carga de trabalho de teste para verificar a configuração do GPUDirect
  6. Adote o GPUDirect para suas próprias cargas de trabalho

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a Google Cloud CLI para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.
  • Verifique se você tem capacidade para VMs A3 Edge. Para isso, primeiro escolha uma das opções de consumo. Para seguir as instruções nesta página, use capacidade sob demanda, reservas sob demanda ou reservas adiantadas por até 90 dias (no modo de calendário). Depois de escolher uma opção de consumo, siga as instruções respectivas para conseguir capacidade usando a opção escolhida.
  • Verifique se você tem cota suficiente para GPUs H100. Para solicitar mais cota, consulte Cotas de GPU.

Requisitos

Os seguintes requisitos se aplicam ao GPUDirect-TCPX:

Padrão

  • O GPUDirect-TCPX é compatível com todas as versões secundárias disponíveis do GKE usando versões de patch específicas:
    • Para as versões 1.30 a 1.33 do GKE, use qualquer versão de patch.
    • Para a versão 1.34 do GKE, use a versão de patch 1.34.5-gke.1153000 ou mais recente.
    • Para a versão 1.35 do GKE, use a versão de patch 1.35.2-gke.1485000 ou mais recente.
    • Para a versão 1.36 ou mais recente do GKE, use qualquer versão de patch.
  • O nó do GKE precisa usar uma imagem de nó do Container-Optimized OS (COS). As imagens de nós do Ubuntu e do Windows não são compatíveis.
  • Os nós da GPU precisam usar o driver da NVIDIA versão 535 ou mais recente.
  • É preciso usar o GKE Dataplane V2.
  • No GKE versão 1.34 e mais recentes, use a versão 3.1.9 ou mais recente do instalador do GPUDirect-TCPX e a versão 2.0.12 ou mais recente do sidecar do GPUDirect-TCPX. As versões do instalador e do sidecar têm um mapeamento de um para um e precisam corresponder. Por exemplo, a versão 3.1.12 do instalador corresponde à versão 2.0.15 do sidecar. Para mais informações sobre versões do instalador e do sidecar, consulte as Notas da versão do GPUDirect-TCPX.
  • Para cargas de trabalho do GPUDirect-TCPX que são executadas em vários pools de nós, todos os pools precisam estar nas mesmas zonas do Compute Engine e usar os mesmos conjuntos de rede, como VPCs e sub-redes.

Piloto automático

  • Para usar o GPUDirect-TCPX, seu cluster precisa executar as seguintes versões mínimas de patch do GKE:
    • Para a versão 1.31 do GKE, use a versão de patch 1.31.1-gke.1621000 ou mais recente.
    • Para as versões 1.32 a 1.33 do GKE, use qualquer versão de patch.
    • Para a versão 1.34 do GKE, use a versão de patch 1.34.5-gke.1153000 ou mais recente.
    • Para a versão 1.35 do GKE, use a versão de patch 1.35.2-gke.1485000 ou mais recente.
    • Para a versão 1.36 ou mais recente do GKE, use qualquer versão de patch.
  • Os nós da GPU precisam usar o driver da NVIDIA versão 535 ou mais recente.
  • É preciso usar o GKE Dataplane V2.
  • No GKE versão 1.34 e mais recentes, use a versão 3.1.9 ou mais recente do instalador do GPUDirect-TCPX e a versão 2.0.12 ou mais recente do sidecar do GPUDirect-TCPX. As versões do instalador e do sidecar têm um mapeamento um para um e precisam corresponder. Por exemplo, a versão 3.1.12 do instalador corresponde à versão 2.0.15 do sidecar. Para mais informações sobre as versões do instalador e do sidecar, consulte as Notas da versão do GPUDirect-TCPX.
  • Para cargas de trabalho do GPUDirect-TCPX que são executadas em vários pools de nós, todos os pools precisam estar nas mesmas zonas do Compute Engine e usar os mesmos conjuntos de rede, como VPCs e sub-redes.

Limitações

Considere as seguintes limitações:

Criar VPCs e sub-redes

Crie redes VPC separadas no seu projeto para cada placa de rede virtual que você adicionar aos nós. Cada rede VPC precisa ter uma sub-rede e uma regra de firewall que permita o tráfego de rede interno.

  1. Para maximizar a largura de banda, recomendamos que você crie quatro novas redes.

    for N in $(seq 1 4); do
    gcloud compute networks create PREFIX-net-$N \
        --subnet-mode=custom \
        --mtu=8244
    
    gcloud compute networks subnets create PREFIX-sub-$N \
        --network=PREFIX-net-$N \
        --region=REGION \
        --range=SUBNET_RANGE
    
    gcloud compute firewall-rules create PREFIX-internal-$N \
    --network=PREFIX-net-$N \
    --action=ALLOW \
    --rules=tcp:0-65535,udp:0-65535,icmp \
    --source-ranges=SOURCE_RANGE
    done
    

    Substitua:

    • PROJECT_ID: o ID do projeto Google Cloud .
    • REGION: a região do Compute Engine para cada sub-rede.
    • SUBNET_RANGE: o intervalo de endereços IP de cada sub-rede na notação CIDR. Este comando de exemplo faz a iteração de quatro sub-redes. Portanto, use uma variável para mudar o endereço IP de cada uma delas. Por exemplo, especifique 192.168.$N.0/24 para que a primeira sub-rede use 192.168.1.0/24, a segunda use 192.168.2.0/24 etc.
    • SOURCE_RANGE: o intervalo de endereços IP de origem para que a regra de firewall permita o tráfego de entrada, na notação CIDR. Por exemplo, 192.168.0.0/16.
  2. Verifique se as redes foram criadas:

    gcloud compute networks list
    

Crie o ambiente do GKE

Crie um novo cluster do GKE que use várias redes (pré-lançamento) e um pool de nós de GPU com as seguintes características:

  • gVNIC ativada
  • Sub-redes de várias redes especificadas para cada placa de rede (NIC) secundária
  • Série de máquinas A3 Edge com GPUs H100 que oferecem suporte aos nós
  • Drivers da NVIDIA instalados mais recentes

Não é possível atualizar um cluster atual para usar várias redes.

  1. Crie um cluster:

    Padrão

    gcloud beta container clusters create CLUSTER_NAME \
      --enable-dataplane-v2 \
      --enable-ip-alias \
      --location=CONTROL_PLANE_LOCATION \
      --enable-multi-networking \
      --cluster-version=VERSION \
      --no-enable-autoupgrade \
      --project=PROJECT_ID
    

    Substitua:

    • CLUSTER_NAME: o nome do novo cluster;
    • CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Forneça uma região para clusters regionais ou uma zona para clusters zonais.
    • VERSION: uma versão do GKE que oferece suporte ao GPUDirect-TCPX, conforme descrito em Requisitos.

    Piloto automático

    gcloud beta container clusters create-auto CLUSTER_NAME \
        --project=PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION \
        --cluster-version=VERSION \
        --enable-multi-networking \
        --workload-policies=allow-net-admin
    

    Substitua:

    • CLUSTER_NAME: o nome do novo cluster;
    • CONTROL_PLANE_LOCATION: a região do Compute Engine do plano de controle do cluster.
    • VERSION: uma versão do GKE que oferece suporte ao GPUDirect-TCPX, conforme descrito em Requisitos.
  2. Crie recursos de rede e GKENetworkParamSet no cluster que correspondem às redes e sub-redes VPC que você criou:

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc1
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc1
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc2
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc2
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc3
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc3
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc4
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc4
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc1
    spec:
      vpc: PREFIX-net-1
      vpcSubnet: PREFIX-sub-1
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc2
    spec:
      vpc: PREFIX-net-2
      vpcSubnet: PREFIX-sub-2
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc3
    spec:
      vpc: PREFIX-net-3
      vpcSubnet: PREFIX-sub-3
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc4
    spec:
      vpc: PREFIX-net-4
      vpcSubnet: PREFIX-sub-4
      deviceMode: NetDevice
    EOF
    

    Esses recursos orientam o GKE a configurar as placas de rede (NICs) para o tráfego da GPU no modo de passagem. O GKE não aplica a programação de rede integrada usando eBPF a esse tráfego.

Criar um pool de nós de GPU (somente Standard)

  1. Crie um pool de nós para as GPUs H100:

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION \
        --machine-type=a3-edgegpu-8g \
        --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \
        --additional-node-network=network=PREFIX-net-1,subnetwork=PREFIX-sub-1 \
        --additional-node-network=network=PREFIX-net-2,subnetwork=PREFIX-sub-2 \
        --additional-node-network=network=PREFIX-net-3,subnetwork=PREFIX-sub-3 \
        --additional-node-network=network=PREFIX-net-4,subnetwork=PREFIX-sub-4 \
        --enable-gvnic \
        --no-enable-autoupgrade \
        --placement-policy=POLICY_NAME \
        --reservation-affinity=specific \
        --reservation=projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME
    

    Substitua NODE_POOL_NAME pelo nome do pool de nós.

    Para usar uma reserva, use as flags --placement-policy, --reservation-affinity e --reservation. Especifique essas flags para configurar o nome da política e a reserva no pool de nós. Se a reserva não exigir uma política de recursos, omita a flag --placement-policy.

    A flag --reservation-affinity pode ter os valores specific ou any. No entanto, para cargas de trabalho de IA distribuídas de alta performance, recomendamos usar uma reserva específica. Você pode encontrar informações sobre sua reserva, como o nome dela ou de um bloco específico. Para encontrar esses valores em reservas sob demanda, confira uma lista de suas reservas ou veja solicitações de reserva adiantada.

    Substitua o seguinte para usar uma reserva:

    • PROJECT_ID: opcionalmente, ID do projeto Google Cloud. Se a reserva estiver no projeto atual (não uma reserva compartilhada), omita projects/PROJECT_ID/reservations/ do valor da reserva.
    • RESERVATION_NAME: o nome da sua reserva.
    • BLOCK_NAME: opcionalmente, o nome de um bloco específico dentro da reserva. Omita /reservationBlocks/BLOCK_NAME se não quiser usar um bloco específico.

    Se esse comando falhar, talvez você não tenha cota suficiente de GPU H100 no projeto. Verifique se você tem cota e tente executar o comando novamente.

  2. Depois de criar o pool de nós, verifique se cada nó tem as GPUs anexadas:

    1. Confira uma lista de nós no cluster:

      kubectl get nodes
      
    2. Verifique se cada nó da GPU tem oito GPUs:

      kubectl describe node NODE_NAME
      

      Substitua NODE_NAME pelo nome do nó a ser descrito.

      O resultado será o seguinte:

      Capacity:
        ...
        nvidia.com/gpu:             8
      Allocatable:
        ...
        nvidia.com/gpu:             8
      

Instalar o binário GPUDirect e o plug-in NCCL

Esta seção mostra como instalar o binário GPUDirect-TCPX e uma versão específica da biblioteca NCCL usando um DaemonSet.

Esse DaemonSet faz o seguinte:

  1. Instala a biblioteca NCCL e o binário GPUDirect-TCPX no nó.
  2. Armazena a biblioteca e o binário no diretório /home/kubernetes/bin/nvidia/lib64 na VM. Por padrão, o GKE monta esse diretório no caminho /usr/local/nvidia/lib64 em contêineres de GPU que precisam usar NCCL e GPUDirect-TCPX.

Para instalar o binário e configurar o NCCL, faça o seguinte:

Padrão

  1. Revise o manifesto do Daemonset nccl-tcpx-installer.yaml no GitHub.

  2. Implante o DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
    

    O plug-in do NCCL leva aproximadamente dois minutos para começar a ser executado.

  3. Verifique o status dos pods do DaemonSet:

    kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
    

    O resultado será o seguinte:

    nccl-tcpx-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpx-installer-qgg82                    1/1     Running   0          2m11s
    

Piloto automático

  1. Revise o manifesto do Daemonset nccl-tcpx-installer-autopilot.yaml no GitHub.

  2. Crie um namespace dedicado:

    kubectl create ns gpudirect-system
    
  3. Implante o DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer-autopilot.yaml
    

    O plug-in do NCCL leva aproximadamente dois minutos para começar a ser executado.

Implantar o plug-in de injeção de dispositivo NRI

Esta seção mostra como instalar o injetor de dispositivo NRI usando um DaemonSet. Esse plug-in faz o seguinte:

  1. Ativa a interface de recursos do nó (NRI) no nó que tem GPUs H100. A NRI é ativada por padrão no GKE versão 1.29 e mais recente.
  2. Implanta um contêiner de plug-in de injeção de dispositivo NRI que injeta dispositivos de GPU em contêineres especificados por anotações de pod.

Para instalar o plug-in, proceda da seguinte maneira:

Padrão

  1. Revise o manifesto de implantação nri-device-injector.yaml no GitHub.

  2. Implante o DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
    

    O plug-in do NCCL leva aproximadamente dois minutos para começar a ser executado.

  3. Verifique o status dos pods do DaemonSet:

    kubectl get pods -n=kube-system -l=name=device-injector
    

    O resultado será o seguinte:

    # Output
    device-injector-md6hb                         1/1     Running   0       4h54m
    device-injector-vh9bm                         1/1     Running   0       4h54m
    

Piloto automático

  1. Revise o manifesto de implantação nri-device-injector-autopilot.yaml no GitHub.

  2. Implante o DaemonSet:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector-autopilot.yaml
    

    O plug-in do NCCL leva aproximadamente dois minutos para começar a ser executado.

Implantar uma carga de trabalho de teste

Nesta seção, você vai implantar uma carga de trabalho de amostra para verificar se o NCCL e o GPUDirect-TCPX funcionam conforme o esperado. Esta carga de trabalho de exemplo faz o seguinte:

  1. Implanta dois pods, cada um executado em um nó que tem GPUs H100.
  2. Implanta um contêiner secundário em cada pod para permitir que esses pods usem o GPUDirect-TCPX.

Essa carga de trabalho inclui um contêiner secundário chamado tcpx-daemon, que executa um serviço que permite ao pod usar o GPUDirect-TCPX. Você precisa adicionar esse contêiner secundário a qualquer pod no seu próprio ambiente que precise usar GPUDirect-TCPX. Para conferir um snippet dos campos obrigatórios a serem adicionados aos manifestos, consulte Adicionar GPUDirect ao manifesto.

  1. Revise o manifesto ConfigMap nccl-config.yaml no GitHub. Esse manifesto implanta scripts que inicializam um teste all-gather do NCCL e define configurações específicas do NCCL.

  2. Faça o seguinte com base no modo de cluster:

  3. Implante o ConfigMap e a carga de trabalho de teste:

    Padrão

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest.yaml
    

    Piloto automático

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test-latest-autopilot.yaml
    
  4. Verifique se os pods estão em execução e prontos. As imagens são grandes (aproximadamente 5 GB) e podem levar vários minutos para serem baixadas.

    kubectl get pods -w
    

    O comando monitora atualizações e imprime uma nova linha quando o status de um pod muda. O resultado será o seguinte:

    NAME               READY   STATUS              RESTARTS   AGE
    nccl-test-host-1   0/2     ContainerCreating   0          23s
    nccl-test-host-2   2/2     Running             0          23s
    nccl-test-host-1   2/2     Running             0          46s
    

    Aguarde até que a mensagem STATUS de todos os pods seja Running e o valor de READY seja 2/2 antes de prosseguir para a próxima etapa.

  5. Execute os seguintes comandos para acionar um teste de todos os nós do NCCL:

    kubectl exec \
      --stdin --tty --container=nccl-test nccl-test-host-1 \
      -- /configs/allgather.sh nccl-host-1 nccl-host-2
    

    O resultado será o seguinte:

    Padrão

      #                                                              out-of-place                       in-place
      #        size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
      #         (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
                  0             0     float    none      -1     0.24    0.00    0.00      0     0.18    0.00    0.00      0
                  0             0     float    none      -1     0.19    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                  0             0     float    none      -1     0.17    0.00    0.00      0     0.17    0.00    0.00      0
                256             4     float    none      -1    235.2    0.00    0.00      0    235.1    0.00    0.00      0
                512             8     float    none      -1    241.0    0.00    0.00      0    236.1    0.00    0.00      0
               1024            16     float    none      -1    236.3    0.00    0.00      0    233.3    0.00    0.00      0
               2048            32     float    none      -1    234.1    0.01    0.01      0    233.4    0.01    0.01      0
               4096            64     float    none      -1    237.1    0.02    0.02      0    235.3    0.02    0.02      0
               8192           128     float    none      -1    236.2    0.03    0.03      0    235.2    0.03    0.03      0
              16384           256     float    none      -1    236.6    0.07    0.06      0    238.5    0.07    0.06      0
              32768           512     float    none      -1    237.9    0.14    0.13      0    238.8    0.14    0.13      0
              65536          1024     float    none      -1    242.3    0.27    0.25      0    239.4    0.27    0.26      0
             131072          2048     float    none      -1    263.0    0.50    0.47      0    275.1    0.48    0.45      0
             262144          4096     float    none      -1    279.2    0.94    0.88      0    269.9    0.97    0.91      0
             524288          8192     float    none      -1    273.5    1.92    1.80      0    273.5    1.92    1.80      0
            1048576         16384     float    none      -1    315.1    3.33    3.12      0    314.1    3.34    3.13      0
            2097152         32768     float    none      -1    319.2    6.57    6.16      0    311.5    6.73    6.31      0
            4194304         65536     float    none      -1    331.8   12.64   11.85      0    331.3   12.66   11.87      0
            8388608        131072     float    none      -1    356.3   23.54   22.07      0    353.8   23.71   22.23      0
           16777216        262144     float    none      -1    409.1   41.01   38.45      0    405.2   41.40   38.81      0
           33554432        524288     float    none      -1    451.4   74.34   69.69      0    447.7   74.94   70.26      0
           67108864       1048576     float    none      -1    713.4   94.07   88.19      0    713.8   94.01   88.13      0
          134217728       2097152     float    none      -1   1122.1  119.62  112.14      0   1116.3  120.23  112.72      0
          268435456       4194304     float    none      -1   1785.8  150.32  140.92      0   1769.2  151.72  142.24      0
          536870912       8388608     float    none      -1   2859.7  187.74  176.00      0   2852.6  188.20  176.44      0
         1073741824      16777216     float    none      -1   5494.1  195.44  183.22      0   5568.2  192.83  180.78      0
         2147483648      33554432     float    none      -1    10841  198.09  185.71      0    10798  198.88  186.45      0
         4294967296      67108864     float    none      -1    21453  200.21  187.70      0    21490  199.86  187.37      0
         8589934592     134217728     float    none      -1    42603  201.63  189.03      0    42670  201.31  188.73      0
      # Out of bounds values : 0 OK
      # Avg bus bandwidth    : 45.7587
      #
      ```
    

    Piloto automático

    #                                                              out-of-place                       in-place
    #       size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
    #        (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)
        1048576         16384     float    none      -1    696.8    1.50    1.41      0    729.0    1.44    1.35      0
        2097152         32768     float    none      -1    776.4    2.70    2.53      0    726.7    2.89    2.71      0
        4194304         65536     float    none      -1    774.3    5.42    5.08      0    805.1    5.21    4.88      0
        8388608        131072     float    none      -1    812.1   10.33    9.68      0    817.6   10.26    9.62      0
       16777216        262144     float    none      -1   1035.2   16.21   15.19      0   1067.8   15.71   14.73      0
       33554432        524288     float    none      -1   1183.3   28.36   26.59      0   1211.8   27.69   25.96      0
       67108864       1048576     float    none      -1   1593.4   42.12   39.49      0   1510.5   44.43   41.65      0
      134217728       2097152     float    none      -1   2127.8   63.08   59.13      0   2312.7   58.03   54.41      0
      268435456       4194304     float    none      -1   3603.0   74.50   69.85      0   3586.2   74.85   70.17      0
      536870912       8388608     float    none      -1   7101.7   75.60   70.87      0   7060.9   76.03   71.28      0
    # Out of bounds values : 0 OK
    # Avg bus bandwidth    : 29.8293
    

Adotar o GPUDirect para suas próprias cargas de trabalho

Depois de verificar se a rede do cluster está funcionando corretamente com a carga de trabalho de teste de exemplo, a próxima etapa é adotar o GPUDirect para suas cargas de trabalho reais. Para adotar o GPUDirect, atualize as configurações do NCCL e os manifestos de pod do Kubernetes.

Usar as configurações necessárias do NCCL para melhorar o desempenho

Os pares de chave-valor a seguir são as configurações de configuração do NCCL necessárias para GPUDirect-TCPX. Ao implantar cargas de trabalho que usam NCCL, defina-as como variáveis de ambiente para otimizar o desempenho.

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_SOCKET_IFNAME=\"eth0\"",
"NCCL_ALGO=Ring",
"NCCL_PROTO=Simple",
"NCCL_CROSS_NIC=0",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_P2P_PXN_LEVEL=0",
"NCCL_GPUDIRECTTCPX_SOCKET_IFNAME=eth1,eth2,eth3,eth4",
"NCCL_GPUDIRECTTCPX_CTRL_DEV=eth0",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_BUFFSIZE=4194304",
"NCCL_NSOCKS_PERTHREAD=4",
"NCCL_SOCKET_NTHREADS=1",
"NCCL_GPUDIRECTTCPX_TX_BINDINGS=\"eth1:8-21,112-125;eth2:8-21,112-125;eth3:60-73,164-177;eth4:60-73,164-177\"",
"NCCL_GPUDIRECTTCPX_RX_BINDINGS=\"eth1:22-35,126-139;eth2:22-35,126-139;eth3:74-87,178-191;eth4:74-87,178-191\"",
"NCCL_GPUDIRECTTCPX_PROGRAM_FLOW_STEERING_WAIT_MICROS=500000"

Adicionar GPUDirect aos manifestos

Esta seção mostra os campos obrigatórios que você precisa adicionar aos manifestos do Kubernetes para que seus pods usem o GPUDirect.

Dependendo do modo do cluster, faça o seguinte:

Padrão

  1. Adicione as seguintes anotações aos metadados do pod. Sem essas anotações, hostNetwork:true será necessário para o pod, e privileged:true será necessário para o contêiner tcpx-daemon.

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. Adicione os seguintes campos à especificação do pod:

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. Adicione o seguinte contêiner ao manifesto para executar o serviço tcpx-daemon:

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. Adicione as seguintes montagens de volume a todos os contêineres que solicitarem GPUs:

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. Adicione variáveis de ambiente para configurar as opções da NCCL. Para mais detalhes, consulte a seção Usar as configurações recomendadas do NCCL para melhorar o desempenho neste documento.

  6. Adicione a seguinte variável de ambiente a cada contêiner de GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    

Para um exemplo de especificação de pod concluída, consulte o manifesto nccl-test-latest.yaml no GitHub.

Piloto automático

No modo Autopilot, também é necessário selecionar as GPUs adequadas nos manifestos de pod para que o GKE provisione o hardware.

Adicione os seguintes seletores de nós ao pod:

nodeSelector:
  cloud.google.com/gke-accelerator: a3-edgegpu-8g
  cloud.google.com/gke-gpu-driver-version: latest

Além disso, se você quiser usar a capacidade reservada, forneça informações sobre a reserva. Para mais informações, consulte as subseções sobre como consumir reservas em Consumir reservas de capacidade em clusters do Autopilot.

  1. Adicione as seguintes anotações aos metadados do pod:

    metadata:
      annotations:
        devices.gke.io/container.tcpx-daemon: |+
          - path: /dev/nvidia0
          - path: /dev/nvidia1
          - path: /dev/nvidia2
          - path: /dev/nvidia3
          - path: /dev/nvidia4
          - path: /dev/nvidia5
          - path: /dev/nvidia6
          - path: /dev/nvidia7
          - path: /dev/nvidiactl
          - path: /dev/nvidia-uvm
        networking.gke.io/default-interface: 'eth0'
        networking.gke.io/interfaces: |
          [
            {"interfaceName":"eth0","network":"default"},
            {"interfaceName":"eth1","network":"vpc1"},
            {"interfaceName":"eth2","network":"vpc2"},
            {"interfaceName":"eth3","network":"vpc3"},
            {"interfaceName":"eth4","network":"vpc4"},
          ]
    
  2. Adicione os seguintes campos à especificação do pod:

    spec:
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: sys
        hostPath:
          path: /sys
      - name: proc-sys
        hostPath:
          path: /proc/sys
    
  3. Adicione o seguinte contêiner ao manifesto para executar o serviço tcpx-daemon:

    - name: tcpx-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.9
      command:
        - /tcpgpudmarxd/build/app/tcpgpudmarxd
        - --gpu_nic_preset
        - a3vm
        - --gpu_shmem_type
        - fd
        - --uds_path
        - /run/tcpx
        - --setup_param
        - \"--verbose 128 2 0 \"
      securityContext:
        capabilities:
            add:
              - NET_ADMIN
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. Adicione as seguintes montagens de volume a todos os contêineres que solicitarem GPUs:

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  5. Adicione variáveis de ambiente para configurar as opções da NCCL. Para mais detalhes, consulte a seção Usar as configurações recomendadas do NCCL para melhorar o desempenho neste documento.

Para ver um exemplo de especificação de pod concluída, consulte o manifesto nccl-test-latest-autopilot.yaml no GitHub.

Coletar registros de depuração do NCCL

Para registrar erros do NCCL, recomendamos que você adicione a seguinte configuração do NCCL:

NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH
NCCL_DEBUG_FILE=/DIRECTORY/FILE_NAME.%h.%p
  • NCCL_DEBUG=INFO: imprime informações de depuração.
    • Para cargas de trabalho de grande escala (64 nós ou mais), pode ocorrer um registro extenso. Para evitar esse cenário, e a menos que você tenha especificado NCCL_DEBUG_FILE, recomendamos definir NCCL_DEBUG=WARN para limitar os registros apenas a erros.
  • NCCL_DEBUG_SUBSYS: filtra os subsistemas para os quais o NCCL coleta informações de depuração. Recomendamos que você colete registros dos seguintes subsistemas:

    • INIT: a fase de inicialização do NCCL.
    • NET: a rede NCCL.
    • ENV: as variáveis de ambiente usadas pela NCCL.
    • COLL: operações coletivas.
    • GRAPH: detecção de topologia e pesquisa de gráficos.

    Se você quiser coletar registros de diferentes subsistemas, consulte NCCL_DEBUG_SUBSYS na documentação do NCCL para ver uma lista de valores aceitos.

  • NCCL_DEBUG_FILE (opcional): direciona a saída de registro de depuração da NCCL para um arquivo especificado. Essa variável grava os registros do NCCL em arquivos padrão, o que evita que a saída do registro se misture com a saída do aplicativo. Essa variável também grava registros de diferentes classificações da NCCL em arquivos diferentes, o que evita que os registros se misturem.

    Use o seguinte formato de nome de arquivo:

    /DIRECTORY/FILE_NAME.%h.%p
    

    Substitua:

    • DIRECTORY: o diretório em que você quer armazenar os arquivos de registro.
    • FILE_NAME: o nome dos arquivos de registro.

    O marcador de posição %h é resolvido como o nome do host do nó, enquanto %p é resolvido como o ID do processo (PID) que está gerando o registro.

Para mais informações sobre como depurar registros do NCCL, consulte Solucionar problemas de GPUs no GKE.

A seguir