Cours complet LLM Infrastructure Honnête et concret

Le vrai coût des LLM : GPU, mémoire, KV cache et infrastructure

Ce cours explique pourquoi, pendant l’inférence d’un LLM, le GPU passe une grande partie de son temps à attendre la mémoire plutôt qu’à calculer. Il montre concrètement que le coût réel n’est pas “le calcul GPU” au sens marketing, mais l’infrastructure complète : serveurs, HBM, réseau, refroidissement, amortissement, disponibilité 24/7 et ingénierie.

Écouter ce cours (22 min)

Version audio générée localement (Pocket TTS, Kyutai, voix Estelle). Les exemples de code et tableaux sont à retrouver sur cette page.

1. Objectifs du cours

Comprendre
Pourquoi un LLM en génération token par token est souvent limité par la mémoire, pas par le calcul.
Quantifier
Le coût du KV cache, de la bande passante HBM, de l’électricité et de l’amortissement matériel.
Démêler
Le coût technique réel du discours commercial simplifié autour du “coût de calcul GPU”.
Analyser
Les métriques de facturation : tokens, pourcentage, crédits, quota, et leur niveau de transparence.
Idée centrale : pour beaucoup d’inférences LLM, la ressource critique n’est pas “combien d’opérations le GPU peut faire”, mais “combien de données peuvent arriver assez vite depuis la mémoire vers le GPU”.

2. Avertissement d’honnêteté

Ce cours se veut honnête. Cela signifie plusieurs choses importantes :

  • Les chiffres donnés sont des ordres de grandeur, pas des données confidentielles exactes.
  • Le coût réel dépend du modèle, de la quantification, du batching, du serveur, du datacenter et de la région.
  • Un fournisseur peut utiliser un affichage en pourcentage sans que cela soit forcément une fraude.
  • En revanche, l’absence de métriques techniques précises réduit la transparence pour l’utilisateur.
Point honnête : dire “le GPU attend” est vrai surtout pendant la phase de génération token par token. Pendant la phase de préremplissage du prompt, le GPU peut être beaucoup plus occupé par du calcul massif.

3. Le problème : le mythe du coût GPU

Dans le discours commercial, on entend souvent :

« Votre requête coûte cher parce que le GPU a fait beaucoup de calcul. »

Cette phrase est souvent trompeuse pour les LLM en inférence, car elle mélange plusieurs choses :

Calcul GPU
Opérations matricielles effectuées par les cœurs CUDA/Tensor Cores.
Mémoire HBM
Capacité et bande passante nécessaires pour déplacer poids, activations et KV cache.
Infrastructure
Serveurs, réseau, refroidissement, électricité, licences, maintenance, amortissement.
Disponibilité
Le serveur doit être payé même quand il est peu utilisé, surtout pour un service 24/7.

Dans la réalité, une requête LLM mobilise surtout :

  • de la mémoire GPU rare et coûteuse ;
  • de la bande passante mémoire ;
  • du réseau entre GPU ;
  • de l’électricité et du refroidissement ;
  • un serveur qu’il faut amortir sur plusieurs années.
Problème de transparence : si un fournisseur ne montre que “pourcentage utilisé” sans expliquer ce que ce pourcentage représente réellement, l’utilisateur ne peut pas vérifier si la consommation correspond à des tokens, du temps GPU, de la mémoire, du contexte long, des tokens de raisonnement, ou un mélange de tout cela.

4. Le GPU attend la mémoire : compute-bound vs memory-bound

Un GPU moderne est extrêmement rapide pour calculer, mais il doit être alimenté en données. Si les données arrivent trop lentement depuis la mémoire, les unités de calcul attendent.

Deux régimes possibles

Régime Ce qui limite Exemple
Compute-bound La puissance de calcul du GPU Préremplissage d’un long prompt, entraînement, grandes multiplications matricielles
Memory-bound La bande passante mémoire Génération token par token, lecture du KV cache, chargement des poids

Pendant la génération autoregressive, le modèle doit souvent lire beaucoup de données pour produire un seul token. Le calcul effectué sur ces données est relativement faible par rapport au volume déplacé.

Temps de calcul utile
Temps passé à attendre la mémoire

