SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Cache KV ou prompt cache : quelles différences ?

Le cache KV consomme la RAM ou la VRAM à chaque requête et peut bloquer le chargement. Le prompt caching réduit seulement la facture en cas de cache hit.

Cache KV ou cache de prompt : réponse courte

Le cache KV et le prompt cache d’un fournisseur partagent un terme, mais presque rien d’autre. Le cache KV est une mémoire de travail propre à chaque requête. Il se trouve dans la RAM ou la VRAM de votre serveur pendant toute la durée d’une requête. Sa taille augmente avec la longueur du contexte et avec le nombre de requêtes exécutées simultanément. Le prompt caching fourni par un fournisseur est une fonctionnalité de facturation et de latence. Le fournisseur stocke un préfixe stable de votre prompt sur ses serveurs, puis vous le facture à tarif réduit lorsque vous le renvoyez.

Dans un cas, vous achetez la mémoire sous forme de matériel. Dans l’autre, quelqu’un d’autre conserve la mémoire et vous facture sa location.

La différence pratique est plus importante que la définition. Vous pouvez manquer de cache KV. Dans ce cas, le modèle refuse de se charger ou la requête est rejetée. Vous ne pouvez pas manquer de prompt cache. Vous pouvez seulement ne pas obtenir de cache hit. Vous payez alors discrètement le tarif complet.

Ce que contient le KV cache et pourquoi il existe

Un transformer qui génère le token numéro 500 doit prendre en compte les 499 tokens précédents. Pour chacun de ces tokens, chaque layer a besoin d’un key vector et d’un value vector. Les recalculer tous pour chaque nouveau token ferait croître le temps de génération avec le carré de la longueur. Le runtime les conserve donc dans un cache. Ce cache est le KV cache (key/value cache).

Il s’agit d’un état propre à chaque requête, car il est construit à partir de la séquence exacte de tokens de cette requête. Deux utilisateurs qui envoient des prompts différents ne peuvent pas le partager, sauf si le runtime utilise le prefix caching, une fonctionnalité distincte décrite plus loin.

Le serving se déroule en deux phases. Le prefill lit l’intégralité de votre prompt et remplit le cache. Il est limité par la capacité de calcul. Le decode produit un token à la fois et l’ajoute au cache. Il est limité par la bande passante mémoire. C’est pourquoi le traitement du prompt et la génération des tokens affichent des vitesses différentes lorsque vous mesurez les tokens par seconde sur votre propre serveur.

Quelle quantité de mémoire le cache KV utilise-t-il ?

Ne cherchez pas un tableau fourni par un éditeur. La taille se calcule. Vous pouvez refaire ce calcul pour n’importe quel modèle :

bytes per token = 2 * layers * kv_heads * head_dim * bytes per element

Le 2 correspond à la clé et à la valeur. Tous les autres nombres proviennent de la config.json du modèle, publiée sur sa page Hugging Face.

Prenons Llama 3.1 8B. Sa configuration indique num_hidden_layers 32 et num_key_value_heads 8. Le hidden_size de 4096 réparti entre 32 têtes d’attention donne une dimension de tête de 128. En f16, chaque élément occupe 2 octets :

2 * 32 * 8 * 128 * 2 = 131072 bytes = 128 KiB per token

Multipliez cette valeur par le contexte demandé, puis par le nombre de requêtes exécutées simultanément.

ChartLlama 3.1 8B KV cache at f16, in GiB
The data behind this chart
[
  {
    "label": "2k context",
    "one_request_gib": 0.25,
    "four_requests_gib": 1
  },
  {
    "label": "8k context",
    "one_request_gib": 1,
    "four_requests_gib": 4
  },
  {
    "label": "32k context",
    "one_request_gib": 4,
    "four_requests_gib": 16
  },
  {
    "label": "128k context",
    "one_request_gib": 16,
    "four_requests_gib": 64
  }
]

Avec un contexte de 8k, le cache occupe 1 GiB pour une requête. Avec 32k, il occupe 4 GiB, soit un volume comparable à celui des poids en 4 bits. Avec le contexte maximal de 128k du modèle, il occupe 16 GiB pour une requête, et 64 GiB si quatre requêtes utilisent chacune toute cette capacité. Les poids n’ont pas changé. Seul le cache a changé.

