Maximize a largura de banda da rede GPU com o GPUDirect-TCPX e o recurso de várias redes


Nesta página, mostramos como maximizar a largura de banda e a capacidade de processamento para cargas de trabalho da GPU de alto desempenho nos clusters do Google Kubernetes Engine (GKE) no modo Standard. Esta página é destinada a engenheiros de machine learning (ML) e administradores de plataforma que facilitam cargas de trabalho de ML. Você já deve conhecer as tecnologias de rede, como placas de rede (NICs) e TCP, e com tecnologias de aceleradores, como a NVIDIA Collective Communications Library (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.
  • Até quatro NICs secundárias, 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 neste documento é 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:

  • GPUDirect-TCPX: reduz 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 GPUDirect-TCPX.
  • gVNIC: ativa os recursos do GPUDirect-TCPX, como divisão de cabeçalho de pacote, direcionamento de fluxo e gerenciamento de buffer. A gVNIC é necessária para usar o GPUDirect-TCPX. Para detalhes sobre a gVNIC, consulte Aumentar a velocidade do tráfego de rede para nós da GPU.
  • Várias redes: adicione NICs secundárias à máquina otimizada para aceleradores. Para máquinas A3, mais quatro NICs são adicionadas. 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:

  1. Crie nuvens privadas virtuais (VPC) e sub-redes
  2. Crie o ambiente do GKE:
    1. Crie um cluster com várias redes ativado
    2. Crie um pool de nós com estas características:
      1. gVNIC ativada
      2. Sub-redes de várias redes especificadas para cada placa de rede (NIC) secundária
      3. Série de máquinas A3 com GPUs H100 (quatro NICs secundárias e oito GPUs) que oferecem suporte aos nós
      4. Drivers da NVIDIA instalados mais recentes
  3. Instale o binário GPUDirect-TCPX e o plug-in NCCL.
  4. Implante uma carga de trabalho de teste para verificar a configuração do GPUDirect-TCPX

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

  • O GPUDirect-TCPX é compatível com o GKE versão 1.27 ou mais recente e requer:
    • 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.
  • Os nós da GPU precisam usar o driver da NVIDIA versão 535 ou mais recente.
  • É preciso usar o GKE Dataplane V2.

Limitações

Considere as seguintes limitações:

  • Não é possível usar o GPUDirect-TCPX em clusters do Autopilot
  • Só é possível usar o GPUDirect-TCPX na versão 1.27 ou posterior do GKE e com as seguintes versões de patch:
    • 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.
  • Não é possível usar o GPUDirect-TCPX com GPUs de várias instâncias ou compartilhamento de tempo de GPU.
  • Não é possível usar o NCCL FastSocket
  • Seu ambiente precisa ser compatível com a configuração hostNetwork: true na especificação do pod
  • Se quiser usar SSDs locais para armazenamento de pods, especifique explicitamente o número exato de SSDs locais que serão anexados à VM do A3 usando a sinalização --ephemeral-storage-local-ssd=count=SSD_COUNT para armazenamento temporário ou o sinalização --local-nvme-ssd-block=count=SSD_COUNT para bloquear o acesso. Se você omitir essa sinalização, não será possível usar os SSDs locais nos pods. Essas sinalizações serão necessárias apenas se você quiser usar o SSD local para acesso aos dados.

    O tamanho de máquina compatível no GKE é a3-highgpu-8g, e a contagem de SSD local correspondente é 16.

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 VPC precisa ter uma sub-rede e uma regra de firewall que permita o tráfego de rede interno. Para maximizar a largura de banda, recomendamos que você crie quatro novas redes.

  1. Atualize a sub-rede VPC padrão no projeto para adicionar intervalos de endereços IP secundários para pods e serviços:

    gcloud compute networks subnets update DEFAULT_NETWORK \
        --region=REGION \
        --add-secondary-ranges="CLUSTER_NAME-pods=POD_IP_ADDRESS_RANGE,CLUSTER_NAME-services=SERVICE_IP_ADDRESS_RANGE"
    

    Substitua:

    • DEFAULT_NETWORK: o nome da sub-rede padrão no projeto.
    • REGION: a região da sub-rede padrão.
    • CLUSTER_NAME: o nome do cluster do GKE.
    • POD_IP_ADDRESS_RANGE: o intervalo de endereços IP para os pods no cluster, na notação CIDR. Por exemplo, 10.64.0.0/19.
    • SERVICE_IP_ADDRESS_RANGE: o intervalo de endereços IP para os serviços no cluster usar, na notação CIDR. Precisa ser diferente do intervalo de pods. Por exemplo, 10.65.0.0/19.
  2. Crie as redes VPC para GPUDirect-TCPX no projeto, cada uma com uma sub-rede e uma regra de firewall:

    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, especifique 192.168.$N.0/24 para que a primeira sub-rede use 192.168.1.0/24, a segunda use 192.168.2.0/24 etc.
    • SOURCE_RANGE: o intervalo de endereços IP de origem para que a regra de firewall permita o tráfego de entrada, na notação CIDR. Por exemplo, 192.168.0.0/16.
  3. 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 anexadas e quatro NICs adicionais. Não é possível atualizar um cluster atual para usar várias redes.

  1. Crie um cluster:

    gcloud container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=VERSION \
        --enable-dataplane-v2 --enable-ip-alias \
        --enable-multi-networking \
        --no-enable-autoupgrade \
        --cluster-secondary-range-name=CLUSTER_NAME-pods \
        --services-secondary-range-name=CLUSTER_NAME-services
    

    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. Precisa ser uma versão compatível, conforme descrito na seção "Requisitos".

    Esse comando também especifica explicitamente o endereço IP secundário para pods e serviços para o cluster que você criou na seção anterior.

  2. Crie recursos de rede e GKENetworkParamSet no cluster que correspondem às redes e sub-redes VPC que você criou:

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc1
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc1
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc2
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc2
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc3
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc3
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: vpc4
    spec:
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: vpc4
      type: Device
    ---
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: vpc1
    spec:
      vpc: 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.

  3. 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 \
        [--ephemeral-storage-local-ssd=count=16]
    

    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.

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

    kubectl get nodes
    
  5. 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 GPUDirect-TCPX e configurar o NCCL

Esta seção mostra como instalar o binário GPUDirect-TCPX e um NCCL específico usando um DaemonSet.

  1. Revise o manifesto de DaemonSet:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nccl-tcpx-installer
      namespace: kube-system
      labels:
        k8s-app: nccl-tcpx-installer
    spec:
      selector:
        matchLabels:
          k8s-app: nccl-tcpx-installer
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            name: nccl-tcpx-installer
            k8s-app: nccl-tcpx-installer
        spec:
          priorityClassName: system-node-critical
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: cloud.google.com/gke-accelerator
                        operator: In
                        values:
                          - nvidia-h100-80gb
          tolerations:
            - operator: "Exists"
          hostNetwork: true
          hostPID: true
          volumes:
            - name: var-lib
              hostPath:
                path: /var/lib
            - name: tcpx
              hostPath:
                path: /var/lib/tcpx
            - name: library-dir-host
              hostPath:
                path: /home/kubernetes/bin
          initContainers:
            - image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/nccl-plugin-gpudirecttcpx-dev:v3.1.9
              name: nccl-tcpx-installer
              resources:
                requests:
                  cpu: 150m
              securityContext:
                privileged: true
              volumeMounts:
                - name: var-lib
                  mountPath: /var/lib
                - name: library-dir-host
                  mountPath: /usr/local
              command: ["/bin/sh", "-c"]
              args:
                - |
                  set -ex
                  /scripts/container_entry.sh install --install-nccl
                  mkdir -p /usr/local/nvidia/lib64
                  cp -r /var/lib/tcpx/lib64/. /usr/local/nvidia/lib64
                  echo "installation finishes"
          containers:
            - image: "gcr.io/google-containers/pause:2.0"
              name: pause
    

    Esse DaemonSet faz o seguinte:

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

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

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

  3. Verifique o status dos pods do DaemonSet:

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

    O resultado será assim:

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

Implantar uma carga de trabalho de teste

Nesta seção, você vai implantar uma carga de trabalho de amostra para verificar se o NCCL e o GPUDirect-TCPX funcionam conforme o esperado. 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 ver um snippet dos campos obrigatórios a serem adicionados aos manifestos, consulte Adicionar GPUDirect-TCPX ao manifesto neste documento.

  1. Revise o manifesto ConfigMap nccl-config-default.yaml no GitHub. Esse manifesto implanta scripts que inicializam um teste NCCL allgather e define variáveis de ambiente específicas do NCCL.
  2. Revise o manifesto nccl-test.yaml no GitHub. Esse manifesto faz o seguinte:

    1. Implanta dois pods, cada um executado em um nó que tem GPUs H100.
    2. Implanta um contêiner de arquivo secundário chamado tcpx-daemon em cada pod para permitir que esses pods usem o GPUDirect-TCPX.
  3. 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-default.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test.yaml
    
  4. Execute os seguintes comandos para acionar um teste de todos os nós do NCCL:

    head_pod=$(kubectl get pods --output='custom-columns=POD:.metadata.name' --no-headers | head -n1)
    
    nodes=($(kubectl get pods --output='custom-columns=NODE:.spec.nodeName' --no-headers))
    
    kubectl exec --stdin --tty --container=nccl-test ${head_pod} -- /configs/allgather.sh ${nodes[@]}
    

    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 variáveis de ambiente do NCCL para melhorar o desempenho

Também é possível definir variáveis de ambiente específicas para melhorar o desempenho das cargas de trabalho que usam NCCL. O ConfigMap nccl-config-default.yaml que você implanta na seção Implantar uma carga de trabalho de teste define algumas variáveis do NCCL por padrão. A configuração da variável é armazenada no script run-nccl.sh no ConfigMap.

Para alterar as variáveis de ambiente do NCCL, implante um manifesto ConfigMap atualizado com variáveis modificadas. O manifesto nccl-config-latest.yaml no GitHub contém todas as variáveis recomendadas com um script run-nccl.sh atualizado.

O comando a seguir atualiza o ConfigMap atual que tem as variáveis padrão com o ConfigMap nccl-config-latest.yaml atualizado:

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

O Kubernetes leva aproximadamente dois minutos para atualizar o ConfigMap.

Para verificar as variáveis de ambiente do NCCL, execute o seguinte comando:

head_pod=$(kubectl get pods --output='custom-columns=POD:.metadata.name' --no-headers | head -n1)

kubectl exec --stdin --tty --container=nccl-test ${head_pod} -- cat /configs/run-nccl.sh

Adicionar GPUDirect-TCPX aos seus manifestos

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

  1. Adicione os seguintes campos à especificação do pod:

    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: tcpx-socket
        hostPath:
          path: /run/tcpx
    
  2. 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:
        privileged: true
      volumeMounts:
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
        - name: tcpx-socket
          mountPath: /run/tcpx
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  3. 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
    
  4. Adicione a seguinte variável de ambiente a cada contêiner de GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    
  5. Como opção, adicione variáveis de ambiente para configurar as opções da NCCL. Para mais detalhes, consulte a seção Usar variáveis de ambiente do NCCL para melhorar o desempenho deste documento.

Uma especificação de pod completa tem esta aparência:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  labels:
    name: example-pod
spec:
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
  containers:
  - 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:
      privileged: true
    volumeMounts:
      - name: libraries
        mountPath: /usr/local/nvidia/lib64
      - name: tcpx-socket
        mountPath: /run/tcpx
    env:
      - name: LD_LIBRARY_PATH
        value: /usr/local/nvidia/lib64
    - name: nccl-test
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpx/nccl-plugin-gpudirecttcpx:v3.1.2
      imagePullPolicy: Always
      command:
        - /bin/sh
        - -c
        - "while true; do echo hello; sleep 1; done"
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
      volumeMounts:
        - name: tcpx-socket
          mountPath: /run/tcpx
        - name: libraries
          mountPath: /usr/local/nvidia/lib64
      resources:
        limits:
          nvidia.com/gpu: 8
  volumes:
    - name: libraries
      hostPath:
        path: /home/kubernetes/bin/nvidia/lib64
    - name: tcpx-socket
      hostPath:
        path: /run/tcpx