Le malentendu sur les FLOPS
Quand on compare deux GPU, le premier chiffre cité est toujours le même : les FLOPS Floating-Point Operations Per Second. Métrique brute de débit de calcul flottant, en téra ou péta. Pour l'inférence LLM, c'est rarement le facteur limitant : la bande passante mémoire le devance presque toujours. Approfondir dans le glossaire . C’est aussi le moins utile pour l’inférence LLM. Pour comprendre pourquoi, il faut suivre ce qui se passe à chaque token généré : le GPU prend un vecteur d’entrée, le multiplie par chaque matrice de poids du modèle, lit chaque vecteur clé et chaque vecteur valeur déjà accumulés dans le KV cache Mémoire des vecteurs clé et valeur déjà calculés pour chaque token traité par un LLM. Évite de recalculer l'attention sur tout l'historique, au prix d'une consommation mémoire qui croît avec le contexte. Approfondir dans le glossaire , puis recommence pour le token suivant. À chaque étape, des milliards d’octets traversent le bus mémoire pour quelques milliers d’opérations utiles par octet lu.
Le modèle du roofline formalise cette intuition : on trace, pour chaque kernel, son intensité arithmétique (opérations par octet transféré) et on regarde si elle plafonne contre le débit mémoire ou contre le débit de calcul. À faible batch, le decode Phase de génération autorégressive d'un LLM : un token est produit à la fois en relisant les poids et l'état de contexte utile. À faible batch, ce trafic peut limiter le decode par la bande passante mémoire. Sa part dans le coût total dépend toutefois des longueurs d'entrée et de sortie, du batching et de la réutilisation du cache. Approfondir dans le glossaire autorégressif d’un LLM tombe du côté mémoire lorsque le trafic des poids et du contexte dépasse la capacité à alimenter les unités de calcul. Le GPU attend alors que la HBM High Bandwidth Memory. Mémoire DRAM empilée, intégrée au même package que l'accélérateur et reliée par une interface très large. Elle fournit plusieurs To/s, mais sa topologie de packaging exacte dépend du produit. Approfondir dans le glossaire livre ces données au lieu d’occuper pleinement ses Tensor Cores Unités matérielles spécialisées dans les multiplications de matrices à basse précision, introduites par NVIDIA avec Volta (2017). Chaque génération ajoute des formats supportés : FP16 → FP8 (Hopper) → FP6/FP4 (Blackwell). Ce sont elles qui exécutent l'essentiel du calcul d'inférence. Approfondir dans le glossaire . Le point de bascule dépend du modèle, du batch, de la longueur de séquence et des kernels.
Prefill vs decode : deux régimes opposés
Une requête LLM se déroule en deux phases qu’il faut absolument distinguer, parce qu’elles sollicitent le GPU de manière diamétralement opposée.
Le prefill Phase initiale d'une inférence LLM : les tokens du prompt sont traités en parallèle pour construire l'état du contexte. Cette réutilisation augmente l'intensité arithmétique et peut rendre la phase limitée par le calcul ; le régime exact dépend du modèle, du batch, du contexte et du backend. Approfondir dans le glossaire traite le prompt entier d’un coup. Toutes les positions du prompt passent ensemble dans la même matmul Multiplication de matrices, l'opération dominante des couches d'un réseau de neurones. Quand on dit qu'un GPU « calcule », il fait à 90 % des matmul. : un prompt de 2 000 tokens produit des matrices de 2 000 lignes, et chaque ligne de poids lue depuis la HBM est réutilisée 2 000 fois. L’intensité arithmétique grimpe, et cette phase peut effectivement saturer les Tensor Cores. Le decode génère ensuite les tokens un par un. Chaque nouveau token relit l’intégralité des poids et tout le KV cache accumulé, mais ne fait qu’une seule ligne de matmul. Le ratio opérations/octets s’effondre d’un facteur égal à la longueur du prompt qu’on traitait juste avant.
La HBM, vrai plafond du decode
La mémoire à haute bande passante empile des dies DRAM et les intègre au package de l’accélérateur par une interface très large. La topologie exacte varie selon le produit et son interposeur. Au lieu d’un canal mémoire à quelques dizaines de Go/s, l’agrégat se chiffre en téraoctets par seconde. Pour un decode à faible batch déjà placé du côté mémoire du roofline, ce plafond prédit mieux le débit que les seuls FLOPS de pointe.
| Génération | Bande passante / pile | Usage typique | Génération GPU |
|---|---|---|---|
| HBM2e | ≈ 410 Go/s | A100 80 Go (~2,0 To/s) | Ampere |
| HBM3 | ≈ 670 Go/s | H100 80 Go (3,35 To/s) | Hopper |
| HBM3e | ≈ 1,0 To/s | B100 / B200 192 Go (~8 To/s) | Blackwell |
Le saut Hopper → Blackwell tient surtout à la mémoire, comme on le détaille dans H100 vs B100. Doubler la bande passante double, en première approximation, le débit de decode d’un modèle memory-bound : c’est la même règle qui transforme deux GPU identiques en deux machines aux tokens/s très différents quand on change la HBM.
Le KV cache, ce poids qu’on oublie
Les poids du modèle, une fois chargés, sont une constante : 140 Go en FP16 pour un 70B, qu’on relit à chaque token sans jamais y écrire. Le KV cache, lui, est une variable qui grossit à chaque token généré. Le mécanisme est direct : à chaque nouvelle position, l’attention doit comparer le token courant à tous les précédents. Plutôt que de recalculer les projections clé et valeur de tout l’historique à chaque pas, ce qui rendrait la génération quadratique en longueur de contexte, on les stocke. Une fois calculé, un vecteur clé reste en HBM jusqu’à la fin de la requête. Le coût d’attention par token redevient linéaire ; le coût mémoire devient une rampe qui monte avec le contexte.
Le calcul de taille suit la même mécanique. Pour un Llama 70B en FP16, chaque token ajoute deux vecteurs (clé et valeur) par couche, par tête KV : 80 couches × 8 têtes en GQA (grouped-query attention, qui partage les têtes KV entre plusieurs têtes Q pour réduire le cache) × 128 dimensions × 2 octets × 2 vecteurs ≈ 320 Ko par token. À 8 000 tokens de contexte, ça fait de l’ordre de 2,6 Go par requête. Servez 32 requêtes en parallèle pour amortir le coût de chargement des poids : on atteint ~80 Go, déjà plus de la moitié des 140 Go des poids eux-mêmes, et à lui seul de quoi remplir toute la HBM d’un H100 80 Go. Poussez le contexte ou le batch plus loin et le cache finit par dépasser les poids : c’est lui, pas le modèle, qui fait déborder la mémoire en premier.
C’est précisément ce que cherchent à corriger les runtimes modernes. PagedAttention Algorithme introduit par vLLM qui gère le KV cache comme la mémoire virtuelle d'un système d'exploitation : par pages, sans exiger un bloc contigu par requête. Élimine la fragmentation interne et externe, permet de servir 2 à 4× plus de requêtes concurrentes sur la même VRAM. Approfondir dans le glossaire , détaillé dans le comparatif des runtimes, traite le KV cache comme la mémoire virtuelle d’un système d’exploitation : par pages de quelques dizaines de tokens, sans réserver un bloc contigu par requête. La fragmentation interne disparaît, et on tient plus de requêtes simultanées sur la même HBM. La quantification du cache attaque l’autre levier : passer les clés et valeurs en INT8 voire INT4 divise la taille d’un facteur 2 à 4 au prix d’une dégradation contrôlée de la qualité d’attention.
NVLink : quand un GPU ne suffit plus
Dès qu’un modèle, ou son KV cache, ne tient plus sur une seule carte, il faut le répartir. Le tensor parallelism découpe chaque matrice de poids le long d’un axe : chaque GPU détient une tranche verticale, calcule sa contribution partielle, puis échange les activations résultantes pour que la sortie reconstituée soit cohérente. Cet échange (un all-reduce, primitive collective où chaque carte envoie son résultat partiel et reçoit la somme agrégée) arrive à chaque couche, des dizaines de fois par token.
Voici ce qui se passe concrètement quand l’interconnexion est lente : le GPU termine sa matmul en quelques microsecondes, puis attend que ses voisins lui livrent leur part avant de pouvoir entamer la couche suivante. La bande passante de l’interconnexion devient un prolongement de la bande passante mémoire, un goulot supplémentaire, en série.
La règle pratique tient en une ligne : tout ce qui force à descendre d’un cran dans cette hiérarchie coûte cher. Un modèle qui tient sur un seul GPU avec un NVLink Interconnexion propriétaire NVIDIA entre GPU. NVLink 5 (Blackwell) atteint 1,8 To/s bidirectionnels par GPU ; NVLink 6 (Rubin) double à 3,6 To/s. Avec NVSwitch, elle accélère les échanges GPU-GPU et les collectifs ; les mémoires restent physiquement distribuées et un accès distant n'a pas le coût de la HBM locale. Approfondir dans le glossaire rapide bat presque toujours un modèle éclaté sur un réseau Ethernet, même avec plus de FLOPS cumulés, parce qu’on déplace alors les activations à 10-25 Go/s au lieu de plusieurs centaines, et que le decode passe son temps à attendre.
Ce que ça change pour le dimensionnement
Trois réflexes en découlent, tous dérivés du même constat memory-bound. Choisir un GPU pour sa bande passante et sa capacité HBM avant ses FLOPS : un H100 et un B200 diffèrent surtout par leur mémoire, pas par leurs Tensor Cores. Budgéter le KV cache comme un poste de mémoire à part entière, fonction du contexte maximal et du batch cible : à 8k de contexte et batch 32, le cache d’un 70B pèse déjà 80 Go en FP16. Et préférer, à FLOPS égaux, la configuration qui garde le modèle sur le moins de GPU possible avec l’interconnexion la plus rapide : chaque cran descendu dans la hiérarchie de transport coûte un facteur sur le débit.
Pour observer ces régimes sur une machine réelle (ordonnancement, page faults, I/O qui gèlent le calcul), voir eBPF et perf appliqués à l’inférence.
Conclusion
Le débat « combien de FLOPS » occulte la vraie contrainte. La prochaine fois qu’un vendeur ouvre une fiche technique sur les pétaflops, posez la question miroir : combien de To/s sur la HBM, combien de Go/s sur l’interconnexion, et combien de Go par requête pour le KV cache à votre contexte cible ? Ce sont ces trois chiffres qui décident du coût par token en production. Le reste, c’est de la décoration.
Sources et méthode
Calculateur ouvert. Le plancher de débit memory-bound (tokens/s déduits de la bande passante, pour chaque modèle × GPU) : llm-roofline (démo).
Modèle roofline. S. Williams, A. Waterman, D. Patterson, Roofline: an insightful visual performance model for multicore architectures, Communications of the ACM, vol. 52, n° 4, p. 65-76, 2009 (DOI 10.1145/1498765.1498785).
Spécifications mémoire. Bandes passantes totales issues des fiches constructeur : NVIDIA A100 (80 Go HBM2e, ~2,0 To/s), H100 (80 Go HBM3, 3,35 To/s) et B100/B200 (192 Go HBM3e, ~8 To/s) ; NVIDIA Hopper Architecture In-Depth pour le détail des piles. Les valeurs par pile du tableau sont des ordres de grandeur dérivés (bande passante totale ÷ nombre de piles actives : 5 pour A100 et H100, 8 pour B100/B200), pas des chiffres publiés tels quels.
Ordres de grandeur du KV cache. Estimations calculées via 2 × couches × têtes KV × dimension de tête × longueur × octets, à partir des dimensions publiées de Llama 2/3 70B (80 couches, 8 têtes KV en GQA, dimension 128).
NVLink. Bandes passantes par GPU issues de la documentation NVIDIA : 3ᵉ génération 600 Go/s (A100), 4ᵉ génération 900 Go/s (H100), 5ᵉ génération 1,8 To/s (Blackwell).