L’attention à requêtes groupées (GQA) joue un rôle important dans ce résultat. Llama 3.1 8B possède 8 têtes de clé/valeur pour 32 têtes de requête. Quatre têtes de requête partagent donc une même paire clé/valeur stockée. Un modèle dont le num_key_value_heads est égal à son num_attention_heads utilise quatre fois plus de cache avec le même nombre de paramètres. Vérifiez ce champ avant de supposer que deux modèles 8B ont le même coût d’exécution.

Pourquoi un modèle qui fonctionnait en 2k refuse de se charger en 32k

Le runtime réserve le cache KV au chargement du modèle, en fonction de la longueur de contexte configurée et non du prompt réellement envoyé. La fenêtre de contexte par défaut d’Ollama est de 4096 tokens. En la portant à 32k, vous demandez 4 GiB d’allocation supplémentaire avant l’arrivée du moindre token.

OLLAMA_CONTEXT_LENGTH=32768 ollama serve

Le même réglage pour une session, depuis le prompt interactif :

ollama run llama3.1:8b
/set parameter num_ctx 32768

L’échec varie selon la stack. vLLM vérifie le calcul au démarrage et refuse de s’exécuter :

ValueError: The model's max seq len (131072) is larger than the maximum number of tokens that can be stored in KV cache (78336). Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.

Sur un VPS limité au CPU, cette vérification n’existe pas, car l’allocation utilise la RAM système ordinaire. Le kernel OOM killer termine alors le processus et laisse la preuve dans le ring buffer du kernel :

dmesg -T | grep -i "killed process"

Une ligne qui nomme votre processus de serving signifie que la machine a promis plus de mémoire qu’elle n’en avait. La solution consiste à réduire le contexte, pas à agrandir le fichier de swap : un cache KV paginé sur disque est lu à chaque token généré, ce qui ralentit la génération au point de la rendre inutilisable. Pour choisir une valeur raisonnable, consultez notre guide sur num_ctx et la longueur du contexte dans Ollama.

L’effet de la concurrence sur le nombre

Chaque requête en cours d’exécution possède son propre KV cache. C’est le point que la plupart des plans de capacité négligent. Quatre utilisateurs conservant chacun un contexte de 32k ont besoin de 16 GiB au total, en plus des poids du modèle.

Les runtimes diffèrent par le degré de contrainte appliqué. Ollama et llama.cpp réservent le contexte demandé lors du chargement du modèle. La mémoire est donc allouée, même si personne ne l’utilise. vLLM divise le pool en blocs de taille fixe et les attribue à mesure que chaque requête augmente. Une requête de 500 tokens ne conserve donc que l’équivalent de 500 tokens. Dans les deux cas, le pool est limité. Lorsqu’il est plein, les nouvelles requêtes sont mises en file d’attente au lieu d’être exécutées. L’effet de cette mise en file sur les temps de réponse est expliqué dans le nombre d’utilisateurs simultanés qu’un LLM auto-hébergé peut servir.

Quatre façons de réduire la taille du cache KV

  1. Réduisez la longueur du contexte. C’est le levier le plus important et généralement le moins coûteux. La plupart des charges de travail de chat n’atteignent jamais 32k.
  2. Quantifiez le cache lui-même. Le OLLAMA_KV_CACHE_TYPE d’Ollama utilise f16 par défaut et accepte q8_0, qui utilise environ deux fois moins de mémoire, ainsi que q4_0, qui en utilise environ quatre fois moins. Les équivalents dans llama.cpp sont -ctk q8_0 et -ctv q8_0.
  3. Choisissez un modèle avec moins de têtes key/value ou moins de couches. Lisez config.json avant de télécharger 40 GB de poids.
  4. Traitez moins de requêtes simultanément et mettez les autres en file d’attente.

Avec q4_0, la valeur pour Llama 3.1 8B passe de 128 KiB par token à environ 32 KiB. Un contexte de 32k coûte donc environ 1 GiB au lieu de 4 GiB. Cette économie n’est pas gratuite. Les keys et les values sont stockées avec une précision moindre. Comparez donc la sortie avec vos propres prompts avant de conserver ce réglage.

Ce que le prompt caching des fournisseurs permet réellement

Le prompt caching des fournisseurs est un produit différent, avec une unité de facturation différente. Vous indiquez un préfixe stable, le fournisseur le stocke, puis les appels ultérieurs qui reprennent exactement ce préfixe sont facturés à un tarif réduit au lieu du plein tarif des tokens d’entrée.

