vLLM démonté : paged attention, continuous batching et scheduling expliqués par le code
Ce qui s’est passé. Aleksa Gordić a publié une analyse technique qui démonte vLLM composant par composant : du KV cache manager avec paged attention, au scheduler avec continuous batching, jusqu’au serving layer multi-nœud. Le post suit le code du moteur V1 (commit d’août 2025) et part des bases pour ajouter des couches une par une.
Pourquoi ça te concerne. Si tu déploies des modèles open-weight en production, vLLM est probablement sous ta stack. Comprendre comment il gère la mémoire vidéo, le scheduling des requêtes et le batching continu t’aide à diagnostiquer les goulots d’étranglement et le configurer mieux, au lieu de le traiter comme une boîte noire. Quand le throughput s’effondre ou la latence explose, savoir ce que fait le scheduler sous le capot fait la différence entre un tuning ciblé et une hypothèse.
Si tu veux essayer. L’article est gratuit, il part d’un exemple Python avec une seule GPU et grimpe progressivement. Niveau après niveau : scheduler, paged attention, continuous batching, prefix caching, speculative decoding, multi-GPU, serving layer.
En détail
vLLM est le moteur d’inference que la plupart de ceux qui déploient des modèles open-weight en production ont sous le capot. Le projet a introduit l’idée de paged attention : au lieu de réserver un bloc contigu de mémoire vidéo pour chaque requête, le KV cache est divisé en pages de taille fixe, allouées et libérées à la demande. La mémoire se réutilise sans fragmentation, et le throughput augmente significativement par rapport à une allocation naïve. Pense à un bureau où chaque personne a un casier dédié, à moitié vide : tu gaspilles de l’espace. Avec les pages, tu assignes seulement les étagères dont tu as besoin, quand tu en as besoin, et tu les libères dès que tu as fini.
L’article de Gordić suit le code du moteur V1 et l’explique de bas en haut. Il part de l’exemple le plus simple : une instance offline, single-GPU, synchrone. De là, il ajoute des couches. Le scheduler avec sa policy FCFS ou prioritaire décide qui entre dans le batch et qui attend, en fonction de la mémoire disponible. Le KV cache manager avec sa free_block_queue garde la trace des blocs libres et occupés, comme une liste de chambres vides dans un hôtel. Le model executor fait tourner les forward pass, c’est-à-dire les véritables passages de calcul du modèle sur la GPU.
Puis il monte d’un cran. Continuous batching : vLLM n’attend pas qu’un batch de requêtes finisse complètement avant d’en charger de nouvelles. À chaque étape de decoding, le scheduler remixe les requêtes actives, en insérant les nouvelles où il y a de la place. Une requête courte n’attend pas une longue pour libérer le batch. Dans un système traditionnel, si tu mets ensemble dix requêtes et que l’une est beaucoup plus longue que les autres, les neuf courtes restent bloquées à attendre la dixième. Avec le batching continu, chaque fois qu’une requête finit, sa place dans le batch est immédiatement prise par une autre en file d’attente.
Prefix caching reconnaît quand plusieurs requêtes partagent le même préfixe (system prompt, contexte partagé) et en cache le résultat, économisant du calcul. Si cent utilisateurs envoient le même prompt système, vLLM calcule les tokens de ce préfixe une seule fois. Speculative decoding utilise un petit modèle pour générer des brouillons de tokens que le grand modèle vérifie en un seul forward pass, échangeant le throughput pour la latence. Le petit modèle suggère, par exemple, cinq tokens ; le grand modèle vérifie en une seule fois combien sont corrects et les accepte, en régénérant seulement les restants.
Les deux derniers niveaux traitent du saut d’une GPU à plusieurs GPUs et plusieurs nœuds : data parallelism, tensor parallelism, pipeline parallelism, expert parallelism. Le tensor parallelism divise les poids du modèle sur plusieurs GPUs, ainsi un modèle trop gros pour une seule carte y tient divisé. Le pipeline parallelism assigne des couches différentes à des GPUs différentes, en passant les résultats en avant à tour de rôle. Et le serving layer met tout derrière une API asynchrone, capable de gérer des milliers de requêtes simultanées sans se bloquer.
La limite de ce writeup est que vLLM évolue rapidement : le moteur V0 est déjà déprécié, le V1 change de semaine en semaine. L’article est ancré à un commit spécifique, et certaines interfaces pourraient avoir changé. Les concepts de base restent stables : qui les comprend sait diagnostiquer les problèmes de throughput, configurer mieux les paramètres de mémoire, et choisir quand vLLM est le bon outil par rapport aux alternatives comme SGLang ou TensorRT-LLM.