Massimizza la larghezza di banda della rete GPU con GPUDirect e networking multiplo


Questa pagina mostra come massimizzare la larghezza di banda e la velocità effettiva della rete per carichi di lavoro GPU ad alte prestazioni nei cluster Google Kubernetes Engine (GKE) in modalità Standard. Questa pagina è rivolta agli ingegneri di machine learning (ML) e agli amministratori di piattaforma che facilitano i carichi di lavoro ML. Dovresti già avere familiarità con le tecnologie di networking come le schede di interfaccia di rete (NIC) e TCP, nonché con tecnologie di acceleratore come la NVIDIA Collective Communications Library (NCCL).

Le applicazioni di intelligenza artificiale (AI), ML e computing ad alte prestazioni (HPC) richiedono una potente accelerazione per ottimizzare le prestazioni riducendo i tempi di completamento dei job. Ad esempio, i modelli ML incentrati sull'AI conversazionale e sulla generazione di immagini richiedono un'elevata scalabilità e potenza di calcolo.

Informazioni sui supercomputer GPU Google Cloud

Google Cloud dispone di supercomputer ottimizzati per l'acceleratore, creati per modelli scalabili e di grandi dimensioni. Queste macchine offrono i seguenti vantaggi:

  • Otto GPU NVIDIA H100 per macchina.
  • Larghezza di banda fino a 200 Gbit/s sul NIC principale.
  • NIC secondarie (fino a otto sui tipi di macchina A3 Mega e fino a quattro sui tipi di macchina standard A3), ciascuna che supporta una larghezza di banda fino a 200 Gbps per il trasferimento di dati GPU.

Per un elenco completo dei vantaggi, consulta Serie di macchine A3 nella documentazione di Compute Engine.

Il carico di lavoro GKE deve utilizzare tutte le GPU disponibili e tutte le NIC secondarie disponibili su un singolo nodo e utilizzare una parte significativa della larghezza di banda disponibile. La soluzione descritta in questo documento è ideale per carichi di lavoro che richiedono prestazioni elevate, velocità effettiva elevata e bassa latenza.

Funzionalità e caratteristiche richieste per massimizzare la larghezza di banda

Per massimizzare la larghezza di banda della rete nei nodi dei supercomputer GPU, utilizza tutte le seguenti funzionalità:

  • Stack di rete GPUDirect: la serie di macchine A3 supporta due stack di rete per l'accesso RDMA personalizzato e remoto):
    • Sui tipi di macchina standard A3, utilizza GPUDirect-TCPX per ridurre l'overhead necessario per trasferire i payload dei pacchetti da e verso le GPU, il che migliora notevolmente la velocità effettiva su larga scala rispetto alle GPU che non utilizzano GPUDirect.
    • Sui tipi di macchine A3 Mega, utilizza GPUDirect-TCPXO, che migliora ulteriormente la comunicazione tra GPU e VM.
  • gVNIC attiva le funzionalità GPUDirect come la suddivisione delle intestazioni dei pacchetti, il flow steering e la gestione del buffer. gVNIC è necessario per utilizzare GPUDirect-TCPX o GPUDirect-TCPXO. Per maggiori dettagli su gVNIC, consulta Aumentare la velocità del traffico di rete per i nodi GPU.
  • Networking multiplo: aggiungi NIC secondarie alla macchina ottimizzata per l'acceleratore. Ogni NIC è associato a una subnet separata nel proprio VPC per evitare conflitti. Per maggiori dettagli sul supporto di più reti, consulta Configurare il supporto di più reti per i pod.
  • Criteri di posizionamento: utilizza un criterio di posizionamento delle risorse per posizionare tutti i nodi GPU per un carico di lavoro specifico su server fisicamente chiusi per ridurre al minimo la latenza. Per maggiori dettagli, consulta Definire il posizionamento compatto per i nodi GKE.

Struttura della procedura