Les multiplicateurs publiés par Anthropic, en août 2026, sont les suivants : l’écriture dans un cache de 5 minutes coûte 1.25 fois le prix de base des tokens d’entrée. Une écriture dans un cache d’une heure coûte 2 fois ce prix, et une lecture du cache coûte 0.1 fois ce prix. Appliqués à un system prompt de 20,000 tokens, ces chiffres montrent clairement l’intérêt de l’opération.

ChartCost of a 20,000 token prefix, in base input token equivalents
The data behind this chart
[
  {
    "label": "No caching, every call",
    "billed_token_equivalents": "20,000"
  },
  {
    "label": "First call, 5 minute cache write",
    "billed_token_equivalents": "25,000"
  },
  {
    "label": "First call, 1 hour cache write",
    "billed_token_equivalents": "40,000"
  },
  {
    "label": "Every later call, cache hit",
    "billed_token_equivalents": "2,000"
  }
]

Considérez cela comme un calcul. La majoration de l’écriture dans le cache de 5 minutes équivaut à 5,000 tokens lors du premier appel : 25,000 contre 20,000 pour l’envoyer sans cache. Chaque appel suivant effectué pendant cette période est facturé 2,000 au lieu de 20,000, soit une économie de 18,000 tokens. Le cache de 5 minutes devient donc rentable dès le deuxième appel.

Le cache d’une heure repose sur un calcul différent. L’écriture est facturée 40,000, soit une majoration de 20,000 tokens, et il faut donc deux lectures pendant cette heure pour qu’il devienne rentable. Cela dépend de votre modèle de trafic, pas du modèle d’IA. Le calcul complet, y compris le choix de la durée, se trouve dans le calcul du seuil de rentabilité du prompt caching de Claude.

Deux détails déterminent si vous utilisez réellement le cache. Premièrement, un préfixe inférieur à la longueur minimale du modèle n’est pas mis en cache, sans message d’erreur : en août 2026, la longueur minimale documentée est de 512 tokens pour Claude Opus 5 et de 1,024 tokens pour Claude Sonnet 5, et une requête plus courte est traitée normalement. Deuxièmement, la durée de vie est calculée depuis le début de la requête qui écrit ou lit l’entrée, et chaque lecture prolonge cette durée sans coût supplémentaire. Un endpoint très sollicité peut donc maintenir indéfiniment un cache de 5 minutes. Un endpoint appelé toutes les dix minutes paie la majoration d’écriture à chaque appel sans jamais bénéficier de lectures.

Vérifiez la réponse au lieu de partir du principe que le cache est utilisé. L’objet usage indique cache_creation_input_tokens et cache_read_input_tokens. Si le nombre de lectures est égal à zéro à chaque appel, vous payez les écritures sans rien récupérer.

À l’intersection des deux caches

Un long system prompt est le point de rencontre, et il vous est facturé des deux côtés simultanément.

Localement, un system prompt de 20,000 tokens occupe environ 2.4 GiB de KV cache sur un serveur Llama 3.1 8B en f16. Cette mémoire est utilisée séparément pour chaque requête simultanée qui l’inclut. À distance, ce même préfixe entraîne une écriture dans le cache, puis coûte 0.1 fois le tarif de l’input à chaque appel suivant. Le coût local évolue avec le nombre d’utilisateurs. Le coût distant évolue avec votre trafic et est réinitialisé pendant vos périodes d’inactivité.

Il existe une fonctionnalité locale qui ressemble au prompt caching des providers et qui est souvent confondue avec lui : le prefix caching. La documentation de vLLM décrit l’automatic prefix caching comme la mise en cache « du KV cache des requêtes existantes, afin qu’une nouvelle requête puisse réutiliser directement le KV cache si elle partage le même préfixe avec l’une des requêtes existantes ». Le serveur llama.cpp conserve par défaut un prompt cache par slot, et --cache-reuse N définit la plus petite taille de bloc qu’il tentera de réutiliser.

Le prefix caching économise le calcul du prefill. Votre system prompt de 20,000 tokens est traité une seule fois au lieu d’être retraité à chaque requête, ce qui réduit fortement le délai avant le premier token. Dans vLLM, les blocs partagés sont réutilisés au lieu d’être dupliqués, ce qui réduit également la consommation mémoire. En revanche, cette fonctionnalité ne réduit jamais le cache à conserver pour les tokens actuellement actifs. Conserver les weights en mémoire entre les requêtes est un levier connexe, mais distinct, traité dans conserver un modèle Ollama chargé entre les requêtes.

Mesures à effectuer sur votre propre machine

Chargez le modèle avec le contexte cible, puis consultez les valeurs réelles au lieu de vous fier à l’estimation.

