Anatomie de la latence : où passe chaque microseconde dans un réseau de cluster IA
Ceux qui dimensionnent un réseau de cluster IA commencent en général par la bande passante — 100, 200, 400 GbE — puis s'étonnent que leur benchmark allreduce affiche un chiffre très éloigné du débit nominal. La raison est presque toujours la latence, et ce régime des petits messages où les courbes de bande passante ne servent à rien.
Cet article démonte un aller-retour complet et rend compte de chaque étape. Les chiffres ci-dessous correspondent à la fourchette consensuelle issue des mesures publiques, de la documentation NVIDIA/Mellanox et de nos propres bancs d'essai. Traitez-les comme un budget, pas comme une garantie : ils bougent avec le silicium de la carte réseau, l'ASIC du commutateur, la version du noyau, les réglages du BIOS et votre patience en matière de tuning.
Public visé : celles et ceux qui spécifient ou dépannent des fabrics de cluster IA. Ce n'est pas un livre de recettes de tuning, mais le modèle mental qui rend ce livre de recettes lisible.
L'aller-retour complet, en une diapositive
Un ping-pong de 64 octets entre deux GPU situés sur des nœuds différents, sur un fabric commuté 100 GbE avec RDMA, se décompose à peu près ainsi :
| Composant | Contribution typique | Remarques |
|---|---|---|
| Envoi / sérialisation applicative | 0.1–1 µs | memcpy, construction d'en-tête, écriture du descripteur |
| Chemin TX de la carte réseau (verbes RDMA) | 0.3–0.8 µs | sous la µs sur les ConnectX / BlueField récents |
| Délai de propagation sur le câble | ~5 ns/m | 50 ns sur un DAC de 10 m, négligeable <100 m |
| Saut de commutateur (cut-through, récent) | 250–600 ns | InfiniBand <100 ns ; Ethernet 400–600 ns |
| Saut de commutateur (store-and-forward, 64 B) | 1–3 µs | Ajoutez la sérialisation par octet par-dessus |
| Par saut supplémentaire | +latence du commutateur | Une topologie leaf-spine ajoute 2 sauts face à un commutateur unique |
| Chemin RX de la carte réseau | 0.3–0.8 µs | Symétrique du TX en RDMA |
| Pile TCP/IP du noyau (un sens) | 10–30 µs | Chemin sockets ; avec interruptions et copies |
| Contournement du noyau (DPDK / verbes RDMA, un sens) | <1 µs | Polling en espace utilisateur, zéro copie |
| Réception / désérialisation applicative | 0.1–1 µs | Réveil du consommateur, décodage de l'en-tête |
Un RTT RDMA sur commutateur unique en 100 GbE / InfiniBand NDR se situe autour de 2 µs pour les petits messages. Un leaf-spine à deux sauts ajoute environ 1 µs. Le même trajet en TCP/IP noyau tombe à 20–60 µs, un ordre de grandeur de plus, avec un comportement de queue de distribution bien pire. Ces deux chiffres commandent presque toutes les décisions d'architecture qui suivent.
0.1–1 µs
250–600 ns
0.1–1 µs
Trajet RDMA aller simple : le saut de commutateur (250–600 ns en Ethernet, <100 ns en IB) est la variable dominante ; le délai de propagation à moins de 100 m est négligeable.
Le câble n'est pas le problème
Dans la fibre, la lumière se propage à environ deux tiers de c, soit ~5 ns/m. Une fibre de 30 m le long d'une rangée de racks ajoute 150 ns en aller simple ; même une liaison de campus de 500 m ne coûte qu'une microseconde. La sérialisation est elle aussi faible aux débits actuels : une trame de 64 octets à 100 Gb/s prend 5.12 ns, une trame jumbo de 9000 octets 720 ns. Pour les petits messages de contrôle, la sérialisation est négligeable ; pour les transferts en masse, elle cesse de compter dès que le tuyau est assez large.
La latence vit en réalité dans le logiciel, dans les ASIC des commutateurs et dans le protocole que vous choisissez.
Fabric de commutation : cut-through contre store-and-forward
Un commutateur cut-through commence à retransmettre dès qu'il a lu l'en-tête de destination. Un commutateur store-and-forward met toute la trame en tampon, vérifie éventuellement le CRC, puis la retransmet.
| Classe de commutateur | Latence par saut |
|---|---|
| Commutateur InfiniBand NDR/HDR (cut-through) | <100 ns |
| Ethernet cut-through (classe Tomahawk, fabric IA) | 400–600 ns |
| Ethernet cut-through (ancien / générique) | 600–900 ns |
| Ethernet store-and-forward, 64 B | 1–3 µs |
| Ethernet store-and-forward, 1500 B | 1.5–4 µs |
L'avantage d'InfiniBand est réel : le silicium HPC optimise ce point depuis deux décennies. Les commutateurs Ethernet IA récents (Tomahawk 5, Jericho3-AI, Spectrum-X) comblent l'essentiel de l'écart de latence et dépassent InfiniBand sur la profondeur de tampon, ce qui compte davantage pour l'incast des allreduce.
Dans un leaf-spine, un flux inter-racks traverse leaf → spine → leaf. Les architectures qui minimisent le nombre de sauts (fat-tree peu profond, topologies rail-optimized) ne cherchent pas à économiser de la bande passante : elles économisent 500 ns par saut évité sur chaque collective.
La pile réseau du noyau
Le TCP/IP classique à travers le noyau Linux paie, à chaque paquet : la distribution de l'interruption de la carte réseau (ou le polling NAPI), l'allocation du skb et le softirq, le traitement TCP/IP, une copie du tampon socket entre noyau et espace utilisateur, et un changement de contexte vers l'application.
Pour un petit paquet sur un x86 récent, cela représente 10–30 µs en aller simple dans le meilleur des cas, avec des pointes au-delà de 100 µs en charge. C'est aussi borné par le CPU : un cœur sature vers 1 Mpps bien avant la carte réseau. C'est ce coût que la suite de l'article cherche à éliminer.
Contournement du noyau : DPDK, RDMA, XDP, AF_XDP
Quatre grandes façons de sortir le noyau du chemin de données, qui diffèrent par l'ampleur du contournement et par ce qu'elles laissent de côté :
| Chemin | Plancher de latence | Modèle CPU | Compatibilité | Usage typique |
|---|---|---|---|---|
| TCP/IP noyau | 10–30 µs/sens | Interruptions | Universelle | Tout ce qui n'est pas critique en latence |
| AF_XDP | 6–10 µs/sens | Hybride | Les outils Linux fonctionnent encore | Voie médiane ; programmes eBPF |
| DPDK | 1–3 µs/sens | Busy poll | Le noyau ne voit rien | Télécoms, HFT, NFV, pipelines paquets sur mesure |
| Verbes RDMA | <1 µs/sens | Queue pair / CQE | Exige une carte RDMA + un fabric adapté | HPC, entraînement IA, réseau de stockage |
Quelques remarques pratiques :
- DPDK et RDMA ne sont pas interchangeables. DPDK exécute un traitement de paquets arbitraire en espace utilisateur au débit nominal ; RDMA met en œuvre un protocole précis à sémantique mémoire avec déchargement matériel. Les charges de travail IA veulent du RDMA — NCCL et les piles de stockage le parlent nativement. DPDK se retrouve dans les proxys d'inférence, la télémétrie et les plans de données sur mesure.
- AF_XDP est la voie médiane. Il s'accroche au pilote au niveau eBPF, obtient une latence sous les 10 µs et, contrairement à DPDK, ne confisque pas la carte réseau au système. C'est la bonne réponse pour les machines à usage mixte.
- XDP sans AF_XDP sert au drop, à la redirection et au forwarding en ligne (nettoyage DDoS, répartiteurs de charge). Il traite les paquets dans le noyau, au point d'accroche du pilote, sans les remonter en espace utilisateur.
Pour un cluster IA : RDMA sur InfiniBand ou RoCEv2 pour le GPU à GPU, TCP/IP classique pour tout le reste (gestion, télémétrie, téléchargement de modèles). N'allez pas sur-concevoir les chemins lents.
Coalescence d'interruptions, GRO/LRO : le piège du débit
Linux et la plupart des pilotes de cartes réseau sont livrés réglés pour le débit, pas pour la latence. Deux réglages comptent :
-
Coalescence d'interruptions. La carte attend une fenêtre configurée en µs (ou un nombre de paquets) avant de lever une interruption. Cela réduit le coût par paquet, mais ajoute une latence égale à la fenêtre.
rx-usecs 50ajoute jusqu'à 50 µs sur un lien peu chargé. - GRO / LRO. Le noyau (GRO) ou la carte (LRO) agrège les segments TCP entrants en un skb plus gros avant de les remonter. Le traitement coûte moins cher, mais l'agrégateur attend délibérément d'autres paquets, ce qui ajoute des microsecondes.
L'arbitrage est honnête et non négociable : vous ne pouvez pas avoir à la fois le débit maximal et la latence minimale avec la même configuration. Sur un nœud GPU, la carte RDMA qui porte l'allreduce veut rx-usecs 0 ou 1, la coalescence adaptative désactivée et GRO désactivé sur l'interface RDMA. Une carte de gestion séparée garde les valeurs par défaut : elle n'est pas sur le chemin critique.
Corollaire : une carte réseau qui sert à la fois aux collectives RDMA et aux téléchargements TCP donnera des chiffres médiocres pour les deux, sauf à répartir le trafic sur des files ou des interfaces distinctes. Les nœuds IA sérieux embarquent une ou deux cartes RDMA dédiées (ConnectX-7/8, BlueField-3) plus une carte de gestion séparée.
La couche applicative n'est pas gratuite non plus
Deux coûts situés en haut de la pile figurent rarement sur les schémas d'architecture :
-
memcpy. Un
memcpyde 4 MB prend ~200 µs sur un seul cœur à ~20 GB/s. Si votre collective copie les tenseurs dans un tampon intermédiaire avant l'envoi, vous avez brûlé plus de temps que l'aller-retour réseau tout entier. GPUDirect RDMA supprime cette étape : la carte lit directement dans la mémoire du GPU. - Sérialisation. Protobuf, JSON ou un format maison ajoutent des dizaines de µs pour des charges utiles non triviales. Acceptable dans un RPC de plan de contrôle ; fatal dans la boucle interne d'un allreduce. NCCL l'évite avec des descripteurs binaires de taille fixe et de la mémoire pré-enregistrée.
Si votre pile « optimisée RDMA » reste lente, profilez l'espace utilisateur avant d'accuser le fabric. Nous avons vu des collectives à 30 µs dont 25 µs venaient d'un reshape de tenseur PyTorch et 5 µs seulement du câble et du commutateur.
Opérations collectives : latence contre bande passante, et pourquoi la taille des paquets compte
NCCL (comme toute bibliothèque de collectives) choisit son algorithme selon la taille du message :
- Les petits messages sont bornés par la latence. NCCL utilise des algorithmes en arbre et son protocole LL (4 octets de données et 4 octets de drapeaux via des stores atomiques de 8 octets, sans barrière mémoire). La busbw ne représente qu'une fraction du débit nominal : vous mesurez le coût par message × le nombre de messages.
- Les gros messages sont bornés par la bande passante. NCCL bascule sur des algorithmes en anneau qui approchent le débit du lien le plus lent. La latence par message disparaît sous les mégaoctets.
La transition se situe grosso modo entre 64 KB et 1 MB selon la topologie et la carte réseau. En dessous, la latence du commutateur et de la carte ainsi que la pile protocolaire dominent. Au-dessus, vous lisez la vitesse du câble sur la courbe.
| Taille de message | Algorithme | BusBw (nœud unique, 8× NVLink) | BusBw (8 nœuds, IB NDR) |
|---|---|---|---|
| 1 KB | Arbre / LL | ~5 GB/s | ~2 GB/s |
| 64 KB | Arbre | ~80 GB/s | ~20 GB/s |
| 1 MB | Anneau | ~250 GB/s | ~40 GB/s |
| 64 MB | Anneau | ~370 GB/s | ~45 GB/s |
| 1 GB | Anneau | ~450 GB/s | ~48 GB/s |
Le plafond NVLink publié pour le H100 est de 450 GB/s ; l'atteindre sur de petits messages ou entre nœuds relève du combat de tuning. Pour la gamme Kentino — 5090 / 4090 / RTX Pro 6000 Blackwell en RoCE 100 GbE — comptez une busbw d'environ 10–12 GB/s par nœud sur les gros messages en 100 GbE, avec la même allure de courbe.
La gigue est pire que la latence
Si la latence d'allreduce est de 30 µs ± 1 µs sur chaque nœud, la barrière attend 30 µs. Si elle est de 30 µs en moyenne mais qu'un nœud monte à 300 µs une fois sur mille itérations, tous les autres GPU restent inactifs 270 µs chaque fois que cette queue se déclenche. Sur une époque de 100k itérations réparties sur 16 nœuds, cela fait des heures de calcul perdues.
C'est pourquoi la latence P99 / P999 compte davantage que la latence moyenne pour l'entraînement IA. Une collective à barrière est une opération au rythme du plus lent : le cluster avance à la vitesse de son pire nœud.
Sources de gigue :
- Congestion des tampons en incast. L'allreduce est un many-to-one à chaque itération. Les commutateurs à tampons peu profonds perdent des paquets, la pause PFC entre en jeu et la latence explose d'un facteur 10 à 100. Les commutateurs IA à tampons profonds (Jericho3-AI, Spectrum-X) absorbent la rafale.
- Gigue du CPU hôte. Une tâche cron, un thread noyau non borné ou une excursion de fréquence CPU produisent une valeur aberrante de 1 ms. Isolez les cœurs pour l'ISR/le thread de polling de la carte, désactivez les C-states sur les CPU critiques, épinglez les processus.
- Coalescence adaptative. Le pilote « aide » en augmentant la coalescence sous charge ; la latence s'envole en silence. Désactivez-la explicitement sur la carte RDMA.
- Asymétrie de topologie. Un leaf à 200 GbE, un autre à 100 GbE. Le plus lent devient votre plancher pour chaque collective.
C'est la latence de queue, et non la latence moyenne, qui constitue le bon SLO pour un fabric IA.
Mesurer correctement
ping mesure un RTT ICMP à travers la pile noyau, sur le plan de gestion. C'est inutile pour caractériser un fabric RDMA. Les outils qui marchent :
-
sockperf ping-pong— latence UDP/TCP avec une résolution inférieure à la nanoseconde. Bon pour les références de pile noyau et la détection de régressions. -
ib_send_lat,ib_write_lat(suite perftest) — la latence des verbes RDMA directement. C'est le chiffre qui compte vraiment pour InfiniBand et RoCE. Comptez ~1–2 µs sur un lien passant par le même commutateur. -
Micro-benchmarks OSU —
osu_latency,osu_bw,osu_allreduceau niveau MPI. Le bon outil pour les applications HPC, avant que NCCL n'entre en scène. -
nccl-tests—all_reduce_perf,all_gather_perf,reduce_scatter_perf. Le seul benchmark qui compte pour l'entraînement IA. Il emprunte exactement le chemin de code de vos exécutions. Balayez de 8 B à 1 GB ; la courbe vous dit où le fabric est cassé.
Contrôle de cohérence : si la busbw de nccl-tests all_reduce_perf sur les gros messages reste nettement sous 80 % du débit nominal de la carte, vous avez un problème de fabric, pas un problème logiciel. Reprenez les couches depuis le haut de cet article.
Bonne habitude : conservez la sortie de nccl-tests au titre de la recette, et relancez-la après chaque changement de firmware, de pilote ou de topologie. Une régression détectée le jour même se résume à une ligne de diff. Détectée trois semaines plus tard, elle devient une enquête médico-légale.
Quand la latence compte vraiment — et quand elle ne compte pas
La latence compte :
- Allreduce synchrone des gradients en entraînement data-parallèle. À chaque itération, sur chaque nœud. Latence de queue = calcul perdu.
- Parallélisme de pipeline à grain fin avec de petits micro-lots. Le temps de bulle aux frontières d'étage est plafonné par la latence inter-nœuds.
- Découpages de couches en parallélisme de tenseurs qui se déploient et se referment à l'intérieur d'une passe avant/arrière — une chaîne de petites collectives, pur jeu de latence.
- Communication pas à pas avec un parameter server à cadence de mise à jour élevée.
La latence ne compte guère :
- Le batching d'inférence à l'échelle de la requête. La latence par requête est dominée par le calcul GPU (TTFT, décodage par token). 10 µs de réseau, c'est du bruit face à 50 ms de décodage.
- Le chargement en masse d'un modèle depuis un stockage objet au démarrage du job. Borné par le débit.
- L'écriture de checkpoints vers un stockage réseau. De grosses écritures séquentielles : réglez pour la bande passante.
- Le shuffle du DataLoader via le préchargement des workers. En lots, borné par le débit.
La conséquence, en toute honnêteté : un serveur mono-nœud à 4 ou 8 GPU (le cœur de la gamme Kentino AI) assure sa communication inter-GPU par NVLink ou PCIe, pas par le réseau. Le réseau sert au stockage, à la télémétrie et à l'expérimentation multi-nœuds occasionnelle. Optimiser le fabric pour la latence des collectives ne paie qu'avec un véritable entraînement multi-nœuds, que la plupart des clients Kentino ne pratiquent pas. Pour de l'inférence pure et de l'entraînement mono-nœud, du 25 GbE avec une pile noyau propre suffit.
La suite
Si vous mettez en service un nouveau fabric, déroulez cette séquence :
-
ib_send_latentre chaque paire de nœuds. Tout écart supérieur à 1.5× la médiane est un signal d'alerte : câble défectueux, optique encrassée, topologie mal routée. -
nccl-tests all_reduce_perfde 8 B à 1 GB. Sauvegardez la courbe. Comparez-la à la référence publiée pour votre classe de carte réseau et de commutateur. -
Comparez le
sockperf ping-pongTCP auib_send_latRDMA. L'écart devrait être d'un facteur 10 à 30. S'il n'est que de 2, votre pile noyau est anormalement rapide (peu probable) ou votre chemin RDMA est cassé (probable — mauvaise configuration PFC, mauvais réglage DCQCN, RDMA retombé sur un chemin logiciel). - Relancez nccl-tests en charge. Injectez du trafic de stockage en parallèle et observez la busbw se dégrader. Un cluster sain se dégrade de moins de 20 % sous une charge mixte réaliste ; un cluster malade s'effondre.
- Ne modifiez qu'une variable à la fois. Coalescence, routage adaptatif, seuils PFC, marquages ECN. Documentez chaque changement. Changez trois choses, l'une aide — et vous ne savez pas laquelle.
- Alertez sur la latence P99 des collectives, pas sur la moyenne. La moyenne masque le problème ; le P99 est ce que l'entraînement ressent vraiment.
Les suites — N07 sur le routage et le contrôle de congestion (ECMP, DCQCN, ECN), N08 sur la mise en œuvre du RDMA en pratique, et K02 sur le choix des algorithmes d'entraînement distribué — approfondissent des décisions que cet article ne fait qu'esquisser.
Dans un fabric IA, la latence n'est pas le câble : c'est tout ce qui entoure le câble — et le remède consiste presque toujours à raccourcir le chemin logiciel avant de dépenser plus en matériel.
Cet article fait partie du Kentino Wiki, une série de référence sur le calcul IA, la robotique et les systèmes qui les relient. Commentaires et corrections bienvenus à info@kentino.com.