Maximize a largura de banda da rede da GPU em clusters no modo padrão

Esta página mostra como maximizar a largura de banda da rede e o débito para cargas de trabalho de GPU de alto desempenho em clusters padrão do Google Kubernetes Engine (GKE) através do GPUDirect-TCPXO, GPUDirect-TCPX, gVNIC e várias redes. Se usar clusters do Autopilot, consulte o artigo Maximize a largura de banda da rede da GPU em clusters do modo Autopilot.

Esta página destina-se a engenheiros de aprendizagem automática (ML) e administradores de plataformas que facilitam as cargas de trabalho de ML. Para saber mais sobre as funções comuns e as tarefas de exemplo que referimos no conteúdo, consulte o artigo Funções e tarefas comuns de utilizadores do GKE. Google Cloud

As aplicações de inteligência artificial (IA), AA e computação de alto desempenho (HPC) requerem uma aceleração potente para otimizar o desempenho, reduzindo os tempos de conclusão das tarefas. Por exemplo, os modelos de ML que se focam na IA de conversação e na geração de imagens requerem uma elevada escalabilidade e capacidade de computação.

Antes de ler esta página, certifique-se de que conhece as tecnologias de rede, como as placas de interface de rede (NICs) e o TCP, e as tecnologias de acelerador, como a NVIDIA Collective Communications Library (NCCL).

Acerca dos Google Cloud supercomputadores com GPU

OGoogle Cloud tem supercomputadores otimizados pelo acelerador criados para modelos escaláveis e massivos. Estas máquinas têm as seguintes vantagens:

  • Oito GPUs NVIDIA B200, H200 ou H100 por máquina.
  • Largura de banda até 200 Gbps na NIC principal.
  • NICs secundárias (até oito em tipos de máquinas A3 Mega e até quatro em tipos de máquinas A3 High), cada uma a suportar uma largura de banda de até 200 Gbps para transferência de dados da GPU. Nos tipos de máquinas A3 High, a largura de banda esperada por NIC é de aproximadamente 150 Gbps.

A carga de trabalho do GKE tem de usar todas as GPUs disponíveis e todas as NICs secundárias disponíveis num único nó, bem como usar uma parte significativa da largura de banda disponível. A solução descrita neste documento é ideal para cargas de trabalho que requerem elevado desempenho, elevado débito e baixa latência.

Funcionalidades e capacidades necessárias para maximizar a largura de banda

Para maximizar a largura de banda da rede nos nós de supercomputadores com GPU, use todas as seguintes funcionalidades:

  • Stack de rede GPUDirect: a série de máquinas A3 suporta três stacks de rede para acesso direto à memória (RDMA) remoto e personalizado:
    • Nos tipos de máquinas A3 High e nas GPUs NVIDIA H100, use o GPUDirect-TCPX para reduzir a sobrecarga necessária para transferir payloads de pacotes para e das GPUs, o que melhora significativamente o débito em grande escala em comparação com as GPUs que não usam o GPUDirect.
    • Nos tipos de máquinas A3 Mega e nas GPUs NVIDIA H100 Mega, use o GPUDirect-TCPXO, que melhora ainda mais a comunicação entre a GPU e a VM.
    • Nos tipos de máquinas A3 Ultra e GPUs NVIDIA H200, e nos tipos de máquinas A4 e GPUs NVIDIA B200, use o GPUDirect RDMA para executar cargas de trabalho de IA distribuídas com melhorias adicionais no débito. Para começar, crie um cluster GKE otimizado com IA personalizado.
  • gVNIC: ative as capacidades do GPUDirect, como a divisão do cabeçalho de pacotes, a direção de fluxo e a gestão de buffers. O gVNIC é necessário para usar o GPUDirect-TCPX ou o GPUDirect-TCPXO. Para ver detalhes sobre o gVNIC, consulte o artigo Aumente a velocidade do tráfego de rede para nós de GPU.
  • Várias redes: adicione NICs secundárias à máquina otimizada pelo acelerador. Cada NIC está associada a uma sub-rede separada na sua própria VPC para evitar conflitos. Para ver detalhes sobre a compatibilidade com várias redes, consulte o artigo Configure a compatibilidade com várias redes para os Pods.
  • Políticas de posicionamento: use uma política de posicionamento de recursos para posicionar todos os nós de GPU para uma carga de trabalho específica em servidores fisicamente próximos para minimizar a latência. Para ver detalhes, consulte o artigo Defina o posicionamento compacto para nós do GKE.

