Inferenza LLM: più throughput con il continuous batching
Come il continuous batching migliora il throughput nell’inferenza LLM: effetti su latenza e cache KV, con i limiti di vLLM, SGLang, TensorRT-LLM e TGI.
Pubblicato il

Nell’inferenza LLM, il continuous batching permette a una GPU condivisa di accogliere nuove richieste tra un passo di generazione e il successivo: quando un’attività breve termina, la capacità che libera non resta inutilizzata in attesa di quelle più lunghe. Il paper Orca di Yu e colleghi, pubblicato a OSDI nel 2022, ha posto le basi di questo cambiamento nello scheduling. Con più richieste contemporanee può aumentare il totale dei token generati al secondo, ma un server più occupato non garantisce risposte più rapide a ogni utente.
Per un server che mette un modello a disposizione di più utenti, l’obiettivo utile è completare più lavoro rispettando i limiti sui tempi di risposta. Un grafico del throughput, senza un obiettivo di latenza, non dice quanti clienti il server possa servire con un’esperienza soddisfacente.
Le funzionalità e i parametri dei server descritti di seguito sono stati verificati sulla documentazione ufficiale disponibile il 25 ottobre 2026. L’esempio di scheduling serve a illustrare il meccanismo: non è un benchmark hardware.
Come funziona il batching continuo nell’inferenza LLM
Il continuous batching modifica il gruppo di richieste attive mentre la generazione è ancora in corso. Una richiesta completata esce dal gruppo; una in attesa può entrarvi quando lo scheduler dispone delle risorse necessarie. Questa tecnica viene chiamata anche in-flight batching o iteration-level batching.
Un modello linguistico di grandi dimensioni, o LLM, elabora prima il prompt nella fase di prefill, poi genera il testo che segue nella fase di decode. Nel normale decoding autoregressivo, a ogni passo di generazione ciascuna richiesta attiva produce il token successivo, cioè un frammento di testo. Lo scheduler decide quali richieste partecipano al passo seguente. La guida all’inferenza LLM approfondisce queste fasi.
Si può immaginare un tavolo condiviso al ristorante. Con turni fissi, il gruppo successivo si siede solo quando tutti i commensali del gruppo precedente hanno finito. Con un ricambio continuo, un nuovo cliente può occupare una sedia libera mentre qualcun altro sta ancora mangiando. Il tavolo è condiviso, ma ogni pasto resta distinto.
L’analogia ha un limite: lo scheduler di una GPU deve gestire anche l’elaborazione dei prompt e l’allocazione della memoria. Una sedia libera non significa che qualsiasi richiesta in attesa possa entrare subito.
Qual è stato il contributo di Orca?
Orca ha spostato le decisioni di scheduling dalla singola richiesta alla singola iterazione. Il paper presentato a OSDI 2022 da Gyeong-In Yu e colleghi descrive un sistema che invoca il motore di esecuzione per una sola iterazione del modello, poi rivaluta la composizione del batch.
La tecnica complementare, il selective batching, raggruppa alcune operazioni del modello e al tempo stesso gestisce le diverse cronologie necessarie all’attenzione, l’operazione che collega un token al contesto precedente. Insieme, queste tecniche consentono al sistema di serving di intercalare richieste di lunghezza diversa. Il paper considera anche la dimensione del batch e la memoria key-value disponibile come vincoli per lo scheduling. Leggi il paper Orca.
Il cambiamento riguarda il sistema che esegue e serve il modello. Non occorre addestrare il modello a rispondere a più persone all’interno di un’unica conversazione.
Batching statico, dinamico e continuo: le differenze
La domanda decisiva è quando una nuova richiesta può unirsi al lavoro già in corso. Accettare connessioni HTTP simultanee, da solo, non dimostra che l’esecuzione del modello utilizzi il continuous batching.
La documentazione di NVIDIA sul batching in Triton descrive il batching dinamico convenzionale, compresi i parametri per la dimensione del batch e il ritardo in coda. È una decisione di scheduling diversa dalla sostituzione delle richieste durante la generazione di un LLM.
Batching dinamico in vLLM: conta quando cambia il gruppo
vLLM, un motore per il serving degli LLM, documenta il supporto al continuous batching. «Batching dinamico» è un’etichetta meno precisa. Anche Hugging Face usa dynamic scheduling o dynamic batching per descrivere la sostituzione dei prompt completati durante la generazione nella sua spiegazione del continuous batching. Occorre verificare se il motore ammette nuovo lavoro tra i passi di generazione, senza fermarsi al nome della funzionalità.
Lo streaming è un altro aspetto ancora. Un server può inviare token al client in streaming mantenendo invariata la composizione del batch in esecuzione. Il vantaggio di cui parliamo qui è la possibilità di usare, per le nuove richieste, la capacità liberata da quelle completate.
Un esempio di scheduling
Una richiesta breve può liberare capacità utile mentre una più lunga continua a essere elaborata. Immaginiamo un server con due posti disponibili per il decode. Alla richiesta A servono ancora 2 passi, alla B ne servono 4 e la C è in attesa con 2 passi di lavoro da svolgere. Per questo esempio trascuriamo il prefill, l’overhead dello scheduling e le variazioni nella durata dei passi.
Con un gruppo fisso, A e B partono insieme. A termina, ma C deve aspettare che finisca anche B prima che inizi il gruppo successivo. Con il continuous batching, C può occupare il posto di A appena questa termina e procedere insieme a B.

