Guide pratiche
Mettere gli LLM in produzione: una guida completa
Tutto quello che c’è da sapere per servire modelli linguistici di grandi dimensioni su larga scala. La guida tratta framework di serving, quantizzazione, batching, scalabilità e ottimizzazione dei costi.

AI.info Team ·
Scegliere un framework di serving
Oggi quattro framework coprono quasi tutte le implementazioni di LLM in produzione. La scelta va fatta in base ai vincoli hardware e al profilo del traffico, non soltanto ai benchmark: le differenze tra loro sono reali, ma di solito inferiori a quella tra un’implementazione ottimizzata e una non ottimizzata dello stesso framework.
- vLLM è la scelta predefinita per la maggior parte dei team. Ha introdotto PagedAttention (sviluppato dallo Sky Computing Lab della UC Berkeley e presentato a SOSP 2023), che gestisce la cache KV come la memoria virtuale di un sistema operativo: la suddivide in blocchi di dimensioni fisse (16 token ciascuno), così le sequenze non richiedono memoria contigua e possono condividere pagine quando hanno un prefisso in comune. Insieme al batching continuo, questo permette a vLLM di raggiungere un throughput 2–5 volte superiore a quello del batching statico non ottimizzato. Supporta la più ampia gamma di hardware (NVIDIA, AMD e alcuni chip per l’inferenza) ed è la scelta generalista più sicura.
- SGLang usa RadixAttention, un sistema di caching dei prefissi che riutilizza automaticamente la cache KV tra richieste con lo stesso prefisso nel prompt. Nei carichi di lavoro in cui i prefissi vengono riutilizzati spesso — applicazioni di chat con lunghi prompt di sistema, pipeline RAG, agenti che gestiscono più turni di conversazione — i benchmark hanno mostrato un throughput di SGLang superiore a quello di vLLM di circa il 29%. Tende inoltre a prevalere sulla latenza delle singole richieste.
| Framework | Throughput relativo | Nota |
|---|---|---|
| vLLM | 2-5 volte quello del batching statico non ottimizzato | Riferimento: PagedAttention + batching continuo |
| SGLang | ~29% più veloce di vLLM | Carichi di lavoro con frequente riutilizzo dei prefissi (per esempio Llama-3.1-8B su H100) |
| TensorRT-LLM | 8-13% più veloce di vLLM | Su H100/H200, a seconda del numero di richieste simultanee |
- TensorRT-LLM è l’ambiente di esecuzione di NVIDIA basato su kernel compilati. Su H100/H200 può essere più veloce di vLLM dell’8–13%, a seconda del numero di richieste simultanee, perché compila in anticipo kernel CUDA specifici per il modello. Il prezzo da pagare è la scarsa flessibilità: occorrono 1–2 settimane per la configurazione e la costruzione degli engine per ogni combinazione di modello e GPU, e si resta vincolati all’hardware NVIDIA.
- TGI (Text Generation Inference di Hugging Face) ha concluso il suo sviluppo. È entrato in modalità di manutenzione e il repository è stato archiviato in sola lettura il 21 marzo 2026: niente correzioni, nuove funzionalità o patch di sicurezza. Lo stesso avviso di archiviazione rimanda a vLLM e SGLang, oltre che a llama.cpp o MLX per i motori locali. Non usatelo per avviare un nuovo progetto e, se lo usate ancora, pianificate una migrazione.
Regola pratica: scegliete vLLM come punto di partenza. Passate a SGLang se il vostro traffico è dominato da richieste che condividono un prefisso (bot di assistenza, framework per agenti, RAG con un prompt di sistema fisso). Passate a TensorRT-LLM solo se disponete di un parco GPU NVIDIA stabile e standardizzato, la latenza è il KPI principale e avete il tempo e le competenze ingegneristiche per mantenere gli engine compilati quando aggiornate i modelli.
Quantizzazione
La quantizzazione è di solito la leva più efficace sia per i costi sia per la latenza, e la scelta dipende dal fatto che il limite principale sia la memoria delle GPU o il throughput.
- AWQ (Activation-aware Weight Quantization) preserva i pochi canali dei pesi più importanti per le attivazioni, anziché quantizzare tutto in modo uniforme. In un confronto del 2025 sui modelli Llama-3.1 Instruct, il divario tra AWQ a 4 bit e GPTQ era ridotto nei benchmark accademici e più ampio, a favore di GPTQ, nei benchmark basati su attività reali (a risposta aperta); l’ambiente di esecuzione TinyChat di AWQ mostra una velocità circa 2,7–3,9 volte superiore a FP16 sulle GPU consumer e per dispositivi edge. Usate AWQ quando vi servono 4 bit e non potete tollerare la perdita di accuratezza di una quantizzazione non ottimizzata.
| Metodo | Effetto | Dettaglio |
|---|---|---|
| AWQ | Velocità ~2,7-3,9 volte superiore a FP16 | Ambiente di esecuzione TinyChat, GPU consumer/per dispositivi edge |
| FP8 | Throughput fino al 25-30% superiore a FP16 | Con batch di grandi dimensioni |
| Cache KV FP8 | Entro ~0,01 punti di perplexity rispetto alla precisione piena | Perdita di qualità minima rispetto al riferimento a precisione piena |
- GPTQ è un metodo di quantizzazione post-addestramento, applicato strato per strato e ottimizzato per il throughput delle GPU. Resta una scelta valida per l’inferenza in produzione incentrata sulle GPU, quando si punta esclusivamente a ottimizzare i token al secondo con INT4 e si è verificata l’accuratezza sul proprio set di valutazione: GPTQ e AWQ sono abbastanza vicini perché a fare la differenza siano spesso il supporto dei framework e la maturità degli strumenti.
- FP8 è il formato nativo dei tensor core Hopper (H100/H200) e Blackwell (B200). Con batch di grandi dimensioni offre un throughput fino al 25–30% superiore a FP16, con una perdita di qualità molto inferiore a quella dei sistemi INT4, perché l’intervallo dinamico di FP8 gestisce meglio i valori anomali. Nei benchmark recenti, la cache KV FP8 (che quantizza la cache stessa, non solo i pesi) può mantenere la perplexity entro ~0,01 punti rispetto a un riferimento a precisione piena. Se le vostre GPU supportano FP8 nativamente (Hopper/Blackwell), è spesso la scelta predefinita migliore: meno rischi per l’accuratezza rispetto a INT4 e gran parte del vantaggio in termini di throughput.
- GGUF (il formato di llama.cpp, da Q3_K_M a Q8_0) è la scelta giusta per l’inferenza su CPU, le implementazioni edge o il serving su una sola GPU su scala amatoriale: in genere non è ciò che serve per un cluster di serving in produzione con più GPU.
Raccomandazione di partenza per un cluster di produzione su Hopper o architetture successive: usate pesi FP8 e cache KV FP8. Passate ad AWQ INT4 solo se la memoria è un vincolo e potete verificare sulle vostre attività il compromesso in termini di accuratezza. Ricordate che AWQ, GPTQ e FP8 richiedono tutti una verifica per ogni modello e ogni attività prima di scegliere: i valori di perplexity pubblicati per benchmark generici non garantiscono che la vostra attività tolleri la stessa perdita.
Batching, cache KV e decodifica speculativa
Il batching continuo sostituisce il vecchio modello «aspetta che un batch sia completo, eseguilo, aspetta il batch successivo» con uno scheduler che aggiunge nuove richieste al batch in esecuzione non appena si libera uno slot sulla GPU (quando termina un’altra sequenza) e rimuove subito le sequenze completate. Da solo, spiega gran parte del vantaggio in termini di throughput dei server moderni rispetto al batching dell’epoca del 2022.
PagedAttention (vLLM) e i suoi equivalenti in altri motori risolvono il problema della frammentazione della memoria creato dal batching continuo: le sequenze di lunghezza variabile sprecano memoria della GPU se la cache KV deve essere contigua. Suddividere la cache in blocchi di dimensione fissa — e consentire a più sequenze di condividere pagine quando hanno un prefisso comune — riduce l’uso della VRAM di oltre il 50% negli scenari con contesti lunghi e un’elevata sovrapposizione dei prefissi (chat con un prompt di sistema condiviso, prompt few-shot, spazi di lavoro degli agenti).
Il chunked prefill suddivide la fase di elaborazione del prompt (prefill) in blocchi intervallati da passaggi di decodifica di altre richieste, invece di lasciare che un prompt lungo occupi la GPU per una richiesta alla volta. È importante quando il carico di lavoro combina prompt brevi e lunghi: senza questa tecnica, una richiesta con un prompt da 20K token può far impennare la latenza di tutte le altre richieste simultanee. Per una nuova installazione di vLLM, l’ordine consigliato per la messa a punto è: abilitare il batching continuo (attivo per impostazione predefinita), aumentare gpu_memory_utilization verso 0,90–0,95 per dare a PagedAttention un pool più ampio, quindi attivare il chunked prefill se si osservano picchi di latenza causati dal prefill.
La decodifica speculativa è ormai standard in tutti i principali motori di inferenza (vLLM, SGLang, TensorRT-LLM, LMDeploy). Un piccolo modello di bozza propone in anticipo diversi token; il modello completo li verifica in un unico passaggio, accettando quelli che avrebbe comunque generato. Con tassi di accettazione comunemente superiori all’80% su testi strutturati o prevedibili, questa tecnica offre accelerazioni da 2 a 4 volte in produzione, mentre metodi specializzati per il modello di bozza (EAGLE-3 e simili) portano i carichi di lavoro incentrati sulla programmazione ad accelerazioni da 3,5 a 5 volte.
È meno efficace per output ad alta entropia, come la scrittura creativa, in cui le proposte del modello di bozza vengono respinte più spesso e il costo aggiuntivo non vale il beneficio: conviene riservarla anzitutto agli assistenti per la programmazione, all’estrazione strutturata e ad altri carichi di lavoro con output vincolato.
Un avvio minimale di vLLM che riflette queste scelte — con i pesi lasciati come variabile, perché sono la parte dello stack che cambia più rapidamente:
MODEL=<your-instruct-checkpoint> # current open-weight family, see below
DRAFT=<small-checkpoint-same-family> # ~1B, for speculative decoding
vllm serve "$MODEL" \
--quantization fp8 \
--kv-cache-dtype fp8 \
--gpu-memory-utilization 0.92 \
--enable-chunked-prefill \
--max-num-seqs 256 \
--tensor-parallel-size 4 \
--speculative-config "{\"model\": \"$DRAFT\", \"num_speculative_tokens\": 5}"
Il panorama dei modelli a pesi aperti è cambiato due volte tra il 2025 e il 2026. Una classifica per il self-hosting aggiornata il 20 luglio 2026 colloca ai primi posti DeepSeek-V4-Pro (1,6T parametri, MIT), Kimi K2.6 (1T, MIT modificata) e GLM-5.2 (753B, MIT), seguiti da DeepSeek-V4-Flash (284B, MIT) e Hunyuan Hy3 (295B, Apache 2.0), con Llama 3.3 70B diversi livelli più in basso. La maggior parte dei modelli ai vertici è costituita da modelli mixture-of-experts sparsi, il cui fabbisogno di memoria ha poco a che vedere con il numero di parametri dichiarato: dimensionate quindi l’infrastruttura in base allo specifico checkpoint, non a una regola empirica.
Dimensionamento dell’hardware
La scelta e il numero delle GPU dipendono direttamente dalle dimensioni del modello, dalla quantizzazione e dal livello di concorrenza desiderato.
| GPU | VRAM | Tariffa cloud tipica (on demand) | Note |
|---|---|---|---|
| H100 SXM | 80 GB | on demand circa 1,25–7 dollari/ora, mediana di circa 3,38 dollari su 40 cloud con prezzi rilevati | Resta la GPU più utilizzata; FP8 nativo |
| H200 SXM | 141 GB | da circa 2,09 dollari/ora | Stessa capacità di calcolo dell’H100, 76% di memoria in più, larghezza di banda superiore di circa il 43% — più adatta a contesti lunghi o a modelli più grandi per GPU |
| B200 | 192 GB | on demand circa 3,75–14 dollari/ora, mediana di circa 6,25 dollari su 36 cloud | FP8/FP4 della generazione Blackwell, e non è più la scheda difficile da reperire di un tempo; è la fascia Blackwell Ultra (B300, 288 GB) a comportare ora un sovrapprezzo dovuto alla scarsità, da circa 6,50 dollari/ora per GPU |
Le tariffe variano molto a seconda del fornitore e del livello di impegno contrattuale: il giorno in cui sono stati rilevati questi dati, lo stesso modello di H100 costava 1,25 dollari/ora presso il fornitore disponibile più economico e 6,98 dollari/ora su Azure. Prima di definire un budget, chiedete sempre preventivi aggiornati: la tabella qui sopra è un punto di partenza, non un preventivo.
Dimensionamento di un modello denso della classe 70B in FP8: i soli pesi occupano circa 70 GB. Una singola H100 da 80 GB non li ospita comodamente una volta aggiunta la memoria necessaria per la cache KV e le attivazioni, quindi la suddivisione del modello fra 2–4 GPU tramite parallelismo tensoriale è la norma: 4 H100 (320 GB di memoria complessiva) offrono un margine ampio per la cache KV con contesti lunghi e un’elevata concorrenza; 2 H200 (282 GB di memoria complessiva) sono un’alternativa più snella, grazie alla maggiore memoria per scheda.
Per un modello della classe 8B, FP8 entra in una singola H100/H200 lasciando spazio per batch grandi. Dimensionate sempre esplicitamente la cache KV: la dimensione della cache per token varia secondo 2 × num_layers × num_kv_heads × head_dim × dtype_bytes, moltiplicato per il numero desiderato di sequenze simultanee e per la lunghezza massima del contesto. Spesso è questa, non i pesi, la vera limitazione di capacità.
Budget di latenza
Due metriche dominano gli SLO di latenza percepita dagli utenti:
- TTFT (time to first token) — dipende dal tempo di prefill e dall’attesa in coda. Un obiettivo comune in produzione per le chat interattive è un TTFT al p99 inferiore a 1 secondo.
- TPOT (time per output token), detto anche latenza tra token — dipende dal throughput della fase di decode per singola sequenza. Un obiettivo comune è un TPOT al p99 inferiore a 100ms (una velocità di streaming percepita di circa 10 token/sec, anche se con 20–40+ token/sec la lettura risulta fluida).
Queste metriche comportano compromessi rispetto alla dimensione dei batch e alla concorrenza: batch più grandi aumentano il throughput complessivo, ma possono far salire il TPOT di ogni richiesta se la GPU è satura. Inoltre, un prefill lungo dovuto a una richiesta di grandi dimensioni può far schizzare il TTFT di tutte le altre richieste in coda dietro di essa (è il motivo per cui conviene abilitare il chunked prefill). Prima di fissare gli SLO, eseguite test di carico con la distribuzione di richieste concorrenti che vi aspettate, non con un benchmark artificiale su una singola richiesta. Sia vLLM sia SGLang espongono istogrammi TTFT/TPOT per richiesta, così potete osservare l’effettiva distribuzione p50/p95/p99 sotto un carico realistico, anziché dedurla dai soli dati di throughput.
Scalabilità e affidabilità
Non basate l’autoscaling dei pod di inferenza degli LLM sulla CPU o sul semplice utilizzo della GPU. La CPU conta pochissimo per un carico di lavoro vincolato dalla GPU, mentre l’utilizzo della GPU è un indicatore tardivo e fuorviante per motori come vLLM: PagedAttention mantiene elevato l’utilizzo della GPU per sua natura, quindi un pod all’85% di utilizzo potrebbe gestire 5 richieste oppure 500, senza alcuna differenza visibile nella metrica. Quando l’utilizzo sembra indicare saturazione, spesso il TTFT al p99 ha già superato il suo SLO: durante un picco di traffico si è accumulata una coda che la metrica di utilizzo ha smussato.
Il principale indicatore corretto è la lunghezza della coda: vLLM la espone come vllm:num_requests_waiting. Aumentate il numero di repliche quando supera una soglia per replica e riducetelo quando è vicina a zero. Affiancatele le metriche a livello di GPU fornite da DCGM Exporter (dcgm_fi_dev_gpu_util, utilizzo della memoria/larghezza di banda) come indicatore secondario: un utilizzo sostenuto della capacità di calcolo del 60–80% è un margine operativo sano, non una soglia che faccia scattare l’autoscaling.
KEDA (Kubernetes Event-Driven Autoscaling) è il meccanismo standard per farlo: l’Horizontal Pod Autoscaler predefinito reagisce troppo lentamente al traffico di inferenza soggetto a picchi, mentre KEDA supporta la riduzione a zero repliche per i carichi di lavoro sensibili ai costi o caratterizzati da picchi. Ecco un ScaledObject KEDA minimale basato sulla metrica Prometheus di vLLM:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: vllm-inference-scaler
spec:
scaleTargetRef:
name: vllm-deployment
minReplicaCount: 1
maxReplicaCount: 10
cooldownPeriod: 120
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc:9090
metricName: vllm_num_requests_waiting
query: sum(vllm:num_requests_waiting)
threshold: "10"
Per garantire l’affidabilità oltre all’autoscaling, eseguite controlli di integrità che mettano davvero alla prova l’inferenza (una generazione reale poco costosa, non una semplice verifica della porta), mantenete almeno una replica già pronta per ogni modello per evitare picchi di latenza dovuti agli avvii a freddo e separate i pool di GPU per modello/quantizzazione, così che un rilascio difettoso di un modello non sottragga capacità a un altro.
Osservabilità
vLLM e la maggior parte dei motori di serving espongono direttamente un endpoint /metrics compatibile con Prometheus. Le metriche importanti per una dashboard SRE sono:
vllm:time_to_first_token_seconds(istogramma) — TTFT, da monitorare ai percentili p50/p95/p99vllm:inter_token_latency_seconds(istogramma) — TPOT / latenza tra token; ha sostituitovllm:time_per_output_token_seconds, deprecata in vLLM 0.11vllm:num_requests_waitingevllm:num_requests_running(indicatori istantanei) — lunghezza della coda e carico attivo, indicatori per l’autoscaling e la pianificazione della capacitàdcgm_fi_dev_gpu_util, memoria GPU utilizzata/totale (da DCGM Exporter) — saturazione dell’hardware, indicatore secondario rispetto alla lunghezza della coda- Conteggi dei token delle richieste e delle risposte e tassi di errore — attribuzione dei costi e affidabilità
Integrate queste metriche in Grafana (vLLM fornisce una dashboard di riferimento) anziché costruire dashboard personalizzate da zero, e impostate gli avvisi sul superamento delle soglie SLO per TTFT/TPOT al p99, non sul solo utilizzo della GPU: quando scattano gli avvisi sull’utilizzo, spesso gli utenti hanno già risentito della latenza.
Controllo dei costi: gestione in proprio o API
La scelta tra gestire un modello in proprio e usare un’API ospitata dipende soprattutto dal volume di traffico e dal grado di utilizzo delle risorse. Il confronto cambia man mano che diminuiscono i prezzi delle API e migliora l’efficienza delle GPU.
Prezzi di listino delle API ospitate per milione di token (input/output), rilevati dalle pagine dei prezzi dei rispettivi fornitori il 19 settembre 2026:
| Modello | Input | Output |
|---|---|---|
| Claude Fable 5.1 | 10,00 $ | 50,00 $ |
| Claude Opus 5 | 5,00 $ | 25,00 $ |
| Claude Sonnet 5 | 2,00 $ | 10,00 $ |
| Claude Haiku 4.5 | 1,00 $ | 5,00 $ |
| gpt-6-astra | 10,00 $ | 50,00 $ |
| gpt-5.6-terra | 2,00 $ | 12,00 $ |
| gpt-5.6-luna | 0,20 $ | 1,20 $ |
| Gemini 3.1 Pro (preview) | 2,00 $ fino a un prompt di 200K token | 12,00 $ |
| Gemini 3.8 Flash | 0,75 $ fino al 2026-12-31, poi 1,50 $ | 3,75 $, poi 7,50 $ |
| DeepSeek V4-Pro (cache miss) | 0,66–1,32 $ | 1,98–3,96 $ |
(Alcuni di questi prezzi sono soggetti a condizioni che la tabella non può riportare: la tariffa di Gemini 3.8 Flash è promozionale fino alla fine del 2026, Gemini applica prezzi più alti oltre i 200K token per prompt e DeepSeek dimezza le tariffe nelle ore non di punta, quindi il valore inferiore del suo intervallo è il prezzo applicato in quelle ore. Su tutte queste piattaforme, l’input memorizzato nella cache costa meno delle cifre riportate sopra. Prima di decidere un acquisto, verificate i prezzi direttamente con il fornitore.)
La gestione in proprio di un modello di classe 70B su un piccolo cluster di GPU (2–4 GPU di classe H100/H200) comporta in genere un costo infrastrutturale complessivo di 3.000–5.000 dollari al mese. Che sia più conveniente di un’API dipende interamente dal volume continuativo e dal grado di utilizzo: le stime pubblicate della soglia di convenienza per un modello 70B gestito in proprio variano molto a seconda della fonte, ma in genere si collocano tra diversi miliardi e oltre dieci miliardi di token al mese, con un grado di utilizzo delle GPU elevato (70% o più) e mantenuto costantemente.
Al di sotto di quel volume, o con un traffico discontinuo o un basso grado di utilizzo, le API ospitate sono quasi sempre più economiche se si considerano il costo fisso della capacità GPU inattiva, il tempo degli ingegneri reperibili e il costo opportunità di non usare le funzionalità più recenti di un modello di frontiera. Il calcolo favorisce chiaramente la gestione in proprio solo con volumi continuativi elevati (da decine a centinaia di milioni di token al giorno), oppure quando i requisiti di residenza dei dati, latenza legata alla vicinanza ai dati o fine-tuning rendono impraticabile un’API ospitata indipendentemente dal costo.
Le principali leve pratiche per controllare i costi di un’implementazione gestita in proprio, grosso modo in ordine di impatto:
- Quantizzazione (FP8 o AWQ) — riduce sia la memoria necessaria sia il costo per token prima di qualsiasi altro intervento.
- Dimensionare correttamente la concorrenza e i limiti dei batch — una GPU sottoutilizzata è puro spreco; regolate
max-num-seqsegpu-memory-utilizationin base all’andamento reale del vostro traffico, non ai valori predefiniti di un benchmark. - Scalare automaticamente in base alla lunghezza della coda, fino a zero negli ambienti a basso traffico — se il traffico lo consente, non pagate repliche inattive di notte o nei fine settimana.
- Decodifica speculativa per carichi di lavoro sensibili alla latenza e con output strutturato — aumenta il throughput per GPU senza aggiungere hardware.
- Instradare le richieste in base alla difficoltà del compito — usate un modello più piccolo ed economico, o una fascia tariffaria API meno costosa, per classificazioni ed estrazioni semplici, riservando il grande modello gestito in proprio o il modello di frontiera accessibile via API ai compiti che ne hanno davvero bisogno.
Rivalutate periodicamente la scelta tra gestione in proprio e API, anziché farlo una sola volta: sia i prezzi delle API ospitate sia la qualità dei modelli a pesi aperti cambiano abbastanza rapidamente da rendere opportuno ricontrollare una decisione presa un anno prima alla luce dei prezzi attuali.