Resumo do procedimento

Para usar todas estas capacidades em conjunto, faça o seguinte:

  1. Crie nuvens virtuais privadas (VPCs) e sub-redes
  2. Crie o ambiente do GKE.
  3. Instale o ficheiro binário GPUDirect e o plug-in NCCL
  4. Implemente o plugin do injetor de dispositivos NRI
  5. Implemente uma carga de trabalho de teste para validar a configuração do GPUDirect

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. 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.
  • Certifique-se de que tem capacidade para VMs A3 Mega ou A3 High. Para obter esta capacidade, primeiro, escolha entre as opções de consumo. Para seguir as instruções nesta página, pode usar a capacidade a pedido, as reservas a pedido, as reservas futuras ou as reservas futuras durante um máximo de 90 dias (no modo de calendário). Depois de escolher uma opção de consumo, siga as instruções respetivas para obter capacidade através da opção de consumo que escolheu.
  • Certifique-se de que tem quota suficiente para GPUs H100. Para pedir mais quota, consulte o artigo Quotas de GPUs.

Requisitos

Os seguintes requisitos aplicam-se ao GPUDirect-TCPX e ao GPUDirect-TCPXO, salvo indicação em contrário.

  • O GPUDirect-TCPX é suportado na versão 1.27 ou posterior do GKE com versões de patch específicas e requer o seguinte:

    • O a3-highgpu-8g tipo de máquina.
    • Para a versão 1.27 do GKE, use a versão de patch 1.27.7-gke.1121000 ou posterior do GKE.
    • Para a versão 1.28 do GKE, use a versão de patch 1.28.10-gke.1141000 ou posterior do GKE.
    • Para a versão 1.29 do GKE, use a versão de patch 1.29.5-gke.1121000 ou posterior do GKE.
    • Para as versões 1.30 a 1.33 do GKE, use qualquer versão de patch.
    • Não use a versão 1.34 ou posterior do GKE. Para mais informações, consulte o problema conhecido: o GPUDirect-TCPX está indisponível com o A3 High para o GKE versão 1.34 e posterior.
  • O GPUDirect-TCPXO é suportado na versão 1.28 ou posterior do GKE e requer o seguinte:

    • O a3-megagpu-8g tipo de máquina.
    • Para a versão 1.28 do GKE, use a versão de patch 1.28.9-gke.1250000 ou posterior do GKE.
    • Para a versão 1.29 do GKE, use a versão de patch 1.29.4-gke.1542000 ou posterior do GKE.
    • Para a versão 1.30 do GKE, use a versão de patch 1.30.4-gke.1129000 ou posterior do GKE.
    • Para a versão 1.31 do GKE, use a versão de patch 1.31.1-gke.2008000 ou posterior do GKE.
    • Para a versão 1.32 do GKE, use a versão de patch 1.32.2-gke.1489001 ou posterior do GKE.
  • O nó do GKE tem de usar uma imagem do nó do SO otimizado para contentores (COS). As imagens de nós do Ubuntu e do Windows não são suportadas.

  • Os nós de GPU têm de usar a versão 535 ou posterior do controlador da NVIDIA.
  • Tem de usar o GKE Dataplane V2.
  • Para cargas de trabalho GPUDirect-TCPX ou GPUDirect-TCPXO executadas em vários conjuntos de nós, todos os conjuntos de nós têm de estar nas mesmas zonas do Compute Engine e têm de usar os mesmos conjuntos de rede, como VPCs e sub-redes.

Limitações

Aplicam-se as seguintes limitações:

  • O GPUDirect-TCPX e o GPUDirect-TCPXO não são suportados com GPUs de várias instâncias, partilha de tempo da GPU ou NVIDIA MPS.
  • Não pode usar o NCCL FastSocket com o GPUDirect-TCPX ou o GPUDirect-TCPXO .
  • A carga de trabalho do GKE tem de usar todas as GPUs disponíveis e todas as NICs secundárias disponíveis num único nó. Vários pods não podem usar GPUDirect-TCPX nem GPUDirect-TCPXO num único nó.
  • Só pode usar os tipos de máquinas a3-highgpu-8g e a3-megagpu-8g. Outros tipos de máquinas A3 não são suportados.