L’esempio mostra un ingresso anticipato, non un’accelerazione misurata. Un chatbot di assistenza che alterna risposte brevi e riepiloghi lunghi offre la stessa opportunità allo scheduler; il guadagno effettivo dipende dalle richieste, dall’hardware e dalla configurazione del sistema di serving.
Perché aumenta il throughput e dove interviene il limite della cache KV
Il batching permette di ricavare più lavoro utile dallo stesso trasferimento dei pesi del modello. I pesi sono i parametri numerici appresi che il modello usa per calcolare una risposta. Più richieste dirette allo stesso modello possono condividere il lavoro necessario a trasferire quei pesi attraverso la memoria della GPU, sfruttando meglio la capacità di calcolo disponibile. Lo scheduling continuo aiuta a mantenere questo batch utile man mano che le singole richieste terminano. NVIDIA spiega il rapporto tra batching, trasferimenti di memoria e utilizzo della GPU.
La GPU può restare occupata anche con un batch inefficiente. Conta quanto lavoro utile per le richieste produce quell’attività, non quanto appare pieno il grafico di utilizzo.
Ogni richiesta attiva, però, ha anche bisogno di memoria di lavoro. La sua cache KV, abbreviazione di key-value cache, conserva lo stato dell’attenzione relativo ai token già elaborati. Più richieste contemporanee e cronologie più lunghe aumentano la pressione su questa memoria. La guida alla cache KV chiarisce la differenza tra questo stato e la cache riutilizzabile dei prompt.
PagedAttention sfrutta meglio lo spazio in memoria
Il continuous batching decide cosa eseguire; PagedAttention cambia il modo in cui viene memorizzato lo stato dell’attenzione. Il paper su vLLM del 2023, di Woosuk Kwon e colleghi, descrive la suddivisione dello stato KV in blocchi di dimensione fissa che non devono necessariamente occupare aree adiacenti nella memoria fisica. Una mappa dei blocchi preserva l’ordine logico della sequenza.
Questo riduce la memoria sprecata per frammentazione e duplicazioni superflue. Una disposizione più efficiente permette di ospitare in memoria i dati di lavoro di più richieste e offre allo scheduler più lavoro utile tra cui scegliere. Il paper presenta esplicitamente questo approccio alla gestione della memoria come complementare allo scheduling di Orca.

