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.
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
Pourquoi un LLM en génération token par token est souvent limité par la mémoire, pas par le calcul.
Le coût du KV cache, de la bande passante HBM, de l’électricité et de l’amortissement matériel.
Le coût technique réel du discours commercial simplifié autour du “coût de calcul GPU”.
Les métriques de facturation : tokens, pourcentage, crédits, quota, et leur niveau de transparence.
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.
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 :
Opérations matricielles effectuées par les cœurs CUDA/Tensor Cores.
Capacité et bande passante nécessaires pour déplacer poids, activations et KV cache.
Serveurs, réseau, refroidissement, électricité, licences, maintenance, amortissement.
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.
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é.
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.
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 :
La performance effective est approximativement bornée par :
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.
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 :
Le modèle traite tout le prompt initial en parallèle. Il remplit le KV cache.
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 :
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 :
Et une borne basse du temps par token est :
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 :
| 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$
Pour une requête avec 131 072 tokens de contexte, le cache peut être environ quatre fois plus grand :
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
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 :
Il faut ajouter l’électricité par GPU-heure :
Si le serveur n’est utilisé qu’à un taux $U$, le coût par GPU-heure réellement utilisée augmente :
Calculateur de coût GPU
Estimer un coût GPU-h
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
Un pourcentage est plus compréhensible pour un utilisateur non technique.
Il peut limiter les usages intensifs sans exposer une facturation complexe.
Il évite de révéler précisément le coût interne d’une requête.
Le fournisseur peut changer les modèles ou l’infrastructure sans changer l’affichage.
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
Il faut stocker le KV cache de nombreux utilisateurs simultanément.
À chaque token généré, le système peut devoir relire une grande quantité de cache.
Plus le contexte est long, plus la génération peut ralentir si la mémoire suit mal.
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 :
Si une requête longue utilise 40 Go de KV cache, alors seulement 16 requêtes de ce type peuvent tenir en mémoire :
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é.
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
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
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.
- Prends un modèle avec 80 couches.
- Suppose 8 têtes KV.
- Suppose une dimension de 128 par tête.
- Calcule la taille du cache pour 8k, 32k et 128k tokens.
- 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.
Exemple :
- Données à déplacer : 12 Go par token
- Bande passante : 3.2 To/s
Cela donne une limite théorique d’environ :
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.
- Crée deux requêtes avec le même nombre de tokens de sortie.
- Requête A : prompt court.
- Requête B : très long document.
- Observe la consommation affichée.
- 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
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.