Crie VPCs e sub-redes

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

  1. Crie as redes VPC para o GPUDirect no seu projeto, cada uma com uma sub-rede e uma regra de firewall. Escolha o separador GPUDirect-TCPX para tipos de máquinas A3 de alta capacidade ou escolha o separador GPUDirect-TCPXO para tipos de máquinas A3 Mega e, de seguida, conclua as seguintes instruções:

    GPUDirect-TCPXO

    Para maximizar a largura de banda, recomendamos que crie oito novas redes.

    for N in $(seq 1 8); 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 o seguinte:

    • PROJECT_ID: o ID do seu Google Cloud projeto.
    • 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 itera oito sub-redes, pelo que deve usar uma variável para alterar o endereço IP de cada sub-rede. Por exemplo, especifique 192.168.$N.0/24 para que a primeira sub-rede use 192.168.1.0/24, a segunda sub-rede use 192.168.2.0/24 e assim sucessivamente.
    • SOURCE_RANGE: o intervalo de endereços IP de origem para a regra de firewall para permitir tráfego de entrada, na notação CIDR. Por exemplo, 192.168.0.0/16.

    GPUDirect-TCPX

    Para maximizar a largura de banda, recomendamos que 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 o seguinte:

    • PROJECT_ID: o ID do seu Google Cloud projeto.
    • 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 itera para quatro sub-redes, pelo que deve usar uma variável para alterar o endereço IP de cada sub-rede. Por exemplo, especifique 192.168.$N.0/24 para que a primeira sub-rede use 192.168.1.0/24, a segunda sub-rede use 192.168.2.0/24, etc.
    • SOURCE_RANGE: o intervalo de endereços IP de origem para a regra de firewall para permitir 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é-visualização) e crie um conjunto de nós de GPU com as seguintes caraterísticas:

  • gVNIC ativado
  • Sub-redes de várias redes especificadas para cada NIC secundário
  • Série de máquinas A3 com GPUs H100 a suportar os nós
  • Os controladores NVIDIA mais recentes instalados

Não pode atualizar um cluster existente para usar várias redes.

GPUDirect-TCPXO

  1. Escolha uma versão do GKE disponível que suporte o GPUDirect-TCPXO. Para listar as versões, execute este comando:

    gcloud container get-server-config \
        --format="yaml(validMasterVersions)" \
        --region=REGION \
        --project=PROJECT_ID
    

    Substitua o seguinte:

    • REGION: a região de computação para o plano de controlo do cluster.
    • PROJECT_ID: o ID do seu Google Cloud projeto.
  2. Crie um cluster:

    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 o seguinte:

    • CLUSTER_NAME: o nome do novo cluster.
    • VERSION: uma versão do GKE que suporta o GPUDirect-TCPXO, conforme descrito nos requisitos.
    • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.
  3. Crie recursos Network e GKENetworkParamSet no cluster que correspondem às redes VPC e sub-redes que 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: Network
    metadata:
      name: vpc5
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc5
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc6
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc6
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc7
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc7
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc8
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc8
      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
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc5
    spec:
      vpc: PREFIX-net-5
      vpcSubnet: PREFIX-sub-5
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc6
    spec:
      vpc: PREFIX-net-6
      vpcSubnet: PREFIX-sub-6
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc7
    spec:
      vpc: PREFIX-net-7
      vpcSubnet: PREFIX-sub-7
      deviceMode: NetDevice
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc8
    spec:
      vpc: PREFIX-net-8
      vpcSubnet: PREFIX-sub-8
      deviceMode: NetDevice
    EOF
    

    Estes recursos indicam ao GKE para configurar as NICs para o tráfego de GPU no modo de passagem. O GKE não aplica a programação de rede incorporada através do eBPF a este tráfego.

