Auf dieser Seite wird beschrieben, wie Sie die Netzwerkbandbreite und den Durchsatz für leistungsstarke GPU-Arbeitslasten in GKE-Clustern (Google Kubernetes Engine) im Standardmodus maximieren. Diese Seite richtet sich an Entwickler von maschinellem Lernen (ML) und Plattformadministratoren, die ML-Arbeitslasten ermöglichen. Sie sollten mit Netzwerktechnologien wie Netzwerkkarten (NICs) und TCP sowie mit Beschleunigertechnologien wie der NVIDIA Collective Communications Library (NCCL) vertraut sein.
Anwendungen für künstliche Intelligenz (KI), ML und Hochleistungs-Computing (HPC) erfordern eine leistungsstarke Beschleunigung, um die Leistung durch Reduzierung der Durchlaufzeiten von Jobs zu optimieren. Beispielsweise erfordern ML-Modelle, die sich auf konversationelle KI und Bildgenerierung konzentrieren, hohe Skalierbarkeit und Rechenleistung.
Informationen zu Google Cloud GPU-Supercomputern
Google Cloud hat beschleunigungsoptimierte Supercomputer, die für skalierbare, umfangreiche Modelle entwickelt wurden. Diese Maschinen bieten folgende Vorteile:
- Acht NVIDIA H100-GPUs pro Maschine.
- Bis zu 200 Gbit/s Bandbreite auf der primären NIC.
- Bis zu vier sekundäre NICs, die jeweils bis zu 200 Gbit/s Bandbreite für die GPU-Datenübertragung unterstützen.
Eine vollständige Liste der Vorteile finden Sie in der Compute Engine-Dokumentation unter A3-Maschinenserie.
Ihre GKE-Arbeitslast muss alle verfügbaren GPUs und alle verfügbaren sekundären NICs auf einem einzelnen Knoten verwenden und einen erheblichen Teil der verfügbaren Bandbreite nutzen. Die in diesem Dokument beschriebene Lösung eignet sich ideal für Arbeitslasten, die eine hohe Leistung, einen hohen Durchsatz und eine niedrige Latenz erfordern.
Erforderliche Funktionen für maximale Bandbreite
Verwenden Sie alle der folgenden Features, um die Netzwerkbandbreite in GPU-Supercomputer-Knoten zu maximieren:
- GPUDirect-TCPX: Der Aufwand für die Übertragung von Paketnutzlasten an und von GPUs wird reduziert. Dadurch wird der Durchsatz in großem Maßstab im Vergleich zu GPUs, die GPUDirect-TCPX nicht verwenden, erheblich verbessert.
- gVNIC: Aktivieren Sie GPUDirect-TCPX-Funktionen wie Paketheader-Aufteilung, Ablaufsteuerung und Zwischenspeicherverwaltung. gVNIC ist erforderlich, um GPUDirect-TCPX zu verwenden. Weitere Informationen zu gVNIC finden Sie unter Netzwerkgeschwindigkeit für GPU-Knoten erhöhen.
- Multi-Netzwerk: Fügen Sie der beschleunigungsoptimierten Maschine sekundäre NICs hinzu. Für A3-Maschinen werden vier zusätzliche NICs hinzugefügt. Jede NIC ist einem separaten Subnetz in ihrer eigenen VPC zugeordnet, um Konflikte zu vermeiden. Weitere Informationen zur Unterstützung für mehrere Netzwerke finden Sie unter Unterstützung mehrerer Netzwerke für Pods einrichten.
- Platzierungsrichtlinien: Verwenden Sie eine Richtlinie für Ressourcenplatzierungen, um alle GPU-Knoten für eine bestimmte Arbeitslast auf physisch nahe Servern zu platzieren, um die Latenz zu minimieren. Weitere Informationen finden Sie unter Kompakte Platzierung für GKE-Knoten definieren.
Prozedurübersicht
So verwenden Sie alle diese Funktionen:
- Virtual Private Cloud (VPC) und Subnetze erstellen
- GKE-Umgebung erstellen:
- Cluster mit aktiviertem Multi-Netzwerk erstellen
- Erstellen Sie einen Knotenpool mit den folgenden Eigenschaften:
- gVNIC aktiviert
- Für jede sekundäre NIC angegebene Multi-Netzwerk-Subnetze
- A3-Maschinenserie mit H100-GPUs (vier sekundäre NICs und acht GPUs) zur Unterstützung der Knoten
- Neueste NVIDIA-Treiber installiert
- GPUDirect-TCPX-Binärdatei und NCCL-Plug-in installieren
- Testarbeitslast bereitstellen, um die GPUDirect-TCPX-Einrichtung zu prüfen
Hinweise
Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:
- Aktivieren Sie die Google Kubernetes Engine API. Google Kubernetes Engine API aktivieren
- Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit
gcloud components update
ab.
- Prüfen Sie, ob Ihr Kontingent für H100-GPUs ausreicht. Informationen zum Anfordern eines höheren Kontingents finden Sie unter GPU-Kontingente.
Voraussetzungen
- GPUDirect-TCPX wird in GKE Version 1.27 oder höher unterstützt und erfordert Folgendes:
- Verwenden Sie für die GKE-Version 1.27 die GKE-Patchversion 1.27.7-gke.1121000 oder höher.
- Verwenden Sie für die GKE-Version 1.28 die GKE-Patchversion 1.28.8-gke.1095000 oder höher.
- Verwenden Sie für die GKE-Version 1.29 die GKE-Patchversion 1.29.3-gke.1093000 oder höher.
- Ihre GPU-Knoten müssen die NVIDIA-Treiberversion 535 oder höher verwenden.
- Sie müssen GKE Dataplane V2 verwenden.
Beschränkungen
Es gelten folgende Einschränkungen:
- Sie können GPUDirect-TCPX nicht in Autopilot-Clustern verwenden
- Sie können GPUDirect-TCPX nur in GKE-Version 1.27 oder höher und mit den folgenden Patchversionen verwenden:
- Verwenden Sie für die GKE-Version 1.27 die GKE-Patchversion 1.27.7-gke.1121000 oder höher.
- Verwenden Sie für die GKE-Version 1.28 die GKE-Patchversion 1.28.8-gke.1095000 oder höher.
- Verwenden Sie für die GKE-Version 1.29 die GKE-Patchversion 1.29.3-gke.1093000 oder höher.
- Sie können GPUDirect-TCPX nicht mit GPUs mit mehreren Instanzen oder GPU-Timesharing verwenden.
- Sie können NCCL FastSocket nicht verwenden.
- Ihre Umgebung muss die Einstellung
hostNetwork: true
in der Pod-Spezifikation unterstützen.
VPCs und Subnetze erstellen
Erstellen Sie in Ihrem Projekt separate VPC-Netzwerke für jede virtuelle NIC, die Sie Ihren Knoten hinzufügen. Jede VPC muss ein Subnetz und eine Firewallregel haben, die internen Netzwerktraffic zulässt. Zum Maximieren der Bandbreite empfehlen wir, vier neue Netzwerke zu erstellen.
Erstellen Sie in Ihrem Projekt die VPC-Netzwerke für GPUDirect-TCPX mit jeweils einem Subnetz und einer Firewallregel:
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
Ersetzen Sie Folgendes:
PROJECT_ID
ist Ihre Google Cloud-Projekt-ID.REGION
: Die Compute Engine-Region für jedes Subnetz.SUBNET_RANGE
: der IP-Adressbereich jedes Subnetzes in CIDR-Notation. Dieser Beispielbefehl gilt für vier Subnetze. Verwenden Sie daher eine Variable, um die IP-Adresse für jedes Subnetz zu ändern. Geben Sie beispielsweise192.168.$N.0/24
an, damit das erste Subnetz192.168.1.0/24
, das zweite Subnetz192.168.2.0/24
usw. verwendet.SOURCE_RANGE
: Der Quell-IP-Adressbereich für die Firewallregel, der eingehenden Traffic in CIDR-Notation zulässt. Beispiel:192.168.0.0/16
Prüfen Sie, ob die Netzwerke erstellt wurden:
gcloud compute networks list
GKE-Umgebung erstellen
Erstellen Sie einen neuen GKE-Cluster, der Multi-Netzwerke (Vorschau) verwendet, und erstellen Sie einen GPU-Knotenpool, der A3-Maschinen mit angehängten H100-GPUs und vier zusätzlichen NICs verwendet. Sie können einen vorhandenen Cluster nicht aktualisieren, um Multi-Netzwerke zu verwenden.
Erstellen Sie einen Cluster.
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-dataplane-v2 --enable-ip-alias \ --enable-multi-networking \ --no-enable-autoupgrade \
Ersetzen Sie Folgendes:
CLUSTER_NAME
: Der Name des neuen Clusters.LOCATION
: die Compute Engine-Region für den Cluster.VERSION
: die GKE-Version für den Cluster. Es muss sich um eine unterstützte Version handeln, wie im Abschnitt Anforderungen beschrieben.
Mit diesem Befehl wird auch explizit die sekundäre IP-Adresse für Pods und Services für den Cluster angegeben, den Sie im vorherigen Abschnitt erstellt haben.
Erstellen Sie im Cluster Netzwerk- und GKENetworkParamSet-Ressourcen, die den von Ihnen erstellten VPC-Netzwerken und Subnetzwerken entsprechen:
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
Diese Ressourcen weisen GKE an, die NICs für den GPU-Traffic im Passthrough-Modus zu konfigurieren. GKE wendet keine integrierte Netzwerkprogrammierung mit eBPF auf diesen Traffic an.
Erstellen Sie einen Knotenpool für die H100-GPUs:
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 \
Ersetzen Sie
NODE_POOL_NAME
durch den Namen des Knotenpools.Wenn dieser Befehl fehlschlägt, ist möglicherweise nicht ein ausreichendes H100-GPU-Kontingent in Ihrem Projekt vorhanden. Prüfen Sie, ob Ihr Kontingent vorhanden ist, und wiederholen Sie den Befehl.
Rufen Sie eine Liste der Knoten im Cluster ab:
kubectl get nodes
Prüfen Sie, ob jeder GPU-Knoten acht GPUs hat:
kubectl describe node NODE_NAME
Die Ausgabe sieht in etwa so aus:
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
GPUDirect-TCPX installieren und NCCL konfigurieren
In diesem Abschnitt erfahren Sie, wie Sie die GPUDirect-TCPX-Binärdatei und eine bestimmte NCCL mit einem DaemonSet installieren.
Prüfen Sie das DaemonSet-Manifest:
Dieses DaemonSet tut Folgendes:
- Installiert eine NCCL-Bibliothek und die GPUDirect-TCPX-Binärdatei auf dem Knoten.
- Speichert die Bibliothek und die Binärdatei im Verzeichnis
/home/kubernetes/bin/nvidia/lib64
auf der VM. Standardmäßig stellt GKE dieses Verzeichnis im Pfad/usr/local/nvidia/lib64
in GPU-Containern bereit, die NCCL und GPUDirect-TCPX verwenden müssen.
Stellen Sie das DaemonSet bereit:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
Die Ausführung des NCCL-Plug-ins dauert ungefähr zwei Minuten.
Prüfen Sie den Status der DaemonSet-Pods:
kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
Die Ausgabe sieht in etwa so aus:
nccl-tcpx-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpx-installer-qgg82 1/1 Running 0 2m11s
Testarbeitslast bereitstellen
In diesem Abschnitt stellen Sie eine Beispielarbeitslast bereit, um zu prüfen, ob NCCL und GPUDirect-TCPX wie erwartet funktionieren. Diese Arbeitslast enthält einen Sidecar-Container mit dem Namen tcpx-daemon, der einen Dienst ausführt, mit dem der Pod GPUDirect-TCPX verwenden kann. Sie müssen diesen Sidecar-Container allen Pods in Ihrer eigenen Umgebung hinzufügen, die GPUDirect TCPX verwenden müssen. Ein Snippet der erforderlichen Felder, die Sie Ihren Manifesten hinzufügen müssen, finden Sie in diesem Dokument unter GPUDirect-TCPX zu Ihrem Manifest hinzufügen.
- ConfigMap-Manifest
nccl-config.yaml
in GitHub prüfen Dieses Manifest stellt Scripts bereit, die einen NCCL-Allgather-Test initialisieren und NCCL-spezifische Konfigurationen festlegen. Prüfen Sie das Manifest
nccl-test.yaml
in GitHub. Das Manifest tut Folgendes:- Stellt zwei Pods bereit, die jeweils auf einem Knoten mit H100-GPUs ausgeführt werden.
- Stellt einen Sidecar-Container mit dem Namen
tcpx-daemon
in jedem Pod bereit, damit diese Pods GPUDirect-TCPX verwenden können.
Stellen Sie die ConfigMap und die Testarbeitslast bereit:
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.yaml
Führen Sie die folgenden Befehle aus, um einen NCCL-Test-All-Gather-Test für die Knoten auszulösen:
kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /configs/allgather.sh nccl-host-1 nccl-host-2
Die Ausgabe sieht in etwa so aus:
# 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
Empfohlene NCCL-Konfigurationen
Die folgenden Schlüssel/Wert-Paare sind die empfohlenen NCCL-Konfigurationseinstellungen für TCPDirect-TCPX. Wenn Sie Arbeitslasten bereitstellen, die NCCL verwenden, müssen Sie sie als Umgebungsvariablen festlegen, um die Leistung zu optimieren.
"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-TCPX zu Manifesten hinzufügen
Dieser Abschnitt enthält die Pflichtfelder, die Sie Ihren Kubernetes-Manifesten hinzufügen müssen, damit Ihre Pods GPUDirect-TCPX verwenden können.
Fügen Sie der Pod-Spezifikation die folgenden Felder hinzu:
spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet volumes: - name: libraries hostPath: path: /home/kubernetes/bin/nvidia/lib64 - name: tcpx-socket hostPath: path: /run/tcpx
Fügen Sie dem Manifest den folgenden Container hinzu, um den Dienst tcpx-daemon auszuführen:
- 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
Fügen Sie allen Containern, die GPUs anfordern, die folgenden Volume-Bereitstellungen hinzu:
volumeMounts: - name: tcpx-socket mountPath: /tmp - name: libraries mountPath: /usr/local/nvidia/lib64
Fügen Sie jedem GPU-Container die folgende Umgebungsvariable hinzu:
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
Fügen Sie Umgebungsvariablen hinzu, um NCCL-Optionen zu konfigurieren. Weitere Informationen finden Sie im Abschnitt Empfohlene NCCL-Konfigurationen in diesem Dokument.
Eine fertige Pod-Spezifikation sieht so aus:
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