Quantification du KV-Cache : TurboQuant et l'état de l'art en 2026
Tu fais tourner un LLM à 128K tokens de contexte et ta VRAM fond comme neige au soleil. Le coupable n'est pas le modèle lui-même — ce sont les clés et valeurs intermédiaires que l'attention stocke à chaque couche. Le fameux KV-cache. Sur un Llama 3.1 70B à 128K tokens, il pèse 40 Go de VRAM en FP16. Plus que les poids du modèle lui-même.
En 2026, la quantification du KV-cache est devenue le champ de bataille principal de l'optimisation inférence. Et TurboQuant — publié par Microsoft Research en février — a changé la donne. Compression 7x, perte de qualité inférieure à 1 %, compatible avec le décodage par blocs. Voici comment ça marche, pourquoi c'est différent, et ce que ça change pour toi.
Le problème : le KV-cache, gouffre silencieux
Pour comprendre le problème, il faut comprendre ce que fait l'attention dans un transformer. À chaque couche, le modèle projette les tokens en trois vecteurs : Query, Key, Value. Les Queries servent à interroger. Les Keys et Values sont stockées — c'est le cache — pour que chaque nouveau token puisse « regarder en arrière » sans recalculer toute la séquence.
Le problème est arithmétique. Pour un modèle à $L$ couches, $H$ têtes d'attention et une dimension par tête $d$, le KV-cache consomme :
$$\text{Mémoire} = 2 \times L \times H \times d \times S \times \text{bytes\_par\_élément}$$
Avec $S$ la longueur de la séquence. Le facteur 2, c'est pour les Keys ET les Values. Chaque token ajouté grossit linéairement le cache. Et en FP16 (2 octets par élément), ça explose vite.
Résultat concret : tu ne peux pas servir de longs contextes sans des GPU haut de gamme. Et même avec un A100 80 Go, tu es limité à un seul utilisateur simultané à 128K tokens. C'est inacceptable en production.
L'approche naïve : quantifier brutalement en INT8/INT4
La première idée est évidente : quantifier les tenseurs KV en INT8 ou INT4 comme on le fait pour les poids du modèle. Après tout, si GPTQ et AWQ fonctionnent pour les poids, pourquoi pas pour le cache ?
Le problème, c'est la distribution. Les poids d'un modèle entraîné suivent une distribution gaussienne relativement propre, centrée autour de zéro, avec des queues fines. Les valeurs du KV-cache, elles, sont une autre bête. Certaines têtes d'attention produisent des distributions quasi-uniformes. D'autres génèrent des outliers massifs — des valeurs 100x plus grandes que la médiane — qui concentrent l'essentiel de l'information.
C'est le problème que chaque papier de la dernière année a tenté de résoudre. Et chacun a trouvé un angle différent.
L'état de l'art avant TurboQuant
KIVI (2024) — la quantification asymétrique par canal
KIVI, publié par l'université de Virginia, a posé les bases. Leur observation clé : les Keys et les Values ne se comportent pas de la même manière. Les Keys ont des outliers par canal (certaines dimensions de la tête d'attention sont systématiquement plus grandes). Les Values ont des outliers par token (certains tokens produisent des valeurs extrêmes dans toutes les dimensions).
La solution KIVI : quantifier les Keys par canal (chaque dimension a ses propres paramètres min/max) et les Values par token. Résultat : INT2 sur les Keys, INT2 sur les Values, avec un résidu FP16 pour les derniers tokens. 2,6x de compression avec une perte acceptable.
Gear (2024) — la quantification avec résidu compressé
Gear a adopté une approche différente. Au lieu de jouer sur la granularité de la quantification, ils gardent un résidu explicite : la différence entre la valeur FP16 originale et la valeur dé-quantifiée. Ce résidu est ensuite compressé par une matrice de rang faible (SVD tronquée). Bonne idée en théorie, mais le coût computationnel de la SVD à chaque couche rend l'approche impraticable à grande échelle.
KVQuant (2024) — la quantification non-uniforme
KVQuant a poussé la réflexion plus loin. Leur insight : pourquoi utiliser une quantification linéaire (espacement uniforme entre les niveaux) quand la distribution n'est pas uniforme ? Ils ont introduit la quantification non-uniforme via un dictionnaire de codes appris (vector quantization). Les résultats étaient excellents sur le papier — INT2 avec une perte minimale — mais le décodage par dictionnaire casse les pipelines GPU optimisés. Le throughput chute de 40 %.
TurboQuant : les cinq innovations
TurboQuant n'invente pas une seule technique révolutionnaire. Il combine cinq idées complémentaires, chacune ciblant un aspect précis du problème. C'est cette combinaison qui en fait l'état de l'art.
1. Rotation Walsh-Hadamard : normaliser la distribution
Le premier coup de génie est de ne pas quantifier la distribution brute. Avant quantification, TurboQuant applique une transformation de Walsh-Hadamard (WHT) aux vecteurs Key et Value.
La WHT est une transformation orthogonale — comme une FFT, mais avec uniquement des additions et des soustractions (pas de multiplication par des complexes). Elle « étale » les outliers sur l'ensemble des dimensions. Un vecteur avec un outlier à 100 et le reste à 1 devient un vecteur où toutes les valeurs oscillent entre -10 et 10. La distribution est quasi-gaussienne, bien plus facile à quantifier.
L'opération est réversible : au moment de calculer l'attention, on applique la WHT inverse sur les vecteurs déquantifiés. Grâce à l'orthogonalité, l'erreur de quantification ne s'amplifie pas lors de la transformation inverse.
2. Quantification Lloyd-Max optimale
Une fois la distribution normalisée, TurboQuant utilise la quantification de Lloyd-Max au lieu de la quantification uniforme classique.
L'idée du Lloyd-Max est simple : placer les niveaux de quantification là où il y a le plus de données. Si 80 % des valeurs sont entre -1 et 1, c'est là qu'on met le plus de niveaux. Les queues de la distribution — peu peuplées — sont couvertes par des niveaux plus espacés. Mathématiquement, on minimise l'erreur quadratique moyenne (MSE) en ajustant itérativement les centroids et les frontières de décision.
En pratique, TurboQuant pré-calcule les tables Lloyd-Max pour une distribution gaussienne standard (puisque la WHT normalise). Ces tables sont fixées au moment du déploiement — pas de calcul itératif à l'inférence. Le surcoût est nul.
3. Bit-packing dense : INT4 et INT2 en mémoire GPU
La compression en mémoire ne suffit pas si le décodage est lent. TurboQuant utilise un schéma de bit-packing dense : 8 valeurs INT4 dans un uint32, ou 16 valeurs INT2. Les kernels CUDA de déquantification sont parallélisés sur les 32 bits du registre.
Le résultat : le bandwidth mémoire GPU — le vrai goulot d'étranglement à l'inférence — est divisé par 4 en INT4 et par 8 en INT2. Le décodage par blocs (paged attention, vLLM) reste compatible parce que le bit-packing s'aligne sur les blocs de 16 tokens.
4. Fenêtre résiduelle : les 128 derniers tokens en pleine précision
TurboQuant conserve les 128 derniers tokens du KV-cache en FP16 non quantifié. Pourquoi ? Parce que l'attention locale — les tokens récents — est la plus critique pour la qualité de génération. Un mot mal quantifié dans le contexte récent cause une erreur immédiate. Un mot mal quantifié 10 000 tokens en arrière a un impact négligeable (la softmax l'atténue naturellement).
Cette fenêtre résiduelle crée un cache hybride : FP16 pour le contexte immédiat, INT4 ou INT2 pour le contexte lointain. La transition est transparente pour le kernel d'attention.
5. Skip des couches anomaliques
Dernière innovation : TurboQuant identifie automatiquement les couches du modèle dont le KV-cache résiste mal à la quantification. Ces « couches anomaliques » — typiquement 2 à 4 sur un modèle de 80 couches — sont laissées en FP16.
L'identification se fait lors d'une phase de calibration : on passe 1 000 tokens de texte diversifié et on mesure l'erreur de reconstruction couche par couche. Les couches dont l'erreur dépasse un seuil (2x la médiane) sont marquées comme anomaliques. Cette calibration prend 30 secondes et se fait une seule fois par modèle.
Les résultats : 7x de compression, moins de 1 % de perte
Les benchmarks TurboQuant sur Llama 3.1 70B à 128K tokens sont éloquents :
| Configuration | Mémoire KV | Compression | MMLU | LongBench |
|---|---|---|---|---|
| FP16 (baseline) | 42 Go | 1x | 79,2 | 46,1 |
| INT8 naïf | 21 Go | 2x | 78,5 | 44,8 |
| KIVI INT2 | 10,5 Go | 4x | 77,1 | 42,3 |
| KVQuant INT2 | 10,5 Go | 4x | 78,4 | 44,7 |
| TurboQuant INT2+skip | 6 Go | 7x | 78,8 | 45,6 |
Moins de 1 % de perte sur MMLU. Moins de 2 % sur LongBench. Et surtout : 6 Go au lieu de 42 Go. Sur un A100 80 Go, tu passes de 1 utilisateur simultané à 6. Sur un L40 48 Go, tu passes de « impossible » à « confortable ».
Comparaison des approches : quand utiliser quoi
Chaque technique a son créneau :
KIVI reste pertinent si tu veux une solution simple, sans phase de calibration. Sa quantification asymétrique Keys/Values est plug-and-play. Mais tu perds en compression (4x max vs 7x pour TurboQuant).
Gear est intéressant académiquement mais impraticable en production. Le coût de la SVD par couche est rédhibitoire pour le serving temps réel.
KVQuant offre une excellente qualité mais casse la compatibilité avec les frameworks d'inférence standard. Si tu utilises un pipeline custom, c'est une option viable. Sinon, TurboQuant fait aussi bien avec une compatibilité standard.
TurboQuant est le choix par défaut en 2026 si tu sers des modèles à long contexte. La combinaison WHT + Lloyd-Max + skip est élégante et le code est bien maintenu.
L'avenir : vers le cache adaptatif
La prochaine frontière, c'est le cache adaptatif. Au lieu de choisir un niveau de quantification fixe pour tout le contexte, l'idée est d'adapter la précision token par token en fonction de l'importance estimée. Un token « d'ancrage » (instruction système, nom de variable, chiffre clé) reste en FP16. Un token de remplissage (articles, prépositions, formatage) est quantifié agressivement en INT2 ou même carrément évicté.
Les travaux récents de Google DeepMind sur le « KV-cache scoring » vont dans cette direction. Le score d'importance est calculé à partir du poids d'attention moyen sur les derniers tokens générés. C'est une heuristique, mais elle fonctionne remarquablement bien : les expériences montrent qu'on peut évincer 60 % des tokens du cache sans perte mesurable sur la plupart des tâches.
Combiné avec TurboQuant, un système de scoring pourrait atteindre des compressions de 20x ou plus. À ce stade, le KV-cache cesse d'être un problème. Un modèle 70B pourrait servir des contextes de 1M tokens sur un seul GPU de 80 Go.
Ce que ça change pour toi
Si tu déploies des LLM en production, la quantification du KV-cache n'est plus optionnelle en 2026. C'est la différence entre un GPU par utilisateur et six utilisateurs par GPU. Entre un coût de serving de 50 €/heure et 8 €/heure.
Mon conseil : commence par TurboQuant INT4 (4x compression, quasi aucune perte). Si tu as besoin de plus, passe en INT2 avec la fenêtre résiduelle de 128 tokens. Et surveille les benchmarks spécifiques à ton cas d'usage — la perplexité globale ne capture pas tout.
Pour aller plus loin sur les architectures mémoire des LLM — du KV-cache aux systèmes de mémoire épisodique et sémantique —, j'ai écrit un guide complet qui couvre tout le pipeline.
Soutenez mon travail sur Patreon
Accès anticipé aux articles, contenu exclusif, et la satisfaction de soutenir un auteur indépendant.
Rejoindre — à partir de 3€/mois