Comment comprendre les GPU
(jax-ml.github.io)- Les GPU jouent un rôle central dans le machine learning moderne et reposent sur une architecture qui combine de nombreux Streaming Multiprocessors (SMs) spécialisés dans les multiplications de matrices rapides avec de la HBM (mémoire à large bande passante)
- Les SM d’un GPU se divisent entre Tensor Cores (multiplication de matrices) et CUDA Cores (calcul vectoriel), ce qui permet à la fois un calcul massivement parallèle et une programmation flexible
- Les GPU et les TPU diffèrent par leur structure interne et leur configuration réseau ; les GPU offrent une plus grande polyvalence et une meilleure extensibilité, mais atteindre des performances optimales demande davantage d’attention
- À l’intérieur d’un nœud (Node), les GPU peuvent communiquer à très haute vitesse via NVLink et NVSwitch ; entre les nœuds, ils sont reliés par des réseaux comme InfiniBand, ce qui permet l’entraînement distribué à grande échelle
- Les opérations collectives (Collectives) sur GPU (par ex. AllReduce, AllGather, etc.) voient leurs performances varier fortement selon la structure matérielle et les couches réseau, et elles restent en pratique souvent inférieures à la bande passante théorique
Qu’est-ce qu’un GPU ?
- Les GPU de ML (machine learning) récents (par ex. H100, B200) combinent de plusieurs dizaines à plusieurs centaines de Streaming Multiprocessors (SM) spécialisés dans les multiplications de matrices avec de la mémoire HBM rapide
- Chaque SM contient des Tensor Cores (multiplication de matrices), des Warp Schedulers (calcul vectoriel) et de la SMEM (cache on-chip)
- Contrairement aux TPU, les GPU permettent un traitement parallèle plus flexible et à plus grande échelle grâce à plus de 100 SM
Structure détaillée des SM
- Un SM est divisé en 4 sous-partitions, chacune contenant ses propres Tensor Cores, CUDA Cores (calcul vectoriel), Warp Scheduler, fichier de registres, etc.
- Les CUDA Cores prennent en charge l’arithmétique vectorielle (SIMD/SIMT), tandis que les Tensor Cores sont spécialisés dans les multiplications de matrices
- Les FLOPs des Tensor Cores sont de loin supérieurs, et le débit augmente encore avec des calculs de plus faible précision
- Les GPU récents (par ex. B200) ajoutent une grande TMEM, qui prend en charge des entrées de plus grande taille pour les Tensor Cores
La flexibilité des CUDA Cores
- Les CUDA Cores des GPU utilisent le modèle SIMT (Single Instruction Multiple Threads), dans lequel une même instruction est exécutée en parallèle sur plusieurs threads
- Chaque thread dispose de son propre pointeur d’instruction (compteur ordinal), ce qui apporte de la flexibilité, notamment pour les branchements conditionnels ; en revanche, une forte divergence d’instructions au sein d’un warp dégrade les performances
- Chaque CUDA Core dispose d’un état individuel et d’un accès mémoire flexible (contrairement au TPU, qui ne peut traiter que de la mémoire contiguë)
Ordonnancement / parallélisme
- Un SM ordonnance de nombreux warps (jusqu’à 64) pour une exécution simultanée, et chaque warp scheduler n’exécute qu’un seul programme à la fois
- Grâce à cette structure, le GPU peut offrir à la fois une grande flexibilité et un haut niveau de concurrence
Structure mémoire du GPU
- Sur un GPU, la HBM est la mémoire la plus volumineuse ; à côté, on trouve aussi une hiérarchie mémoire avec L2/L1 (SMEM)/TMEM/registres
Résumé des spécifications des GPU récents
- Le nombre de SM (Streaming Multiprocessors), la fréquence, la mémoire, les FLOPs et la bande passante (BW) varient selon les modèles
- La capacité mémoire (HBM), la bande passante et les FLOPs (virgule flottante / entier / basse précision) augmentent au fil des générations
- Principales caractéristiques du tableau (omis) : Blackwell (B200) propose 192 Go de HBM, une bande passante HBM de 8.0 TB/s, des FLOPs FP8 de 4.5e15, etc.
- D’une génération à l’autre, les progrès matériels sont nets : capacité des registres et du cache on-chip (SMEM), ajout de TMEM, etc.
Comparaison GPU / TPU
- Les GPU sont polyvalents et modulaires, avec de nombreux petits SM (unités parallèles), mais leur richesse en contrôles matériels rend leur compréhension et leur optimisation plus difficiles
- Les TPU se composent d’un petit nombre de grands Tensor Cores et de nombreuses ALU vectorielles (VPU), avec un contrôle en mono-thread qui simplifie le matériel et réduit les coûts
- En conséquence, l’optimisation par le compilateur est indispensable sur TPU, tandis que les GPU peuvent exécuter plusieurs kernels de façon indépendante, ce qui les rend plus simples à utiliser
- Du point de vue performances / prix, un GPU H200 récent offre environ 2 fois plus de FLOPs/s qu’un TPU v5p, 1,5 fois plus de HBM, pour un prix d’environ 2,5 fois supérieur
- Les TPU disposent d’une VMEM (cache on-chip) plus grande et plus rapide, ce qui peut représenter un avantage important, notamment pour l’inférence de modèles LLM
Points clés du quiz matériel GPU (Q&A)
- Le H100 compte au total 16 896 cœurs CUDA fp32 (132 SM x 4 x 32), le B200 en compte 18 944
- Les FLOPs de calcul vectoriel atteignent au maximum 33.5 TFLOPs/s sur H100, soit environ 30 fois moins que les FLOPs de multiplication de matrices des Tensor Cores (990 TFLOPs/s)
- La capacité combinée du L1/SMEM et des registres du H100 est de 66 Mo, contre 120 Mo de VMEM sur TPU
- Le ratio entre bandwidth (bande passante) et FLOPs (intensité de calcul théorique) est d’environ 280 à 300 pour H100/B200, proche de celui des TPU
Réseau GPU (structure de communication)
Structure nœud / cluster
- Un nœud GPU regroupe généralement 8 GPU, reliés en direct à pleine bande passante via NVLink (très haute vitesse) et NVSwitch (commutateur)
- Entre les nœuds, on utilise InfiniBand (ou Ethernet, etc.) pour permettre le scale-out
- Les GPU les plus récents (Blackwell) peuvent s’étendre jusqu’à 72 nœuds
Caractéristiques par couche réseau
- À l’intérieur du nœud (zone NVLink) : egress de 450 GB/s par GPU (H100), 900 GB/s (B200), jusqu’à 1.6 TB/s par NVSwitch
- Niveau supérieur du nœud (InfiniBand Leaf/Spine) : structure Leaf Switch (8) à Spine Switch (16), avec maintien théorique de 400 GB/s de pleine bande passante entre GPU
- Dans de grandes architectures comme SuperPod, on atteint 1024 GPU (128 nœuds), et le nœud GB200 (72 GPU) offre une bande passante amplifiée par 9 (3600 GB/s)
Points clés sur les performances réseau
- En théorie, la structure réseau (Full Fat Tree) est conçue pour fournir la bande passante maximale y compris entre nœud et nœud
- En raison de contraintes sur les ports matériels, l’extension à 1024–4096 GPU passe par une hiérarchisation supplémentaire avec davantage de Spine/Core Switches
- Le passage de la bande passante intra-nœud (450 GB/s) à la bande passante inter-nœuds (400 GB/s) entraîne une différence de performances dans les opérations collectives
Structure des opérations collectives (Collectives)
- Prise en charge d’opérations collectives de haut niveau comme AllGather, AllReduce (somme), AllToAll (distribution)
- À l’intérieur d’un nœud, la connexion directe via NVLink permet des performances optimales (bande passante théorique) ; entre nœuds, le trafic passe par InfiniBand
- Utilisation des bibliothèques NVIDIA NCCL et NVSHMEM
Analyse des performances des collectives
- AllGather/ReduceScatter : implémentation en anneau (Ring) à la bande passante (450 GB/s sur H100), avec possibilité d’une implémentation en arbre (Tree) pour les petits messages
- AllToAll : chaque GPU envoie directement au GPU cible, avec un schéma qui divise la bande passante par N ; en pratique, cela peut être 2 fois plus rapide à l’intérieur d’un nœud
- Les mesures réelles montrent environ 370 GB/s sur AllReduce, donc en dessous du maximum matériel
- Par rapport aux TPU, il faut des volumes importants (de plusieurs dizaines de Mo à des Go) pour s’approcher de la peak bandwidth matérielle
Synthèse et enseignements
- Les GPU se distinguent par leur polyvalence et leur extensibilité, mais la difficulté d’optimisation et la visibilité sur les performances sont plus élevées que sur TPU en raison de la structure matérielle et réseau
- Le réseau (Intra-Node/NVLink/InfiniBand/Leaf/Spine, etc.) est un élément clé des performances en entraînement à grande échelle, et il faut prêter attention à l’écart entre bande passante réelle et théorique
- La compréhension des opérations collectives et de la structure réseau est indispensable pour l’entraînement et le serving de modèles distribués géants
- Une démarche fondée sur des benchmarks concrets et une bonne compréhension de l’architecture matérielle est nécessaire pour identifier les goulots d’étranglement et les conditions d’optimisation
1 commentaires
Commentaire Hacker News
J’ai trouvé cet article et plusieurs autres documents assez peu clairs, surtout parce que les termes sont souvent employés de façon ambiguë quand il s’agit d’expliquer les GPU. Par exemple, dans la première image, le « Warp Scheduler » est présenté comme une unité vectorielle SIMD comparable au VPU d’un TPU, avec 32 « CUDA Cores », mais on n’explique pas clairement ce qu’est un « CUDA core », ce qui empêche de bien transmettre l’objet central de l’explication. À cause de ce genre d’erreurs imbriquées, les débutants ou les lecteurs qui essaient d’acquérir les concepts ont toujours du mal à comprendre, tandis que ceux qui connaissent déjà un peu le sujet n’y apprennent rien. Même s’il s’agit d’un brouillon, dès qu’on publie il faut traiter chaque terme avec une précision chirurgicale, sans les confondre ni les mélanger. Il faut aussi être prudent avec les analogies. Et des termes comme MXU (unité d’opérations matricielles) devraient, à mon avis, être accompagnés d’une explication complémentaire ou d’un lien pour qu’on puisse facilement les retrouver. Aujourd’hui on peut confier ce rôle à une IA, ce qui est un peu triste.
Je réponds directement en tant qu’auteur : je suis globalement d’accord avec ces remarques. Plus j’essaie d’assurer la précision des explications, plus je me débats avec l’équilibre à trouver avec une sorte de « vérité morale ». Par exemple, je pourrais écrire « une unité similaire au VPU d’un TPU, composée de 32 ALU, des unités vectorielles SIMD (single instruction, multiple data) que NVIDIA appelle CUDA Cores », mais la phrase devient alors longue, et la définition d’autres termes comme « unité vectorielle » risque encore de manquer. J’essaie d’utiliser beaucoup de notes de bas de page, mais on ne peut pas vraiment s’attendre à ce que les lecteurs cliquent sur chacune d’elles, et les notes latérales sont compliquées à mettre en œuvre en HTML. Des termes comme MXU étaient déjà définis dans un chapitre précédent, mais il me semble excessif de supposer que chaque lecteur lira forcément tous les chapitres. « Warp Scheduler » lui-même est ambigu comme terme, car il désigne en réalité plusieurs rôles à la fois (scheduler, unité de dispatch, SIMD ALU), mais c’est aussi parce que NVIDIA ne donne pas de nom distinct à cette unité composite. Je vais essayer d’améliorer cela à l’avenir, mais ce n’est qu’une suite de compromis difficiles.
Les LLM sont de très bons outils pour surmonter ce genre de difficultés de chaînage terminologique. Quand on cherche un terme et qu’une cascade d’autres termes inconnus apparaît, ils guident assez bien sur le point de départ à adopter pour l’apprentissage.
Presque tout est expliqué dans la documentation sur l’architecture des systèmes TPU de Google.
Je pose la question sérieusement : quel niveau de connaissances préalables en architecture des ordinateurs vous semble approprié ? Le concept même de SIMD a déjà plus de 50 ans. Au début de cette ressource, on considère comme acquise une compréhension des LLM et de l’architecture Transformer, mais on dit aussi qu’aucune compréhension du fonctionnement d’un ordinateur n’est nécessaire. Pourtant, j’ai l’impression qu’il faut au moins connaître les bases du fonctionnement d’un CPU.
Ce contenu est un chapitre d’un livre écrit pour des personnes travaillant dans le domaine du machine learning.
J’ai l’impression qu’il est très difficile de justifier le temps investi quand ce n’est ni open source ni une technologie interopérable entre plusieurs fournisseurs. Bien exploiter les puces Nvidia me fait penser à l’ancien métier de consultant SAP ABAP. Certes, cela rapporte beaucoup dans ce domaine, mais historiquement ce type d’expertise n’a pas été si avantageux.
Je pensais la même chose il y a 10 ans à l’université, au point de sauter volontairement les cours sur CUDA.
CUDA comporte deux aspects : l’architecture matérielle et la pile logicielle qui va avec. La pile logicielle est fermée, donc si vous ne prévoyez pas de faire vous-même des optimisations bas niveau, il n’y a pas vraiment besoin de vous en soucier. En revanche, l’architecture matérielle vaut clairement la peine d’être étudiée. Tous les GPU fonctionnent fondamentalement de manière similaire (la philosophie de base de l’architecture CUDA n’a pas changé depuis 2007), et cette architecture influence fortement les langages de shaders comme les méthodes d’abstraction des GPU. Si l’on comprend des caractéristiques détaillées comme l’ordonnancement des threads, les warps, ou la structure de mémoire privée/partagée, on peut mieux adapter les algorithmes au modèle d’exécution du matériel et exploiter une énorme puissance de calcul.
Je veux insister sur le fait que les principes du calcul parallèle et la manière dont cela fonctionne au niveau matériel et pilote ont une portée assez générale. Une partie est spécifique à certaines plateformes, mais une grande partie peut être réutilisée largement. À l’inverse, croire aveuglément à cette généralité peut aussi se retourner contre vous. Le caractère open source ou non, et le caractère générique ou spécialisé, sont deux axes distincts ; cela mérite donc une exploration plus large.
La transition n’est pas si difficile. Pour quelqu’un qui avait déjà écrit du code OpenMP ou MPI, débuter avec CUDA était en soi assez simple. Et apprendre à optimiser les performances sous CUDA accélère aussi le code parallèle sur CPU, donc c’est essentiellement une évolution des modèles de calcul existants.
J’ai moi aussi appris la programmation très jeune sur IBM PC/MS-DOS. Aucun des deux n’était open source, et pourtant cela m’est encore très utile aujourd’hui.
Je pense que les calculs de la partie « Quiz 2: GPU nodes » sont inexacts. En pratique, le nombre de ports est limité sur chaque GPU ou commutateur, donc les 450GB/s théoriques ne sont pas réellement garantis ; c’est d’ailleurs pour cela que les grands clouds et les systèmes de référence proposent 3.2TB/s. Si 3.6TB/s étaient réellement possibles, il y aurait un goulot d’étranglement sur les charges distribuées en anneau. Par ailleurs, je cherche un emploi.
Toute cette série était vraiment excellente. Elle explique les limites théoriques des workloads IA modernes et vulgarise bien les principes techniques comme l’architecture et la parallélisation. C’est centré sur les TPU, mais cela reste globalement applicable à d’autres domaines, donc très utile.
Il faut d’abord optimiser au maximum le code intensif en calcul dans un langage à typage fort, puis seulement envisager l’option GPU s’il faut encore aller plus vite. D’après mon expérience, un GPU apporte environ un facteur 8. Si l’on peut faire passer une réponse web de 4 secondes à 0,5 seconde, c’est un changement énorme. Mais en pratique, il est souvent plus simple d’afficher une latence via WebSocket avec un spinner, ou d’utiliser un cache en arrière-plan. Et il faut aussi tenir compte du coût élevé de l’exécution sur GPU dans le cloud.
Je trouve intéressant que
nvshmemsoit autant mis en avant dans le ML. À l’inverse, MPI offrant une fonctionnalité équivalente n’était pas si satisfaisant dans l’ancien monde des simulations scientifiques. Pour situer le contexte, je travaillais surtout sur des problèmes difficiles comme le calcul de forces à longue portée sur plusieurs nœuds.Je me demande pourquoi Nvidia n’a pas développé son propre TPU.
Ils n’en ont pas besoin. Ils occupent déjà une position dominante sur le marché du matériel et des modèles de programmation, et un TPU est en fait plus difficile à programmer.
En pratique, comme l’explique cet article, 90 % des performances des GPU Nvidia viennent des unités de calcul matriciel, donc leur structure est presque celle d’un TPU. Ils abandonnent un peu de performance, mais gagnent un écosystème de compilation bien plus flexible.
Je suis encore surpris que Nvidia n’ait jamais fourni officiellement des ressources de ce niveau. On en arrive à une situation où des tiers font de la rétro-ingénierie du matériel pour produire des schémas conceptuels réellement utilisables. Je me demande quelle est la motivation réelle de Nvidia. Si l’objectif n’est que le marketing, alors c’est un succès, mais j’ai des doutes sur la culture d’ingénierie derrière.
Du point de vue d’un ingénieur en rendu temps réel, ça a toujours été comme ça. NV garde la plupart des informations sous clé pour empêcher les concurrents de détecter facilement les changements entre générations. Les autres fournisseurs ne font pas tellement mieux. Dans le jeu vidéo, ils donnent davantage de détails architecturaux sous NDA, mais en dehors de cela, à part Intel, je n’ai jamais vu de publication vraiment complète.
Nvidia publie en réalité beaucoup de documentation officielle d’excellente qualité par rapport aux autres acteurs.
Je suis curieux de savoir pourquoi vous avez cette impression, parce qu’en réalité la plupart des éléments de cet article semblent quasiment repris tels quels de la documentation officielle de Nvidia. Par exemple, le schéma du H100 a en fait été copié sans attribution depuis le whitepaper H100. Les chiffres de calcul et de bande passante viennent eux aussi des whitepapers officiels et des chapitres 5, 6 et 7 du guide CUDA C++. Il y a de la valeur à résumer et à interpréter ces documents de manière plus concise depuis l’extérieur, mais sans les ressources officielles de Nvidia, ce genre d’article aurait été difficile à écrire ; les spéculations et soupçons sans fondement me paraissent donc un peu excessifs.
En ne publiant qu’une documentation d’un niveau moyen, Nvidia fait en sorte que seules des bibliothèques fermées comme cuBLAS ou cuDNN soient vraiment rapides, ce qui renforce le verrouillage fournisseur. Cela complique aussi la tâche des autres entreprises qui voudraient rattraper leur retard par rétro-ingénierie.
Au vu de nombreux indices, Nvidia semble fournir des ressources sur mesure uniquement aux signataires de NDA et aux VIP, tout en négligeant délibérément la publication de manuels officiels publics, car cela les avantage commercialement. Même si l’on met des barrières autour de la documentation officielle des API, les développeurs ordinaires auront plus de mal à y accéder ; mais comme Nvidia se concentre sur la vente de l’ensemble de l’écosystème — IA, GPU, logiciel, documentation réservée aux VIP — ils semblent tout simplement moins se soucier du développeur lambda.
Il faut absolument garder à l’esprit que, lorsque nous regardons des schémas d’architecture, ils ne reflètent pas forcément parfaitement le matériel réel. Nvidia ne garantit pas que les blocs ou composants du schéma existent tels quels dans le matériel ; ils servent surtout de modèle mental pour réfléchir à la structure du GPU et des SM. Par exemple, on ne sait pas officiellement combien d’unités fonctionnelles il y a réellement dans un SM, si le « tensor core » est un matériel indépendant ou le résultat d’une combinaison de plusieurs unités, ni quels sont les détails du fonctionnement en dessous du niveau du warp.
Ressource vraiment fantastique, j’y ai appris plein de choses utiles.