Ce document explique comment optimiser la bande passante et le débit du réseau pour les charges de travail GPU hautes performances dans Google Kubernetes Engine (GKE) en utilisant des clusters standards avec GPUDirect-TCPXO, GPUDirect-TCPX, gVNIC, et le multiréseau.
Ce document est destiné aux ingénieurs en machine learning (ML) et aux administrateurs de plate-forme qui facilitent les charges de travail de ML. Avant de lire ce document, assurez-vous de maîtriser les technologies de mise en réseau, telles que les cartes d'interface réseau (NIC) et TCP, ainsi que les technologies d'accélération telles que la bibliothèque NVIDIA Collective Communications Library (NCCL).
Les applications d'intelligence artificielle (IA), de ML et de calcul hautes performances nécessitent une accélération puissante pour optimiser les performances en réduisant les délais d'exécution des tâches. Par exemple, les modèles de ML axés sur l'IA conversationnelle et la génération d'images nécessitent une évolutivité et une puissance de calcul élevées.
À propos des superordinateurs sur GPU Google Cloud
Google Cloud dispose de superordinateurs optimisés pour les accélérateurs, conçus pour des modèles massifs et évolutifs. Ces machines présentent les avantages suivants :
- Huit GPU NVIDIA H100 par machine.
- Jusqu'à 200 Gbit/s sur la carte d'interface réseau principale.
- Cartes d'interface réseau secondaires (jusqu'à huit sur les types de machines A3 Mega et jusqu'à quatre sur les types de machines A3 High), chacune acceptant jusqu'à 200 Gbit/s de bande passante pour le transfert de données GPU.
Pour obtenir la liste complète des avantages, consultez la section Série de machines A3 dans la documentation Compute Engine.
Votre charge de travail GKE doit utiliser tous les GPU et toutes les cartes d'interface réseau secondaires disponibles sur un seul nœud, et utiliser une part importante de la bande passante disponible. La solution décrite dans ce document est idéale pour les charges de travail qui nécessitent de hautes performances, un débit élevé et une faible latence.
Fonctionnalités et capacités requises pour une bande passante maximale
Pour optimiser la bande passante de votre réseau dans les nœuds GPU de supercalculateur, utilisez toutes les fonctionnalités suivantes :
- Sur les types de machines Méga A3, utilisez GPUDirect-TCPXO pour améliorer davantage la communication entre GPU et VM.
- Pile réseau GPUDirect : la série de machines A3 est compatible avec deux piles réseau pour l'accès à la mémoire directe distante (RDMA) personnalisée :
- Sur les types de machines A3 High, utilisez GPUDirect-TCPX pour réduire les frais généraux requis pour transférer les charges utiles de paquets vers et depuis les GPU, ce qui améliore considérablement le débit à grande échelle par rapport aux GPU qui n'utilisent pas GPUDirect.
- gVNIC : activez les fonctionnalités GPUDirect telles que la division de l'en-tête du paquet, l'orientation du flux et la gestion de la mémoire tampon. gVNIC est requis pour utiliser GPUDirect-TCPX ou GPUDirect-TCPXO. Pour en savoir plus sur gVNIC, consultez la section Augmenter la vitesse de trafic réseau pour les nœuds GPU.
- Multiréseau : ajoutez des cartes d'interface réseau secondaires à la machine optimisée pour les accélérateurs. Pour éviter les conflits, chaque carte d'interface réseau est associée à un sous-réseau distinct de son propre VPC. Pour en savoir plus sur la compatibilité multiréseau, consultez la section Configurer la compatibilité multiréseau pour les pods.
- Stratégies d'emplacement : utilisez une règle d'emplacement des ressources pour placer tous les nœuds GPU d'une charge de travail spécifique sur des serveurs physiquement proches afin de minimiser la latence. Pour en savoir plus, consultez la section Définir un emplacement compact pour les nœuds GKE.
Aperçu de la procédure
Pour utiliser toutes ces fonctionnalités ensemble, procédez comme suit :
- Créer des clouds privés virtuels (VPC) et des sous-réseaux
- Créez l'environnement GKE :
- Créer un cluster avec le multiréseau activé
- Créez un pool de nœuds présentant les caractéristiques suivantes :
- gVNIC activé
- Sous-réseaux à mise en réseau spécifiés pour chaque carte d'interface réseau secondaire
- Série de machines A3 avec des GPU H100 qui sauvegardent les nœuds
- Derniers pilotes NVIDIA installés
- Installer le binaire GPUDirect et le plug-in NCCL
- Déployer le plug-in d'injecteur d'appareils NRI
- Déployer une charge de travail de test pour vérifier la configuration de GPUDirect
Avant de commencer
Avant de commencer, effectuez les tâches suivantes :
- Activez l'API Google Kubernetes Engine. Activer l'API Google Kubernetes Engine
- Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande
gcloud components update
.
- Assurez-vous de disposer d'un quota suffisant pour les GPU H100. Pour demander une augmentation de quota, consultez la page Quotas de GPU.
Exigences
Les exigences suivantes s'appliquent à la fois à GPUDirect-TCPX et à GPUDirect-TCPXO, sauf indication contraire.
- GPUDirect-TCPX est compatible avec GKE version 1.27 ou ultérieure et nécessite les éléments suivants :
- Type de machine A3 High (par exemple,
a3-highgpu-8g
). - Pour GKE version 1.27, utilisez la version de correctif 1.27.7-gke.1121000 ou ultérieure de GKE.
- Pour GKE version 1.28, utilisez la version de correctif 1.28.8-gke.1095000 ou ultérieure de GKE.
- Pour GKE version 1.29, utilisez la version de correctif 1.29.3-gke.1093000 ou ultérieure de GKE.
- Type de machine A3 High (par exemple,
- GPUDirect-TCPXO est compatible avec GKE version 1.28 ou ultérieure et nécessite les éléments suivants :
- Type de machine A3 Mega (par exemple,
a3-megagpu-8g
). - Pour GKE version 1.28, utilisez la version de correctif 1.28.9-gke.1250000 ou ultérieure de GKE.
- Pour GKE version 1.29, utilisez la version de correctif 1.29.4-gke.1542000 ou ultérieure de GKE.
- Type de machine A3 Mega (par exemple,
- Vos nœuds GPU doivent utiliser le pilote NVIDIA version 535 ou ultérieure.
- Vous devez utiliser GKE Dataplane V2.
- Le nœud GKE doit utiliser une image de nœud Container-Optimized OS (COS). Les images de nœuds Ubuntu et Windows ne sont pas acceptées.
Limites
Les limites suivantes s'appliquent :
- GPUDirect-TCPX et GPUDirect-TCPXO ne sont pas compatibles avec les clusters Autopilot
- GPUDirect-TCPX et GPUDirect-TCPXO ne sont pas compatibles avec les GPU multi-instances, le temps partagé des GPU ou NVIDIA MPS
- Vous ne pouvez pas utiliser le protocole NCCL FastSocket
- Votre charge de travail GKE doit utiliser tous les GPU et toutes les cartes d'interface réseau secondaires disponibles sur un seul nœud. Plusieurs pods ne peuvent pas utiliser GPUDirect-TCPX ou GPUDirect-TCPXO sur un seul nœud.
Créer des VPC et des sous-réseaux
Créez des réseaux VPC distincts dans votre projet pour chaque carte d'interface réseau virtuelle que vous ajouterez à vos nœuds. Chaque réseau VPC doit comporter un sous-réseau et une règle de pare-feu autorisant le trafic réseau interne.
Créez les réseaux VPC pour GPUDirect dans votre projet, chacun avec un sous-réseau et une règle de pare-feu : Choisissez l'onglet GPUDirect-TCPX pour les types de machines A3 High ou l'onglet GPUDirect-TCPXO pour les types de machines A3 Mega, puis suivez les instructions suivantes :
GPUDirect-TCPXO
Pour optimiser votre bande passante, nous vous recommandons de créer huit autres réseaux.
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
Remplacez les éléments suivants :
PROJECT_ID
: ID de votre projet Google Cloud.REGION
: région Compute Engine de chaque sous-réseau.SUBNET_RANGE
: plage d'adresses IP de chaque sous-réseau au format CIDR. Cet exemple de commande effectue une itération pour huit sous-réseaux. Vous devez donc utiliser une variable pour modifier l'adresse IP de chaque sous-réseau. Par exemple, spécifiez192.168.$N.0/24
pour que le premier sous-réseau utilise192.168.1.0/24
, le second sous-réseau utilise192.168.2.0/24
, etc.SOURCE_RANGE
: plage d'adresses IP source de la règle de pare-feu pour autoriser le trafic entrant, au format CIDR. Exemple :192.168.0.0/16
.
GPUDirect-TCPX
Pour optimiser votre bande passante, nous vous recommandons de créer quatre autres réseaux.
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
Remplacez les éléments suivants :
PROJECT_ID
: ID de votre projet Google Cloud.REGION
: région Compute Engine de chaque sous-réseau.SUBNET_RANGE
: plage d'adresses IP de chaque sous-réseau au format CIDR. Cet exemple de commande effectue une itération pour quatre sous-réseaux. Utilisez donc une variable pour modifier l'adresse IP de chaque sous-réseau. Par exemple, spécifiez192.168.$N.0/24
pour que le premier sous-réseau utilise192.168.1.0/24
, le second sous-réseau utilise192.168.2.0/24
, etc.SOURCE_RANGE
: plage d'adresses IP source de la règle de pare-feu pour autoriser le trafic entrant, au format CIDR. Exemple :192.168.0.0/16
.
Vérifiez que les réseaux ont été créés :
gcloud compute networks list
Créer l'environnement GKE
Créez un cluster GKE qui utilise le multiréseau (preview) et créez un pool de nœuds GPU utilisant des machines A3 et des GPU H100, ainsi que des cartes d'interface réseau supplémentaires. Vous ne pouvez pas mettre à jour un cluster existant pour utiliser le multiréseau.
GPUDirect-TCPXO
Choisissez une version de GKE disponible compatible avec GPUDirect-TCPXO. Pour lister les versions, exécutez la commande suivante :
gcloud container get-server-config \ --format="yaml(validMasterVersions)" \ --zone=ZONE \ --project=PROJECT_ID
Remplacez les éléments suivants :
ZONE
: zone de calcul du plan de contrôle du cluster.PROJECT_ID
: ID de votre projet Google Cloud.
Créez 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
Remplacez les éléments suivants :
CLUSTER_NAME
: nom de votre nouveau clusterVERSION
: version de GKE compatible avec GPUDirect-TCPXO, comme décrit dans la section Conditions requises.REGION
: région Compute Engine du cluster.ZONE
: zone de calcul du cluster.
Créez des ressources Network et GKENetworkParamSet dans le cluster correspondant aux réseaux et sous-réseaux VPC que vous avez créés :
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
Ces ressources indiquent à GKE de configurer les cartes d'interface réseau pour le trafic GPU en mode passthrough. GKE n'applique pas la programmation réseau intégrée en utilisant eBPF à ce trafic.
Créez un pool de nœuds pour les 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 "https://www.googleapis.com/auth/cloud-platform" \ [--placement-policy=POLICY_NAME \ --reservation-affinity=specific \ --reservation=RESERVATION_NAME \ --host-maintenance-interval=PERIODIC]
Remplacez
NODE_POOL_NAME
par le nom de votre pool de nœuds.Dans l'exemple, l'argument
--scopes
"https://www.googleapis.com/auth/cloud-platform" définit le champ d'application de l'instance de nœud surcloud-platform
pour plus de commodité. Pour la production, vous pouvez limiter la portée afin de configurer des identifiants plus précis.Utilisez les options
--placement-policy
,--reservation-affinity
et--reservation
si vous utilisez une réservation. Spécifiez ces indicateurs pour configurer le nom de la règle et la réservation dans le pool de nœuds.Si cette commande échoue, il est possible que votre quota de GPU H100 ne soit pas suffisant dans votre projet. Vérifiez que vous disposez d'un quota suffisant et relancez la commande.
Obtenez la liste des nœuds du cluster :
kubectl get nodes
Vérifiez que chaque nœud GPU comporte huit GPU :
kubectl describe node NODE_NAME
Le résultat ressemble à ce qui suit :
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
GPUDirect-TCPX
Créez 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 \
Remplacez les éléments suivants :
CLUSTER_NAME
: nom de votre nouveau clusterLOCATION
: région Compute Engine du cluster.VERSION
: version de GKE pour le cluster. Utilisez une version compatible, comme décrit dans la section Conditions requises.
Créez des ressources Network et GKENetworkParamSet dans le cluster correspondant aux réseaux et sous-réseaux VPC que vous avez créés :
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
Ces ressources indiquent à GKE de configurer les cartes d'interface réseau pour le trafic GPU en mode passthrough. GKE n'applique pas la programmation réseau intégrée en utilisant eBPF à ce trafic.
Créez un pool de nœuds pour les 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
Remplacez
NODE_POOL_NAME
par le nom du pool de nœuds.Si cette commande échoue, il est possible que votre quota de GPU H100 ne soit pas suffisant dans votre projet. Vérifiez que vous disposez d'un quota et relancez la commande.
Obtenez la liste des nœuds du cluster :
kubectl get nodes
Vérifiez que chaque nœud GPU comporte huit GPU :
kubectl describe node NODE_NAME
Le résultat ressemble à ce qui suit :
Capacity: ... nvidia.com/gpu: 8 Allocatable: ... nvidia.com/gpu: 8
Installer le binaire GPUDirect et configurer NCCL
Cette section explique comment installer le binaire GPUDirect, en fonction de votre type de machine A3 (GPUDirect-TCPX pour A3 High, GPUDirect-TCPXO pour A3 Mega) et d'une version de bibliothèque NCCL spécifique à l'aide d'un DaemonSet.
GPUDirect-TCPXO
Examinez le fichier manifeste Daemonset
nccl-tcpxo-installer.yaml
dans GitHub. Ce DaemonSet effectue les opérations suivantes :- Préinstallation pour configurer les configurations associées à GPUDirect-TCPXO
- Installe la bibliothèque NCCL et le binaire GPUDirect-TCPXO sur le nœud.
- Stocke la bibliothèque et le binaire dans le répertoire
/home/kubernetes/bin/nvidia/lib64
de la VM. Par défaut, GKE installe ce répertoire dans le chemin d'accès/usr/local/nvidia/lib64
dans les conteneurs de GPU qui doivent utiliser NCCL et GPUDirect-TCPXO.
Déployez le DaemonSet :
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-tcpxo-installer.yaml
Le démarrage du plug-in NCCL prend environ deux minutes.
Vérifiez l'état des pods DaemonSet :
kubectl get pods -n=kube-system -l=name=nccl-tcpxo-installer
Le résultat ressemble à ce qui suit :
# Output nccl-tcpxo-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpxo-installer-qgg82 1/1 Running 0 2m11s
GPUDirect-TCPX
Examinez le fichier manifeste Daemonset
nccl-tcpx-installer.yaml
dans GitHub. Ce DaemonSet effectue les opérations suivantes :- Installe la bibliothèque NCCL et le binaire GPUDirect-TCPX sur le nœud.
- Stocke la bibliothèque et le binaire dans le répertoire
/home/kubernetes/bin/nvidia/lib64
de la VM. Par défaut, GKE installe ce répertoire dans le chemin d'accès/usr/local/nvidia/lib64
dans les conteneurs de GPU qui doivent utiliser NCCL et GPUDirect-TCPX.
Déployez le DaemonSet :
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpx/nccl-tcpx-installer.yaml
Le démarrage du plug-in NCCL prend environ deux minutes.
Vérifiez l'état des pods DaemonSet :
kubectl get pods -n=kube-system -l=name=nccl-tcpx-installer
Le résultat ressemble à ce qui suit :
nccl-tcpx-installer-6c2pv 1/1 Running 0 2m11s nccl-tcpx-installer-qgg82 1/1 Running 0 2m11s
Déployer le plug-in d'injecteur d'appareils NRI
Cette section vous explique comment installer l'injecteur d'appareils NRI à l'aide d'un DaemonSet. Les deux types de machines H100 (GPUDirect-TCPX pour A3 High, GPUDirect-TCPXO pour A3 Mega) installent le même plug-in d'injecteur d'appareils NRI.
Examinez le fichier manifeste de déploiement
nri-device-injector.yaml
dans GitHub. Ce DaemonSet effectue les opérations suivantes :- Active l'interface de ressource de nœud (NRI) sur le nœud doté de GPU H100.
- Déploie un conteneur de plug-in d'injecteur d'appareils NRI qui injecte des appareils GPU dans les conteneurs spécifiés par les annotations de pod.
Déployez le DaemonSet :
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/nri_device_injector/nri-device-injector.yaml
Le démarrage du plug-in NCCL prend environ deux minutes.
Vérifiez l'état des pods DaemonSet :
kubectl get pods -n=kube-system -l=name=device-injector
Le résultat ressemble à ce qui suit :
# Output device-injector-md6hb 1/1 Running 0 4h54m device-injector-vh9bm 1/1 Running 0 4h54m
Déployer une charge de travail de test
Dans cette section, vous déployez un exemple de charge de travail pour vérifier que la bibliothèque NCCL et les GPU GPU-TCPX ou GPUDirect-TCPXO fonctionnent comme prévu.
GPUDirect-TCPXO
Cette charge de travail inclut un conteneur side-car nommé tcpxo-daemon, qui exécute un service permettant au pod d'utiliser GPUDirect-TCPXO. Vous devez ajouter ce conteneur side-car à tous les pods de votre propre environnement qui doivent utiliser GPUDirect-TCPXO. Pour obtenir un extrait des champs obligatoires à ajouter à vos fichiers manifestes, consultez la section Ajouter GPUDirect à votre fichier manifeste.
Examinez le fichier manifeste
nccl-test-latest.yaml
dans GitHub. Ce fichier manifeste effectue les opérations suivantes :- Déploie deux pods, chacun s'exécutant dans un nœud doté de GPU H100.
- Il déploie un conteneur side-car nommé
tcpxo-daemon
dans chaque pod pour permettre à ces pods d'utiliser GPUDirect-TCPXO.
Déployez deux pods avec la charge de travail de test:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-tcpxo/nccl-test-latest.yaml
Exécutez les commandes suivantes pour déclencher un test NCCL complet pour les deux nœuds :
kubectl exec --stdin --tty --container=nccl-test nccl-test-host-1 -- /scripts/allgather.sh nccl-host-1 nccl-host-2
Le résultat ressemble à ce qui suit :
# 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
Cette charge de travail inclut un conteneur side-car nommé tcpx-daemon, qui exécute un service permettant au pod d'utiliser GPUDirect-TCPX. Vous devez ajouter ce conteneur side-car à tous les pods de votre propre environnement qui doivent utiliser GPUDirect-TCPX. Pour obtenir un extrait des champs obligatoires à ajouter à vos fichiers manifestes, consultez la section Ajouter GPUDirect à votre fichier manifeste.
- Consultez le fichier manifeste ConfigMap
nccl-config.yaml
dans GitHub. Ce fichier manifeste déploie des scripts qui initialisent un test global de la bibliothèque NCCL et définissent des paramètres de configuration spécifiques à la bibliothèque NCCL. Examinez le fichier manifeste de déploiement
nccl-test-latest.yaml
dans GitHub. Ce fichier manifeste effectue les opérations suivantes :- Déploie deux pods, chacun s'exécutant dans un nœud doté de GPU H100.
- Il déploie un conteneur side-car nommé
tcpx-daemon
dans chaque pod pour permettre à ces pods d'utiliser GPUDirect-TCPX.
Déployez le ConfigMap et la charge de travail de test :
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
Exécutez les commandes suivantes pour déclencher un test NCCL complet pour les nœuds :
kubectl exec \ --stdin --tty --container=nccl-test nccl-test-host-1 \ -- /configs/allgather.sh nccl-host-1 nccl-host-2
Le résultat ressemble à ce qui suit :
# 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
Utiliser les paramètres de configuration de NCCL recommandés pour améliorer les performances
Les paires clé/valeur suivantes sont les paramètres de configuration de la bibliothèque NCCL recommandés pour GPUDirect-TCPX et GPUDirect-TCPXO. Lorsque vous déployez vos charges de travail qui utilisent NCCL, définissez-les en tant que variables d'environnement pour optimiser les performances.
GPUDirect-TCPXO
"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64\"",
"NCCL_FASTRAK_CTRL_DEV=eth0",
"NCCL_FASTRAK_IFNAME=eth1,eth2,eth3,eth4,eth5,eth6,eth7,eth8",
"NCCL_SOCKET_IFNAME=eth0",
"NCCL_CROSS_NIC=0",
"NCCL_ALGO=Ring,Tree",
"NCCL_PROTO=Simple",
"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"
GPUDirect-TCPX
"LD_LIBRARY_PATH=\"${LD_LIBRARY_PATH}:/usr/local/tcpx/lib64\"",
"NCCL_SOCKET_IFNAME=\"eth0\"",
"NCCL_ALGO=Ring",
"NCCL_PROTO=Simple",
"NCCL_CROSS_NIC=0",
"NCCL_NET_GDR_LEVEL=PIX",
"NCCL_P2P_PXN_LEVEL=0",
"NCCL_GPUDIRECTTCPX_SOCKET_IFNAME=eth1,eth2,eth3,eth4",
"NCCL_GPUDIRECTTCPX_CTRL_DEV=eth0",
"NCCL_DYNAMIC_CHUNK_SIZE=524288",
"NCCL_P2P_NET_CHUNKSIZE=524288",
"NCCL_P2P_PCI_CHUNKSIZE=524288",
"NCCL_P2P_NVL_CHUNKSIZE=1048576",
"NCCL_BUFFSIZE=4194304",
"NCCL_NSOCKS_PERTHREAD=4",
"NCCL_SOCKET_NTHREADS=1",
"NCCL_GPUDIRECTTCPX_TX_BINDINGS=\"eth1:8-21,112-125;eth2:8-21,112-125;eth3:60-73,164-177;eth4:60-73,164-177\"",
"NCCL_GPUDIRECTTCPX_RX_BINDINGS=\"eth1:22-35,126-139;eth2:22-35,126-139;eth3:74-87,178-191;eth4:74-87,178-191\"",
"NCCL_GPUDIRECTTCPX_PROGRAM_FLOW_STEERING_WAIT_MICROS=500000"
"NCCL_NVLS_ENABLE=0"
Ajouter GPUDirect à vos fichiers manifestes
Cette section montre les champs obligatoires que vous devez ajouter à vos fichiers manifestes Kubernetes pour que vos pods puissent utiliser GPUDirect.
GPUDirect-TCPXO
Ajoutez les annotations suivantes aux métadonnées du pod. Sans ces annotations,
hostNetwork:true
est requis pour le pod etprivileged:true
pour le conteneurtcpxo-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"} ]
Ajoutez les champs suivants à la spécification de 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
Ajoutez le conteneur suivant au fichier manifeste pour exécuter le service
tcpxo-daemon
avec l'imageus-docker.pkg.dev/gce-ai-infra/gpudirect-tcpxo/tcpgpudmarxd-dev:v1.0.10
:- 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: nvidia-install-dir-host mountPath: /usr/local/nvidia - name: sys mountPath: /hostsysfs - name: proc-sys mountPath: /hostprocsysfs env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
Ajoutez la variable d'environnement suivante à chaque conteneur de GPU :
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64 - name: NCCL_FASTRAK_LLCM_DEVICE_DIRECTORY value: /dev/aperture_devices
Ajoutez les volumeMounts suivants à chaque conteneur de GPU. Sans configuration
aperture_devices
,privileged:true
est requis pour les conteneurs de GPU:volumeMounts: - name: aperture-devices mountPath: /dev/aperture_devices
Vous pouvez également ajouter des variables d'environnement pour configurer les options NCCL. Pour en savoir plus, consultez la page Utiliser les paramètres de configuration de la bibliothèque NCCL recommandés pour améliorer les performances.
Une spécification de pod terminée ressemble à ce qui suit :
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: nvidia-install-dir-host
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: nvidia-install-dir-host
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
Ajoutez les annotations suivantes aux métadonnées du pod. Sans ces annotations,
hostNetwork:true
est requis pour le pod etprivileged:true
pour le conteneurtcpx-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"}, ]
Ajoutez les champs suivants à la spécification de pod :
spec: volumes: - name: nvidia-install-dir-host hostPath: path: /home/kubernetes/bin/nvidia/lib64 - name: sys hostPath: path: /sys - name: proc-sys hostPath: path: /proc/sys
Ajoutez le conteneur suivant au fichier manifeste pour exécuter le service 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
Ajoutez les installations de volume suivantes à tous les conteneurs qui demandent des GPU :
volumeMounts: - name: tcpx-socket mountPath: /tmp - name: libraries mountPath: /usr/local/nvidia/lib64
Ajoutez la variable d'environnement suivante à chaque conteneur de GPU :
env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64
Vous pouvez également ajouter des variables d'environnement pour configurer les options NCCL. Pour en savoir plus, consultez la section Utiliser les paramètres de configuration de NCCL recommandés pour améliorer les performances dans ce document.
Une spécification de pod terminée ressemble à ce qui suit :
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
Étapes suivantes
- Découvrez les bonnes pratiques de mise en réseau GKE.
- En savoir plus sur la famille de technologies Nvidia GPUDirect pour le transfert de données et l'accès aux GPU Nvidia
- Découvrez la disponibilité actuelle des versions de GPU et la demande de GPU dans GKE.