Nesta página, mostramos como maximizar a largura de banda e a capacidade de processamento para cargas de trabalho de GPU de alto desempenho no Google Kubernetes Engine (GKE) usando clusters padrão com GPUDirect-TCPXO, 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. Antes de ler esta página, confira se você conhece 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).
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.
Sobre os supercomputadores de GPU do Google Cloud
O Google Cloud tem supercomputadores otimizados para aceleradores que são desenvolvidos para modelos grandes e escalonáveis. Essas máquinas têm os seguintes benefícios:
- Oito GPUs NVIDIA H100 por máquina.
- Até 200 Gbps de largura de banda na placa de rede (NIC) principal.
- NICs secundárias (até oito em tipos de máquina A3 Mega e até quatro em tipos de máquina A3 High), cada uma com suporte de largura de banda de até 200 Gbps para transferência de dados de GPU.
Para uma lista completa de benefícios, consulte a série de máquinas A3 na documentação do Compute Engine.
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 nesta página é ideal 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 todos os recursos a seguir:
- Pilha de rede GPUDirect: a série de máquinas A3 oferece suporte
a duas pilhas de rede para acesso direto à memória (RDMA, na sigla em inglês) personalizado e remoto:
- Em tipos de máquina A3 High, use 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.
- Em tipos de máquina A3 Mega, use o GPUDirect-TCPXO, que melhora ainda mais a comunicação da GPU com a VM.
- 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 ou o GPUDirect-TCPXO. Para detalhes sobre a gVNIC, consulte Aumentar a velocidade do tráfego de rede para nós da GPU.
- 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 todos esses recursos juntos, faça o seguinte:
- Crie nuvens privadas virtuais (VPC) e sub-redes
- Crie o ambiente do GKE:
- Crie um cluster com várias redes ativado
- Crie um pool de nós com estas 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 com GPUs H100 que oferecem suporte aos nós
- Drivers da NVIDIA instalados mais recentes
- Instalar o binário GPUDirect e o plug-in NCCL
- Implantar o plug-in de injeção de dispositivo NRI
- Implante uma carga de trabalho de teste para verificar a configuração do GPUDirect
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Ativar 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
gcloud components update
.
- Verifique se você tem cota suficiente para GPUs H100. Para solicitar mais cotas, consulte as cotas de GPU.
Requisitos
Os requisitos a seguir se aplicam a GPUDirect-TCPX e GPUDirect-TCPXO, a menos que indicado de outra forma.
- O GPUDirect-TCPX é compatível com o GKE versão 1.27 ou mais recente e requer:
- Tipo de máquina A3 High (por exemplo,
a3-highgpu-8g
). - Para a versão 1.27 do GKE, use a versão de patch do GKE 1.27.7-gke.1121000 ou mais recente.
- Para a versão 1.28 do GKE, use a versão de patch do GKE 1.28.8-gke.1095000 ou mais recente.
- Para a versão 1.29 do GKE, use a versão de patch do GKE 1.29.3-gke.1093000 ou mais recente.
- Para a versão 1.30 do GKE, use a versão de patch do GKE 1.30.2-gke.1023000 ou mais recente.
- Tipo de máquina A3 High (por exemplo,
- O GPUDirect-TCPXO é compatível com o GKE versão 1.28 ou mais recente e requer:
- Tipo de máquina A3 Mega (por exemplo,
a3-megagpu-8g
). - Para a versão 1.28 do GKE, use a versão de patch do GKE 1.28.9-gke.1250000 ou mais recente.
- Para a versão 1.29 do GKE, use a versão de patch do GKE 1.29.4-gke.1542000 ou mais recente.
- Para a versão 1.30 do GKE, use a versão de patch do GKE 1.30.4-gke.1129000 ou mais recente.
- Tipo de máquina A3 Mega (por exemplo,
- Os nós da GPU precisam usar o driver da NVIDIA versão 535 ou mais recente.
- É preciso usar o GKE Dataplane V2.
- 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.
Limitações
Considere as seguintes limitações:
- O GPUDirect-TCPX e o GPUDirect-TCPXO não têm suporte em clusters do Autopilot
- O GPUDirect-TCPX e o GPUDirect-TCPXO não são compatíveis com GPUs de várias instâncias, compartilhamento de tempo de GPU ou NVIDIA MPS.
- Não é possível usar o NCCL FastSocket
- Sua carga de trabalho do GKE precisa usar todas as GPUs e NICs secundárias disponíveis em um único nó. Vários pods não podem usar GPUDirect-TCPX ou GPUDirect-TCPXO em um único nó.
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.
Crie as redes VPC para GPUDirect no projeto, cada uma com uma sub-rede e uma regra de firewall: Escolha a guia "GPUDirect-TCPX" para tipos de máquina A3 High ou a guia "GPUDirect-TCPXO" para tipos de máquina A3 Mega e siga estas instruções:
GPUDirect-TCPXO
Para maximizar a largura de banda, recomendamos que você crie oito novas redes.
for N in $(seq 1 8); do gcloud compute networks create PROJECT_ID-net-$N \ --subnet-mode=custom \ --mtu=8244 gcloud compute networks subnets create PROJECT_ID-sub-$N \ --network=PROJECT_ID-net-$N \ --region=REGION \ --range=SUBNET_RANGE gcloud compute firewall-rules create PROJECT_ID-internal-$N \ --network=PROJECT_ID-net-$N \ --action=ALLOW \ --rules=tcp:0-65535,udp:0-65535,icmp \ --source-ranges=SOURCE_RANGE done
Substitua:
PROJECT_ID
: é seu ID do projeto no 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 itera para oito sub-redes. Portanto, use uma variável para alterar o endereço IP de cada sub-rede. Por exemplo, especifique192.168.$N.0/24
para que a primeira sub-rede use192.168.1.0/24
, a segunda use192.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
.
GPUDirect-TCPX
Para maximizar a largura de banda, recomendamos que você crie quatro novas redes.
for N in $(seq 1 4); do gcloud compute networks create PROJECT_ID-net-$N \ --subnet-mode=custom \ --mtu=8244 gcloud compute networks subnets create PROJECT_ID-sub-$N \ --network=PROJECT_ID-net-$N \ --region=REGION \ --range=SUBNET_RANGE gcloud compute firewall-rules create PROJECT_ID-internal-$N \ --network=PROJECT_ID-net-$N \ --action=ALLOW \ --rules=tcp:0-65535,udp:0-65535,icmp \ --source-ranges=SOURCE_RANGE done
Substitua:
PROJECT_ID
: é seu ID do projeto no 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 alterar o endereço IP de cada sub-rede. Por exemplo, especifique192.168.$N.0/24
para que a primeira sub-rede use192.168.1.0/24
, a segunda use192.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
.
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 crie um pool de nós de GPU que usa máquinas A3 com GPUs H100 e NICs adicionais. Não é possível atualizar um cluster atual para usar várias redes.
GPUDirect-TCPXO
Escolha uma versão disponível do GKE compatível com o GPUDirect-TCPXO. Para listar as versões, execute este comando:
gcloud container get-server-config \ --format="yaml(validMasterVersions)" \ --zone=ZONE \ --project=PROJECT_ID
Substitua:
ZONE
: a zona de computação do plano de controle do cluster.PROJECT_ID
: é seu ID do projeto no Google Cloud.
Crie um cluster:
gcloud --project ${PROJECT} beta container clusters create CLUSTER_NAME \ --enable-dataplane-v2 --enable-ip-alias --zone=ZONE \ --enable-multi-networking --cluster-version=VERSION --no-enable-autoupgrade
Substitua:
CLUSTER_NAME
: o nome do novo cluster;VERSION
: uma versão do GKE que oferece suporte ao GPUDirect-TCPXO, conforme descrito em Requisitos.REGION
: a região do Compute Engine para o cluster.ZONE
: a zona do Compute para o cluster.
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: 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: PROJECT_ID-net-1 vpcSubnet: PROJECT_ID-sub-1 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc2 spec: vpc: PROJECT_ID-net-2 vpcSubnet: PROJECT_ID-sub-2 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc3 spec: vpc: PROJECT_ID-net-3 vpcSubnet: PROJECT_ID-sub-3 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc4 spec: vpc: PROJECT_ID-net-4 vpcSubnet: PROJECT_ID-sub-4 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc5 spec: vpc: PROJECT_ID-net-5 vpcSubnet: PROJECT_ID-sub-5 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc6 spec: vpc: PROJECT_ID-net-6 vpcSubnet: PROJECT_ID-sub-6 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc7 spec: vpc: PROJECT_ID-net-7 vpcSubnet: PROJECT_ID-sub-7 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc8 spec: vpc: PROJECT_ID-net-8 vpcSubnet: PROJECT_ID-sub-8 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.
Crie um pool de nós para as GPUs H100:
gcloud beta container node-pools create NODE_POOL_NAME \ --zone=ZONE \ --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=RESERVATION_NAME \ --host-maintenance-interval=PERIODIC]
Substitua
NODE_POOL_NAME
pelo nome do pool de nós.No exemplo, o argumento
--scopes
"https://www.googleapis.com/auth/cloud-platform" define o escopo da instância do nó comocloud-platform
para facilitar o teste. Para a produção, é recomendável limitar o escopo para configurar credenciais mais refinadas.Use as flags
--placement-policy
,--reservation-affinity
e--reservation
se você estiver usando uma reserva. Especifique essas flags para configurar o nome da política e a reserva no pool de nós.Se esse comando falhar, talvez você não tenha cota suficiente de GPU H100 no projeto. Verifique se você tem cota sufuciente e tente executar o comando novamente.
Confira uma lista de nós no cluster:
kubectl get nodes
Verifique se cada nó da GPU tem oito GPUs:
kubectl describe node NODE_NAME
O resultado será assim:
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
GPUDirect-TCPX
Criar um cluster padrão
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-dataplane-v2 --enable-ip-alias \ --enable-multi-networking \ --no-enable-autoupgrade \
Substitua:
CLUSTER_NAME
: o nome do novo cluster;LOCATION
: a região do Compute Engine para o cluster.VERSION
: a versão do GKE para o cluster. Use uma versão compatível, conforme descrito na seção "Requisitos".
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: PROJECT_ID-net-1 vpcSubnet: PROJECT_ID-sub-1 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc2 spec: vpc: PROJECT_ID-net-2 vpcSubnet: PROJECT_ID-sub-2 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc3 spec: vpc: PROJECT_ID-net-3 vpcSubnet: PROJECT_ID-sub-3 deviceMode: NetDevice --- apiVersion: networking.gke.io/v1 kind: GKENetworkParamSet metadata: name: vpc4 spec: vpc: PROJECT_ID-net-4 vpcSubnet: PROJECT_ID-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.
Crie um pool de nós para as GPUs H100:
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=LOCATION \ --machine-type=a3-highgpu-8g \ --accelerator=type=nvidia-h100-80gb,count=8,gpu-driver-version=LATEST \ --additional-node-network=network=PROJECT_ID-net-1,subnetwork=PROJECT_ID-sub-1 \ --additional-node-network=network=PROJECT_ID-net-2,subnetwork=PROJECT_ID-sub-2 \ --additional-node-network=network=PROJECT_ID-net-3,subnetwork=PROJECT_ID-sub-3 \ --additional-node-network=network=PROJECT_ID-net-4,subnetwork=PROJECT_ID-sub-4 \ --enable-gvnic \ --no-enable-autoupgrade
Substitua
NODE_POOL_NAME
pelo nome do pool de nós.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.
Confira uma lista de nós no cluster:
kubectl get nodes
Verifique se cada nó da GPU tem oito GPUs:
kubectl describe node NODE_NAME
O resultado será assim:
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
Instalar o binário GPUDirect e configurar o NCCL
Esta seção mostra como instalar o binário GPUDirect com base no tipo de máquina A3 (GPUDirect-TCPX para A3 High, GPUDirect-TCPXO para A3 Mega) e uma versão específica da biblioteca NCCL usando um DaemonSet.
GPUDirect-TCPXO
Revise o manifesto do Daemonset
nccl-tcpxo-installer.yaml
no GitHub. Esse DaemonSet faz o seguinte:- Pré-instalação para configurar configurações relacionadas ao GPUDirect-TCPXO.
- Instala a biblioteca NCCL e o binário GPUDirect-TCPXO no nó.
- 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
nos contêineres de GPU que precisam usar o NCCL e o GPUDirect-TCPXO.
Implante o DaemonSet:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-tcpxo-installer.yaml
O plug-in do NCCL leva aproximadamente dois minutos para começar a ser executado.
Verifique o status dos pods do DaemonSet:
kubectl get pods -n=kube-system -l=name=nccl-tcpxo-installer
O resultado será assim:
# Output nccl-tcpxo-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpxo-installer-qgg82 1/1 Running 0 2m11s
GPUDirect-TCPX
Revise o manifesto do Daemonset
nccl-tcpx-installer.yaml
no GitHub. Esse DaemonSet faz o seguinte:- Instala a biblioteca NCCL e o binário GPUDirect-TCPX no nó.
- 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
nos contêineres de GPU que precisam usar o NCCL e o GPUDirect-TCPX.
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.
Verifique o status dos pods do DaemonSet:
kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
O resultado será assim:
nccl-tcpx-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpx-installer-qgg82 1/1 Running 0 2m11s
Implantar o plug-in de injeção de dispositivo NRI
Esta seção mostra como instalar o injetor de dispositivo NRI usando um DaemonSet. Os dois tipos de máquina H100(GPUDirect-TCPX para A3 High e GPUDirect-TCPXO para A3 Mega) instalam o mesmo plug-in de injeção de dispositivo NRI.
Revise o manifesto de implantação
nri-device-injector.yaml
no GitHub. Esse DaemonSet faz o seguinte:- Ativa a interface de recursos do nó (NRI) no nó que tem GPUs H100.
- 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.
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.
Verifique o status dos pods do DaemonSet:
kubectl get pods -n=kube-system -l=name=device-injector
O resultado será assim:
# Output device-injector-md6hb 1/1 Running 0 4h54m device-injector-vh9bm 1/1 Running 0 4h54m
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 ou o GPUDirect-TCPXO funcionam conforme o esperado.
GPUDirect-TCPXO
Essa carga de trabalho inclui um contêiner de arquivo secundário chamado tcpxo-daemon, que executa um serviço que permite ao pod usar o GPUDirect-TCPXO. Você precisa adicionar esse contêiner de arquivo secundário a qualquer pod no seu próprio ambiente que precise usar GPUDirect-TCPXO. Para conferir um snippet dos campos obrigatórios a serem adicionados aos manifestos, consulte Adicionar GPUDirect ao manifesto.
Revise o manifesto
nccl-test-latest.yaml
no GitHub. Esse manifesto faz o seguinte:- Implanta dois pods, cada um executado em um nó que tem GPUs H100.
- Implanta um contêiner de arquivo secundário chamado
tcpxo-daemon
em cada pod para permitir que esses pods usem o GPUDirect-TCPXO.
Implante 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
Execute os seguintes comandos para acionar um teste de todos os dois nós do NCCL:
kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /scripts/allgather.sh nccl-host-1 nccl-host-2
O resultado será assim:
# 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 4654.5 0.23 0.21 0 3890.9 0.27 0.25 0 2097152 32768 float none -1 4117.2 0.51 0.48 0 5153.5 0.41 0.38 0 4194304 65536 float none -1 6417.4 0.65 0.61 0 7295.5 0.57 0.54 0 8388608 131072 float none -1 7872.1 1.07 1.00 0 6451.4 1.30 1.22 0 16777216 262144 float none -1 6990.7 2.40 2.25 0 5609.3 2.99 2.80 0 33554432 524288 float none -1 8254.0 4.07 3.81 0 7415.1 4.53 4.24 0 67108864 1048576 float none -1 5546.3 12.10 11.34 0 6484.0 10.35 9.70 0 134217728 2097152 float none -1 6507.3 20.63 19.34 0 6015.4 22.31 20.92 0 268435456 4194304 float none -1 6744.1 39.80 37.32 0 7023.1 38.22 35.83 0 536870912 8388608 float none -1 8939.8 60.05 56.30 0 11706 45.86 43.00 0 1073741824 16777216 float none -1 8241.7 130.28 122.14 0 8375.2 128.20 120.19 0 # Out of bounds values : 0 OK # Avg bus bandwidth : 22.449
GPUDirect-TCPX
Essa carga de trabalho inclui um contêiner de arquivo secundário chamado tcpx-daemon, que executa um serviço que permite ao pod usar o GPUDirect-TCPX. Você precisa adicionar esse contêiner de arquivo 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.
- 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. Revise o manifesto de implantação
nccl-test-latest.yaml
no GitHub. Esse manifesto faz o seguinte:- Implanta dois pods, cada um executado em um nó que tem GPUs H100.
- Implanta um contêiner de arquivo secundário chamado
tcpx-daemon
em cada pod para permitir que esses pods usem o GPUDirect-TCPX.
Implante 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
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á assim:
# 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
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 e GPUDirect-TCPXO Ao implantar cargas de trabalho que usam o NCCL, defina-as como variáveis de ambiente para otimizar o desempenho.
GPUDirect-TCPXO
## required
"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",
"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"
## recommended, to log NCCL errors
"NCCL_DEBUG=WARN",
"NCCL_DEBUG_SUBSYS=INIT,NET,ENV,COLL,GRAPH"
Também é possível definir todas as configurações de uma vez seguindo estas etapas:
Adicione o seguinte par de chave-valor como uma variável de ambiente no manifesto do contêiner da carga de trabalho:
NCCL_LIB_DIR="/usr/local/nvidia/lib64"
Confira se o script
nccl-env-profile.sh
é executado quando o contêiner de carga de trabalho é iniciado. Por exemplo, você pode fazer isso na especificação do pod, substituindo o comando do contêiner para incluir o seguinte:source ${NCCL_LIB_DIR}/nccl-env-profile.sh
GPUDirect-TCPX
## required
"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"
"NCCL_NVLS_ENABLE=0"
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.
GPUDirect-TCPXO
Adicione as seguintes anotações aos metadados do pod. Sem essas anotações,
hostNetwork:true
será necessário para o pod, eprivileged:true
será necessário para o contêinertcpxo-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"} ]
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
Adicione o contêiner a seguir ao manifesto para executar o serviço
tcpxo-daemon
. Substitua (TCPXO_DAEMON_IMAGE
) pela imagem mais recenteus-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.11
:- 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 - name: sys mountPath: /hostsysfs - name: proc-sys mountPath: /hostprocsysfs env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
Adicione a seguinte variável de ambiente a cada contêiner de GPU:
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64 - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY value: /dev/aperture_devices
Adicione as seguintes volumeMounts a cada contêiner de GPU. Sem as configurações de
aperture_devices
, oprivileged:true
é necessário para contêineres de GPU:volumeMounts: - name: aperture-devices mountPath: /dev/aperture_devices
Adicione variáveis de ambiente para configurar as opções da NCCL. Para mais detalhes, consulte Usar as configurações recomendadas do NCCL para melhorar o desempenho.
Uma especificação de pod completa tem esta aparência:
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
- 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
Adicione as seguintes anotações aos metadados do pod. Sem essas anotações,
hostNetwork:true
será necessário para o pod, eprivileged:true
será necessário para o contêinertcpx-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"}, ]
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
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
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
Adicione a seguinte variável de ambiente a cada contêiner de GPU:
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
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 nesta página.
Uma especificação de pod completa tem esta aparência:
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
A seguir
- Saiba mais sobre as práticas recomendadas para redes do GKE.
- Saiba mais sobre a família de tecnologias Nvidia GPUDirect para movimentação e acesso de dados em GPUs Nvidia.
- Saiba mais sobre a disponibilidade atual da versão da GPU e como solicitar GPUs no GKE.