Illustration pédagogique : pendant le décodage, une grande partie du temps peut être passée à attendre les données mémoire. Les proportions exactes dépendent du modèle, du batch, de la quantification et du moteur d’inférence.

Image simple : le GPU est un moteur très puissant, mais la mémoire est un tuyau. Si le tuyau est trop petit, le moteur ne peut pas utiliser toute sa puissance.

5. Roofline et intensité arithmétique

Pour analyser si une charge est limitée par le calcul ou par la mémoire, on utilise souvent le modèle roofline.

On définit l’intensité arithmétique :

$$ I = \frac{\text{FLOPs}}{\text{bytes lus ou écrits}} $$

La performance effective est approximativement bornée par :

$$ P_{\text{effective}} = \min \left( P_{\text{peak}}, BW_{\text{memory}} \times I \right) $$

Où :

  • $P_{\text{peak}}$ est la puissance de calcul maximale du GPU ;
  • $BW_{\text{memory}}$ est la bande passante mémoire ;
  • $I$ est l’intensité arithmétique de l’opération.

Exemple avec un GPU moderne

Métrique Ordre de grandeur
Puissance FP16/BF16 ~900 à 1000 TFLOPS
Bande passante HBM ~3 à 3.5 TB/s
Seuil roofline approximatif ~250 à 350 FLOPs par byte

Beaucoup d’opérations de décodage LLM ont une intensité arithmétique faible, souvent bien inférieure à ce seuil. Donc elles sont limitées par la mémoire.

$$ I_{\text{decode}} \ll I_{\text{seuil}} $$

Résultat : le GPU ne peut pas exprimer sa pleine puissance de calcul pendant une grande partie de la génération token par token.

6. Prefill vs decode : deux phases très différentes

L’inférence d’un LLM contient deux grandes phases :

Prefill
Le modèle traite tout le prompt initial en parallèle. Il remplit le KV cache.
Decode
Le modèle génère les tokens suivants un par un. Il relit le KV cache à chaque étape.

6.1 Prefill

Pour un prompt de longueur $T_{\text{prompt}}$, le modèle calcule les représentations de tous les tokens du prompt. Cette phase est souvent plus proche d’un régime compute-bound.

Une approximation simple du coût de calcul des couches linéaires est :

$$ C_{\text{prefill}} \approx 2 \times N_{\text{params}} \times T_{\text{prompt}} $$

Cette formule est simplifiée : elle ne compte pas toute l’attention, les normalisations, les activations, ni les surcoûts système.

6.2 Decode

Pendant la génération, chaque nouveau token demande :

  • de charger une partie des poids du modèle ;
  • de lire le KV cache existant ;
  • de calculer la nouvelle query, key, value ;
  • de mettre à jour le cache ;
  • de produire le token suivant.

Le volume mémoire à déplacer pour un token généré peut être approximé par :

$$ B_{\text{decode}} \approx B_{\text{weights}} + B_{\text{KV read}} $$

Et une borne basse du temps par token est :

$$ t_{\text{token}} \ge \frac{B_{\text{decode}}}{BW_{\text{memory}}} $$
Conséquence : si le KV cache est volumineux, chaque token généré peut obliger le système à déplacer plusieurs gigaoctets de données.

7. KV cache : le vrai poids mémoire

Le KV cache est la mémoire contextuelle du Transformer pendant la génération. Il stocke les clés et valeurs des tokens précédents pour éviter de recalculer tout le passé.

Sa taille est donnée par :

$$ M_{KV} = 2 \times B \times L \times T \times H_{KV} \times d_h \times b $$
Symbole Signification
$2$ stockage de $K$ et $V$
$B$ batch size
$L$ nombre de couches
$T$ longueur de séquence
$H_{KV}$ nombre de têtes KV
$d_h$ dimension par tête
$b$ octets par valeur

Exemple concret

Prenons un modèle de type 70B avec Grouped Query Attention :

  • $L = 80$ couches
  • $H_{KV} = 8$ têtes KV
  • $d_h = 128$
  • $b = 2$ octets
  • $T = 32768$ tokens
  • $B = 1$
$$ M_{KV} = 2 \times 1 \times 80 \times 32768 \times 8 \times 128 \times 2 $$
$$ M_{KV} \approx 1.07 \times 10^{10} \text{ bytes} \approx 10 \text{ GiB} $$