ollama ps
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
free -g

ollama ps répertorie le modèle chargé, sa taille et indique s’il s’exécute sur le GPU ou le CPU. Si un modèle que vous pensiez charger entièrement sur le GPU indique une répartition sur le CPU, cela signifie que le cache KV a repoussé une partie du modèle vers le CPU. La vitesse de génération diminue alors en conséquence. nvidia-smi indique la quantité réelle de VRAM utilisée. free -g fournit la même information sur un VPS utilisant uniquement le CPU. Augmentez le contexte par étapes, rechargez le modèle et surveillez l’évolution de la valeur. Votre calcul et la valeur affichée devraient être proches. Lorsque ce n’est pas le cas, l’écart provient généralement des tampons de calcul internes du runtime, et non d’une erreur dans la formule.

Si ces valeurs vous orientent vers du matériel que vous préférez ne pas louer, la comparaison avec une facturation au token est présentée dans Comparaison entre un GPU VPS et les tokens d’une API.

FAQ

Le KV cache est-il la même chose que la mise en cache du prompt ?

Non. Le KV cache est une mémoire par requête dans le processus de serving. Il contient les vecteurs key et value de chaque token du contexte courant. Il se trouve dans votre RAM ou votre VRAM et est libéré à la fin de la requête. La mise en cache du prompt proposée par un provider est une fonctionnalité de facturation. Elle stocke un préfixe stable du prompt sur l’infrastructure du provider et applique un tarif réduit lorsque vous le renvoyez. L’épuisement du KV cache empêche le chargement d’un modèle. L’absence de prompt cache augmente seulement votre facture et votre délai avant le premier token.

Pourquoi mon modèle se charge-t-il avec un contexte de 2k, mais échoue-t-il avec 32k ?

Parce que le runtime alloue la totalité du KV cache au chargement. Sa taille dépend de la longueur de contexte configurée, et non du prompt que vous envoyez. Pour Llama 3.1 8B en f16, le cache occupe 128 KiB par token. Un contexte de 2k coûte donc 0.25 GiB et un contexte de 32k coûte 4 GiB. Les poids tiennent dans les deux cas. C’est la réservation qui échoue. vLLM le signale avec un ValueError qui indique le nombre maximal de tokens pouvant être stockés, et suggère d’augmenter gpu_memory_utilization ou de réduire max_model_len. Sur une machine CPU-only, l’out-of-memory killer du kernel termine plutôt le processus. Vous pouvez le confirmer avec dmesg -T | grep -i "killed process".

Comment calculer la taille du KV cache de mon modèle ?

Multipliez 2 par le nombre de couches, le nombre de heads key/value, la dimension des heads et le nombre d’octets par élément. Vous obtenez le nombre d’octets par token. Multipliez ensuite ce résultat par la longueur du contexte et par le nombre de requêtes concurrentes. Relevez le nombre de couches et de heads dans le config.json du modèle. Utilisez 2 octets par élément pour f16 ou bf16. Un cache q8_0 occupe environ deux fois moins de mémoire, et un cache q4_0 environ quatre fois moins.

La mise en cache du prompt réduit-elle la mémoire nécessaire sur mon propre serveur ?

La mise en cache du prompt par un provider ne change rien pour votre matériel, car le stockage se trouve chez le provider. L’équivalent local est le prefix caching, proposé par vLLM et par le serveur llama.cpp. Il réutilise les vecteurs key et value déjà calculés pour un préfixe partagé. Cela économise du calcul de prefill et réduit le délai avant le premier token. Dans vLLM, les blocs partagés sont réutilisés au lieu d’être dupliqués, ce qui réduit aussi la mémoire nécessaire. Aucune de ces fonctionnalités ne réduit la taille du cache nécessaire pour les tokens actuellement en cours de traitement. Votre calcul de la mémoire requise selon le contexte et la concurrence reste donc déterminant.

Est-il utile de mettre en cache un prompt que je n’envoie qu’une seule fois ?

Non. L’écriture dans le cache coûte plus cher qu’une entrée standard : 1.25 fois le tarif de base pour l’option de 5 minutes en août 2026. Un préfixe qui n’est jamais renvoyé pendant cette période représente donc une perte nette. La mise en cache devient intéressante lorsque le même préfixe est répété, par exemple pour un long prompt système ou un document sur lequel vous poserez plusieurs questions. Vérifiez cache_read_input_tokens dans la réponse de l’API pour confirmer que vous obtenez des hits au lieu de payer des écritures.