vLLM Setup Guide: Production-Speed Local LLM Serving

Written by Jakub Rusinowski · Last updated July 10, 2026

vLLM serves local LLMs at production throughput — typically 5–20x more requests per second than Ollama under concurrent load — using PagedAttention and continuous batching. This guide installs it, exp

In This Guide

vLLM serves local LLMs at production throughput — typically 5–20x more requests per second than Ollama under concurrent load — using PagedAttention and continuous batching. This guide installs it, explains those two ideas in plain terms, picks the right quantization (AWQ/GPTQ/FP8), and stands up an OpenAI-compatible endpoint you can put real traffic on.

Last Updated: July 2026

Ollama vs vLLM: Which Problem Do You Actually Have?

Be clear-eyed before installing anything — for a single user, vLLM is *not* faster:

Ollama / llama.cppvLLM
One user chattingExcellentComparable, no win
10–100 concurrent requestsQueues up, throughput collapsesThis is what it's built for
Model formatGGUF (quantized, CPU offload)HF safetensors, AWQ/GPTQ/FP8
HardwareAnything, incl. MacsNVIDIA (CUDA) first-class; AMD ROCm supported
Ops modelDesktop app simplicityA real server you administer

If you're serving yourself, stay with Ollama's local API. If you're serving a team, an app, or batch pipelines — anything where requests *overlap* — vLLM is the standard answer, and the gap is dramatic: on one RTX 4090 serving an 8B model, Ollama sustains roughly 100–150 total tok/s across concurrent users, while vLLM sustains 1,000–2,500+ tok/s of aggregate throughput at 30–100 parallel requests.

The Two Ideas That Make vLLM Fast

PagedAttention. Every conversation needs a KV cache (the model's working memory), which naive servers allocate as one contiguous block sized for the *maximum possible* context — wasting 60–80% of VRAM on padding. vLLM manages the KV cache the way an operating system manages RAM: in small pages, allocated on demand. Same GPU, several times more concurrent conversations held in memory.

Continuous batching. Naive batching waits for every request in a batch to finish before starting the next batch — one long answer stalls everyone. vLLM schedules at the *token* level: the moment any sequence finishes, a waiting request takes its slot in the very next forward pass. The GPU never idles while there's work queued.

Neither trick helps a single request; both multiply aggregate throughput. That's why the "is vLLM faster?" answer is "at what concurrency?"

Step 1 — Install

Requirements: Linux (or WSL2), Python 3.10–3.12, an NVIDIA GPU with a recent driver (Compute Capability 7.0+; 16GB+ VRAM recommended for 7–8B models at full quality).

python -m venv .venv && source .venv/bin/activate
pip install vllm

That single package includes the inference engine and the OpenAI-compatible server. Docs: docs.vllm.ai.

Step 2 — Serve a Model

vLLM pulls straight from Hugging Face. For a 24GB card, an AWQ-quantized 7–8B model is the right first test:

vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
  --max-model-len 8192 \
  --gpu-memory-utilization 0.90 \
  --api-key localtoken

The flags you'll actually touch:

Step 3 — Point OpenAI Clients at It

The endpoint is drop-in OpenAI-compatible — existing SDK code needs only a base URL:

from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="localtoken")

resp = client.chat.completions.create(
    model="Qwen/Qwen2.5-7B-Instruct-AWQ",
    messages=[{"role": "user", "content": "Summarize PagedAttention in one sentence."}],
)
print(resp.choices[0].message.content)

Structured output (response_format with a JSON schema) and tool calling work here too — the patterns from our structured output guide carry over unchanged.

Which Quantization: AWQ vs GPTQ vs FP8

vLLM doesn't use GGUF well — its quantization world is different:

FormatQualitySpeed in vLLMUse when
None (BF16)ReferenceFast, most VRAMVRAM is plentiful
FP8~99% of BF16Fastest on Ada/Hopper (RTX 40xx+)Modern GPU, best default
AWQ (4-bit)~97–98%FastFitting 2x the model in VRAM
GPTQ (4-bit)~96–98%FastWidest choice of pre-quantized repos

Practical rule: search Hugging Face for your model plus "AWQ" or "FP8" and serve a pre-quantized repo; only quantize yourself when nobody has. A 7B at AWQ needs ~6GB for weights, leaving the rest of a 24GB card for KV-cache pages — i.e., for concurrency.

Production Checklist

Frequently Asked Questions

Is vLLM faster than Ollama?

For one user: no — single-stream latency is similar, and Ollama is far simpler. For concurrent load: dramatically, 5–20x aggregate throughput, because continuous batching keeps the GPU saturated while Ollama processes a shallow queue.

Can vLLM run GGUF models?

GGUF support exists but is experimental and slow — it bypasses vLLM's optimized paths. Serve the original HF weights, or an AWQ/GPTQ/FP8 quantization of them. Keep GGUF for the llama.cpp/Ollama world.

Does vLLM run on a Mac?

Not meaningfully — vLLM targets CUDA (and ROCm) datacenter-style serving. On Apple Silicon, llama.cpp-based servers are the right tool; a Mac serving a household doesn't need continuous batching anyway.

How much VRAM do I need to serve N users?

Weights once, plus KV cache per active sequence. An 8B AWQ model (~6GB) on a 24GB card leaves ~15GB of page pool — roughly 40–80 active 2K-context sequences. Longer contexts shrink that fast, which is why capping --max-model-len is the first tuning lever.

Related Guides

← All Guides | Check GPU Compatibility