vLLM batte Ollama quando: guida alla scelta del runtime di inference self-hosted
Una volta che un'azienda ha deciso di portare l'inferenza di un modello linguistico sui propri server, per sovranità del dato, per disponibilità garantita o per costo, resta la domanda che separa un proof of concept da un sistema di produzione: con quale runtime lo servi? È la decisione che più spesso vedo presa male, perché quasi tutti partono da Ollama, lo installano in cinque minuti, vedono il modello rispondere sul portatile e concludono "funziona, mettiamolo in produzione". Poi arriva il secondo utente concorrente, e il terzo, e la latenza esplode. Ollama è uno strumento eccellente, ma è uno strumento da workstation, e usarlo per servire un reparto è come usare il server di sviluppo PHP integrato per reggere il traffico di un e-commerce. La scelta del motore di inferenza, vLLM, SGLang, Text Generation Inference, llama.cpp server o Ollama, non è una questione di gusti: è determinata da tre variabili misurabili, l'hardware disponibile, la concorrenza richiesta e il budget di latenza. In questo articolo le metto in fila e spiego quale runtime è la scelta giusta in ciascun caso, partendo dal motivo per cui il default da cui tutti cominciano è quasi sempre quello sbagliato per la produzione.
Perché Ollama non basta per la produzione?
Perché è progettato per uno o pochi utenti, non per servire concorrenza. Ollama è costruito sopra llama.cpp, usa la quantizzazione GGUF per far girare modelli su hardware modesto, e ha un'esperienza d'uso quasi magica: un comando, e il modello è scaricato e in esecuzione. Quella semplicità è esattamente il suo dominio, lo sviluppo, la prototipazione, l'uso personale, l'edge su una singola macchina. Ma quando arrivano richieste concorrenti, Ollama non ha il meccanismo che rende efficiente il serving su GPU: il continuous batching, cioè la capacità di processare insieme richieste che arrivano in momenti diversi, riempiendo la GPU invece di servirle una alla volta.
La conseguenza è che un setup Ollama che risponde benissimo a te da solo crolla sotto dieci utenti simultanei, non perché il modello sia lento, ma perché il runtime non è fatto per saturare l'hardware con carico parallelo. Un PoC su Ollama non dice nulla sul dimensionamento di produzione: ti dice che il modello produce l'output giusto, non quanti utenti reggerà né a quale costo. È la stessa trappola che ho descritto parlando di quando conviene davvero self-hostare un LLM: la demo che gira in locale è il punto di partenza dell'analisi, non la sua conclusione.
Ollama è il runtime giusto per sapere se un modello fa quello che ti serve. È il runtime sbagliato per scoprire quanto regge sotto carico. Confondere le due domande è il modo più rapido per promettere un sistema che poi non scala.
Cosa fa vLLM che Ollama non fa?
Gestisce la memoria della GPU e il batching in modo da spremere ordini di grandezza di throughput in più sotto concorrenza. Il cuore di vLLM è una tecnica chiamata PagedAttention, che amministra la cache delle chiavi e dei valori, la cosiddetta KV cache, come un sistema operativo amministra la memoria virtuale: a pagine, senza sprechi e senza frammentazione. Questo permette di tenere in memoria molte più richieste contemporanee, e quindi di applicare il continuous batching in modo aggressivo, raggruppando dinamicamente le richieste che arrivano in tempi diversi.
Il risultato pratico è che vLLM è il motore di riferimento per servire un modello open-weight su GPU di datacenter a molti utenti concorrenti. Espone un'API compatibile con quella di OpenAI, il che significa che il codice applicativo che già parla con un'API di frontiera può puntare al tuo server self-hosted cambiando solo l'endpoint. Supporta il tensor parallelism per distribuire un modello grande su più GPU, e i suoi maintainer dichiarano il supporto day-zero per i modelli open-weight più recenti come DeepSeek V4 e Qwen3.6, un dettaglio operativo che conta: vuol dire che quando esce un modello nuovo non devi aspettare settimane per poterlo servire in produzione. La documentazione ufficiale di vLLM è il riferimento per il dimensionamento, perché la variabile critica, quanta memoria GPU dedicare alla KV cache rispetto ai pesi del modello, va calcolata sul carico reale.
Se stai progettando l'integrazione di un modello self-hosted dentro un'applicazione di produzione e vuoi vedere come imposto questo tipo di architettura, dalla scelta del runtime al routing tra modello locale e API, nel mio hub dedicato all'AI per le aziende raccolgo gli articoli sul tema con metodologia e perimetro dichiarati.
Quando SGLang è la scelta migliore di vLLM?
Quando il tuo carico è fatto di molte richieste che condividono un lungo prefisso comune. SGLang è l'altro grande motore di serving ad alto throughput, e la sua arma distintiva è RadixAttention, un meccanismo che condivide la cache del prefisso tra richieste diverse invece di ricalcolarlo ogni volta. La differenza diventa enorme in due scenari molto comuni nelle architetture aziendali.
Il primo è il RAG con system prompt condiviso: se ogni richiesta inizia con lo stesso lungo blocco di istruzioni e di contesto, e cambia solo la domanda finale dell'utente, SGLang riconosce il prefisso comune e non lo riprocessa. Il secondo è il carico agentico, dove un agente fa molte chiamate che condividono la stessa testa, lo stesso elenco di tool e lo stesso stato. In entrambi i casi la condivisione del prefisso si traduce in un risparmio di calcolo che vLLM, pur avendo anch'esso forme di prefix caching, è nato per gestire in modo meno aggressivo. La regola pratica: se il tuo workload ha prefissi lunghi e ripetuti, metti SGLang nel confronto; se è serving generico e vario, vLLM resta il default più semplice da gestire e con la community più ampia su cui appoggiarsi quando qualcosa va storto in produzione.
Vale la pena ricordare un punto trasversale del 2026: la maturità del tool-use, output strutturato e function calling affidabili, conta più di qualunque punteggio di benchmark per le pipeline agentiche. Sia vLLM sia SGLang li supportano, ma la differenza la fa il test sul workload reale del cliente, non la classifica. Sui rischi che questi carichi agentici introducono ho scritto separatamente, perché un server di inferenza esposto è anche una superficie da mettere in sicurezza, non solo da ottimizzare.
Dove si collocano TGI e llama.cpp server?
Ai due estremi opposti dello spettro. Text Generation Inference (TGI) è il server di produzione mantenuto da Hugging Face: è la scelta a minor attrito se la tua organizzazione vive già nell'ecosistema transformers, perché si integra in modo nativo con l'hub dei modelli e con il tooling che probabilmente usi già. Tecnicamente è nello stesso campionato di vLLM, batching dinamico e serving su GPU; la ragione per sceglierlo è quasi sempre di ecosistema e di familiarità del team, non di performance pura.
All'estremo opposto, llama.cpp server è il motore che sta sotto Ollama, esposto direttamente. È la scelta giusta quando l'hardware è modesto: solo CPU, o una GPU consumer, o un dispositivo edge. La documentazione di Text Generation Inference e quella di llama.cpp coprono i rispettivi domini, ma il discrimine è semplice: TGI presuppone una GPU seria, llama.cpp è nato per farne a meno.
Il meccanismo che rende llama.cpp praticabile su hardware modesto è la quantizzazione GGUF, e vale la pena capirla perché è una leva di dimensionamento, non un dettaglio. Quantizzare significa rappresentare i pesi del modello con meno bit: una variante Q8 resta vicina alla precisione piena ma occupa molto; una Q4 dimezza l'occupazione di memoria a costo di una perdita di qualità che, su molti task, è accettabile; le quantizzazioni più aggressive sotto i quattro bit servono solo a far entrare il modello in una RAM piccola, e vanno testate sul caso d'uso prima di fidarsene. È la stessa logica con cui si sceglie la qualità di compressione di un'immagine: il livello giusto è il più aggressivo che il tuo occhio, o qui il tuo caso d'uso, non distingue dal pieno. La concorrenza che llama.cpp regge è bassa, ma per un tool interno a uso sporadico, o per un deployment su hardware che non ha una GPU di datacenter, è la soluzione pragmatica. Pretendere da llama.cpp il throughput di vLLM è insensato quanto pretendere da vLLM di girare su un mini-PC senza GPU.
Una nota di precisione che faccio sempre, perché ha implicazioni legali: i modelli che servirai hanno licenze diverse, e "open-weight" non significa "open source". Llama ha pesi aperti con una licenza community che porta restrizioni d'uso; Qwen e gli open-weight di Mistral sono Apache 2.0; DeepSeek V4 è MIT. Quando un cliente in un settore regolato deve documentare la provenienza e i termini d'uso di ciò che esegue, questa differenza non è un cavillo: è parte del deliverable.
Come si sceglie il runtime in pratica?
Si parte dalle tre variabili misurabili e si lascia che siano loro a decidere, in quest'ordine: hardware, concorrenza, forma del carico. Non si parte dal runtime "di moda".
hardware = solo CPU o GPU consumer
-> llama.cpp server (o Ollama per il PoC)
hardware = GPU di datacenter
concorrenza bassa, uso interno sporadico
-> Ollama / llama.cpp bastano ancora
concorrenza alta, applicazione o reparto
carico con prefissi lunghi e ripetuti (RAG, agenti)
-> SGLang (RadixAttention)
serving generico e vario
-> vLLM (default), o TGI se sei gia in ecosistema HFLa logica dietro questo albero è che ogni scelta più in alto rende inutili quelle più in basso: se non hai una GPU di datacenter, la discussione vLLM contro SGLang non si pone proprio. E la variabile che la maggior parte dei progetti dimentica di stimare prima è la concorrenza: quanti utenti useranno il sistema nello stesso istante, in un'ora di picco. Senza quel numero, qualunque scelta di runtime è un tiro al buio. Lo si ricava dal numero di persone che useranno il sistema e dalla frequenza con cui lo interrogano, non dalla sensazione che "sarà usato parecchio".
C'è poi una dimensione che non compare nelle tabelle comparative ma domina il costo totale: la complessità operativa. Ollama è quasi a zero configurazione; vLLM e SGLang richiedono CUDA, una pianificazione attenta della memoria GPU, la configurazione del tensor parallelism per i modelli grandi e un monitoraggio del throughput sotto carico. Il throughput non è gratis: lo paghi in competenze e in tempo di gestione. Per questo la scelta del runtime non è separabile dalla domanda "chi lo terrà in piedi", che è esattamente il punto in cui un sistema self-hosted progettato bene si distingue da uno abbandonato a sé stesso sei mesi dopo il lancio.
Cosa costa davvero il throughput?
Costa GPU, competenze e una pianificazione che la demo non richiede. La GPU di datacenter necessaria per servire un modello di buona taglia a un reparto è un investimento visibile, e il dimensionamento, quante GPU per quanti utenti concorrenti, va fatto prima dell'acquisto, non dopo aver scoperto che una non basta. Ma il costo che sorprende i decisori è quello continuativo: un server di inferenza ad alto throughput è un sistema di produzione che qualcuno deve aggiornare, mettere in sicurezza, monitorare e ottimizzare. Il vantaggio di un'API gestita è proprio che quel lavoro lo fa il vendor; portandola in casa, lo erediti tu.
Questo è il motivo per cui la scelta del runtime è inseparabile dalla decisione, più a monte, di self-hostare o no. Se il carico è basso e non sensibile, il calcolo spesso suggerisce che un'API di frontiera in regione europea resta la risposta migliore, e tutta la discussione su vLLM contro SGLang è prematura. Se invece il carico è alto e regolato, allora il runtime giusto, vLLM o SGLang su GPU di datacenter, è ciò che trasforma una buona idea architetturale in un sistema che regge davvero il reparto che lo userà. Il confine tra i due mondi non lo traccia la moda del momento, lo traccia il numero di utenti concorrenti e la sensibilità del dato.
La scelta del motore di inferenza, in fondo, è una di quelle decisioni tecniche apparentemente minori che determinano se un progetto AI self-hosted resta un esperimento simpatico o diventa infrastruttura. Partire da Ollama per capire se il modello fa il suo lavoro è corretto; fermarsi lì quando il sistema deve servire persone reali è l'errore che produce le architetture che funzionano in demo e si piantano in produzione. Se stai dimensionando un'inferenza on-premise e vuoi capire quale runtime regge il tuo carico reale, e quanta GPU serve davvero per il numero di utenti che hai, puoi usare il modulo di preventivo gratuito: sette domande, due minuti, e ragioniamo insieme sul dimensionamento prima che diventi un acquisto sbagliato.