Per utilizzare tutte queste funzionalità insieme, procedi nel seguente modo:

  1. Crea Virtual Private Cloud (VPC) e subnet
  2. Crea l'ambiente GKE:
    1. Crea un cluster con più reti abilitate
    2. Crea un pool di nodi con le seguenti caratteristiche:
      1. gVNIC attivato
      2. Subnet di networking multiplo specificate per ogni NIC secondario
      3. Serie di macchine A3 con GPU H100 a supporto dei nodi
      4. I driver NVIDIA più recenti installati
  3. Installa il programma binario GPUDirect e il plug-in NCCL
  4. Esegui il deployment di un carico di lavoro di test per verificare la configurazione di GPUDirect

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e initialize gcloud CLI. Se hai già installato gcloud CLI, scarica la versione più recente eseguendo gcloud components update.
  • Assicurati di disporre di una quota sufficiente per le GPU H100. Per richiedere un aumento della quota, consulta la pagina Quote delle GPU.

Requisiti

Se non diversamente indicato, i seguenti requisiti sono applicabili a GPUDirect-TCPX e GPUDirect-TCPXO.

  • GPUDirect-TCPX è supportato su GKE versione 1.27 o successive e richiede:
    • Tipo di macchina standard A3 (ad esempio a3-highgpu-8g).
    • Per GKE versione 1.27, utilizza la patch GKE 1.27.7-gke.1121000 o successive.
    • Per GKE versione 1.28, utilizza la patch GKE 1.28.8-gke.1095000 o successive.
    • Per GKE versione 1.29, utilizza la patch GKE 1.29.3-gke.1093000 o successive.
  • GPUDirect-TCPXO è supportato su GKE versione 1.28 o successive e richiede:
    • Tipo di macchina A3 Mega (ad esempio, a3-megagpu-8g).
    • Per GKE versione 1.28, utilizza la patch GKE 1.28.9-gke.1250000 o successive.
    • Per GKE versione 1.29, utilizza la patch GKE 1.29.4-gke.1542000 o successive.
  • I nodi GPU devono utilizzare il driver NVIDIA versione 535 o successiva.
  • Devi utilizzare GKE Dataplane V2.
  • Il nodo GKE deve utilizzare un'immagine del nodo Container-Optimized OS (COS). Le immagini dei nodi Ubuntu e Windows non sono supportate.

Limitazioni

Si applicano le seguenti limitazioni:

Crea VPC e subnet

Crea reti VPC separate nel progetto per ogni NIC virtuale che aggiungerai ai nodi. Ogni rete VPC deve avere una subnet e una regola firewall che consenta il traffico di rete interno.

  1. Crea le reti VPC per GPUDirect nel progetto, ognuna con una subnet e una regola firewall. Scegli la scheda GPUDirect-TCPX per i tipi di macchina standard A3 o GPUDirect-TCPXO per i tipi di macchine A3 Mega, quindi completa le seguenti istruzioni:

    GPUDirect-TCPX

    Per ottimizzare la larghezza di banda, consigliamo di creare quattro nuove reti.

    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
    

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo ID progetto Google Cloud.
    • REGION: la regione di Compute Engine per ogni subnet.
    • SUBNET_RANGE: l'intervallo di indirizzi IP di ogni subnet in notazione CIDR. Questo comando di esempio viene ripetuto per quattro subnet, quindi devi utilizzare una variabile per modificare l'indirizzo IP di ogni subnet. Ad esempio, specifica 192.168.$N.0/24 in modo che la prima subnet utilizzi 192.168.1.0/24, la seconda subnet utilizzi 192.168.2.0/24 e così via.
    • SOURCE_RANGE: l'intervallo di indirizzi IP di origine in notazione CIDR per consentire alla regola firewall di consentire il traffico in entrata. Ad esempio, 192.168.0.0/16.

    GPUDirect-TCPXO

    Per ottimizzare la larghezza di banda, è consigliabile creare otto nuove reti.

    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
    

    Sostituisci quanto segue:

    • PROJECT_ID: il tuo ID progetto Google Cloud.
    • REGION: la regione di Compute Engine per ogni subnet.
    • SUBNET_RANGE: l'intervallo di indirizzi IP di ogni subnet in notazione CIDR. Questo comando di esempio viene ripetuto per otto subnet, quindi devi utilizzare una variabile per modificare l'indirizzo IP di ogni subnet. Ad esempio, specifica 192.168.$N.0/24 in modo che la prima subnet utilizzi 192.168.1.0/24, la seconda subnet utilizzi 192.168.2.0/24 e così via.
    • SOURCE_RANGE: l'intervallo di indirizzi IP di origine in notazione CIDR per consentire alla regola firewall di consentire il traffico in entrata. Ad esempio, 192.168.0.0/16.
  2. Verifica che le reti siano state create:

    gcloud compute networks list
    

