Ollama vs vLLM: quale server scegliere per LLM
Scopri le differenze tra Ollama e vLLM. Scegli Ollama per uso locale singolo su CPU o GPU, oppure vLLM per massimizzare il throughput su server multi-utente con accelerazione.
Ollama contro vLLM, in sintesi
Ollama è un gestore di modelli con server integrato: scarica i pesi quantizzati, li carica in memoria e risponde sulla porta 127.0.0.1:11434, utilizzando la CPU se il sistema non dispone di altro. vLLM è un motore ottimizzato per il throughput: mantiene una GPU satura gestendo molteplici richieste simultanee ed è lo strumento inadatto su macchine prive di accelerazione hardware. Questa è l'unica discriminante. Un singolo utente che interagisce con un assistente locale è il caso d'uso ideale per Ollama. Un'applicazione che serve un intero team richiede vLLM.
Entrambi espongono un'API HTTP compatibile con OpenAI, pertanto il codice client può passare dall'uno all'altro semplicemente modificando la base URL. La differenza non risiede nell'API, ma in ciò che accade quando arriva una seconda richiesta mentre la prima sta ancora generando token.
Cos'è realmente Ollama
Ollama è un livello di astrazione orientato alla semplicità. Fornisce un registro dei modelli (ollama pull llama3.1:8b), un archivio locale dei pesi, un prompt per la chat, un servizio systemd e un'API HTTP, tutto tramite un unico comando di installazione. I modelli distribuiti sono file GGUF, solitamente quantizzati a 4-bit; questo è il motivo per cui un modello da 7B o 8B occupa circa 5 GB su disco invece di 16 GB. La quantizzazione è ciò che rende possibile l'inferenza su CPU.
Il suo motore di esecuzione è basato su llama.cpp, la libreria di inferenza in C++ che ha reso pratica la quantizzazione GGUF su hardware comune. Ollama ha successivamente aggiunto un proprio motore per alcune famiglie di modelli più recenti, ma llama.cpp rimane la base per la maggior parte di ciò che viene distribuito. Pertanto, quando si confronta Ollama con llama.cpp, si sta essenzialmente confrontando un livello di ergonomia con lo strumento che esso racchiude.
L'obiettivo di progettazione è l'utente singolo. A luglio 2026, il valore predefinito per OLLAMA_NUM_PARALLEL è 1, il che significa che un modello elabora una richiesta alla volta e tutto il resto rimane in attesa in una coda che contiene 512 elementi per impostazione predefinita (OLLAMA_MAX_QUEUE). È possibile aumentare il parametro di parallelismo, e la sezione seguente spiega quali sono i costi in termini di risorse. Se non hai mai utilizzato Ollama, inizia da ospitare Ollama su un VPS mantenendo chiusa la porta 11434, poiché l'API non dispone di alcun tipo di autenticazione.
Cos'è effettivamente vLLM
vLLM è esclusivamente un server di inferenza. Non gestisce una libreria di modelli, non dispone di un'interfaccia di chat e non scarica modelli su richiesta. Al momento dell'avvio si specifica un repository Hugging Face: il software carica quel modello e lo mantiene attivo finché il processo non viene terminato.
Il vantaggio di questa specializzazione è il throughput. Due meccanismi svolgono il lavoro principale. PagedAttention archivia la KV cache (key-value cache, ovvero lo stato di attenzione per ogni token che il modello mantiene per ogni richiesta attiva) in blocchi di dimensione fissa, in modo analogo alla paginazione della memoria nei sistemi operativi. Una richiesta non necessita più di una grande riserva contigua dimensionata per lo scenario peggiore; la memoria precedentemente riservata e inutilizzata diventa quindi disponibile per gestire più richieste simultanee. Il continuous batching permette a una nuova richiesta di unirsi al batch in esecuzione al passo di decodifica successivo, invece di attendere il completamento dell'intero batch corrente. Una sequenza terminata abbandona immediatamente il batch e il suo slot viene reso disponibile.
Il risultato pratico: su una singola GPU, passare da un utente simultaneo a trenta aumenta drasticamente il numero totale di token al secondo, mentre la velocità per singolo utente diminuisce molto meno di quanto ci si aspetterebbe. Con le impostazioni predefinite di Ollama, passare da un utente a trenta significa semplicemente far attendere ventinove persone.
Il continuous batching fa tutta la differenza
Immagina cinque richieste che arrivano contemporaneamente su ogni server con hardware identico.
Ollama con le impostazioni predefinite esegue la prima richiesta fino al completamento, poi la seconda, e così via. Il quinto chiamante attende quattro generazioni complete. Il throughput totale è approssimativamente la velocità di una singola generazione, poiché il processore lavora sempre su una sola sequenza alla volta.
vLLM decodifica tutte e cinque le richieste nello stesso forward pass. Generare un token per cinque sequenze costa appena di più che generarlo per una sola, perché la parte onerosa è la lettura dei pesi del modello dalla memoria, e tale lettura è condivisa sull'intero batch. È lo stesso principio di larghezza di banda della memoria che rende lenta l'inferenza su CPU: il costo è dato dallo spostamento dei pesi, non dai calcoli aritmetici.
È possibile impostare OLLAMA_NUM_PARALLEL=4 per ottenere parte di questo vantaggio. Il costo è la memoria. Ogni slot parallelo necessita della propria KV cache e Ollama divide la finestra di contesto tra gli slot; pertanto, quattro richieste parallele su un modello configurato per 8192 token lasciano a ogni richiesta 2048 token di contesto. Quel valore di 8192 è una scelta e non un dato fisso, quindi aumentare num_ctx e dimensionare la RAM necessaria è il passaggio che determina se quattro slot siano effettivamente utilizzabili. La paged cache di vLLM è ciò che evita questo compromesso, poiché i blocchi vengono allocati a una richiesta man mano che questa cresce effettivamente. In ogni caso, il limite massimo di utenti che una singola macchina può servire contemporaneamente dipende dalla dimensione della KV cache, dal costo di prefill e dalla profondità della coda, che è il motivo per cui un server che sembrava adeguato per una persona rallenta drasticamente con cinque.
Installazione e distribuzione con Ollama
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.1:8b
ollama run --verbose llama3.1:8b "Write two sentences about Linux."Lo script di installazione crea un utente di sistema ollama, installa il binario e registra ollama.service associato a 127.0.0.1:11434. La riga eval rate stampata da --verbose indica i token al secondo reali su quella macchina. È un dato più affidabile di qualsiasi cifra pubblicata. Una singola lettura da un prompt è solo un punto di partenza e non un valore di capacità; pertanto, misurare i token al secondo durante un test di concorrenza è l'unico modo per capire se la macchina regge il carico previsto e se il noleggio di una GPU sia più conveniente rispetto al pagamento per singolo token.
Per aumentare la concorrenza, utilizza un file di drop-in di systemd in modo che un aggiornamento non sovrascriva la modifica:
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_KEEP_ALIVE=30m"sudo systemctl restart ollama
ollama psollama ps mostra cosa è caricato e la sua colonna PROCESSOR riporta il dato reale. 100% CPU indica che non viene utilizzata alcuna GPU; questa è la spiegazione tecnica per la maggior parte delle segnalazioni riguardanti la lentezza di Ollama. La riga OLLAMA_KEEP_ALIVE=30m nel file di drop-in è altrettanto importante su una macchina poco utilizzata, poiché l'impostazione predefinita scarica il modello dopo cinque minuti di inattività. Mantenere il modello residente tra le richieste evita di dover attendere nuovamente l'intero tempo di caricamento per il primo prompt dopo un'ora di inattività.
Installazione ed esecuzione con vLLM
vLLM richiede Linux e Python da 3.10 a 3.13. Installalo all'interno di un ambiente virtuale dedicato, poiché richiede una build specifica di PyTorch:
uv venv --python 3.12 --seed
source .venv/bin/activate
uv pip install vllm --torch-backend=autoSuccessivamente, avvia un modello. Il nome deve corrispondere all'ID del repository su Hugging Face, non a un tag breve:
vllm serve Qwen/Qwen2.5-1.5B-InstructL'avvio è lento al primo utilizzo, poiché il sistema scarica i pesi e analizza la GPU per determinare quanti blocchi di cache KV possono essere allocati. Il servizio rimane in ascolto sulla porta 8000. Verifica il funzionamento prima di scrivere il codice client:
curl http://localhost:8000/v1/models
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [{"role": "user", "content": "Who won the world series in 2020?"}]}'Se Docker è già presente sul sistema, l'immagine ufficiale evita la gestione manuale delle dipendenze CUDA:
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
--env "HF_TOKEN=$HF_TOKEN" \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6B--ipc=host è obbligatorio, non opzionale: PyTorch scambia tensori tra processi tramite memoria condivisa e l'allocazione predefinita di Docker è insufficiente per l'inferenza con parallelismo dei tensori.
I flag più rilevanti in produzione sono --max-model-len (la finestra di contesto che si intende gestire), --gpu-memory-utilization (la frazione della scheda che vLLM può occupare, impostata al 0.92 di default a luglio 2026), --tensor-parallel-size per suddividere un singolo modello su più GPU e --api-key.
L'autenticazione è un flag su vLLM ed è assente su Ollama
vLLM impone un bearer token se ne viene fornito uno:
vllm serve Qwen/Qwen2.5-1.5B-Instruct --api-key token-abc123Lo stesso valore può essere impostato tramite la variabile d'ambiente VLLM_API_KEY. Una richiesta priva di tale token riceve un errore HTTP 401. Questo non costituisce comunque un motivo valido per pubblicare la porta 8000 su un'interfaccia pubblica, dato che vLLM non dispone di rate limiting e un token HTTP in chiaro è leggibile durante il transito, ma significa che il server è in grado di distinguere il chiamante.
Ollama non dispone di alcuna funzione simile. Non esistono chiavi, login o allow-list. Qualsiasi processo in grado di raggiungere la porta 11434 può eseguire, scaricare o eliminare modelli. Mantenere il servizio su loopback e accedervi tramite una VPN WireGuard gestita autonomamente, oppure tramite un reverse proxy con autenticazione che termini la connessione TLS (transport layer security).
Hardware: requisiti per ciascuna soluzione
Ollama viene eseguito su CPU. Un modello quantizzato a 4-bit richiede circa mezzo gigabyte di RAM per ogni miliardo di parametri, più circa un gigabyte di overhead di runtime e ulteriore memoria per il contesto; pertanto, un modello da 3B necessita di circa 4 GB liberi e uno da 8B di circa 8 GB. La velocità su una vCPU condivisa si attesta su un numero di token al secondo compreso tra una cifra singola e una doppia bassa. Si tratta di un limite della larghezza di banda della memoria, non di una configurazione errata, e nessun flag può risolvere il problema. Per osservare questo calcolo applicato a una specifica release invece di una regola empirica, eseguire Nemotron 3.5 Lightning su una VPS permette di definire il tag esatto da scaricare, la RAM occupata una volta caricato il modello e se la sola CPU sia sufficientemente rapida per l'uso previsto.
vLLM presuppone l'uso di una GPU. Il suo percorso predefinito gestisce pesi non quantizzati a 16-bit, che corrispondono a circa 2 GB per ogni miliardo di parametri: un modello da 8B richiede circa 16 GB di memoria video solo per i pesi, prima ancora di considerare la KV cache che fornisce la concorrenza per cui vLLM è stato installato. Su una scheda da 24 GB rimane una cache utilizzabile. Su una scheda da 16 GB non è così, quindi è necessario scegliere un modello più piccolo o passare --quantization con un checkpoint quantizzato. Esiste un backend per CPU, ma i pacchetti standard non sono compilati per questo scopo e il suo utilizzo annulla il motivo principale per cui si sceglie vLLM.
La questione hardware risponde quindi alla maggior parte dei dubbi sul software. L'assenza di una GPU implica l'uso di Ollama. Una GPU a noleggio con un utilizzo al 5 percento, dovuto alla serializzazione delle richieste, indica la necessità di vLLM.
Quale scegliere per il proprio carico di lavoro
- Un singolo utente, un VPS con una CPU, per stesura e riassunti: Ollama. La velocità è accettabile e non esiste nulla di più semplice.
- Un assistente alla programmazione, o un server MCP che collega i tuoi strumenti a un modello locale, utilizzato solo da te: Ollama. Una concorrenza pari a uno è il carico di lavoro reale.
- Confronto tra cinque modelli questa settimana: Ollama. Scaricare ed eliminare modelli tramite tag è esattamente ciò che sa fare meglio, mentre vLLM richiede il riavvio del processo per ogni modello.
- Un'applicazione interna, un prodotto di chat o una pipeline di recupero dati con utenti reali: vLLM. È qui che il batching giustifica il costo di una GPU.
- Un job batch per elaborare centomila documenti durante la notte: vLLM, con un
--max-num-seqselevato. Il throughput è l'unica metrica che conta e la latenza per singolo documento è irrilevante. - Una piattaforma di agenti in cui diversi agenti IA self-hosted interrogano il modello contemporaneamente: vLLM, poiché il traffico degli agenti è per natura a picchi e parallelo.
Modalità di errore e messaggi associati
vLLM rifiuta di avviarsi con un errore relativo alla KV cache. Il messaggio indica entrambi i valori numerici:
ValueError: The model's max seq len (32768) is larger than the maximum number of tokens that can be stored in KV cache (8192). Try increasing gpu_memory_utilization or decreasing max_model_len when initializing the engine.Il modello dichiara una finestra di contesto superiore alla memoria disponibile dopo il caricamento dei pesi. Riducila con --max-model-len 8192, oppure aumenta --gpu-memory-utilization se nessun altro processo sta utilizzando la scheda. Spingere l'utilizzo oltre circa 0.95 tende a trasformare questo errore di avvio in un crash per CUDA out-of-memory durante il carico, il che rappresenta lo scenario peggiore.
Ollama stampa Killed durante la generazione. Il killer out-of-memory di Linux ha terminato il processo perché il modello richiedeva più RAM di quella disponibile sul sistema. Verifica con sudo dmesg | grep -i oom. La soluzione consiste nell'utilizzare un modello più piccolo o con una quantizzazione più spinta, non in una modifica delle impostazioni.
Ollama risponde correttamente da solo ma si blocca sotto carico. Non appare alcun errore. Le richieste richiedono semplicemente più tempo all'aumentare degli utenti, poiché OLLAMA_NUM_PARALLEL=1 le serializza. Le risposte lunghe peggiorano la coda, dato che un singolo utente che occupa l'unico slot disponibile fino al termine della generazione blocca tutti gli altri; pertanto limitare la risposta con num_predict imposta un tetto massimo alla durata di ogni singolo turno sul server. Aumenta il parametro di parallelismo accettando un contesto minore per singola richiesta, oppure sposta il carico di lavoro su vLLM.
vLLM restituisce 401 a ogni chiamata. Hai avviato il servizio con --api-key e il client non invia alcun header Authorization. La maggior parte delle librerie client OpenAI invia il valore fornito come chiave, quindi impostalo lì invece di rimuovere il flag.
vLLM indica che il modello non è stato trovato. Ollama scarica i modelli su richiesta, vLLM no. Il campo model nel corpo della richiesta deve corrispondere all'ID del repository utilizzato all'avvio, oppure al valore di --served-model-name se ne hai impostato uno. Verifica la stringa esatta con curl http://localhost:8000/v1/models.
Eseguirli entrambi è una soluzione ragionevole
Non sono esclusivi. Una configurazione comune prevede vLLM su un'istanza GPU che serve l'applicazione, con Ollama sulla normale VPS a fianco per script locali, cron job e per testare nuove release di modelli. Entrambi gli endpoint sono compatibili con OpenAI, quindi una singola libreria client e un cambio di base-URL sono sufficienti per gestirli. Il controllo dei costi è più importante della scelta del motore, poiché una GPU inattiva ha lo stesso costo di una sotto carico, e mantenere prevedibili i costi di agenti e inferenza è una disciplina distinta dalla scelta del server.
FAQ
vLLM è più veloce di Ollama?
Per una singola richiesta sulla stessa GPU il divario è modesto, poiché entrambi eseguono gli stessi calcoli. Per molte richieste simultanee vLLM è nettamente superiore, poiché il continuous batching decodifica ogni sequenza attiva in un unico passaggio forward, mentre l'impostazione predefinita di Ollama le esegue una dopo l'altra. Su una macchina basata solo su CPU la domanda non è pertinente: Ollama funziona, mentre vLLM di fatto no.
vLLM può funzionare senza una GPU?
Non in modo utile. I pacchetti standard sono destinati a GPU NVIDIA o AMD; la ragione d'essere di vLLM, ovvero mantenere un acceleratore saturo con richieste in batch, viene meno su una CPU. Esiste un backend CPU per attività di sviluppo. Per l'inferenza reale su CPU, utilizzare direttamente Ollama o llama.cpp.
Qual è la differenza tra Ollama e llama.cpp?
llama.cpp è la libreria di inferenza e GGUF è il suo formato di pesi quantizzati. Il runner di Ollama è basato su di essa e aggiunge le componenti che llama.cpp lascia all'utente: un registro dei modelli, il download automatico, un server residente, una unit systemd e un endpoint compatibile con OpenAI. Ollama ha aggiunto il proprio motore per alcune famiglie di modelli più recenti, quindi i due non sono più identici a livello di architettura interna.
Quanta memoria GPU richiede vLLM per un modello da 8B?
A una precisione di 16-bit i soli pesi occupano circa 16 GB, approssimativamente 2 GB per miliardo di parametri, e la KV cache richiede spazio aggiuntivo. Una scheda da 24 GB è adeguata. Una scheda da 16 GB richiede un checkpoint quantizzato o un modello più piccolo. vLLM occupa una frazione della scheda definita da --gpu-memory-utilization, che a luglio 2026 è impostata di default a 0.92.
Devo modificare il codice della mia applicazione per passare dall'uno all'altro?
Di solito solo l'URL di base, la API key e il nome del modello. Ollama espone la sua interfaccia compatibile con OpenAI su http://127.0.0.1:11434/v1 e ignora la chiave, mentre vLLM espone http://localhost:8000/v1 e richiede la chiave se ne è stata impostata una. I nomi dei modelli differiscono nella forma: llama3.1:8b per Ollama, un ID di repository completo come Qwen/Qwen2.5-1.5B-Instruct per vLLM.