GPUDirect-TCPX

  1. Crie um cluster:

    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 o seguinte:

    • CLUSTER_NAME: o nome do novo cluster.
    • CONTROL_PLANE_LOCATION: a localização do Compute Engine do plano de controlo do seu cluster. Indique uma região para clusters regionais ou uma zona para clusters zonais.
    • VERSION: uma versão do GKE que suporta o GPUDirect-TCPX, conforme descrito nos requisitos.
  2. Crie recursos Network e GKENetworkParamSet no cluster que correspondem às redes VPC e sub-redes que 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
    

    Estes recursos indicam ao GKE para configurar as NICs para o tráfego de GPU no modo de passagem. O GKE não aplica a programação de rede incorporada através do eBPF a este tráfego.

Crie um node pool de GPU

GPUDirect-TCPXO

Crie um node pool para as GPUs H100:

gcloud beta container node-pools create NODE_POOL_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --cluster=CLUSTER_NAME \
    --project=PROJECT_ID \
    --accelerator=type=nvidia-h100-mega-80gb,count=8,gpu-driver-version=LATEST \
    --machine-type=a3-megagpu-8g \
    --num-nodes=2 \
    --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 \
    --additional-node-network network=PREFIX-net-5,subnetwork=PREFIX-sub-5 \
    --additional-node-network network=PREFIX-net-6,subnetwork=PREFIX-sub-6 \
    --additional-node-network network=PREFIX-net-7,subnetwork=PREFIX-sub-7 \
    --additional-node-network network=PREFIX-net-8,subnetwork=PREFIX-sub-8 \
    --enable-gvnic \
    --no-enable-autoupgrade \
    --scopes "https://www.googleapis.com/auth/cloud-platform" [\
    --placement-policy=POLICY_NAME \
    --reservation-affinity=specific \
    --reservation=projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME \
    --host-maintenance-interval=PERIODIC]

Substitua NODE_POOL_NAME pelo nome do conjunto de nós.

No exemplo, o argumento --scopes "https://www.googleapis.com/auth/cloud-platform" define o âmbito da instância do nó como cloud-platform para facilitar os testes. Para produção, é recomendável limitar o âmbito para configurar credenciais mais detalhadas.

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

A flag --reservation-affinity pode assumir os valores specific ou any. No entanto, para cargas de trabalho de IA distribuídas de alto desempenho, recomendamos que use uma reserva específica. Pode encontrar informações sobre a sua reserva, como o nome da reserva ou o nome de um bloco específico na reserva. Para encontrar estes valores para reservas a pedido, veja uma lista das suas reservas ou veja pedidos de reservas futuras.

Substitua o seguinte para usar uma reserva:

  • PROJECT_ID: opcionalmente, o seu Google Cloud ID do projeto. Se a reserva estiver localizada no projeto atual (não for uma reserva partilhada), pode omitir 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 na reserva. Omit /reservationBlocks/BLOCK_NAME se não quiser usar um bloco específico.

Se este comando falhar, é possível que não tenha quota de GPU H100 suficiente no seu projeto. Certifique-se de que tem quota e tente novamente o comando.

GPUDirect-TCPX

Crie um node pool para as GPUs H100:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --machine-type=a3-highgpu-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 conjunto de nós.

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

A flag --reservation-affinity pode assumir os valores specific ou any. No entanto, para cargas de trabalho de IA distribuídas de alto desempenho, recomendamos que use uma reserva específica. Pode encontrar informações sobre a sua reserva, como o nome da reserva ou o nome de um bloco específico na reserva. Para encontrar estes valores para reservas a pedido, veja uma lista das suas reservas ou veja pedidos de reservas futuras.

Substitua o seguinte para usar uma reserva:

  • PROJECT_ID: opcionalmente, o seu Google Cloud ID do projeto. Se a reserva estiver localizada no projeto atual (não for uma reserva partilhada), pode omitir 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 na reserva. Omit /reservationBlocks/BLOCK_NAME se não quiser usar um bloco específico.

Se este comando falhar, é possível que não tenha quota de GPU H100 suficiente no seu projeto. Certifique-se de que tem quota e tente novamente o comando.

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

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

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

    kubectl describe node NODE_NAME
    

    Substitua NODE_NAME pelo nome do nó a descrever.

    O resultado é semelhante ao seguinte:

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

Instale o ficheiro binário GPUDirect e configure o NCCL

Esta secção mostra como instalar o ficheiro binário GPUDirect, com base no seu tipo de máquina A3 (GPUDirect-TCPX para A3 High, GPUDirect-TCPXO para A3 Mega) e numa versão específica da biblioteca NCCL através de um DaemonSet.