Crea l'ambiente GKE

Crea un nuovo cluster GKE che utilizza il networking multiplo (anteprima) e crea un pool di nodi GPU che utilizzi macchine A3 con GPU H100 e NIC aggiuntive. Non puoi aggiornare un cluster esistente per utilizzare il networking multiplo.

GPUDirect-TCPX

  1. Crea un cluster Standard:

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

    Sostituisci quanto segue:

    • CLUSTER_NAME: il nome del nuovo cluster.
    • LOCATION: la regione di Compute Engine per il cluster
    • VERSION: la versione di GKE per il cluster. Utilizza una versione supportata come descritto nella sezione Requisiti.
  2. Crea nel cluster risorse di rete e GKENetworkParamSet corrispondenti alle reti e alle subnet VPC che hai creato:

    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
    

    Queste risorse indicano a GKE di configurare le NIC per il traffico della GPU in modalità passthrough. GKE non applica a questo traffico la programmazione di networking integrata tramite eBPF.

  3. Crea un pool di nodi per le GPU 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
    

    Sostituisci NODE_POOL_NAME con il nome del pool di nodi.

    Se questo comando non riesce, la quota GPU H100 potrebbe non essere sufficiente nel progetto. Assicurati di avere una quota sufficiente e riprova a eseguire il comando.

  4. Recupera un elenco di nodi nel cluster:

    kubectl get nodes
    
  5. Verifica che ogni nodo GPU abbia otto GPU:

    kubectl describe node NODE_NAME
    

    L'output è simile al seguente:

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

GPUDirect-TCPXO

  1. Scegli una versione GKE disponibile che supporti GPUDirect-TCPXO. Per elencare le versioni, esegui questo comando:

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

    Sostituisci quanto segue:

    • ZONE: la zona di computing per il piano di controllo del cluster.
    • PROJECT_ID: il tuo ID progetto Google Cloud.
  2. Crea un 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
    

    Sostituisci quanto segue:

    • CLUSTER_NAME: il nome del nuovo cluster.
    • VERSION: una versione di GKE che supporta GPUDirect-TCPXO, come descritto in Requisiti.
    • REGION: la regione di Compute Engine per il cluster.
    • ZONE: la zona di computing per il cluster.
  3. Crea nel cluster risorse di rete e GKENetworkParamSet corrispondenti alle reti e alle subnet VPC che hai creato:

    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
    

    Queste risorse indicano a GKE di configurare le NIC per il traffico della GPU in modalità passthrough. GKE non applica a questo traffico la programmazione di networking integrata tramite eBPF.

  4. Crea un pool di nodi per le GPU 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 "http://www.googleapis.com/auth/cloud-platform" \
        [--placement-policy=POLICY_NAME \
        --reservation-affinity=specific \
        --reservation=RESERVATION_NAME \
        --host-maintenance-interval=PERIODIC]
    

    Sostituisci NODE_POOL_NAME con il nome del tuo pool di nodi.

    Nell'esempio, l'argomento --scopes "http://www.googleapis.com/auth/cloud-platform" imposta l'ambito dell'istanza del nodo su cloud-platform per facilitare i test. Per la produzione, è consigliabile limitare l'ambito per configurare credenziali più granulari.

    Utilizza i flag --placement-policy, --reservation-affinity e --reservation se usi una prenotazione. Specifica questi flag per configurare il nome e la prenotazione del criterio nel pool di nodi.

    Se questo comando non riesce, la quota GPU H100 potrebbe non essere sufficiente nel progetto. Assicurati di disporre di una quota sufficiente e riprova a eseguire il comando.

  5. Recupera un elenco di nodi nel cluster:

    kubectl get nodes
    
  6. Verifica che ogni nodo GPU abbia otto GPU:

    kubectl describe node NODE_NAME
    

    L'output è simile al seguente:

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