Pour une requête avec 131 072 tokens de contexte, le cache peut être environ quatre fois plus grand :

$$ M_{KV} \approx 40 \text{ GiB} $$

Cela signifie qu’un seul utilisateur avec un long contexte peut mobiliser une quantité importante de mémoire GPU très coûteuse.

Calculateur KV cache

Calculer la taille du KV cache

Résultat ici.
Point concret : plus le contexte est long, plus le KV cache est gros, plus la bande passante mémoire devient critique. C’est un coût d’infrastructure majeur pour les modèles long contexte.

8. Décomposition réelle du coût

Le coût réel d’un service LLM n’est pas seulement le coût marginal d’une requête. Il faut payer l’infrastructure complète, qu’elle soit utilisée ou non.

8.1 Coûts matériels

Poste Impact
GPU Composant principal, très coûteux, souvent soumis à forte demande.
HBM Mémoire GPU rapide mais chère, indispensable pour le KV cache.
CPU / RAM Nécessaires pour l’orchestration, le stockage temporaire, le batching.
Réseau InfiniBand, NVLink, switches, NICs : critique pour le parallélisme.
Stockage Modèles, checkpoints, logs, cache de préfixe, datasets.
Refroidissement Les serveurs GPU consomment beaucoup et chauffent beaucoup.

8.2 Coûts opérationnels

Poste Impact
Électricité Un serveur GPU peut consommer plusieurs kW en continu.
Datacenter Espace, sécurité, redondance, onduleurs, climatisation.
Ingénierie Optimisation, monitoring, déploiement, sécurité, support.
Licences Logiciels, outils, firmware, stack GPU, monitoring.
Capacité inutilisée Un serveur payé 24/7 n’est pas toujours utilisé à 100%.

8.3 Formule d’amortissement

Si un serveur coûte $C_{\text{server}}$, contient $N_{\text{GPU}}$ GPU, est amorti sur $Y$ années, alors le coût matériel par GPU-heure disponible est :

$$ C_{\text{amort,GPU}} = \frac{C_{\text{server}}}{N_{\text{GPU}} \times Y \times 8760} $$

Il faut ajouter l’électricité par GPU-heure :

$$ C_{\text{power,GPU}} = \frac{P_{\text{server}} \times C_{\text{kWh}}}{N_{\text{GPU}}} $$

Si le serveur n’est utilisé qu’à un taux $U$, le coût par GPU-heure réellement utilisée augmente :

$$ C_{\text{busy}} = \frac{C_{\text{available}}}{U} $$
Point honnête : si un serveur coûte cher mais tourne seulement à 30% de capacité utile, chaque heure réellement utilisée doit supporter une partie des heures inutilisées.

Calculateur de coût GPU

Estimer un coût GPU-h

Résultat ici.

9. Pourcentage, tokens et opacité commerciale

Beaucoup de services LLM affichent des tokens pour les API, mais des quotas ou pourcentages pour les interfaces grand public. Ce n’est pas forcément une fraude, mais cela peut être opaque.

9.1 Pourquoi les tokens seuls sont insuffisants

Avec les modèles modernes, deux requêtes ayant le même nombre de tokens peuvent avoir des coûts très différents.

Situation Impact sur le coût réel
Prompt court, réponse courte Faible contexte, KV cache petit, coût plus faible.
Prompt long, réponse courte Le contexte long remplit le KV cache, même si la réponse est courte.
Réponse avec raisonnement interne Le modèle peut générer beaucoup de tokens cachés avant de répondre.
Long document analysé Le coût dépend fortement de la longueur du document et du contexte.
Plusieurs utilisateurs simultanés Le batching change le coût par requête et la latence.

9.2 Pourquoi un fournisseur peut afficher un pourcentage

Simplicité
Un pourcentage est plus compréhensible pour un utilisateur non technique.
Fair-use
Il peut limiter les usages intensifs sans exposer une facturation complexe.
Masquage des coûts
Il évite de révéler précisément le coût interne d’une requête.
Flexibilité
Le fournisseur peut changer les modèles ou l’infrastructure sans changer l’affichage.
Problème : si le pourcentage est utilisé sans explication, l’utilisateur ne sait pas s’il consomme des tokens, du temps GPU, de la mémoire, du contexte long, ou une combinaison pondérée. Cela réduit la capacité d’audit et de comparaison.

