vLLM smontato: paged attention, continuous batching e scheduling spiegati dal codice
Cos’è successo. Aleksa Gordić ha pubblicato un’analisi tecnica che smonta vLLM componente per componente: dal KV cache manager con paged attention, allo scheduler con continuous batching, fino al serving layer multi-nodo. Il post segue il codice del motore V1 (commit di agosto 2025) e parta dalle basi per aggiungere strati uno alla volta.
Perché ti riguarda. Se servi modelli open-weight in produzione, vLLM è probabilmente sotto il tuo stack. Capire come gestisce la memoria video, lo scheduling delle richieste e il batching continuo ti aiuta a diagnosticare colli di bottiglia e configurarlo meglio, invece di trattarlo come una scatola nera. Quando il throughput crolla o la latenza impazzisce, sapere cosa fa il scheduler sotto il cofano fa la differenza fra un tuning mirato e un’ipotesi.
Se vuoi provarci. L’articolo è gratuito, parte da un esempio Python con una GPU singola e va in salita. Livello by livello: scheduler, paged attention, continuous batching, prefix caching, speculative decoding, multi-GPU, serving layer.
Nel dettaglio
vLLM è il motore di inference che la maggior parte di chi serve modelli open-weight in produzione ha sotto il cofano. Il progetto ha introdotto l’idea di paged attention: invece di riservare un blocco contiguo di memoria video per ogni richiesta, la KV cache viene divisa in pagine di dimensione fissa, allocate e liberate on demand. La memoria si riutilizza senza frammentazione, e il throughput cresce significativamente rispetto a un’allocazione ingenua. Pensa a un ufficio dove ogni persona ha un armadietto dedicato, vuoto per metà: sprechi spazio. Con le pagine, assegni solo i ripiani che servono, quando servono, e li liberi appena finisci.
L’articolo di Gordić segue il codice del motore V1 e lo spiega dal basso verso l’alto. Parte dall’esempio più semplice: un’istanza offline, single-GPU, sincrona. Da lì aggiunge strati. Lo scheduler con la sua policy FCFS o prioritaria decide chi entra nel batch e chi aspetta, in base alla memoria disponibile. Il KV cache manager con la sua free_block_queue tiene traccia dei blocchi liberi e occupati, come una lista di stanze vuote in un albergo. Il model executor fa girare i forward pass, cioè i veri passaggi di calcolo del modello sulla GPU.
Poi sale di livello. Continuous batching: vLLM non aspetta che un batch di richieste finisca tutto prima di caricarne di nuove. A ogni step di decoding, il scheduler rimescola le richieste attive, inserendo quelle nuove dove c’è spazio. Una richiesta corta non aspetta una lunga per liberare il batch. In un sistema tradizionale, se metti insieme dieci richieste e una è molto più lunga delle altre, le nove corte restano bloccate ad aspettare la decima. Con il batching continuo, ogni volta che una richiesta finisce, il suo posto nel batch viene preso subito da un’altra in coda.
Prefix caching riconosce quando più richieste condividono lo stesso prefisso (system prompt, contesto condiviso) e ne cachezza il risultato, risparmiando calcolo. Se cento utenti mandano lo stesso prompt di sistema, vLLM calcola i token di quel prefisso una volta sola. Speculative decoding usa un modello piccolo per generare bozze di token che il modello grande verifica in un solo forward pass, scambiando throughput per latenza. Il modello piccolo suggerisce, ad esempio, cinque token; il modello grande controlla in un colpo solo quanti sono giusti e li accetta, rigenerando solo i rimanenti.
Gli ultimi due livelli trattano il salto da una GPU a più GPU e più nodi: data parallelism, tensor parallelism, pipeline parallelism, expert parallelism. Il tensor parallelism splitta i pesi del modello su più GPU, così un modello troppo grande per una sola scheda ci sta diviso. Il pipeline parallelism assegna strati diversi a GPU diverse, passando i risultati avanti a turno. E il serving layer mette tutto dietro un’API asincrona, capace di gestire migliaia di richieste simultanee senza bloccarsi.
Il limite di questo writeup è che vLLM si muove velocemente: il motore V0 è già deprecato, il V1 evolve di settimana in settimana. L’articolo è ancorato a un commit specifico, e alcune interfacce potrebbero essere cambiate. I concetti di base restano stabili: chi li capisce sa diagnosticare problemi di throughput, configurare meglio i parametri di memoria, e scegliere quando vLLM è lo strumento giusto rispetto ad alternative come SGLang o TensorRT-LLM.