Trace a request through vLLM's architecture¶
Baseline: vLLM 0.26.0 (V1) · components verified via Context7 (ADR-0004)
Module: Part 5 · Serving & Throughput (vLLM Core) · Tests the lesson: The vLLM Architecture Map
Q: Walk me through vLLM's V1 architecture. Name the components, trace a request end-to-end, and say which optimization lives in which box.¶
Direct answer¶
vLLM V1 is a multi-process pipeline with cleanly separated concerns:
- API server — HTTP (OpenAI-compatible), tokenize/detokenize, input processing. No scheduling, no GPU work. Scales with data parallelism.
- Engine core — the brain; a busy loop, one process per data-parallel rank, that owns two things:
- Scheduler — decides each step's batch: admit/evict (continuous batching), chunk long prefills, spend the
max_num_batched_tokensbudget (chunked prefill). - KV-cache manager — allocates/frees KV blocks from the BlockPool (PagedAttention) and holds the prefix-cache hash map (prefix caching).
- Scheduler — decides each step's batch: admit/evict (continuous batching), chunk long prefills, spend the
- GPU worker — one process per GPU (
TP×PPper engine core); loads weights, runs forward, manages GPU memory. - Model runner (
GPUModelRunner) — inside the worker; input tensors, CUDA-graph capture/replay, runs thenn.Module→ logits (enforce_eagerdisables the graphs; spec-decode verification happens here). - Sampler — logits → next token.
Trace: HTTP → API server (tokenize) → engine core [scheduler picks the step + KV-cache manager ensures blocks] → GPU worker's model runner (tensors → fwd → logits) → sampler (token) → back through the engine core → API server (detokenize) → response. The scheduler can start the next step while these tokens are still in flight (CPU/GPU overlap).
Deep dive¶
- V1 ≠ V0. V1 re-architected the scheduler, KV-cache manager, worker, sampler, and API server (kept V0's models, kernels, utils). Old single-process
LLMEngine.step()descriptions don't match the code. - Why multi-process. Separating talk/decide/compute lets the engine core schedule while the GPU computes — the CPU/GPU overlap that keeps the GPU busy.
- The map is a debugging tool. TTFT → scheduler; OOM at startup → KV-cache profiling / BlockPool sizing (
num_gpu_blocksfromgpu_memory_utilization); slow decode → model runner / CUDA graphs. Symptom → box.
Code¶
The architecture as a map (pure Python):
COMPONENTS = { # component: (responsibility, owning Part-5 lesson)
"APIServer": ("HTTP + tokenize/detokenize", "—"),
"Scheduler": ("admit/evict, chunked prefill", "continuous-batching, scheduler"),
"KVCacheManager":("BlockPool alloc/free + prefix hashes", "paged-attention, prefix-caching"),
"ModelRunner": ("tensors, CUDA graphs, nn.Module fwd", "tuning-knobs (enforce_eager)"),
}
PATH = "APIServer → EngineCore(Scheduler → KVCacheManager) → Worker(ModelRunner → Sampler) → APIServer"
Interviewer follow-ups¶
- "Where does continuous batching live?" → The scheduler, in the engine core — it's a scheduling decision, not a worker kernel.
- "How many GPU workers?" →
tensor_parallel_size × pipeline_parallel_sizeper engine core; one on a single 4090. - "Why is V1 multi-process?" → To overlap CPU scheduling with GPU compute — the engine core plans the next step while the worker executes the current one.
- "OOM at startup — which box?" → KV-cache manager profiling:
num_gpu_blocksis sized fromgpu_memory_utilizationminus weights/activations/CUDA-graph. Lower it, quantize, or shrinkmax_model_len. - "Slow decode — which box?" → Model runner: check
enforce_eager(CUDA graphs off raises decode latency).
Linked concepts¶
- Lesson: The vLLM Architecture Map
- Related: Static vs continuous batching (the scheduler box), PagedAttention: block manager (the KV-cache-manager box), Tuning knobs (which knob turns which box), CUDA graphs & kernel fusion (the model runner)
- Glossary: PagedAttention, continuous batching, KV cache