Tutoriel LMCache : créer une couche de cache KV évolutive pour l’inférence des LLM
Découvrez comment LMCache stocke et réutilise les états KV entre requêtes LLM, s’intègre à vLLM, et réduit les préremplissages répétés pour l’inférence en contexte long.
L’inférence des grands modèles de langage devient de plus en plus coûteuse à mesure que les invites s’allongent.
Les systèmes RAG, les agents de codage, les workflows multi-agents et les longues conversations renvoient souvent, encore et encore, les mêmes documents, invites système, définitions d’outils ou historiques de conversation au modèle.
Chaque fois que ce contexte partagé est traité pendant le préremplissage (prefill), le modèle génère des états clé-valeur (KV) utilisés lors de la génération de tokens.
Recalculer ces états pour le même contexte gaspille des ressources GPU et augmente la latence.
LMCache répond à ce problème en ajoutant une couche de cache KV dédiée dans la pile d’inférence.
Il peut stocker des états KV calculés précédemment et les rendre réutilisables entre requêtes et workers d’inférence, tout en prenant en charge le CPU, le stockage local, des backends distants et des architectures de service désagrégées.
Dans ce tutoriel, je vous montre comment fonctionne LMCache, en quoi il diffère du cache KV natif de vLLM, et où s’inscrivent des fonctionnalités comme le stockage multi-niveaux, le cache partagé, CacheBlend et la désagrégation préremplissage/décodage dans le déploiement moderne des LLM.
Vous connecterez ensuite LMCache à vLLM, servirez IBM Granite 4.2 3B et exécuterez une expérience contrôlée pour mesurer l’impact de la réutilisation d’un large préfixe commun sur la latence d’inférence.
Qu’est-ce que LMCache ?
LMCache est une couche de gestion de cache KV open source pour l’inférence LLM.
Elle permet de stocker les états clé-valeur créés pendant le préremplissage et de les réutiliser lorsque de futures requêtes partagent le même préfixe d’invite.
C’est différent d’un cache de réponse traditionnel.
Un cache de réponse stocke la réponse finale générée et la renvoie quand la même requête réapparaît :
cache ={"What is Python?":"Python is a general-purpose programming language..."}Propulsé par
LMCache intervient plus tôt dans le processus d’inférence. Au lieu de mettre en cache la réponse finale, il conserve les états d’attention KV produits pendant que le modèle traite l’invite.
Par exemple, sans cache KV réutilisable, un long préfixe partagé doit repasser par le préremplissage à chaque nouvelle question ajoutée.
Avec LMCache, la première requête effectue le préremplissage complet et stocke les états KV résultants. Les requêtes suivantes avec le même préfixe peuvent charger ces états et ne traiter que les nouveaux tokens.
Fig. 1 : sans cache KV réutilisable, l’intégralité de l’invite est recomputée à chaque requête ; avec LMCache, les états KV mis en cache sont réutilisés et seuls les nouveaux tokens sont traités.
La valeur ajoutée croît avec la taille des fenêtres de contexte.
Repasser quelques centaines de tokens peut coûter peu, mais traiter à répétition des dizaines de milliers de tokens partagés augmente fortement la latence et l’usage GPU.
Comment fonctionne LMCache
La manière la plus simple de comprendre LMCache est de suivre deux requêtes partageant le même préfixe.
Pour la première requête, LMCache vérifie si des états KV réutilisables existent déjà. Comme c’est la première occurrence de cette invite, la recherche aboutit à un « cache miss ».
vLLM exécute alors le préremplissage sur le GPU, crée les états KV et les transmet à LMCache pour stockage.
Pour la seconde requête, le préfixe partagé reste identique, mais la question change.
LMCache effectue une nouvelle recherche. Cette fois, le préfixe est disponible : « cache hit ». Les états mis en cache sont réutilisés et le GPU ne traite que le suffixe non mis en cache.
Fig. 2 : première requête avec un nouveau préfixe : échec de cache, donc vLLM calcule le préremplissage et stocke les états KV dans LMCache ; une requête ultérieure avec le même préfixe touche le cache et ne calcule que le nouveau suffixe.
L’essentiel est que LMCache n’exige pas que l’ensemble de la requête soit identique. C’est le préfixe réutilisable qui compte.
Cela le rend particulièrement adapté aux applications où le contexte de fond reste le même tandis que la requête utilisateur évolue.
Cache de préfixe vLLM vs LMCache
vLLM prend déjà en charge le cache de préfixe automatique ; il est donc légitime de se demander pourquoi LMCache est nécessaire.
Les deux approches visent à éviter de recalculer les états KV pour des préfixes d’invite déjà traités par le modèle.
La principale différence tient à l’emplacement du cache et à l’étendue de sa réutilisation.
Fonctionnalité
Cache KV natif vLLM
LMCache
Réutilisation KV de préfixe
Oui, via Automatic Prefix Caching
Oui
Réutilisation KV hors préfixe
Non
Oui, via CacheBlend
Cache KV sur GPU
Oui
Fonctionne aux côtés du cache KV GPU de vLLM
Déport KV sur CPU
Oui
Oui
Stockage SSD / NVMe
Pris en charge via des niveaux de stockage secondaires
Oui, y compris disque local, NVMe et GDS
Stockage distant
Prend en charge des options comme le stockage objet compatible S3
Prend en charge plusieurs backends, dont Redis/Valkey, S3, Mooncake, InfiniStore, NIXL, et autres
Partage de cache inter‑processus
Pris en charge dans certaines configurations, y compris P2P et stockage partagé
Fonction clé, avec plusieurs workers d’inférence pouvant utiliser des états KV partagés
Service de cache autonome
Non, le cache est géré au sein de la pile de service vLLM
Oui, le mode MP de LMCache peut fonctionner indépendamment de vLLM
Montée en charge indépendante du cache
Les ressources de cache sont généralement configurées avec le déploiement d’inférence
La capacité de cache peut être dimensionnée séparément des workers vLLM
Désagrégation préremplissage/décodage
Pris en charge via des connecteurs KV
Conçu spécifiquement pour transférer les KV entre workers de préremplissage et de décodage
Idéal pour
Une réutilisation efficace du préfixe et le déport KV au sein de déploiements vLLM
Des charges KV à grande échelle, partagées, multi‑niveaux ou distribuées
Le cache de préfixe intégré de vLLM est l’option la plus simple lorsque des requêtes répétées sont traitées par le même serveur d’inférence.
Si plusieurs requêtes commencent par les mêmes tokens, vLLM peut réutiliser les blocs KV existants au lieu de refaire tout le préremplissage.
LMCache étend cette idée au‑delà du moteur d’inférence.
Plutôt que de conserver les états KV réutilisables uniquement dans le cache propre à vLLM, LMCache introduit une couche de cache séparée qui peut stocker et déplacer des états KV sur des niveaux de stockage supplémentaires et les rendre disponibles à une architecture de service plus large.
Une façon simple de visualiser la différence :
Fig. 3 : cache de préfixe vLLM vs LMCache. LMCache ajoute une couche de cache qui étage les états KV entre mémoire CPU, SSD/NVMe local et stockage distant, au lieu de se limiter à la mémoire GPU.
Ainsi, LMCache ne remplace pas le cache KV de vLLM ; il étend la gestion du cache KV au‑delà des frontières habituelles du moteur d’inférence.
Fonctionnalités clés de LMCache
LMCache va bien au‑delà d’un simple cache en mémoire. Il est conçu pour stocker, déplacer et réutiliser des états KV entre différents niveaux de stockage et workers d’inférence.
1. Réutilisation du cache KV
La fonctionnalité principale de LMCache est la capacité à réutiliser des états KV calculés précédemment au lieu de refaire passer les mêmes tokens dans le modèle.
C’est particulièrement utile lorsque les requêtes incluent à répétition le même contexte ou un contexte similaire, comme :
Documents récupérés
Grandes invites système
Contexte de dépôt (repository)
Historique de conversation
Définitions d’outils
Instructions partagées entre agents
En réutilisant les états KV mis en cache, LMCache diminue les préremplissages répétés et améliore le temps jusqu’au premier token.
2. Stockage multi‑niveaux
La mémoire GPU est limitée et coûteuse, surtout avec de longs contextes.
LMCache peut déplacer les états KV hors de la mémoire GPU et les stocker sur plusieurs niveaux : mémoire CPU, SSD ou NVMe local, et stockage distant ou distribué.
Cela permet de conserver bien plus de contexte réutilisable que ce qui tiendrait en mémoire GPU, tout en rapatriant sur GPU les états KV fréquemment utilisés quand nécessaire.
3. Cache KV partagé entre workers
LMCache peut rendre des états KV mis en cache disponibles pour plusieurs workers d’inférence, au lieu de les lier à un seul processus modèle.
Par exemple, si un worker vLLM traite un long document, un autre worker peut potentiellement réutiliser les états KV mis en cache, plutôt que de recalculer le même contexte.
C’est particulièrement utile pour le service distribué, les déploiements multi‑GPU et les applications où les requêtes sont routées entre plusieurs réplicas d’inférence.
4. Intégration vLLM
LMCache s’intègre à vLLM via son interface de connecteur KV.
L’application continue de communiquer avec l’endpoint vLLM compatible OpenAI habituel, tandis que LMCache opère sous la couche d’inférence.
Les applications existantes n’ont donc pas besoin de changer la manière d’envoyer les invites ou de recevoir les réponses. LMCache gère le stockage et la récupération des KV entre vLLM et le backend de cache configuré.
5. Architecture multiprocessus
LMCache peut s’exécuter dans un processus séparé de vLLM.
Au lieu de gérer le cache au sein de chaque worker d’inférence, un serveur LMCache dédié peut gérer les états KV de façon indépendante et servir plusieurs processus vLLM.
Cette séparation entre gestion du cache et service du modèle permet à plusieurs workers de partager le même cache et facilite le dimensionnement du cache indépendamment des ressources GPU d’inférence.
6. CacheBlend
Le cache de préfixe traditionnel fonctionne au mieux quand les requêtes partagent le même début d’invite.
LMCache propose aussi CacheBlend pour les charges où le contenu réutilisable peut apparaître à des positions différentes.
Par exemple, une application RAG peut récupérer les mêmes documents dans un ordre différent selon la question.
CacheBlend peut réutiliser des portions d’états KV calculés précédemment tout en recalculant sélectivement les tokens dépendant du nouveau contexte.
Cela rend la réutilisation des KV plus utile pour le RAG, les applications multi‑documents et les workflows agentiques où les invites sont fréquemment réorganisées.
7. Désagrégation préremplissage et décodage
LMCache peut aussi faciliter le transfert d’états KV entre des workers distincts de préremplissage et de décodage.
Dans cette architecture, un groupe de GPU gère l’étape de traitement d’invite, très consommatrice en calcul, tandis qu’un autre groupe gère la génération de tokens.
LMCache fournit la couche permettant de déplacer les états KV entre ces groupes.
Cela autorise un dimensionnement indépendant des ressources de préremplissage et de décodage et peut améliorer l’utilisation GPU dans des déploiements d’inférence de grande taille.
Prise en main de LMCache
Maintenant que nous comprenons le fonctionnement de LMCache, connectons‑le à vLLM, un moteur d’inférence LLM haute performance conçu pour un service et une gestion mémoire efficaces.
Pour ce guide, j’utiliserai IBM Granite 4.2 3B, un modèle compact offrant d’excellentes performances pour sa taille tout en restant suffisamment léger pour des tests pratiques.
Nous exécuterons LMCache en mode multiprocessus aux côtés de vLLM et vérifierons que les états KV peuvent être réutilisés entre requêtes.
1. Préparer l’environnement
Pour ce tutoriel, nous utiliserons Python 3.12, uv, vLLM, LMCache, le client Python OpenAI, pandas et matplotlib.
Avant de commencer, assurez‑vous d’avoir :
Un GPU NVIDIA avec les pilotes appropriés installés
Le toolkit CUDA 13 installé et disponible sur votre système
uv installé
Vous pouvez installer uv avec :
curl-LsSf https://astral.sh/uv/install.sh |shPropulsé par
Créez ensuite le projet :
mkdir lmcache-tutorial
cd lmcache-tutorialPropulsé par
Créez et activez un environnement virtuel Python 3.12 :
uv venv --python3.12source .venv/bin/activatePropulsé par
3. Vérifier LMCache avec un « cache hit » contrôlé
Nous allons maintenant réaliser une expérience simple et contrôlée pour confirmer que LMCache fonctionne.
Nous allons créer un grand préfixe partagé, vider le cache, envoyer une première fois le préfixe pour remplir LMCache, puis envoyer une autre requête avec le même préfixe mais une question différente.
Commencez par créer le client OpenAI :
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="local",)Propulsé par
Créez ensuite un long document partagé :
base_text ="""
Large language model inference consists of two main stages:
prefill and decoding.
During prefill, the model processes the input sequence and calculates
the key and value tensors used by the attention mechanism.
During autoregressive decoding, these tensors are reused so the model
does not need to recompute attention states for every previous token.
KV cache management is therefore an important part of modern LLM
serving infrastructure, particularly for long-context applications.
"""
document = base_text *500
SYSTEM_PROMPT =f"""
You are a technical assistant.
Use only the following document to answer the user's question.
DOCUMENT:
{document}
"""Propulsé par
Répéter le document 500 fois produit un large préfixe partagé, suffisamment coûteux pour rendre visible l’effet de la réutilisation des KV.
Avant d’envoyer la première requête, videz LMCache afin de partir d’un cache vide :
import subprocess
import time
subprocess.run(["lmcache","kvcache","clear","--url","http://localhost:8081",],
check=True,)
time.sleep(0.5)Propulsé par
Cela garantit que la première requête est une requête à froid et ne peut pas réutiliser des états KV d’un test antérieur.
Envoyez maintenant la première requête :
prompt_1 = SYSTEM_PROMPT +"""
Question:
Explain the purpose of the KV cache.
"""
start = time.perf_counter()
client.completions.create(
model="granite-4.2-3b",
prompt=prompt_1,
max_tokens=100,
temperature=0,)
latency_1 = time.perf_counter()- startPropulsé par
C’est la requête de chauffe du cache. vLLM doit traiter le long préfixe partagé pendant le préremplissage, tandis que LMCache stocke les états KV produits.
Ensuite, gardez exactement le même préfixe partagé et ne changez que la question :
prompt_2 = SYSTEM_PROMPT +"""
Question:
Explain what happens during prefill.
"""
start = time.perf_counter()
client.completions.create(
model="granite-4.2-3b",
prompt=prompt_2,
max_tokens=100,
temperature=0,)
latency_2 = time.perf_counter()- startPropulsé par
Comme le grand préfixe est inchangé, LMCache peut réutiliser les états KV générés par la première requête au lieu de recomputer tout le préfixe.
La requête à chaud s’est terminée presque 6 fois plus vite, réduisant la latence de bout en bout de 83,2 %.
Les questions sont différentes ; LMCache ne met donc pas en cache la réponse finale. Il réutilise plutôt les états KV du préfixe partagé.
La première requête doit traiter l’intégralité du long préfixe pendant le préremplissage et créer ces états KV à partir de zéro.
Lors de la seconde, LMCache récupère les états mis en cache correspondants, permettant à vLLM d’éviter la majeure partie du préremplissage répété et de se concentrer sur le nouveau suffixe.
Cela confirme que LMCache réutilise bien le préfixe partagé.
Quand LMCache est‑il utile ?
LMCache est particulièrement utile lorsqu’une application envoie à répétition une grande quantité de contexte identique.
Parmi les cas fréquents :
Applications RAG
Un utilisateur peut poser plusieurs questions à propos du même document récupéré.
Au lieu de traiter le document en entier à chaque question, on réutilise ses états KV.
Agents de codage
Les assistants de codage envoient souvent des fichiers de dépôt, des consignes de projet et d’autres gros blocs de contexte à chaque appel modèle.
Une grande partie de ce contexte reste identique tandis que la tâche évolue.
Agents IA
Les agents réutilisent souvent de grandes invites système, des définitions d’outils, de la mémoire, des instructions et l’état d’environnement sur de nombreuses étapes.
Conversations longues
Une conversation au long cours peut renvoyer une part importante de son historique à chaque nouveau message.
Dans tous ces cas, le modèle revoit des informations qu’il a déjà traitées lors de requêtes précédentes.
LMCache offre un moyen de réutiliser ce travail au niveau du cache KV.
Pour conclure
LMCache traite une source majeure de gaspillage dans l’inférence en contexte long en rendant réutilisables les états KV créés pendant le préremplissage.
Au lieu de retraiter sans cesse le même contexte partagé, le modèle réutilise le travail déjà effectué.
Nous n’incluons pas ici le code de benchmark ni les résultats détaillés, mais nous avons mené une série de tests séparés avec la même configuration.
Les résultats sont significatifs : la réutilisation d’un large préfixe partagé a réduit la latence totale d’une requête de 26,276 secondes à 4,386 secondes.
Le temps moyen jusqu’au premier token est passé de 22,149 secondes à 0,726 seconde, soit une amélioration de 30,54 fois. Les gains augmentent aussi avec la taille du contexte, de 3,55 fois avec environ 12 000 caractères partagés à 30,22 fois avec près de 245 000 caractères.
En clair : plus le contexte réutilisable est important, plus LMCache évite de travail.
DeepSeek illustre bien cet enjeu dans le monde réel.
Son système de cache peut réutiliser des préfixes d’invite identiques, ce qui est particulièrement précieux pour les agents de codage qui renvoient à répétition les mêmes invites système, outils, historiques de conversation et contexte de code.
Des taux de « cache hit » plus élevés signifient moins de calcul répété et des coûts plus faibles pour le fournisseur comme pour l’utilisateur.
La leçon principale de ce guide : accélérer l’inférence LLM ne tient pas qu’à de meilleurs GPU ou à une génération de tokens plus rapide. Il s’agit aussi de ne pas répéter inutilement le travail.
Pour les systèmes RAG, assistants de codage, agents et autres applications à contexte long, la réutilisation du cache KV peut jouer un rôle majeur pour améliorer la latence, réduire l’usage GPU et diminuer les coûts d’inférence.
FAQ
LMCache fonctionne‑t‑il uniquement avec vLLM ?⌄
Bien que LMCache soit profondément intégré à vLLM via son connecteur KV, il ne lui est pas exclusif. L’architecture agit comme un middleware de mise en cache et prend déjà en charge d’autres moteurs d’inférence LLM populaires comme SGLang, avec une prise en charge native de TensorRT-LLM en cours de développement.
Quels backends de stockage distant sont pris en charge par LMCache ?⌄
Au‑delà de la RAM CPU standard et des SSD/NVMe locaux, LMCache prend en charge un large éventail de systèmes de stockage distants et distribués.Vous pouvez connecter LMCache à Redis/Valkey, au stockage objet compatible S3, à Mooncake, NIXL et InfiniStore, afin d’étendre votre pool de cache KV sur des architectures distribuées.
Comment LMCache gère‑t‑il les limites de stockage lorsque le cache est plein ?⌄
LMCache utilise des politiques d’éviction configurables pour déterminer quels états KV supprimer lorsque les limites de mémoire CPU, de disque local ou de stockage distant sont atteintes.La politique par défaut est le Least Recently Used (LRU), mais vous pouvez facilement configurer le système pour utiliser Least Frequently Used (LFU) ou First‑In‑First‑Out (FIFO) selon les schémas d’accès de votre application.
LMCache peut‑il stocker des caches KV quantifiés comme FP8 ?⌄
Oui, LMCache gère sans problème les données de cache KV quantifiées.Si votre moteur d’inférence est configuré pour utiliser un cache KV quantifié — comme FP8 — LMCache stockera et transférera les blocs dans ce format compressé. Cela réduit drastiquement l’empreinte de stockage et la bande passante mémoire nécessaire pour déplacer les états KV entre les niveaux matériels.
Y a‑t‑il des risques de sécurité lorsque l’on partage un cache KV entre plusieurs utilisateurs ?⌄
Dans des déploiements multi‑locataires ou d’API publiques, le partage d’un cache KV peut introduire des vulnérabilités de canal auxiliaire temporel.Parce que les « cache hits » répondent bien plus vite que les préremplissages à froid, un utilisateur malveillant pourrait sonder les schémas de latence pour déduire des éléments de l’invite privée d’un autre utilisateur. Dans des environnements « zero‑trust », les architectes système doivent mettre en place une isolation stricte des locataires ou désactiver totalement le partage de cache entre locataires.
En tant que data scientist certifié, je suis passionné par l'utilisation des technologies de pointe pour créer des applications innovantes d'apprentissage automatique. Avec une solide expérience en reconnaissance vocale, en analyse de données et en reporting, en MLOps, en IA conversationnelle et en NLP, j'ai affiné mes compétences dans le développement de systèmes intelligents qui peuvent avoir un impact réel. En plus de mon expertise technique, je suis également un communicateur compétent, doué pour distiller des concepts complexes dans un langage clair et concis. En conséquence, je suis devenu un blogueur recherché dans le domaine de la science des données, partageant mes idées et mes expériences avec une communauté grandissante de professionnels des données. Actuellement, je me concentre sur la création et l'édition de contenu, en travaillant avec de grands modèles linguistiques pour développer un contenu puissant et attrayant qui peut aider les entreprises et les particuliers à tirer le meilleur parti de leurs données.
L'essor du développement de l'intelligence artificielle (IA) a entraîné une augmentation notable de la demande en matière de calcul, d'où la nécessité de disposer de solutions matérielles robustes. Les unités de traitement graphique (GPU) et les unités de traitement tensoriel (TPU) sont devenues des technologies essentielles pour répondre à ces demandes.
Apprenez l'essentiel de l'architecture d'un entrepôt de données, des composants clés aux meilleures pratiques, pour construire un système de données évolutif et efficace !
Découvrez les principaux types d'agents d'intelligence artificielle, comment ils interagissent avec les environnements et comment ils sont utilisés dans les différents secteurs d'activité. Comprendre les agents réflexes simples, les agents basés sur un modèle, les agents basés sur un but, les agents basés sur l'utilité, les agents d'apprentissage, etc.
Gagnez en confiance dans la régression par les MCO en maîtrisant ses fondements théoriques. Découvrez comment réaliser des mises en œuvre simples dans Excel, R et Python.
L’inférence des grands modèles de langage devient de plus en plus coûteuse à mesure que les invites s’allongent.
Les systèmes RAG, les agents de codage, les workflows multi-agents et les longues conversations renvoient souvent, encore et encore, les mêmes documents, invites système, définitions d’outils ou historiques de conversation au modèle.
Chaque fois que ce contexte partagé est traité pendant le préremplissage (prefill), le modèle génère des états clé-valeur (KV) utilisés lors de la génération de tokens.
Recalculer ces états pour le même contexte gaspille des ressources GPU et augmente la latence.
LMCache répond à ce problème en ajoutant une couche de cache KV dédiée dans la pile d’inférence.
Il peut stocker des états KV calculés précédemment et les rendre réutilisables entre requêtes et workers d’inférence, tout en prenant en charge le CPU, le stockage local, des backends distants et des architectures de service désagrégées.
Dans ce tutoriel, je vous montre comment fonctionne LMCache, en quoi il diffère du cache KV natif de vLLM, et où s’inscrivent des fonctionnalités comme le stockage multi-niveaux, le cache partagé, CacheBlend et la désagrégation préremplissage/décodage dans le déploiement moderne des LLM.
Vous connecterez ensuite LMCache à vLLM, servirez IBM Granite 4.2 3B et exécuterez une expérience contrôlée pour mesurer l’impact de la réutilisation d’un large préfixe commun sur la latence d’inférence.
Qu’est-ce que LMCache ?
LMCache est une couche de gestion de cache KV open source pour l’inférence LLM.
Elle permet de stocker les états clé-valeur créés pendant le préremplissage et de les réutiliser lorsque de futures requêtes partagent le même préfixe d’invite.
Source : LMCache – Building the foundation of AI memory tensor with KV Cache Infrastructure
C’est différent d’un cache de réponse traditionnel.
Un cache de réponse stocke la réponse finale générée et la renvoie quand la même requête réapparaît :
LMCache intervient plus tôt dans le processus d’inférence. Au lieu de mettre en cache la réponse finale, il conserve les états d’attention KV produits pendant que le modèle traite l’invite.
Par exemple, sans cache KV réutilisable, un long préfixe partagé doit repasser par le préremplissage à chaque nouvelle question ajoutée.
Avec LMCache, la première requête effectue le préremplissage complet et stocke les états KV résultants. Les requêtes suivantes avec le même préfixe peuvent charger ces états et ne traiter que les nouveaux tokens.
Fig. 1 : sans cache KV réutilisable, l’intégralité de l’invite est recomputée à chaque requête ; avec LMCache, les états KV mis en cache sont réutilisés et seuls les nouveaux tokens sont traités.
La valeur ajoutée croît avec la taille des fenêtres de contexte.
Repasser quelques centaines de tokens peut coûter peu, mais traiter à répétition des dizaines de milliers de tokens partagés augmente fortement la latence et l’usage GPU.
Comment fonctionne LMCache
La manière la plus simple de comprendre LMCache est de suivre deux requêtes partageant le même préfixe.
Pour la première requête, LMCache vérifie si des états KV réutilisables existent déjà. Comme c’est la première occurrence de cette invite, la recherche aboutit à un « cache miss ».
vLLM exécute alors le préremplissage sur le GPU, crée les états KV et les transmet à LMCache pour stockage.
Pour la seconde requête, le préfixe partagé reste identique, mais la question change.
LMCache effectue une nouvelle recherche. Cette fois, le préfixe est disponible : « cache hit ». Les états mis en cache sont réutilisés et le GPU ne traite que le suffixe non mis en cache.
Fig. 2 : première requête avec un nouveau préfixe : échec de cache, donc vLLM calcule le préremplissage et stocke les états KV dans LMCache ; une requête ultérieure avec le même préfixe touche le cache et ne calcule que le nouveau suffixe.
L’essentiel est que LMCache n’exige pas que l’ensemble de la requête soit identique. C’est le préfixe réutilisable qui compte.
Cela le rend particulièrement adapté aux applications où le contexte de fond reste le même tandis que la requête utilisateur évolue.
Cache de préfixe vLLM vs LMCache
vLLM prend déjà en charge le cache de préfixe automatique ; il est donc légitime de se demander pourquoi LMCache est nécessaire.
Les deux approches visent à éviter de recalculer les états KV pour des préfixes d’invite déjà traités par le modèle.
La principale différence tient à l’emplacement du cache et à l’étendue de sa réutilisation.
Fonctionnalité
Cache KV natif vLLM
LMCache
Réutilisation KV de préfixe
Oui, via Automatic Prefix Caching
Oui
Réutilisation KV hors préfixe
Non
Oui, via CacheBlend
Cache KV sur GPU
Oui
Fonctionne aux côtés du cache KV GPU de vLLM
Déport KV sur CPU
Oui
Oui
Stockage SSD / NVMe
Pris en charge via des niveaux de stockage secondaires
Oui, y compris disque local, NVMe et GDS
Stockage distant
Prend en charge des options comme le stockage objet compatible S3
Prend en charge plusieurs backends, dont Redis/Valkey, S3, Mooncake, InfiniStore, NIXL, et autres
Partage de cache inter‑processus
Pris en charge dans certaines configurations, y compris P2P et stockage partagé
Fonction clé, avec plusieurs workers d’inférence pouvant utiliser des états KV partagés
Service de cache autonome
Non, le cache est géré au sein de la pile de service vLLM
Oui, le mode MP de LMCache peut fonctionner indépendamment de vLLM
Montée en charge indépendante du cache
Les ressources de cache sont généralement configurées avec le déploiement d’inférence
La capacité de cache peut être dimensionnée séparément des workers vLLM
Désagrégation préremplissage/décodage
Pris en charge via des connecteurs KV
Conçu spécifiquement pour transférer les KV entre workers de préremplissage et de décodage
Idéal pour
Une réutilisation efficace du préfixe et le déport KV au sein de déploiements vLLM
Des charges KV à grande échelle, partagées, multi‑niveaux ou distribuées
Le cache de préfixe intégré de vLLM est l’option la plus simple lorsque des requêtes répétées sont traitées par le même serveur d’inférence.
Si plusieurs requêtes commencent par les mêmes tokens, vLLM peut réutiliser les blocs KV existants au lieu de refaire tout le préremplissage.
LMCache étend cette idée au‑delà du moteur d’inférence.
Plutôt que de conserver les états KV réutilisables uniquement dans le cache propre à vLLM, LMCache introduit une couche de cache séparée qui peut stocker et déplacer des états KV sur des niveaux de stockage supplémentaires et les rendre disponibles à une architecture de service plus large.
Une façon simple de visualiser la différence :
Fig. 3 : cache de préfixe vLLM vs LMCache. LMCache ajoute une couche de cache qui étage les états KV entre mémoire CPU, SSD/NVMe local et stockage distant, au lieu de se limiter à la mémoire GPU.
Ainsi, LMCache ne remplace pas le cache KV de vLLM ; il étend la gestion du cache KV au‑delà des frontières habituelles du moteur d’inférence.
Fonctionnalités clés de LMCache
LMCache va bien au‑delà d’un simple cache en mémoire. Il est conçu pour stocker, déplacer et réutiliser des états KV entre différents niveaux de stockage et workers d’inférence.
1. Réutilisation du cache KV
La fonctionnalité principale de LMCache est la capacité à réutiliser des états KV calculés précédemment au lieu de refaire passer les mêmes tokens dans le modèle.
C’est particulièrement utile lorsque les requêtes incluent à répétition le même contexte ou un contexte similaire, comme :
En réutilisant les états KV mis en cache, LMCache diminue les préremplissages répétés et améliore le temps jusqu’au premier token.
2. Stockage multi‑niveaux
La mémoire GPU est limitée et coûteuse, surtout avec de longs contextes.
LMCache peut déplacer les états KV hors de la mémoire GPU et les stocker sur plusieurs niveaux : mémoire CPU, SSD ou NVMe local, et stockage distant ou distribué.
Cela permet de conserver bien plus de contexte réutilisable que ce qui tiendrait en mémoire GPU, tout en rapatriant sur GPU les états KV fréquemment utilisés quand nécessaire.
3. Cache KV partagé entre workers
LMCache peut rendre des états KV mis en cache disponibles pour plusieurs workers d’inférence, au lieu de les lier à un seul processus modèle.
Par exemple, si un worker vLLM traite un long document, un autre worker peut potentiellement réutiliser les états KV mis en cache, plutôt que de recalculer le même contexte.
C’est particulièrement utile pour le service distribué, les déploiements multi‑GPU et les applications où les requêtes sont routées entre plusieurs réplicas d’inférence.
4. Intégration vLLM
LMCache s’intègre à vLLM via son interface de connecteur KV.
L’application continue de communiquer avec l’endpoint vLLM compatible OpenAI habituel, tandis que LMCache opère sous la couche d’inférence.
Les applications existantes n’ont donc pas besoin de changer la manière d’envoyer les invites ou de recevoir les réponses. LMCache gère le stockage et la récupération des KV entre vLLM et le backend de cache configuré.
5. Architecture multiprocessus
LMCache peut s’exécuter dans un processus séparé de vLLM.
Au lieu de gérer le cache au sein de chaque worker d’inférence, un serveur LMCache dédié peut gérer les états KV de façon indépendante et servir plusieurs processus vLLM.
Cette séparation entre gestion du cache et service du modèle permet à plusieurs workers de partager le même cache et facilite le dimensionnement du cache indépendamment des ressources GPU d’inférence.
6. CacheBlend
Le cache de préfixe traditionnel fonctionne au mieux quand les requêtes partagent le même début d’invite.
LMCache propose aussi CacheBlend pour les charges où le contenu réutilisable peut apparaître à des positions différentes.
Par exemple, une application RAG peut récupérer les mêmes documents dans un ordre différent selon la question.
CacheBlend peut réutiliser des portions d’états KV calculés précédemment tout en recalculant sélectivement les tokens dépendant du nouveau contexte.
Cela rend la réutilisation des KV plus utile pour le RAG, les applications multi‑documents et les workflows agentiques où les invites sont fréquemment réorganisées.
7. Désagrégation préremplissage et décodage
LMCache peut aussi faciliter le transfert d’états KV entre des workers distincts de préremplissage et de décodage.
Dans cette architecture, un groupe de GPU gère l’étape de traitement d’invite, très consommatrice en calcul, tandis qu’un autre groupe gère la génération de tokens.
LMCache fournit la couche permettant de déplacer les états KV entre ces groupes.
Cela autorise un dimensionnement indépendant des ressources de préremplissage et de décodage et peut améliorer l’utilisation GPU dans des déploiements d’inférence de grande taille.
Prise en main de LMCache
Maintenant que nous comprenons le fonctionnement de LMCache, connectons‑le à vLLM, un moteur d’inférence LLM haute performance conçu pour un service et une gestion mémoire efficaces.
Pour ce guide, j’utiliserai IBM Granite 4.2 3B, un modèle compact offrant d’excellentes performances pour sa taille tout en restant suffisamment léger pour des tests pratiques.
Nous exécuterons LMCache en mode multiprocessus aux côtés de vLLM et vérifierons que les états KV peuvent être réutilisés entre requêtes.
1. Préparer l’environnement
Pour ce tutoriel, nous utiliserons Python 3.12, uv, vLLM, LMCache, le client Python OpenAI, pandas et matplotlib.
Avant de commencer, assurez‑vous d’avoir :
Vous pouvez installer
uvavec :Créez ensuite le projet :
Créez et activez un environnement virtuel Python 3.12 :
Installez les dépendances requises :
Ici, nous utilisons
cu130car notre environnement est configuré avec CUDA 13.Si vous utilisez une autre version de CUDA, adaptez la valeur de
--torch-backendau backend PyTorch compatible avec votre environnement.Granite 4.2 utilise un parseur de raisonnement personnalisé ; téléchargez‑le depuis Hugging Face :
Enfin, vérifiez que votre GPU et votre installation CUDA sont détectés :
Pour ce tutoriel, nous utilisons une NVIDIA GeForce RTX 5070 Ti avec 16 Go de VRAM.
Le système fonctionne avec le pilote NVIDIA 580.126.09, compatible CUDA 13.0.
2. Démarrer vLLM avec LMCache
Nous avons besoin de deux processus : un pour le serveur LMCache et un autre pour vLLM.
Démarrez LMCache dans un premier terminal :
Ici, nous utilisons :
6555pour la communication entre vLLM et LMCache8081pour l’interface HTTP de LMCache20 Gopour le cache L1LRUcomme politique d’évictionLaissez ce terminal ouvert.
Ouvrez un second terminal, activez le même environnement virtuel et supprimez la configuration de l’allocateur CUDA extensible si elle est activée :
Démarrez maintenant vLLM avec le connecteur LMCache :
Nous désactivons le cache de préfixe intégré de vLLM avec :
Cela permet de concentrer les expériences suivantes spécifiquement sur la réutilisation des KV via LMCache.
Une fois vLLM chargé, le modèle est disponible via son endpoint compatible OpenAI :
3. Vérifier LMCache avec un « cache hit » contrôlé
Nous allons maintenant réaliser une expérience simple et contrôlée pour confirmer que LMCache fonctionne.
Nous allons créer un grand préfixe partagé, vider le cache, envoyer une première fois le préfixe pour remplir LMCache, puis envoyer une autre requête avec le même préfixe mais une question différente.
Commencez par créer le client OpenAI :
Créez ensuite un long document partagé :
Répéter le document 500 fois produit un large préfixe partagé, suffisamment coûteux pour rendre visible l’effet de la réutilisation des KV.
Avant d’envoyer la première requête, videz LMCache afin de partir d’un cache vide :
Cela garantit que la première requête est une requête à froid et ne peut pas réutiliser des états KV d’un test antérieur.
Envoyez maintenant la première requête :
C’est la requête de chauffe du cache. vLLM doit traiter le long préfixe partagé pendant le préremplissage, tandis que LMCache stocke les états KV produits.
Ensuite, gardez exactement le même préfixe partagé et ne changez que la question :
Comme le grand préfixe est inchangé, LMCache peut réutiliser les états KV générés par la première requête au lieu de recomputer tout le préfixe.
Enfin, comparez les deux temps de requête :
Dans mon exécution, j’ai obtenu :
La requête à chaud s’est terminée presque 6 fois plus vite, réduisant la latence de bout en bout de 83,2 %.
Les questions sont différentes ; LMCache ne met donc pas en cache la réponse finale. Il réutilise plutôt les états KV du préfixe partagé.
La première requête doit traiter l’intégralité du long préfixe pendant le préremplissage et créer ces états KV à partir de zéro.
Lors de la seconde, LMCache récupère les états mis en cache correspondants, permettant à vLLM d’éviter la majeure partie du préremplissage répété et de se concentrer sur le nouveau suffixe.
Cela confirme que LMCache réutilise bien le préfixe partagé.
Quand LMCache est‑il utile ?
LMCache est particulièrement utile lorsqu’une application envoie à répétition une grande quantité de contexte identique.
Parmi les cas fréquents :
Applications RAG
Un utilisateur peut poser plusieurs questions à propos du même document récupéré.
Au lieu de traiter le document en entier à chaque question, on réutilise ses états KV.
Agents de codage
Les assistants de codage envoient souvent des fichiers de dépôt, des consignes de projet et d’autres gros blocs de contexte à chaque appel modèle.
Une grande partie de ce contexte reste identique tandis que la tâche évolue.
Agents IA
Les agents réutilisent souvent de grandes invites système, des définitions d’outils, de la mémoire, des instructions et l’état d’environnement sur de nombreuses étapes.
Conversations longues
Une conversation au long cours peut renvoyer une part importante de son historique à chaque nouveau message.
Systèmes multi‑agents
Plusieurs agents peuvent partager les mêmes documents de fond ou le même contexte système tout en travaillant sur des tâches différentes.
Dans tous ces cas, le modèle revoit des informations qu’il a déjà traitées lors de requêtes précédentes.
LMCache offre un moyen de réutiliser ce travail au niveau du cache KV.
Pour conclure
LMCache traite une source majeure de gaspillage dans l’inférence en contexte long en rendant réutilisables les états KV créés pendant le préremplissage.
Au lieu de retraiter sans cesse le même contexte partagé, le modèle réutilise le travail déjà effectué.
Nous n’incluons pas ici le code de benchmark ni les résultats détaillés, mais nous avons mené une série de tests séparés avec la même configuration.
Les résultats sont significatifs : la réutilisation d’un large préfixe partagé a réduit la latence totale d’une requête de 26,276 secondes à 4,386 secondes.
Le temps moyen jusqu’au premier token est passé de 22,149 secondes à 0,726 seconde, soit une amélioration de 30,54 fois. Les gains augmentent aussi avec la taille du contexte, de 3,55 fois avec environ 12 000 caractères partagés à 30,22 fois avec près de 245 000 caractères.
En clair : plus le contexte réutilisable est important, plus LMCache évite de travail.
DeepSeek illustre bien cet enjeu dans le monde réel.
Son système de cache peut réutiliser des préfixes d’invite identiques, ce qui est particulièrement précieux pour les agents de codage qui renvoient à répétition les mêmes invites système, outils, historiques de conversation et contexte de code.
Des taux de « cache hit » plus élevés signifient moins de calcul répété et des coûts plus faibles pour le fournisseur comme pour l’utilisateur.
La leçon principale de ce guide : accélérer l’inférence LLM ne tient pas qu’à de meilleurs GPU ou à une génération de tokens plus rapide. Il s’agit aussi de ne pas répéter inutilement le travail.
Pour les systèmes RAG, assistants de codage, agents et autres applications à contexte long, la réutilisation du cache KV peut jouer un rôle majeur pour améliorer la latence, réduire l’usage GPU et diminuer les coûts d’inférence.