9.3 Ce qu’un fournisseur transparent devrait montrer

  • tokens d’entrée et de sortie ;
  • tokens de raisonnement, s’ils existent ;
  • longueur de contexte utilisée ;
  • modèle réellement utilisé ;
  • limitations de débit ;
  • période de remise à zéro du quota ;
  • méthode de calcul du quota ou du pourcentage ;
  • différence entre usage API et usage interface web.

10. Étude de cas : modèle long contexte type Kimi

Considérons un modèle long contexte capable de traiter de très grands documents. Ce type de service est particulièrement sensible au KV cache.

10.1 Ce qui coûte cher

Capacité HBM
Il faut stocker le KV cache de nombreux utilisateurs simultanément.
Bande passante
À chaque token généré, le système peut devoir relire une grande quantité de cache.
Latence
Plus le contexte est long, plus la génération peut ralentir si la mémoire suit mal.
Batching
Pour être rentable, le serveur doit traiter plusieurs requêtes en parallèle.

10.2 Exemple simplifié

Supposons un serveur avec 8 GPU ayant chacun 80 Go de HBM. La mémoire totale est :

$$ 8 \times 80 \text{ Go} = 640 \text{ Go} $$

Si une requête longue utilise 40 Go de KV cache, alors seulement 16 requêtes de ce type peuvent tenir en mémoire :

$$ \frac{640}{40} = 16 $$

Cela ne compte pas les poids du modèle, les activations, le système d’exploitation, les autres requêtes, ni la marge de sécurité.

Conséquence : les requêtes long contexte ne sont pas “juste” des requêtes avec plus de tokens. Elles mobilisent une ressource rare : la mémoire GPU rapide.

10.3 Lecture honnête

Si un service affiche un pourcentage plutôt que des tokens, cela peut être une manière de représenter un “crédit d’infrastructure” plutôt qu’un simple comptage de mots.

Mais sans documentation claire, l’utilisateur ne peut pas vérifier :

  • si le pourcentage est linéaire ;
  • si un long document consomme beaucoup plus ;
  • si le raisonnement interne compte double ou plus ;
  • si le quota est partagé entre tous les utilisateurs ;
  • si les pics de charge influencent la consommation affichée.

11. Comment mesurer concrètement

Pour éviter de se fier uniquement au discours commercial, il faut mesurer.

11.1 Métriques utiles

Métrique Signification
TTFT Time To First Token : temps avant le premier token généré.
ITL Inter-Token Latency : temps entre deux tokens générés.
Tokens/s Débit de génération, mais insuffisant seul.
GPU utilization Peut être trompeur : 100% ne signifie pas calcul utile à 100%.
Memory bandwidth utilization Indique si le système est limité par la mémoire.
KV cache usage Mémoire utilisée pour les contextes en cours.
Batch size Nombre de requêtes traitées simultanément.
Cost per request Coût réel estimé par requête.

11.2 Outils possibles

nvidia-smi
nvidia-smi dmon -s pucvmet
dcgmi dmon
vLLM metrics endpoint
PyTorch Profiler
Nsight Systems
Nsight Compute
Point important : regarder seulement nvidia-smi et voir “GPU 100%” ne prouve pas que le GPU calcule utilement. Le GPU peut être à 100% occupé par des kernels qui attendent principalement la mémoire.

11.3 Formule de coût par requête

$$ C_{\text{request}} = \frac{ C_{\text{GPU-hour}} \times T_{\text{GPU}} } { N_{\text{requests}} } $$

Où :

  • $C_{\text{GPU-hour}}$ est le coût réel d’une heure GPU ;
  • $T_{\text{GPU}}$ est le temps GPU total ;
  • $N_{\text{requests}}$ est le nombre de requêtes servies.

12. Travaux pratiques

TP 1 : Calculer le poids du KV cache

Objectif : comprendre l’impact de la longueur de contexte sur la mémoire GPU.

  1. Prends un modèle avec 80 couches.
  2. Suppose 8 têtes KV.
  3. Suppose une dimension de 128 par tête.
  4. Calcule la taille du cache pour 8k, 32k et 128k tokens.
  5. Compare avec la mémoire disponible d’un GPU de 80 Go.