Il limite resta la capacità fisica. Sfruttare meglio lo spazio non consente di ospitare un numero illimitato di conversazioni lunghe. In vLLM, uno spazio KV insufficiente può causare preemption: una richiesta viene sospesa e il suo stato viene ricalcolato in seguito, con un possibile peggioramento del tempo di completamento. La documentazione sull’ottimizzazione spiega questo comportamento.
Che cosa cambia per la latenza?
Il continuous batching può ridurre l’attesa in coda, mentre batch più grandi o più affollati possono rallentare l’esperienza dopo l’ammissione della richiesta. Le fasi vanno monitorate separatamente:
- Tempo al primo token, o TTFT: quanto aspetta l’utente prima che inizi l’output.
- Latenza tra token: gli intervalli tra un token e il successivo una volta avviato lo streaming.
- Latenza end-to-end: il tempo necessario a completare l’intera richiesta.
Una nuova richiesta può evitare di attendere il completamento di un intero batch fisso. Tuttavia, l’elaborazione di un nuovo prompt lungo può contendere risorse alle richieste già in fase di decode. Il chunked prefill suddivide l’elaborazione del prompt in parti più piccole, così lo scheduler può alternarla alla generazione già in corso.
vLLM, per esempio, documenta un compromesso legato al budget di token per iterazione: valori più bassi possono tutelare la latenza tra token, mentre valori più alti consentono di elaborare più prefill e migliorare il TTFT. Il budget va quindi scelto in base al carico di lavoro, non portato al massimo a prescindere. Indicazioni di vLLM per la configurazione.
Continuous batching negli LLM: dal carico leggero al sovraccarico
Con poco traffico possono esserci poche richieste da raggruppare; con un sovraccarico prolungato la coda rimane. Uno sviluppatore che invia una richiesta alla volta non dovrebbe aspettarsi lo stesso beneficio di un servizio rivolto ai clienti, dove le richieste si sovrappongono. All’estremo opposto, ammettere più lavoro di quanto la GPU possa sostenere finisce per peggiorare i tempi di attesa.
Per un’applicazione interattiva, va osservato il p95, cioè il 95° percentile, oltre alla mediana. Una buona media può nascondere una minoranza di sessioni lente. Il TTFT accettabile e gli intervalli tollerabili nello streaming vanno stabiliti in base all’esperienza del prodotto; solo dopo si misura la capacità entro quei limiti.
Server LLM con continuous batching: supporto e limiti
Tutti e quattro i server seguenti documentano il supporto al continuous batching o all’in-flight batching. Questa funzionalità comune non rende intercambiabili gli scheduler, i budget di memoria o il supporto ai modelli.
Il continuous batching in vLLM
vLLM combina lo scheduling continuo delle richieste con la gestione paginata della cache KV. La documentazione elenca esplicitamente entrambe le funzionalità. Per chi gestisce il servizio, i parametri utili sono il numero massimo di sequenze e i token pianificati per iterazione, non semplicemente il numero desiderato di connessioni API simultanee.
Il limite è la pressione sulla memoria: aumentare le richieste contemporanee può causare preemption e ricalcoli, anziché offrire più capacità utilizzabile. La configurazione va calibrata sul proprio mix di traffico e sull’obiettivo di latenza, mantenendo invariati modello e hardware quando si confrontano le impostazioni.
SGLang
SGLang supporta il continuous batching ed espone controlli espliciti per l’ammissione delle richieste. La documentazione degli argomenti del server definisce --max-running-requests, --chunked-prefill-size e il budget destinato ai pesi del modello e al pool KV, regolato da --mem-fraction-static.
Questi parametri rispondono a domande diverse: quante richieste possono essere eseguite, quanto lavoro sul prompt entra in un blocco di prefill e come viene allocata la memoria. Alzare il limite delle richieste non elimina gli altri vincoli. Per orientarsi nella scelta del motore, è utile il confronto tra vLLM e SGLang; occorre poi valutare il modello preciso e il mix di richieste che si intende servire.
NVIDIA TensorRT-LLM
NVIDIA TensorRT-LLM equipara esplicitamente l’in-flight batching al continuous batching e all’iteration-level batching. La documentazione della funzionalità descrive l’elaborazione congiunta di sequenze nella fase di contesto e nella fase di generazione, con tensori di input impacchettati nell’implementazione descritta.
Il limite delle richieste e il budget di token sono vincoli distinti. Anche la documentazione dello scheduler PyTorch separa la prenotazione delle risorse, compresa la capacità KV, dalla scelta delle richieste compatibili con tali risorse da eseguire. Uno scheduler in-flight non può ammettere lavoro che non supera queste verifiche di capacità.
Hugging Face Text Generation Inference
Hugging Face Text Generation Inference supporta il continuous batching, ma il suo stato di manutenzione cambia la valutazione per una nuova installazione. La documentazione indica che il progetto accetta ora correzioni minori, miglioramenti alla documentazione e interventi limitati di manutenzione; per il futuro consiglia di usare motori alternativi, tra cui vLLM e SGLang.
Un’installazione TGI esistente non perde il batching per effetto di questo stato. Per un nuovo stack di serving, inizierei la valutazione dalle alternative sviluppate attivamente. Per un’installazione consolidata che raggiunge i propri obiettivi, conviene pianificare la migrazione in funzione di un’esigenza concreta di supporto o funzionalità.
Quali promesse vanno ridimensionate?
Il continuous batching non offre un fattore di accelerazione valido ovunque. I paper Orca e PagedAttention valutano sistemi e carichi di lavoro specifici. I loro risultati non isolano un miglioramento universale applicabile a qualsiasi modello, GPU o endpoint di un provider.
Non elimina neppure l’attesa. Una richiesta in coda ha comunque bisogno dell’elaborazione del prompt, della memoria e del proprio turno secondo la politica dello scheduler. Prompt lunghi, molte richieste contemporanee e pressione sulla cache restano vincoli reali.
Infine, un aumento del totale dei token al secondo non dimostra che un prodotto di chat sia migliorato. Se gli utenti aspettano di più il primo token o incontrano pause fastidiose durante lo streaming, il throughput aggiuntivo del server può collocarsi al di fuori dei limiti operativi accettabili per il prodotto.
Da dove iniziare, in pratica
Chi sviluppa dovrebbe valutare il serving condiviso quando le richieste si sovrappongono; chi gestisce il servizio dovrebbe ottimizzarlo entro i limiti di latenza; chi valuta un provider dovrebbe chiedere misurazioni con richieste in competizione per le risorse. Uno strumento personale con richieste occasionali può aspettare. Un servizio con clienti in coda e risposte di lunghezza diversa ha un motivo concreto per intervenire. Il confronto tra Ollama e vLLM affronta il passaggio dall’uso locale al serving condiviso.
Definisci l’esperienza prima di aumentare le richieste simultanee
Stabilisci il tempo al primo token, gli intervalli nello streaming e il tempo di completamento accettabili per il flusso di lavoro reale. Un sistema che produce riepiloghi in background e un assistente di supporto in tempo reale richiedono soglie diverse.
Riproduci un mix rappresentativo di richieste
Mantieni confrontabili il modello, l’hardware, le lunghezze dei prompt, i limiti di output e le condizioni della cache. Includi risposte brevi, prompt lunghi e generazioni lunghe. Riproduci modalità di arrivo realistiche, così una prova tranquilla con un solo utente non viene scambiata per il comportamento di un servizio molto utilizzato.
Registra il throughput insieme alla coda e alla latenza
Misura i token in uscita al secondo dell’intero server, le richieste completate, quelle in attesa, gli errori, il TTFT e gli intervalli tra token. vLLM espone metriche corrispondenti, tra cui
vllm:num_requests_waiting,vllm:time_to_first_token_secondsevllm:inter_token_latency_seconds, nella documentazione delle metriche di produzione.Fermati al carico massimo che rispetta gli obiettivi
Modifica un solo parametro di scheduling o memoria alla volta. Smetti di aumentare le richieste contemporanee quando i limiti di latenza vengono superati o la pressione sulla memoria provoca ricalcoli ripetuti. Chiedi al provider la stessa visione congiunta di throughput e latenza con il numero di richieste simultanee previsto, e verifica se la capacità è condivisa o riservata.
Il risultato da ottenere è un limite operativo misurato: il carico che l’endpoint può sostenere mantenendo l’esperienza utente desiderata. È questo che permette di trasformare una funzionalità di batching in una decisione concreta sul deployment.
Per spiegazioni pratiche sull’infrastruttura AI e su cosa cambiare nel tuo stack, iscriviti alla newsletter.
- Pubblicato
- Categoria
- Build
- Lingua











