Quantifier le KV cache : gagner de la VRAM sur les longs contextes
Vous avez la VRAM pour charger le modèle, mais dès que vous poussez le contexte à 16k ou 32k tokens, ça déborde. Le coupable, c'est le KV cache : une mémoire cachée qui grossit linéairement avec le contexte et qui, sur les longs prompts, peut peser autant que le modèle lui-même. La KV cache quantization le compresse en Q8 ou Q4 pour doubler le contexte tenable sur la même carte. Voici comment l'activer dans Ollama et llama.cpp, les gains chiffrés et l'impact réel sur la qualité.
#Pourquoi le KV cache mange votre VRAM
Quand un LLM génère du texte, il ne recalcule pas l'attention sur tout le prompt à chaque nouveau token : il garde en mémoire les vecteurs clés (K) et valeurs (V) de chaque token déjà vu. C'est le KV cache, et c'est ce qui rend la génération rapide. Le problème : cette mémoire grandit linéairement avec la longueur du contexte. Doublez le contexte, vous doublez le KV cache.
Sur un prompt court de quelques centaines de tokens, c'est négligeable. Mais dès qu'on attaque du RAG avec de gros documents, du résumé de transcriptions ou des agents à mémoire longue, le contexte explose — et le KV cache avec. Sur un 70B en 32k de contexte, il peut dépasser 10 Go à lui seul, en plus des ~40 Go du modèle. C'est souvent lui, et non le modèle, qui provoque l'out of memory sur les longs prompts.
#Combien pèse votre KV cache
La taille du KV cache dépend de quatre facteurs : le nombre de couches du modèle, la dimension d'attention, la longueur de contexte, et la précision de stockage. En FP16 (le défaut), la formule approximative est : 2 (K et V) × couches × dim_kv × contexte × 2 octets. En pratique, retenez ces ordres de grandeur en FP16 sur un contexte de 32k tokens :
- 7B (ex. Qwen3 8B, Mistral)
- ≈ 2 à 4 Go de KV cache à 32k, selon l'architecture (GQA aide beaucoup).
- 14B
- ≈ 4 à 6 Go à 32k tokens.
- 32B
- ≈ 8 à 10 Go à 32k tokens.
- 70B
- ≈ 10 à 16 Go à 32k tokens — souvent le facteur limitant.
#Ce que change la quantification du KV cache
L'idée est la même que pour les poids du modèle : au lieu de stocker chaque valeur du cache en 16 bits (FP16), on la stocke en 8 bits (Q8_0) ou 4 bits (Q4_0). On divise mécaniquement la mémoire du cache par 2 (Q8) ou par 4 (Q4). Comme le KV cache peut représenter une grosse part de la VRAM sur les longs contextes, le gain est direct : à VRAM constante, on peut environ doubler la longueur de contexte tenable en Q8.
- FP16
- Précision de référence, aucune perte, mais la plus gourmande. Le défaut.
- Q8_0
- Moitié moins de mémoire, perte de qualité quasi indétectable sur la plupart des modèles. Le meilleur compromis.
- Q4_0
- Quatre fois moins de mémoire, mais perte de qualité mesurable, variable selon le modèle. À réserver aux cas où la VRAM est vraiment le facteur bloquant.
#Activer la quantification KV dans Ollama
Ollama expose la quantification du KV cache via deux variables d'environnement du daemon. Il faut activer Flash Attention, puis choisir le type de cache. Ces variables se posent sur le service Ollama, pas au moment du ollama run.
- 01Activer Flash AttentionPosez OLLAMA_FLASH_ATTENTION=1 dans l'environnement du daemon. C'est le prérequis pour tout cache non-FP16.
- 02Choisir le type de cachePosez OLLAMA_KV_CACHE_TYPE avec la valeur voulue : f16 (défaut), q8_0 (recommandé) ou q4_0 (agressif).
- 03Redémarrer le daemonLes variables d'environnement ne sont lues qu'au démarrage du service. Redémarrez Ollama pour qu'elles prennent effet.
- 04Vérifier le gainChargez un modèle avec un gros contexte et surveillez la VRAM avec nvidia-smi ou ollama ps. Vous devez pouvoir monter plus haut en num_ctx qu'avant.
#Activer dans llama.cpp
En ligne de commande avec llama.cpp, la quantification du KV cache se contrôle avec deux drapeaux distincts pour les clés (K) et les valeurs (V), plus le drapeau Flash Attention. On peut quantifier K et V indépendamment, mais en pratique on les met au même niveau.
- -fa
- Active Flash Attention. Sans ce drapeau, -ctk/-ctv en dessous de f16 échoue.
- -ctk q8_0
- Quantifie le cache des clés en 8 bits. Valeurs possibles : f16, q8_0, q4_0, q4_1, q5_0, q5_1.
- -ctv q8_0
- Quantifie le cache des valeurs. Même jeu de valeurs que -ctk.
- -c 32768
- La taille de contexte que vous visez. C'est elle que la quant vous permet de monter sans déborder.
#Combien de contexte on gagne : chiffres réels
Le gain concret dépend de la part que représente le KV cache dans votre budget VRAM. Sur un modèle qui tient largement, quantifier le cache libère juste un peu d'air. Sur un modèle qui sature déjà, ça peut faire la différence entre 8k et 24k de contexte. Voici des ordres de grandeur observés, à VRAM constante :
- FP16 → Q8_0
- Cache divisé par 2. En pratique, contexte tenable environ doublé quand le cache dominait le budget.
- FP16 → Q4_0
- Cache divisé par 4. Contexte tenable jusqu'à ~3-4× plus long, au prix d'une perte de qualité mesurable.
- Exemple 14B sur RTX 4080 16GB
- De ~16k de contexte en FP16 à ~32k+ en Q8_0, le modèle et le reste tenant dans les mêmes 16 Go.
- Exemple 32B sur RTX 4090 24GB
- Le passage en Q8_0 du cache permet souvent de franchir le cap des longs documents RAG sans offload CPU.
#L'impact qualité selon les modèles
C'est la vraie question. Quantifier le cache introduit du bruit dans l'attention, et tous les modèles n'y réagissent pas pareil. La règle empirique qui se dégage des tests communautaires :
- Q8_0 sur le cache
- Différence quasi indétectable sur la grande majorité des modèles. Perplexité et qualité perçue quasi identiques à FP16. C'est le réglage à activer par défaut, presque sans réfléchir.
- Q4_0 sur le cache
- Perte visible et variable. Certains modèles encaissent très bien, d'autres se mettent à divaguer sur les très longs contextes, à perdre le fil ou à halluciner davantage. À tester sur VOTRE cas.
- Modèles à GQA
- Généralement plus robustes à la quantification du cache, leur cache étant déjà compact et bien structuré.
- Tâches sensibles (code, calcul, extraction stricte)
- Plus exposées à la dégradation Q4. Restez en Q8 pour tout ce qui demande de la précision factuelle.
#Dépannage
- « flash attention required » ou cache ignoré
- Vous avez oublié -fa (llama.cpp) ou OLLAMA_FLASH_ATTENTION=1 (Ollama). Le cache quantifié est silencieusement ramené à FP16, ou une erreur est levée.
- Aucun gain de VRAM visible
- Votre contexte est trop court pour que le cache pèse. Le gain n'apparaît que sur les longs prompts. Montez num_ctx / -c pour le constater.
- Qualité qui se dégrade sur les longs prompts
- Vous êtes probablement en Q4 sur un modèle qui l'encaisse mal. Repassez K en q8_0 (voire tout en q8_0) et retestez.
- Variables Ollama sans effet
- Elles ne sont lues qu'au démarrage du daemon. Redémarrez le service après les avoir posées, et vérifiez qu'elles sont bien visibles par le processus ollama.
- Toujours en OOM malgré la quant
- C'est le modèle lui-même qui déborde, pas le cache. Quantifiez aussi les poids (Q4_K_M) ou descendez d'une taille de modèle.
#Pour aller plus loin
La quantification du KV cache est un levier parmi d'autres pour tenir de gros contextes en local. Ces guides complètent le tableau :
- Flash Attention 2 sur LLM local : activer et benchmarker le gain
- Le prérequis de la quant KV, et un gain mémoire/vitesse à part entière. À lire en premier si Flash Attention n'est pas encore actif chez vous.
- Choisir sa quantification (Q4, Q5, Q8, FP16)
- Pour quantifier les poids du modèle — l'autre grand poste de VRAM, complémentaire de la quant du cache.
- Installer Ollama : Windows, macOS et Linux
- Si votre stack n'est pas encore en place, avec les prérequis GPU pour bien dimensionner.
Un retour, une erreur, une précision ? Faites-nous signe, ça améliore le guide pour tout le monde.