TP 2 : Estimer le temps minimal par token

Objectif : comprendre la limite de bande passante.

$$ t_{\text{token}} \ge \frac{B_{\text{decode}}}{BW_{\text{memory}}} $$

Exemple :

  • Données à déplacer : 12 Go par token
  • Bande passante : 3.2 To/s
$$ t_{\text{token}} \ge \frac{12}{3200} \approx 0.00375 \text{ s} $$

Cela donne une limite théorique d’environ :

$$ \frac{1}{0.00375} \approx 266 \text{ tokens/s} $$

Cette valeur est une borne idéale. En pratique, les poids du modèle, la latence, le réseau, le batching, le scheduler et les accès mémoire réduisent le débit réel.

TP 3 : Comparer deux facturations

Objectif : comprendre l’effet d’un affichage par tokens contre un affichage par pourcentage.

  1. Crée deux requêtes avec le même nombre de tokens de sortie.
  2. Requête A : prompt court.
  3. Requête B : très long document.
  4. Observe la consommation affichée.
  5. Demande-toi si la consommation est proportionnelle aux tokens, au contexte, ou à autre chose.

TP 4 : Analyser un serveur

Objectif : distinguer GPU occupé et GPU utile.

# Observer utilisation GPU
watch -n 1 nvidia-smi

# Observer puissance, utilisation, mémoire
nvidia-smi dmon -s pucvmet

# Voir les processus
nvidia-smi --query-compute-apps=pid,used_memory --format=csv
Exercice honnête : si tu ne peux pas accéder aux métriques internes du fournisseur, tu peux seulement faire une analyse externe : latence, débit, comportement avec long contexte, et comparaison de quotas.

13. Quiz

Question 1 : Pendant la génération token par token, le LLM est souvent limité par quoi ?

Par la bande passante mémoire. Le GPU doit lire les poids et le KV cache, et le volume de données déplacé est souvent plus contraignant que la puissance de calcul brute.

Question 2 : Le KV cache contient quoi ?

Il contient les anciennes clés et valeurs des tokens précédents, pour chaque couche du modèle. Il évite de recalculer tout le contexte à chaque token généré.

Question 3 : Pourquoi un long contexte coûte cher ?

Parce qu’il augmente la taille du KV cache, donc la mémoire GPU nécessaire et la bande passante à lire pendant la génération. Même une réponse courte peut coûter cher si le contexte est énorme.

Question 4 : Un GPU à 100% dans nvidia-smi signifie-t-il forcément qu’il calcule utilement ?

Non. Il peut être occupé par des kernels qui attendent principalement la mémoire. Il faut regarder des métriques plus fines : bande passante, stalls, profilage, débit utile.

Question 5 : Pourquoi un fournisseur peut afficher un pourcentage plutôt que des tokens ?

Parce que le coût réel dépend de nombreux facteurs : contexte long, tokens cachés de raisonnement, batching, mémoire, disponibilité serveur. Le pourcentage peut représenter un quota d’infrastructure. Mais sans explication, cela manque de transparence.

Question 6 : Le coût marginal d’une requête est-il le seul coût à payer ?

Non. Il faut aussi amortir le serveur, payer l’électricité, le refroidissement, le réseau, la maintenance, l’ingénierie, et la capacité inutilisée.

14. Conclusion honnête

Le discours “le coût vient du calcul GPU” est souvent simplificateur, voire trompeur, lorsqu’il est appliqué à l’inférence token par token des LLM.

En réalité, le système paie surtout :

  • la mémoire GPU rapide ;
  • la bande passance HBM ;
  • le KV cache des longs contextes ;
  • les serveurs disponibles 24/7 ;
  • l’électricité et le refroidissement ;
  • l’amortissement du matériel ;
  • l’ingénierie nécessaire pour rendre le service stable.
Point critique : si un service affiche uniquement un pourcentage sans expliquer ce qu’il mesure, il crée une zone d’opacité. Ce n’est pas forcément une faute technique ou légale, mais c’est un manque de clarté pour l’utilisateur.
À retenir : le GPU est souvent une machine très puissante qui attend des données. Le vrai défi des LLM modernes n’est pas seulement “calculer plus vite”, mais “nourrir le GPU assez vite” tout en payant une infrastructure très coûteuse.