Perché servire è un problema diverso dall'eseguire
Eseguire un modello per una persona è facile: carica i pesi, genera token. Servire significa tante richieste che arrivano su una GPU tutte insieme, e a quel punto tutto ruota attorno al batching — calcolare i token di più utenti nello stesso forward pass così che la costosa GPU non resti mai ferma. Un runtime single-stream che dà 40 tok/s a un utente potrebbe servirne venti a 5 tok/s ciascuno (il 25% della capacità sprecato in overhead); un server con batching serve quegli stessi venti a 30+ tok/s a testa. Quel divario — spesso 10–24× di throughput totale — è l'unica vera ragion d'essere di questi motori.
A far funzionare i motori moderni sono due innovazioni. Il continuous batching sostituisce le richieste concluse con quelle nuove a ogni passo, invece di aspettare che l'intero batch finisca. La PagedAttention (la svolta di vLLM) gestisce la KV-cache come la memoria virtuale di un sistema operativo — in pagine non contigue — ed elimina la frammentazione della memoria che prima limitava quante richieste ci stessero. Se questi termini sono nuovi, la nostra guida alla KV-cache spiega la memoria che qui viene gestita.
I quattro motori in sintesi
| Motore | Migliore per | Pesi | Hardware |
|---|---|---|---|
| vLLM | Serving GPU multi-utente, il default | FP16, AWQ, GPTQ, FP8 | NVIDIA (AMD/altri in crescita) |
| llama.cpp | Single-user, CPU, edge, Apple Silicon | GGUF | Tutto (CPU, NVIDIA, AMD, Metal) |
| SGLang | Prefissi condivisi, output strutturato, throughput di picco | FP16, AWQ, GPTQ, FP8 | NVIDIA (AMD in crescita) |
| TGI | Ecosistema Hugging Face, gestione integrata | FP16, AWQ, GPTQ, EETQ | NVIDIA, AMD, Gaudi, Inferentia |
vLLM — il default di produzione
vLLM è il punto da cui la maggior parte dei team dovrebbe partire, e per molti anche quello a cui fermarsi. Ha introdotto la PagedAttention, ha il continuous batching, un server compatibile OpenAI pronto all'uso, parallelismo tensor e pipeline per il multi-GPU, e il supporto ai nuovi modelli fin dal primo giorno più ampio di qualsiasi motore — le nuove architetture di solito arrivano prima qui. Serve bene i pesi quantizzati AWQ/GPTQ, quindi raramente paghi tutta la memoria dell'FP16. Il nostro tutorial vLLM-in-Docker mette in piedi un server per team su una GPU da 24GB in circa quaranta minuti.
Punti deboli: centrato su NVIDIA (anche se il supporto AMD sta maturando), più pesante da configurare di un runner desktop, e niente GGUF — ti impegni nel mondo AWQ/GPTQ/FP16.
llama.cpp — il runtime universale
llama.cpp è il motore dentro Ollama e LM Studio, e quello che gira ovunque: pura CPU, NVIDIA, AMD, Apple Metal, persino telefoni e Raspberry Pi. Il suo formato GGUF offre la scala di quantizzazione più ricca (da 2-bit a 8-bit) e un offload ibrido CPU/GPU insolitamente ben fatto, così esegue modelli troppo grandi per la tua VRAM quando le altre alternative si arrendono. Per un singolo utente o una manciata di richieste è eccellente. Quello che non riesce a fare è tenere il passo del batching di vLLM/SGLang sotto concorrenza reale — un server ce l'ha, ma il throughput multi-utente pesante non è il suo mestiere.
SGLang — throughput di picco per il carico giusto
SGLang è lo sfidante più recente costruito per la massima efficienza, e su molti benchmark eguaglia o batte vLLM. Il suo tratto distintivo è la RadixAttention: riusa automaticamente la KV-cache tra le richieste che condividono un prefisso. Se il tuo carico ha un grande system prompt fisso, un contesto RAG condiviso, esempi few-shot riutilizzati tra una chiamata e l'altra o agenti multi-turno, SGLang può prendere un vantaggio netto calcolando quel prefisso condiviso una volta sola. Ha anche un output strutturato/JSON veloce e di prim'ordine. In cambio rinunci a maturità e ampiezza dell'ecosistema — vLLM supporta ancora più modelli il giorno del rilascio e ha più risposte dalla community quando qualcosa si rompe.
TGI — l'opzione nativa Hugging Face
Text Generation Inference è il server di produzione di Hugging Face, che alimenta i loro Inference Endpoints. Se il tuo team vive già nell'ecosistema HF — modelli, tokenizer, l'hub — TGI calza a pennello, con il supporto agli acceleratori più ampio di questo gruppo (NVIDIA, AMD, Intel Gaudi, AWS Inferentia). Ha il continuous batching e un throughput solido; è una scelta sicura e ben supportata. Fuori da quell'ecosistema, vLLM di solito offre più copertura di modelli e una community indipendente più grande, ed è per questo che è diventato il default più comune.
Come scegliere — un percorso decisionale
- Un utente, o CPU / Mac / edge / un modello più grande della tua VRAM → llama.cpp (via Ollama o LM Studio).
- Un team o un'app che serve molti utenti su GPU NVIDIA → vLLM — inizia da qui.
- Prefissi condivisi pesanti (grande system prompt, RAG condiviso, agenti) o JSON rigoroso su scala → SGLang.
- Già tutto dentro Hugging Face, o serve Gaudi/Inferentia → TGI.
Un avvertimento onesto: per la maggior parte dei piccoli deployment il motore non è il tuo collo di bottiglia — lo è la GPU. Prima azzecca l'hardware e il dimensionamento della VRAM, prototipa su Ollama, e passa a vLLM quando arriva la concorrenza reale. Cambiare motore dopo è una modifica di deployment, non una riscrittura.