GPUDirect-TCPXO

Este DaemonSet faz o seguinte:

  1. Pré-instalação para configurar configurações relacionadas com o GPUDirect-TCPXO.
  2. Instala a biblioteca NCCL e o binário GPUDirect-TCPXO no nó.
  3. Armazena a biblioteca e o ficheiro binário no diretório /home/kubernetes/bin/nvidia/lib64 na VM. Por predefinição, o GKE monta este diretório no caminho /usr/local/nvidia/lib64 em contentores de GPU que precisam de usar o NCCL e o GPUDirect-TCPXO.

Para instalar o ficheiro binário e configurar a NCCL, siga estes passos:

  1. Reveja o nccl-tcpxo-installer.yaml manifesto Daemonset no GitHub.

  2. Implemente o DaemonSet:

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

    O plug-in NCCL demora aproximadamente dois minutos a começar a ser executado.

  3. Verifique o estado dos pods DaemonSet:

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

    O resultado é semelhante ao seguinte:

    # Output
    nccl-tcpxo-installer-6c2pv                    1/1     Running   0          2m11s
    nccl-tcpxo-installer-qgg82                    1/1     Running   0          2m11s
    

GPUDirect-TCPX

Este DaemonSet faz o seguinte:

  1. Instala a biblioteca NCCL e o binário GPUDirect-TCPX no nó.
  2. Armazena a biblioteca e o ficheiro binário no diretório /home/kubernetes/bin/nvidia/lib64 na VM. Por predefinição, o GKE monta este diretório no caminho /usr/local/nvidia/lib64 nos contentores de GPU que precisam de usar o NCCL e o GPUDirect-TCPX.

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

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

  2. Implemente o DaemonSet:

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

    O plug-in NCCL demora aproximadamente dois minutos a começar a ser executado.

  3. Verifique o estado dos pods DaemonSet:

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

    O resultado é semelhante ao seguinte:

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

Implemente o plugin do injetor de dispositivos NRI

Esta secção mostra como instalar o injetor de dispositivos NRI através de um DaemonSet. Ambos os tipos de máquinas com GPU H100 instalam o mesmo plug-in do injetor de dispositivos NRI. Este plugin faz o seguinte:

  1. Ativa a interface de recursos de nós (NRI) no nó que tem GPUs H100. A NRI está ativada por predefinição na versão 1.29 e posteriores do GKE.
  2. Implementa um contentor de plug-in do injetor de dispositivos NRI que injeta dispositivos de GPU em contentores especificados por anotações de pods.

Para instalar o plug-in, faça o seguinte:

  1. Reveja o nri-device-injector.yamlmanifesto de implementação no GitHub.

  2. Implemente o DaemonSet:

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

    O plug-in NCCL demora aproximadamente dois minutos a começar a ser executado.

  3. Verifique o estado dos pods DaemonSet:

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

    O resultado é semelhante ao seguinte:

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

Implemente uma carga de trabalho de teste

Nesta secção, implementa uma carga de trabalho de exemplo para verificar se o NCCL e o GPUDirect-TCPX ou o GPUDirect-TCPXO funcionam conforme esperado. Esta carga de trabalho de exemplo faz o seguinte:

  1. Implementa dois pods, cada um dos quais é executado num nó com GPUs H100.
  2. Implementa um contentor sidecar em cada pod para permitir que esses pods usem o GPUDirect-TCPXO ou o GPUDirect-TCPX.

Para implementar esta carga de trabalho de exemplo, faça o seguinte:

GPUDirect-TCPXO

Esta carga de trabalho inclui um contentor sidecar com o nome tcpxo-daemon, que executa um serviço que permite ao pod usar o GPUDirect-TCPXO. Tem de adicionar este contentor auxiliar a todos os pods no seu próprio ambiente que precisem de usar o GPUDirect-TCPXO. Para ver um fragmento dos campos obrigatórios a adicionar aos seus manifestos, consulte o artigo Adicione o GPUDirect ao seu manifesto.

  1. Reveja o nccl-test-latest.yamlmanifesto no GitHub.

  2. Implemente dois pods com a carga de trabalho de teste:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest.yaml
    
  3. Após a implementação dos pods, acione um teste de recolha total:

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

    O resultado é semelhante ao seguinte:

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

