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

Inferenza LLM: più throughput con il continuous batching

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.

MetodoQuando si forma o cambia il gruppoConseguenza per una richiesta in attesa
Batching staticoIl gruppo resta invariato per tutta l’esecuzione del batchDeve aspettare un altro batch anche se una richiesta breve del gruppo termina prima
Batching dinamico convenzionaleLe richieste in arrivo vengono raccolte prima dell’esecuzione, secondo le regole di batchingPuò attendere brevemente per consentire la formazione di un gruppo efficiente
Continuous batchingIl gruppo può cambiare tra un passo di generazione e il successivoPuò entrare prima che l’intero gruppo abbia terminato, se le risorse lo consentono

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.

Schema temporale delle richieste: con il batching statico C aspetta B; con il continuous batching entra dopo A
È solo un esempio di scheduling. Nella realtà i passi hanno durate diverse e ogni nuova richiesta necessita anche di prefill e memoria.

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.

Blocchi logici adiacenti di una richiesta mappati su blocchi separati della cache KV, tra spazi di memoria occupati e liberi
L’ordine logico dei token resta intatto anche quando i blocchi KV occupano posizioni fisiche separate. La mappa della memoria è concettuale.

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.

ServerSupporto documentatoParametro o vincolo rilevante
vLLM, un motore per l’inferenza e il serving degli LLMContinuous batching insieme alla memoria KV paginataNumero di sequenze, budget di token per iterazione e memoria KV disponibile
SGLang, un framework per il serving dei modelliContinuous batching nella guida ufficiale al servingLimite alle richieste in esecuzione e impostazioni del chunked prefill nella documentazione del server
NVIDIA TensorRT-LLM, il runtime di inferenza di NVIDIAIn-flight batching, chiamato anche continuous batchingLimiti sulle richieste e sui token impacchettati; scheduling che tiene conto della capacità disponibile
Hugging Face Text Generation Inference, o TGIContinuous batching delle richieste in arrivoIl progetto è ora in modalità manutenzione

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.

Documentazione sull’ottimizzazione di vLLM dedicata a preemption e chunked prefill
vLLM: i compromessi documentati tra scheduling e memoria

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.

Documentazione degli argomenti del server SGLang con i parametri per scheduling e memoria
SGLang: controlli su richieste, prefill e memoria

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.

Documentazione di TensorRT-LLM sull’in-flight batching e sullo scheduling delle richieste
TensorRT-LLM: in-flight batching e budget di token

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.

Documentazione di Hugging Face TGI con l’avviso sullo stato di manutenzione e la funzionalità di continuous batching
TGI: il continuous batching resta documentato; il progetto è in modalità manutenzione

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.

  1. 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.

  2. 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.

  3. 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_seconds e vllm:inter_token_latency_seconds, nella documentazione delle metriche di produzione.

  4. 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
Chain of thought e Tree of Thoughts: quando serve un albero

Chain of thought e Tree of Thoughts: quando serve un albero

Quando passare dal chain of thought a Tree of Thoughts? Esempi, valutazione dei rami e chiamate al modello per capire quando la ricerca ad albero conviene.24 ott 2026Build
Agenti AI: come funziona il ciclo e quando fermarlo

Agenti AI: come funziona il ciclo e quando fermarlo

Come funzionano gli agenti AI: chiamate al modello, strumenti e condizioni di arresto. Confronto tra framework e soluzioni per i cicli che non si fermano.24 ott 2026Build
AI per programmare: come delegare il lavoro agli agenti

AI per programmare: come delegare il lavoro agli agenti

AI per programmare con Claude Code, Codex, Cursor e Copilot: scopri cosa delegare agli agenti e come usare specifiche, permessi, test e revisione.24 ott 2026Build
Finestra di contesto e context rot: perché le chat lunghe peggiorano

Finestra di contesto e context rot: perché le chat lunghe peggiorano

Perché gli agenti perdono precisione prima di riempire la finestra di contesto: lo studio di Chroma e i rimedi tra compattazione e recupero delle informazioni.24 ott 2026Build
BM25 e ricerca ibrida: combinare parole e vettori

BM25 e ricerca ibrida: combinare parole e vettori

Combina BM25 e ricerca vettoriale con RRF o punteggi pesati. Implementa la ricerca ibrida nel database esistente e misura il recall su query annotate.24 ott 2026Build
Mixture of experts: cosa cambia tra parametri attivi e totali

Mixture of experts: cosa cambia tra parametri attivi e totali

Come funziona il mixture of experts: parametri totali e attivi, memoria e latenza. I casi Kimi, Qwen e Mixtral per scegliere tra API e self-hosting.24 ott 2026Build
LLM as a judge e test: il ciclo pratico dell’eval-driven development

LLM as a judge e test: il ciclo pratico dell’eval-driven development

Dai casi reali al rilascio: combina test e LLM as a judge, misura la versione iniziale e verifica ogni modifica con un esempio pratico basato su 20 casi.24 ott 2026Build
Benchmark LLM: come misurare la velocità in token al secondo

Benchmark LLM: come misurare la velocità in token al secondo

Come leggere un benchmark LLM: token al secondo, attesa del primo token e latenza. Misura il flusso reale e scegli il modello in base ai tempi della tua app.24 ott 2026Build
Newsletter

Una lettera, ogni domenica.Sistemi che funzionano, non hot take.

Settimanale. Niente spam. Si cancella quando vuole.