Installa il programma binario GPUDirect e configura l'NCCL

Questa sezione mostra come installare il programma binario GPUDirect in base al tipo di macchina A3 (GPUDirect-TCPX per lo standard A3, GPUDirect-TCPXO per A3 Mega) e a una versione specifica della libreria NCCL utilizzando un DaemonSet.

GPUDirect-TCPX

  1. Esamina il manifest del 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.go888ogle.com.fqhub.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: "gke.gcr.io/pause:3.8@sha256:880e63f94b145e46f1b1082bb71b85e21f16b99b180b9996407d61240ceb9830"
              name: pause
    

    Questo DaemonSet svolge le seguenti operazioni:

    1. Installa la libreria NCCL e il programma binario GPUDirect-TCPX sul nodo.
    2. Archivia la libreria e il programma binario nella directory /home/kubernetes/bin/nvidia/lib64 sulla VM. Per impostazione predefinita, GKE monta questa directory nel percorso /usr/local/nvidia/lib64 nei container GPU che devono utilizzare NCCL e GPUDirect-TCPX.
  2. Esegui il deployment del DaemonSet:

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

    L'esecuzione del plug-in NCCL richiede circa due minuti.

  3. Verifica lo stato dei pod DaemonSet:

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

    L'output è simile al seguente:

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