GPUDirect-TCPX

Esta carga de trabalho inclui um contentor sidecar com o nome tcpx-daemon, que executa um serviço que permite ao pod usar o GPUDirect-TCPX. Tem de adicionar este contentor auxiliar a todos os pods no seu próprio ambiente que precisem de usar o GPUDirect-TCPX. Para ver um fragmento dos campos obrigatórios a adicionar aos seus manifestos, consulte o artigo Adicione o GPUDirect ao seu manifesto.

  1. Reveja o nccl-config.yaml manifesto ConfigMap no GitHub. Este manifesto implementa scripts que inicializam um teste de recolha total da NCCL e define as definições de configuração específicas da NCCL.

  2. Reveja o nccl-test-latest.yamlmanifesto de implementação no GitHub.

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

    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
    
  4. Execute os seguintes comandos para acionar um teste de recolha total da NCCL para os nós:

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

    O resultado é semelhante ao seguinte:

    #                                                              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
    

Use as definições de configuração da NCCL necessárias para melhorar o desempenho

Os seguintes pares de chave-valor são as definições de configuração da NCCL necessárias para o GPUDirect-TCPX e o GPUDirect-TCPXO. Quando implementar as suas cargas de trabalho que usam a NCCL, defina-as como variáveis de ambiente para otimizar o desempenho.

GPUDirect-TCPXO


"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_FASTRAK_CTRL_DEV=eth0",
"NCCL_FASTRAK_IFNAME=eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8",
"NCCL_SOCKET_IFNAME=eth0",
"NCCL_CROSS_NIC=0",
"NCCL_ALGO=Ring,Tree",
"NCCL_PROTO=Simple,LL128",
"NCCL_MIN_NCHANNELS=4",
"NCCL_TUNER_PLUGIN=libnccl-tuner.so",
"NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config.textproto",
"NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config.textproto",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_FASTRAK_NUM_FLOWS=2",
"NCCL_FASTRAK_USE_SNAP=1",
"NCCL_FASTRAK_PLUGIN_ACCEPT_TIMEOUT_MS=600000",
"NCCL_FASTRAK_ENABLE_CONTROL_CHANNEL=0",
"NCCL_BUFFSIZE=8388608",
"CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_FASTRAK_ENABLE_HOTPATH_LOGGING=0",
"NCCL_FASTRAK_USE_LLCM=1",
"NCCL_NVLS_ENABLE=0"

Opcionalmente, pode definir todas as configurações de uma só vez seguindo estes passos:

  1. No manifesto do contentor de carga de trabalho, adicione o seguinte par de chave-valor como uma variável de ambiente:

    NCCL_LIB_DIR="/usr/local/nvidia/lib64"
    
  2. Certifique-se de que o script nccl-env-profile.sh é executado quando o contentor da carga de trabalho é iniciado. Por exemplo, pode fazê-lo na especificação do pod substituindo o comando do contentor para incluir o seguinte:

    source ${NCCL_LIB_DIR}/nccl-env-profile.sh
    

Compatibilidade com LL128

O protocolo de comunicação NVIDIA LL128 (baixa latência 128) NCCL pode melhorar significativamente o desempenho para conjuntos de dados de tamanho pequeno a médio. O GPUDirect-TCPXO suporta o protocolo LL128.

Para usar o LL128, certifique-se de que o ficheiro nccl-tcpxo-installer.yaml na secção Instale o binário GPUDirect e configure o NCCL usa a seguinte versão da imagem do contentor ou posterior:

us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx-
dev:v1.0.8-1

Para configurar o LL128, faça o seguinte:

  • Para a us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx- dev:v1.0.8-1versão do plug-in NCCL, siga estes passos:

    1. No manifesto da carga de trabalho, defina a seguinte variável de ambiente:

      NCCL_LIB_DIR="/usr/local/nvidia/lib64
      
    2. Configure a carga de trabalho para executar o script nccl-env-profile-ll128.sh quando o contentor for iniciado. No manifesto da carga de trabalho, defina o seguinte comando:

      source ${NCCL_LIB_DIR}/nccl-env-profile-ll128.sh
      

      O script nccl-env-profile-ll128.sh tem as seguintes variáveis de ambiente:

      NCCL_PROTO=Simple,LL128
      NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config_ll128.textproto
      NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_guest_config_ll128.textproto
      
  • Para a versão do plug-in NCCL e posteriores, o LL128 torna-se um parâmetro predefinido. Por isso, a utilização do script nccl-env-profile.sh ou do script nccl-env-profile-ll128.sh ativa o LL128.us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx-dev:v1.0.9-1 Para desativar o LL128:

    1. No manifesto da carga de trabalho, defina a seguinte variável de ambiente:

      NCCL_LIB_DIR="/usr/local/nvidia/lib64
      
    2. Configure a carga de trabalho para executar o script nccl-env-profile-ll128.sh quando o contentor for iniciado. No manifesto da carga de trabalho, defina o seguinte comando:

      source ${NCCL_LIB_DIR}/nccl-env-profile-simple.sh
      

      O script nccl-env-profile-simple.sh tem as seguintes variáveis de ambiente:

      NCCL_PROTO=Simple
      NCCL_TUNER_CONFIG_PATH=/usr/local/nvidia/lib64/a3plus_tuner_config_simple.textproto
      NCCL_SHIMNET_GUEST_CONFIG_CHECKER_CONFIG_FILE=/usr/local/nvidia/lib64/a3plus_tuner_config_simple.textproto
      

GPUDirect-TCPX

"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/tcpx/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"

Recolha registos de depuração da NCCL

Para registar erros da NCCL, recomendamos que adicione a seguinte configuração da 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 registo extenso. Para evitar este cenário e, a menos que tenha especificado NCCL_DEBUG_FILE, recomendamos que defina NCCL_DEBUG=WARN para limitar os registos apenas a erros.
  • NCCL_DEBUG_SUBSYS: filtra os subsistemas para os quais o NCCL recolhe informações de depuração. Recomendamos que recolha registos para os seguintes subsistemas:

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

    Se quiser recolher registos para diferentes subsistemas, consulte NCCL_DEBUG_SUBSYS na documentação da NCCL para ver uma lista de valores aceites.

  • NCCL_DEBUG_FILE (Opcional): direciona a saída do registo de depuração do NCCL para um ficheiro que especificar. Esta variável escreve registos da NCCL em ficheiros padrão, o que impede que a saída do registo se misture com a saída da aplicação. Esta variável também escreve registos de diferentes classificações da NCCL em ficheiros diferentes, o que impede a mistura dos registos.

    Use o seguinte formato de nome de ficheiro:

    /DIRECTORY/FILE_NAME.%h.%p
    

    Substitua o seguinte:

    • DIRECTORY: o diretório onde quer armazenar os ficheiros de registo.
    • FILE_NAME: o nome dos ficheiros de registo.

    O marcador de posição %h é resolvido para o nome do anfitrião do nó, enquanto %p é resolvido para o ID do processo (PID) do processo que está a gerar o registo.

Para mais informações sobre a depuração de registos da NCCL, consulte o artigo Resolva problemas de GPUs no GKE.

Adicione o GPUDirect aos seus manifestos

Esta secção mostra os campos obrigatórios que tem de adicionar aos seus manifestos do Kubernetes para que os seus pods usem o GPUDirect.

Consoante o tipo de GPUDirect, faça o seguinte:

GPUDirect-TCPXO

  1. Adicione as seguintes anotações aos metadados do pod. Sem estas anotações, o elemento hostNetwork:true é obrigatório para o Pod e o elemento privileged:true é obrigatório para o contentor tcpxo-daemon.

    metadata:
      annotations:
        devices.gke.io/container.tcpxo-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
          - path: /dev/dmabuf_import_helper
        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"},
            {"interfaceName":"eth5","network":"vpc5"},
            {"interfaceName":"eth6","network":"vpc6"},
            {"interfaceName":"eth7","network":"vpc7"},
            {"interfaceName":"eth8","network":"vpc8"}
          ]
    
  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
      - name: aperture-devices
        hostPath:
          path: /dev/aperture_devices
    
  3. Adicione o seguinte contentor ao manifesto para executar o serviço tcpxo-daemon. Substituir (TCPXO_DAEMON_IMAGE) pela imagem mais recente, us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.17:

    - name: tcpxo-daemon
      image: TCPXO_DAEMON_IMAGE
      imagePullPolicy: Always
      command: ["/bin/sh", "-c"]
      args:
        - |
          set -ex
          chmod 755 /fts/entrypoint_rxdm_container.sh
          /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
      securityContext:
        capabilities:
          add:
            - NET_ADMIN
            - NET_BIND_SERVICE
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: sys
          mountPath: /hostsysfs
        - name: proc-sys
          mountPath: /hostprocsysfs
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  4. Adicione a seguinte variável de ambiente a todos os contentores de GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
      value: /dev/aperture_devices
    
  5. Adicione os seguintes volumeMounts a todos os contentores de GPU. Sem aperture_devices configurações, privileged:true é necessário para contentores de GPU:

    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    
  6. Adicione variáveis de ambiente para configurar as opções da NCCL. Para ver detalhes, consulte o artigo Use as definições de configuração da NCCL recomendadas para melhorar o desempenho.