GPUDirect-TCPXO

  1. Esamina il manifest del DaemonSet:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: nccl-tcpxo-installer
      namespace: kube-system
      labels:
        k8s-app: nccl-tcpxo-installer
    spec:
      selector:
        matchLabels:
          k8s-app: nccl-tcpxo-installer
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            name: nccl-tcpxo-installer
            k8s-app: nccl-tcpxo-installer
        spec:
          priorityClassName: system-node-critical
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                  - matchExpressions:
                      - key: cloud.go888ogle.com.fqhub.com/gke-accelerator
                        operator: In
                        values:
                          - nvidia-h100-mega-80gb
          tolerations:
            - operator: "Exists"
          hostNetwork: true
          hostPID: true
          volumes:
            - name: var-lib
              hostPath:
                path: /var/lib
            - name: tcpxo
              hostPath:
                path: /var/lib/tcpxo
            - name: library-dir-host
              hostPath:
                path: /home/kubernetes/bin
          initContainers:
            - image: "ubuntu"
              name: pre-installation
              securityContext:
                privileged: true
              command:
                - nsenter
                - -at
                - '1'
                - --
                - sh
                - -c
                - |
                  /sbin/iptables -I INPUT -p tcp -m tcp -j ACCEPT && modprobe import-helper
                  sudo mkdir -p /dev/aperture_devices
                  while IFS= read -r line; do
                    BDF=$( echo "$line" | awk '{print $1}' );
                    target_aperture_path="/dev/aperture_devices/$BDF"
                    host_aperture_device=$(readlink -f "/sys/bus/pci/devices/$BDF");
                    sudo mkdir -p $target_aperture_path;
                    sudo umount -R $target_aperture_path;
                    sudo mount --bind $host_aperture_device $target_aperture_path;
                  done < <(lspci -nn -D | grep '1ae0:0084')
                  if [ -d /dev/aperture_devices ]; then
                      chmod -R a+r /dev/aperture_devices/
                      chmod a+rw /dev/aperture_devices/*/resource*
                  fi
            - name: nccl-tcpxo-installer
              image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/nccl-plugin-gpudirecttcpx-dev:v1.0.2
              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
                  chmod 755 /scripts/container_entry.sh
                  /scripts/container_entry.sh install --install-nccl
                  mkdir -p /usr/local/nvidia/lib64
                  cp -r /var/lib/tcpxo/lib64/. /usr/local/nvidia/lib64
                  echo "installation finishes"
          containers:
            - image: "gke.gcr.io/pause:3.8@sha256:880e63f94b145e46f1b1082bb71b85e21f16b99b180b9996407d61240ceb9830"
              name: pause
    

    Questo DaemonSet svolge le seguenti operazioni:

    1. Installa la libreria NCCL e il programma binario GPUDirect-TCPXO sul nodo.
    2. Archivia la libreria e il programma binario nella directory /home/kubernetes/bin/nvidia/lib64 sulla VM. Per impostazione predefinita, GKE monta questa directory nel percorso /usr/local/nvidia/lib64 nei container GPU che devono utilizzare NCCL e GPUDirect-TCPXO.
  2. Esegui il deployment del DaemonSet:

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

    L'esecuzione del plug-in NCCL richiede circa due minuti.

  3. Verifica lo stato dei pod DaemonSet:

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

    L'output è simile al seguente:

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

Esegui il deployment di un carico di lavoro di test

In questa sezione, eseguirai il deployment di un carico di lavoro di esempio per verificare che NCCL e GPUDirect-TCPX o GPUDirect-TCPXO funzionino come previsto.

GPUDirect-TCPX

Questo carico di lavoro include un container collaterale denominato tcpx-daemon, che esegue un servizio che consente al pod di utilizzare GPUDirect-TCPX. Devi aggiungere questo container collaterale a tutti i pod nel tuo ambiente che devono utilizzare GPUDirect-TCPX. Per uno snippet dei campi richiesti da aggiungere ai manifest, consulta Aggiungere GPUDirect al manifest.

  1. Esamina il manifest di ConfigMap di nccl-config.yaml in GitHub. Questo manifest esegue il deployment di script che inizializzano un test della totalità di NCCL e imposta le impostazioni di configurazione specifiche per NCCL.
  2. Esamina il manifest del deployment di nccl-test.yaml in GitHub. Il file manifest svolge le seguenti operazioni:

    1. Esegue il deployment di due pod, ognuno dei quali viene eseguito in un nodo con GPU H100.
    2. Esegue il deployment di un container collaterale denominato tcpx-daemon in ogni pod per consentire a questi pod di utilizzare GPUDirect-TCPX.
  3. Esegui il deployment dell'oggetto ConfigMap e del carico di lavoro di test:

    kubectl apply -f http://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-config.yaml
    kubectl apply -f http://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-test.yaml
    
  4. Esegui questi comandi per attivare un test completo dell'NCCL per i nodi:

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

    L'output è simile al seguente:

    #                                                              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
    

GPUDirect-TCPXO

Questo carico di lavoro include un container collaterale denominato tcpxo-daemon, che esegue un servizio che consente al pod di utilizzare GPUDirect-TCPXO. Devi aggiungere questo container collaterale a tutti i pod nel tuo ambiente che devono utilizzare GPUDirect-TCPXO. Per uno snippet dei campi richiesti da aggiungere ai manifest, consulta Aggiungere GPUDirect al manifest.

  1. Esamina il manifest di nccl-test.yaml in GitHub. Il file manifest svolge le seguenti operazioni:

    1. Esegue il deployment di due pod, ognuno dei quali viene eseguito in un nodo con GPU H100.
    2. Esegue il deployment di un container collaterale denominato tcpxo-daemon in ogni pod per consentire a questi pod di utilizzare GPUDirect-TCPXO.
  2. Esegui il deployment dell'oggetto ConfigMap e del carico di lavoro di test:

    kubectl apply -f http://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test.yaml
    
  3. Esegui il deployment di due pod con il carico di lavoro di test:

    kubectl apply -f http://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test.yaml
    
  4. Esegui i comandi seguenti per attivare un test completo dell'NCCL per i due nodi:

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

    L'output è simile al seguente:

    #                                                              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
    

Utilizza le impostazioni di configurazione NCCL consigliate per migliorare le prestazioni

Le seguenti coppie chiave-valore sono le impostazioni di configurazione NCCL consigliate per GPUDirect-TCPX e GPUDirect-TCPXO. Quando esegui il deployment dei carichi di lavoro che utilizzano NCCL, impostali come variabili di ambiente per ottimizzare le prestazioni.

GPUDirect-TCPX

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

GPUDirect-TCPXO

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

Aggiungere GPUDirect ai tuoi manifest

Questa sezione fornisce i campi obbligatori che devi aggiungere ai file manifest Kubernetes affinché i tuoi pod possano utilizzare GPUDirect.

GPUDirect-TCPX

  1. Aggiungi i seguenti campi alla specifica del pod:

    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
      - name: tcpx-socket
        hostPath:
          path: /run/tcpx
    
  2. Aggiungi il container seguente al manifest per eseguire il servizio 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. Aggiungi i seguenti montaggi di volumi a tutti i container che richiedono GPU:

    volumeMounts:
    - name: tcpx-socket
      mountPath: /tmp
    - name: libraries
      mountPath: /usr/local/nvidia/lib64
    
  4. Aggiungi la seguente variabile di ambiente a ogni container GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    
  5. Aggiungi variabili di ambiente per configurare le opzioni NCCL. Per maggiori dettagli, consulta la sezione Utilizzare le impostazioni di configurazione NCCL consigliate per migliorare le prestazioni in questo documento.

Una specifica di pod completa è simile alla seguente:

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

GPUDirect-TCPXO

  1. Aggiungi i seguenti campi alla specifica del pod:

    spec:
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
      volumes:
      - name: libraries
        hostPath:
          path: /home/kubernetes/bin/nvidia/lib64
    
  2. Aggiungi il container seguente al manifest per eseguire il servizio tcpxo-daemon:

    - name: tcpxo-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.3
      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:
        privileged: true
      volumeMounts:
        - name: nvidia-install-dir-host
          mountPath: /usr/local/nvidia
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    
  3. Aggiungi la seguente variabile di ambiente a ogni container GPU:

    env:
    - name: LD_LIBRARY_PATH
      value: /usr/local/nvidia/lib64
    
  4. Aggiungi privilegid:true a ogni container GPU:

    securityContext:
      privileged: true
    
  5. Aggiungi variabili di ambiente per configurare le opzioni NCCL. Per maggiori dettagli, consulta l'articolo Utilizzare le impostazioni di configurazione dell'NCCL consigliate per migliorare le prestazioni.

Una specifica di pod completa è simile alla seguente:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  labels:
    name: example-pod
spec:
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
  containers:
    - name: tcpxo-daemon
      image: us-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.3
      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:
        privileged: true
      volumeMounts:
        - name: nvidia-install-dir-host
          mountPath: /usr/local/nvidia
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
    - name: example-container
      image: example-image
      imagePullPolicy: Always
    ...
      env:
        - name: LD_LIBRARY_PATH
          value: /usr/local/nvidia/lib64
      securityContext:
        privileged: true
      volumeMounts:
        - name: nvidia-install-dir-host
          mountPath: /usr/local/nvidia
      resources:
        limits:
          nvidia.com/gpu: 8
  volumes:
    - name: nvidia-install-dir-host
      hostPath:
        path: /home/kubernetes/bin/nvidia

Passaggi successivi