Uma especificação de Pod concluída tem o seguinte aspeto:

apiVersion: v1
kind: Pod
metadata:
name: a3plus-workloads
annotations:
  devices.gke.io/container.tcpxo-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
    - path: /dev/dmabuf_import_helper
  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"},
      {"interfaceName":"eth5","network":"vpc5"},
      {"interfaceName":"eth6","network":"vpc6"},
      {"interfaceName":"eth7","network":"vpc7"},
      {"interfaceName":"eth8","network":"vpc8"}
    ]
...
containers:
  - name: tcpxo-daemon
    image: TCPXO_DAEMON_IMAGE
    imagePullPolicy: Always
    command: ["/bin/sh", "-c"]
    args:
      - |
        set -ex
        chmod 755 /fts/entrypoint_rxdm_container.sh
        /fts/entrypoint_rxdm_container.sh --num_hops=2 --num_nics=8 --uid= --alsologtostderr
    securityContext:
      capabilities:
        add:
          - NET_ADMIN
          - NET_BIND_SERVICE
    volumeMounts:
      - name: libraries
        mountPath: /usr/local/nvidia/lib64
      - name: sys
        mountPath: /hostsysfs
      - name: proc-sys
        mountPath: /hostprocsysfs
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
  - name: main-application-container
...
   env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
      - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY
        value: /dev/aperture_devices
    securityContext:
    volumeMounts:
      - name: aperture-devices
        mountPath: /dev/aperture_devices
    resources:
      limits:
        nvidia.com/gpu: 8
volumes:
  - name: libraries
    hostPath:
      path: /home/kubernetes/bin/nvidia
  - name: sys
    hostPath:
      path: /sys
  - name: proc-sys
    hostPath:
      path: /proc/sys
  - name: aperture-devices
    hostPath:
      path: /dev/aperture_devices

GPUDirect-TCPX

  1. Adicione as seguintes anotações aos metadados do pod. Sem estas anotações, o elemento hostNetwork:true é obrigatório para o Pod e o elemento privileged:true é obrigatório para o contentor 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 contentor 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 volumes a todos os contentores que pedem 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 secção Use as definições de configuração da NCCL recomendadas para melhorar o desempenho neste documento.

  6. Adicione a seguinte variável de ambiente a todos os contentores de GPU:

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

Uma especificação de pod concluída tem o seguinte aspeto:

apiVersion: v1
kind: Pod
metadata:
name: a3-gpu-workloads-example
labels:
  name: a3-gpu-workloads-example
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"}
    ]
spec:
containers:
  - name: tcpx-daemon
    image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/tcpgpudmarxd-dev:v2.0.11
    imagePullPolicy: Always
    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
        readOnly: true
      - 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
  - name: a3-gpu-workloads-example
    ...
    volumeMounts:
      - name: tcpx-socket
        mountPath: /tmp
      - name: libraries
        mountPath: /usr/local/nvidia/lib64
        readOnly: true
    resources:
      limits:
        nvidia.com/gpu: 8
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
...
volumes:
  - name: libraries
    hostPath:
      path: /home/kubernetes/bin/nvidia/lib64
  - name: tcpx-socket
    emptyDir:
  - name: sys
    hostPath:
      path: /sys
  - name: proc-sys
    hostPath:
      path: /proc/sys

O que se segue?