Expert Track · Phase J · 19 of 26
Beyond training — how 100B+ parameter models serve production traffic via PagedAttention, continuous batching, speculative decoding, and prefill/decode disaggregation.
Module 65 · Expert 19 / 26 · 90 min

Inference
serving
at scale.

The specific engineering that turns "naive inference at 5% GPU utilization costing $50 per million tokens" into "vLLM-served 70B model at 60% utilization with 200ms TTFT costing $2 per million tokens." Three primary optimizations: PagedAttention (vLLM — KV cache in fixed-size blocks like OS virtual memory pages, near-zero fragmentation, 2-4× throughput), Continuous batching (Orca/vLLM — iteration-level scheduling, requests join/leave batch dynamically), and Speculative decoding + Quantization (small draft model verifies in parallel for 2-3× latency; INT8/INT4/FP8 for 2-4× memory + throughput). Plus prefill vs decode phase separation, prefill/decode disaggregation (DistServe/Mooncake), and framework composition (vLLM, SGLang, TensorRT-LLM, TGI). Understanding these mechanisms — and how they compose for chat, RAG, and long-form workloads — is Expert-tier competence for modern LLM serving infrastructure.

// What you\'ll know by the end

  • KV cache anatomy + PagedAttention block management
  • Continuous batching + iteration-level scheduling
  • Speculative decoding + quantization stack
  • Prefill/decode disaggregation + anti-patterns
§ 01 — Why inference is a separate engineering problem

A trained 70B model.
KV cache dominates.
Prefill is compute-bound.
Decode is memory-bound.
Both must serve
sub-second.

Inference serving is not "training in reverse" — it\'s a specific engineering problem determined by three tight constraints that differ fundamentally from training: latency (users expect sub-second time-to-first-token, particularly for interactive workloads), throughput (batching many concurrent requests to keep GPUs busy), and memory (KV cache grows with sequence length × batch size × layers × attention heads and can dominate GPU memory at long context). Consider concretely what serving a modern foundation model requires. During training (M.64), a large batch flows through the model, gradients are accumulated, optimizer updates state — the workload is uniform, predictable, and throughput-optimized. During inference, requests arrive independently with variable prompt lengths (100 tokens to 100K+), variable output lengths (10 tokens to 10K+), and independent completion times. Autoregressive decoding is sequential per request: each output token depends on all previous tokens (both prompt and prior generations), read from the KV cache. The naive approach — process each request individually, allocate contiguous KV cache buffer, wait for each request to complete before scheduling the next — achieves 5-10% GPU utilization while costing $50+ per million tokens. Modern serving turns this around through three primary optimizations: (a) PagedAttention (vLLM) manages KV cache as fixed-size blocks like OS virtual memory pages, eliminating fragmentation and enabling non-contiguous storage — 2-4× throughput improvement; (b) Continuous batching (Orca/vLLM) schedules per iteration rather than per request, allowing requests to join and leave the batch dynamically as they arrive and complete — high GPU utilization despite variable request lengths; (c) Speculative decoding + Quantization reduce latency and cost — small draft model proposes N tokens verified in parallel by large model (2-3× latency); INT8/INT4/FP8 quantization reduces memory footprint and improves memory-bound decode throughput (2-4× savings). Understanding these mechanisms — and specifically their composition for different workload profiles — is Expert-tier competence.

// PREFILL VS DECODE · KV CACHE MEMORY · WHY INFERENCE IS A SEPARATE PROBLEM
LLM INFERENCE · TWO PHASES · KV CACHE DOMINANT PREFILL PHASE process entire prompt CHARACTERISTICS Compute-bound (matmul) O(N²) attention over prompt WORKLOAD All tokens processed at once GPU compute fully utilized One forward pass Fills KV cache LATENCY Time-to-First-Token (TTFT) Grows O(N²) with prompt chunked prefill for long ctx OPTIMIZATIONS FlashAttention (memory-eff) Chunked prefill (long ctx) Prefix caching (repeat prompts) tensor parallel (in-node) KV CACHE (dominant) the memory bottleneck SIZE FORMULA 2 × layers × heads × head_dim × seq_len × batch × 2 bytes grows linearly with tokens EXAMPLE: LLAMA-70B 80 layers · 64 heads · 128 head_dim 2K seq: ~640MB per request 32K seq: ~10GB per request 100K seq: ~32GB per request quickly dominates memory NAIVE PROBLEM Contiguous allocation Internal fragmentation 60-80% wastes memory · limits batch PAGED ATTENTION FIX Fixed-size blocks (16 tokens) near-zero fragmentation DECODE PHASE generate one token at a time CHARACTERISTICS Memory-bandwidth-bound One token per iteration WORKLOAD Read full KV cache per step GPU compute underutilized Memory bandwidth saturated Sequential over output LATENCY Time-per-Output-Token (TPOT) Grows linearly with seq_len tokens/sec throughput metric OPTIMIZATIONS Continuous batching (large B) Speculative decoding (draft) Quantization (INT4/8, FP8) PagedAttention (KV mgmt)
The two fundamentally different phases of LLM inference and why they require different optimization strategies. Prefill phase: process the entire prompt in one forward pass. Compute-bound: matrix multiplications over all prompt tokens simultaneously; GPU compute fully utilized; attention is O(N²) in prompt length. Determines Time-to-First-Token (TTFT) — user-visible latency until first token appears. Grows quadratically with prompt length (long-context prompts of 32K+ tokens can take seconds). Fills the KV cache. Optimizations: FlashAttention (memory-efficient attention), chunked prefill (split long prompts into manageable chunks for scheduling), prefix caching (reuse KV for repeated prompt prefixes), tensor parallelism within node. KV Cache — the memory bottleneck: for each token in the sequence, per each attention layer, store K (key) and V (value) tensors — the cache the decode phase reads from. Size formula: 2 × layers × heads × head_dim × seq_len × batch × 2 bytes (FP16). For LLaMA-70B (80 layers, 64 heads, 128 head_dim): 640MB per 2K-token request, 10GB per 32K-token request, 32GB per 100K-token request. Grows linearly with sequence length; can quickly dominate the 80GB HBM of H100. Naive contiguous allocation causes 60-80% internal fragmentation (allocate max sequence length per request, waste unused space) — vLLM\'s PagedAttention solves this by using fixed-size blocks like OS virtual memory pages (typical block size 16 tokens), enabling near-zero fragmentation and non-contiguous storage. 2-4× throughput improvement over naive. Decode phase: generate one output token at a time. Memory-bandwidth-bound: for each new token, read the entire KV cache from HBM into compute units, compute attention over all past tokens, write new K/V to cache. GPU compute severely underutilized (typically 1-10% of peak matmul), memory bandwidth saturated. Determines Time-per-Output-Token (TPOT) and tokens/sec throughput. Grows linearly with sequence length (attention over longer past). Sequential: each token depends on all prior tokens. Optimizations: continuous batching (batch many concurrent requests to amortize HBM reads across parallel compute — turns memory-bound into compute-bound); speculative decoding (small draft model proposes N tokens, large model verifies in parallel — 2-3× latency wins for memory-bound decode); quantization (INT4/INT8/FP8 reduces KV cache and weights memory footprint — decode is memory-bound so speedup directly proportional); PagedAttention for KV cache management. The specific engineering: recognize prefill and decode have fundamentally different characteristics; optimize each separately; consider disaggregation (DistServe/Mooncake) at scale to specialize hardware. Standard modern discipline.

The specific engineering task M.65 addresses is understanding how to compose PagedAttention + continuous batching + speculative decoding + quantization for different workload profiles. Modern inference has three primary optimization primitives + phase-aware overlays: (a) PagedAttention (vLLM, Kwon et al. SOSP 2023) — the KV cache management primitive. Allocate cache as fixed-size blocks (typically 16 tokens per block); block table per request maps logical positions to physical blocks; blocks are shared across requests when possible (prefix caching for shared prompt prefixes). Near-zero internal fragmentation vs 60-80% waste for contiguous allocation. Enables 2-4× more concurrent requests and correspondingly higher throughput. Foundational modern primitive. (b) Continuous batching (Orca, Yu et al. OSDI 2022; popularized by vLLM) — the throughput primitive. Traditional "static batching" waits for all requests in the batch to complete before scheduling next batch — GPU sits idle when short requests finish before long ones (30-70% wasted time). Continuous batching (also called "iteration-level scheduling") schedules per iteration: after each forward pass, completed requests leave the batch and new requests join. Requests of variable lengths coexist; GPU utilization stays high. Standard modern discipline. (c) Speculative decoding + Quantization — the latency and cost primitives. Speculative decoding: small draft model (e.g., 1B params) proposes N tokens (typically N=4-8); large model verifies all N tokens in a single forward pass; accept the longest matching prefix. Since decode is memory-bound (weights read once per step), verifying multiple candidate tokens in parallel takes similar time to one — effective 2-3× latency reduction if draft accuracy is decent. Quantization: reduce weight precision from FP16 to INT8 (2× memory), INT4 (4× memory via GPTQ/AWQ), or FP8 (H100 Transformer Engine). 2-4× throughput improvement, minimal quality loss with modern techniques. (d) Prefill vs decode phase separation: prefill is compute-bound; decode is memory-bound. Different optimization strategies for each. Modern schedulers separate them: chunked prefill (split long prompts to interleave with decode), prefill/decode disaggregation (DistServe/Mooncake). Standard 2024+ pattern for frontier-scale serving.

// FOUR APPROACHES TO SERVING · WHERE EACH FAILS OR FITS
Attempt 1: Single request, contiguous KV, no batching// simplest · 5-10% GPU util · $50 per million tokens
"Process one request at a time. Allocate contiguous KV cache buffer for max sequence length. Complete request; deallocate; process next." The pre-modern-serving default. The failures: (a) GPU MASSIVELY UNDERUTILIZED — during decode, one token per iteration; GPU compute at 1-5% of peak. HBM bandwidth partially utilized but compute idle. Waste dominates cost. (b) KV CACHE FRAGMENTATION — allocating for max sequence length wastes 60-80% of memory on requests that don\'t reach max length. Limits concurrent requests further. (c) TAIL LATENCY DOMINATES — long-tail requests (100K+ token generations) block all shorter requests behind them; queueing delays add up. (d) NO BATCH AMORTIZATION — memory-bound decode benefits massively from batching (weights read once, compute across parallel requests); single-request loses this entirely. Standard failure of naive serving. Cost per million tokens: $30-50 typical.// FAIL MODE: 5-10% GPU util · fragmented KV · no batching · $50/M tokens
NAIVE · $50
/M TOKENS
Attempt 2: Static batching, contiguous KV// batch of 8 · 20-30% GPU util · wait for slowest
"Batch 8 requests together. Pad all to same length. Run forward passes together. When all 8 complete, batch next 8." Better throughput than single-request but still hemorrhaging efficiency. The failures: (a) WAIT FOR SLOWEST — 7 requests finish generating at 100 tokens; 1 request continues to 5000 tokens; 7 GPUs sit idle waiting for the 8th. 30-70% of batch time wasted. (b) PADDING WASTE — request A has 100-token prompt; request B has 8000-token prompt; padding A to match B wastes 7900 tokens of compute for A during prefill. (c) FRAGMENTATION STILL — contiguous KV allocation still wastes 60-80% memory. (d) BATCH SIZE LIMITED — total memory / max seq len limits batch to typically 2-8 requests. Standard failure of static batching. GPU util 20-30% typical; cost $15-25 per million tokens.// FAIL MODE: 20-30% GPU util · wait for slowest · padding waste · $20/M tokens
STATIC · $20
/M TOKENS
Attempt 3: Continuous batching alone, contiguous KV// requests dynamic · but KV still fragmented
"Iteration-level scheduling. Requests join and leave the batch as they complete. But KV cache still allocated contiguously per request." Half the modern solution. Orca-style scheduling without vLLM\'s KV management. The failures: (a) FRAGMENTATION LIMITS BATCH — even with dynamic scheduling, contiguous KV allocation limits concurrent requests to what fits in memory when each is over-allocated for potential max length. Typically 8-32 concurrent vs 100-500 with PagedAttention. (b) LONG-CONTEXT REQUESTS PROHIBITIVE — one 100K-token request needs 32GB contiguous → can\'t fit in same batch as short requests. (c) NO PREFIX CACHING — repeated prompt prefixes (e.g., system prompts across many requests) redundantly computed + stored. (d) MEMORY EFFICIENCY 40-50% — vs 95%+ with PagedAttention. Standard partial-solution failure. GPU util 35-45%; cost $8-12 per million tokens.// FAIL MODE: fragmented KV limits batch · no prefix sharing · $10/M tokens
PARTIAL · $10
/M TOKENS
Attempt 4: PagedAttention + continuous batching + speculative + quantization// vLLM/SGLang/TensorRT-LLM · 60% GPU util · $2 /M tokens
"Full modern serving stack: PagedAttention manages KV cache as fixed-size blocks (near-zero fragmentation, prefix caching for shared prompts), continuous batching schedules per iteration (100-500 concurrent requests), speculative decoding (small draft model proposes N tokens, large verifies in parallel, 2-3× latency), quantization (INT4/INT8/FP8 for weights + KV cache, 2-4× memory savings). Optional: prefill/decode disaggregation for large-scale serving." The specific modern engineering. Composition matched to workload: (a) PagedAttention: KV cache as 16-token blocks; block table per request maps logical positions → physical blocks; near-zero fragmentation (memory efficiency 95%+); enables 4-8× more concurrent requests. Prefix caching: shared prefix blocks reused across requests. (b) Continuous batching: iteration-level scheduling. Requests join batch on arrival, leave on completion. Prefill for new requests interleaves with decode for existing. Handles variable-length requests naturally. GPU utilization 50-70%. (c) Speculative decoding: small draft model (Llama-1B for Llama-70B target) proposes N=4-8 tokens autoregressively; large model verifies all in single forward pass; accept longest matching prefix. 60-80% acceptance rate typical → 2-3× effective latency reduction. (d) Quantization: FP8 (H100 Transformer Engine) for weights + KV cache, 2× memory + 1.5-2× throughput vs BF16, ~1% quality loss. INT4 via AWQ/GPTQ for aggressive memory savings, ~3-5% quality loss. (e) Framework choice: vLLM (Berkeley, most popular), SGLang (Berkeley, RadixAttention prefix caching), TensorRT-LLM (NVIDIA, kernel-fused production), TGI (HuggingFace, easy deployment). (f) Prefill/decode disaggregation (frontier): DistServe (Berkeley), Mooncake (Moonshot AI) — separate prefill on compute-rich instances, decode on memory-rich. Standard 2024+ pattern for 100B+ MoE serving. (g) Result: 55-70% GPU utilization; TTFT 200-500ms for chat; TPOT 20-50ms; cost $1-5 per million tokens.// FIT: composed modern stack · 55-70% GPU util · sub-second TTFT · $2/M tokens
PRODUCTION
MODERN
// THE COMPOSITE PATTERN

Each earlier attempt fails specifically. Naive single-request loses to no batching + fragmented KV; $50/M. Static batching waits for slowest, pads waste; $20/M. Continuous batching alone still fragments KV; $10/M. The Expert pattern: compose PagedAttention + continuous batching + speculative decoding + quantization matched to workload. PagedAttention manages KV cache as 16-token blocks (95%+ memory efficiency, prefix caching enabled). Continuous batching schedules per iteration (variable-length requests coexist, 55-70% GPU util). Speculative decoding + quantization reduce latency + memory. Framework choice (vLLM/SGLang/TensorRT-LLM/TGI) matches workload. Prefill/decode disaggregation at frontier scale. Standard modern discipline; $2-5/M tokens; production economics. §02 covers PagedAttention + KV cache anatomy in depth. §03 covers continuous batching + speculative decoding + quantization + framework landscape.

The historical arc of LLM serving optimization traces specifically how each primitive addressed a specific bottleneck as the industry scaled from GPT-3 API to modern frontier serving. 2020: GPT-3 API era. OpenAI serves GPT-3 (175B) via a small number of massive GPU instances. Batching is basic; costs are high; latency is unpredictable. 2021-2022: FasterTransformer (NVIDIA). Fused kernels for transformer inference; tensor parallelism at inference (different constraints than training — no gradients, prefill vs decode differences); mixed precision INT8. Foundational NVIDIA inference stack. 2022: Orca paper (OSDI). Yu et al. propose "iteration-level scheduling" (later called continuous batching): schedule per model iteration rather than per request; requests can join and leave the batch dynamically. Theoretical basis for modern serving. 2023: vLLM paper (SOSP). Kwon et al. propose PagedAttention: manage KV cache as fixed-size blocks like OS virtual memory pages. Combined with continuous batching, achieves 2-4× throughput improvement over prior state-of-art. Open source release becomes industry-standard within months. Foundational modern serving stack. 2023: Speculative decoding. Leviathan et al. (Google) and Chen et al. (DeepMind) independently propose speculative sampling: use small draft model to propose tokens, large model verifies in parallel. 2-3× latency for memory-bound decode. 2023: Quantization matures. GPTQ (post-training quantization to INT4), AWQ (activation-aware quantization), SmoothQuant (activation smoothing for INT8), llama.cpp\'s 4-bit quantized inference on CPU/edge. 2024: SGLang (Berkeley). Zheng et al. propose RadixAttention: prefix tree-based KV cache sharing across requests; automatic prefix caching for repeated prompt segments. Structured generation (JSON, regex-constrained decoding). 2024: TensorRT-LLM production maturity. NVIDIA\'s kernel-fused production stack; FP8 support on H100 Transformer Engine; strong integration with Triton Inference Server. 2024: MoE serving hot topic. Mixtral-8x7B, DeepSeek-V2 (238B / 21B active) drive interest in efficient MoE inference. Expert parallelism at serving time; all-to-all routing optimizations. 2024-2025: Prefill/decode disaggregation. DistServe (Berkeley) and Mooncake (Moonshot AI) propose separating prefill and decode across different hardware instances. Standard for frontier-scale serving. 2025: Sub-second TTFT for 100B+ models standard. Modern production serving of Claude, GPT-4, Gemini, DeepSeek — sub-second TTFT for chat, throughput of thousands of tokens/sec/GPU for batch, cost $1-3/M tokens. Long-context serving (100K+ tokens) via chunked prefill + KV cache offloading to CPU memory. Standard modern production. The historical arc explains why modern inference is a composed stack — each primitive addressed a specific bottleneck.

Inference is not training in reverse. Prefill is compute-bound; decode is memory-bound; KV cache dominates. PagedAttention manages memory. Continuous batching manages throughput. Speculative + quantization manage latency + cost.
§ 02 — KV cache anatomy · PagedAttention · prefix caching

KV cache dominates.
Paged blocks
eliminate
fragmentation.
Prefix sharing
eliminates redundancy.

The KV cache is the specific data structure that makes autoregressive generation fast — and specifically the bottleneck that dominates GPU memory during serving. Consider concretely what the KV cache stores. For each token in a sequence, and for each attention layer, the model computes K (key) and V (value) tensors used by the attention mechanism. During decoding, generating token N requires attending to all previous tokens 0..N-1 — the K and V for those tokens must be reread from memory. Rather than recomputing them, they\'re cached. The size formula: 2 × num_layers × num_heads × head_dim × seq_len × batch × precision_bytes. For LLaMA-70B (80 layers, 64 heads, 128 head_dim, FP16): each token consumes 2 × 80 × 64 × 128 × 2 = 2.6MB per token. Sequence of 2048 tokens = ~5GB KV cache per request. Sequence of 32768 tokens = ~85GB — exceeds a single H100 for a single request. This is why KV cache management dominates serving system design. The naive contiguous allocation problem: when a request arrives, the system doesn\'t know its final sequence length. Options: (a) allocate for max_seq_len (typical 4K-32K): most requests only use 500-2K tokens; 60-80% memory waste (internal fragmentation); (b) allocate small buffer, reallocate as needed: memory churn, contiguous requirement can\'t be satisfied when memory is fragmented; allocation fails. Both fail at scale. The PagedAttention solution (vLLM, Kwon et al. SOSP 2023): manage KV cache like OS virtual memory. Allocate cache in fixed-size blocks (typical 16 tokens per block). Each request has a block table mapping logical positions (token index) to physical blocks (arbitrary memory locations). Growing a sequence allocates a new block from the free pool — no contiguous requirement, no reallocation. Blocks can be shared across requests (prefix caching: two requests with the same prompt prefix share the same physical blocks). Near-zero fragmentation. Memory efficiency 95%+ vs 40-50% naive. Enables 4-8× more concurrent requests. Foundational modern primitive.

// PAGED ATTENTION · KV CACHE AS FIXED-SIZE BLOCKS · PREFIX SHARING

PAGED ATTENTION · KV CACHE MEMORY MANAGEMENT LIKE OS VIRTUAL PAGES NAIVE CONTIGUOUS ALLOCATION allocate max_seq_len per request · 60-80% fragmentation Request A · 4K allocated actual: 500 tokens WASTED Request B · 4K allocated actual: 1200 tokens Request C · 4K allocated actual: 800 tokens ... memory exhausted only 3 concurrent PAGED ATTENTION (vLLM) 16-token blocks · block tables per request · near-zero fragmentation Physical block pool: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 ... (many more free) Block tables (logical → physical): Request A [500 tokens]: [B0, B1, B2, B14, ..., B32] (32 blocks · last partial) Request B [1200 tokens]: [B3, B5, B7, ..., B75] (75 blocks · fully packed) PREFIX CACHING shared prompt blocks reused across requests · zero duplication Shared prefix (system prompt): B100 B101 B102 shared by many requests Request X: [B100, B101, B102, B200, B201, ...] (prefix shared · suffix unique) Request Y: [B100, B101, B102, B300, B301, ...] (prefix shared · suffix unique) SGLang RadixAttention · vLLM prefix caching · 30-80% cache hit rate typical
PagedAttention manages KV cache like OS virtual memory — the specific data structure that eliminates fragmentation and enables prefix sharing. Naive contiguous allocation problem: system doesn\'t know final sequence length; allocates for max_seq_len (typically 4K-32K); most requests only use 500-2K tokens; 60-80% memory wasted per request. With H100\'s 80GB HBM and 70B model weights taking ~40GB (FP16), only ~40GB left for KV cache. Only ~200-400 concurrent requests effectively. PagedAttention solution: divide KV cache into fixed-size blocks (typical block size = 16 tokens). Physical block pool: free list of ~5000 blocks each holding K/V for 16 tokens across all layers/heads. Per-request block table: array mapping logical positions (token index divided by 16) to physical block IDs. Request A with 500 tokens uses 32 blocks (500/16 = 31.25 → 32 blocks; last block partially filled). Request B with 1200 tokens uses 75 blocks. Blocks allocated from free pool on demand as sequence grows. When request completes: all blocks returned to free pool. Result: near-zero fragmentation. Memory efficiency 95%+. Enables 4-8× more concurrent requests. Foundational vLLM contribution. Prefix caching (extends PagedAttention): many production workloads have shared prompt prefixes — system prompts, RAG contexts, multi-turn conversations. Since KV values for a token depend only on preceding tokens, identical prefix → identical KV cache blocks. Cache blocks for shared prefixes: two requests with same first 200 tokens share the same physical blocks B100, B101, B102. Blocks referenced by both, physically stored once. On cache hit: skip prefill computation for shared portion entirely — TTFT drops from seconds to milliseconds. Typical hit rate in production: 30-80% depending on workload. vLLM implements prefix caching; SGLang\'s RadixAttention uses radix tree for automatic prefix sharing detection. Standard modern optimization. The Expert insight: PagedAttention transforms KV cache from "the memory bottleneck that limits concurrency" into "efficiently managed pool that enables 100-1000+ concurrent requests." Combined with prefix caching, dramatically reduces both memory pressure and prefill compute. Standard modern serving foundation.
i
KV cache anatomy.

2 × layers × heads × head_dim × seq_len × batch × precision. Grows linearly with tokens. For LLaMA-70B: ~2.6MB per token. 32K sequence = ~85GB. Dominates GPU memory at long context.

ii
Naive fragmentation.

Contiguous allocation for max_seq_len wastes 60-80% memory. Limits concurrent requests to ~10-30 vs 100-500 possible. Standard pre-2023 failure.

iii
PagedAttention.

Fixed-size blocks (16 tokens typical). Block table per request maps logical→physical. Near-zero fragmentation. 95%+ memory efficiency. Foundational vLLM contribution (Kwon et al. SOSP 2023).

iv
Prefix caching.

Shared prompt prefixes → shared physical blocks. Skip prefill for cached portion. TTFT drops from seconds to milliseconds. 30-80% hit rate typical. Standard vLLM + SGLang optimization.

v
RadixAttention (SGLang).

Prefix tree data structure for automatic prefix sharing detection. Extends vLLM foundations. Popular for RAG + agent workloads with structured prompts. Zheng et al. 2024.

vi
KV cache offloading.

For long context: overflow least-recently-used blocks to CPU memory. Reload on cache hit. Enables 100K+ token contexts on limited HBM. Standard 2024+ pattern.

The KV cache memory math (mech items i-ii) is worth walking through explicitly because it dictates the concrete constraints of every serving deployment. Consider LLaMA-70B on H100 (80GB HBM). Model weights in FP16: 70B × 2 bytes = 140GB — doesn\'t fit on one GPU, requires TP=8 within node (17.5GB weights per GPU). Available for KV cache after weights + activations: ~40GB per GPU × 8 GPUs = 320GB across the TP=8 group. KV cache per token: 2 × 80 × 64 × 128 × 2 = 2.6MB (FP16). Across TP=8: ~325KB per token per GPU. 320GB total ÷ 2.6MB per token = 123K token capacity across all concurrent requests. For 4K-token sequences: 30 concurrent requests naive; with PagedAttention (95% efficient): ~120 concurrent. For 32K-token sequences: 3 concurrent naive; with PagedAttention: ~12 concurrent. Long context is expensive — this is why 100K+ context requires KV cache offloading (mech item vi). Also why FP8/INT4 quantization of KV cache (2-4× reduction) matters significantly for long-context serving. The prefix caching math (mech item iv): for chat workloads with common 500-token system prompt used across N concurrent requests: without prefix caching, N × 500 × 2.6MB = 1.3N GB of KV cache dedicated to duplicated prefix (waste). With prefix caching: 500 × 2.6MB = 1.3GB shared once across all requests (98% savings on prefix portion). For RAG workload where 100 requests each query the same 8K-token document context: without caching, 100 × 8K × 2.6MB = 2.1TB (impossible); with caching, 8K × 2.6MB = 21GB shared (feasible). Prefix caching literally makes long-context RAG serving feasible. Standard modern optimization. Understanding these numbers — memory footprint per token, effect of quantization, effect of prefix caching — is Expert-tier competence.

The PagedAttention block management (mech item iii) deserves specific attention because it\'s the specific data structure that makes modern serving throughput possible. Consider the concrete mechanics: (a) Block size choice: fixed at compile time (typical 16 tokens). Small blocks → less waste in last partial block but more block table overhead. Large blocks → more waste but simpler. 16 tokens is the vLLM default sweet spot. (b) Block table structure: per-request array. For request with 500 tokens: 32 block IDs stored (each ID ~2 bytes → 64 bytes per request block table). Negligible overhead. (c) Allocation: when a request needs a new block (every 16 generated tokens), allocate from free pool. O(1) via free list. When request completes: return all blocks to pool. (d) Attention computation: modified attention kernel (custom CUDA) reads K/V from non-contiguous blocks via block table indirection. Adds small overhead (~5% vs contiguous) but enables massive concurrency gains. vLLM\'s custom PagedAttention kernel is the specific engineering contribution. (e) Prefix sharing: reference-counted blocks. When two requests share prefix blocks: refcount = 2. When one completes: refcount decrements. When refcount reaches 0: block returned to free pool. (f) Preemption: when memory is full and a new request arrives, vLLM can preempt (swap out to CPU or drop) least-important requests. Standard priority-based scheduling. (g) Copy-on-write: for parallel sampling (n>1 generations from same prompt): initially share prefix blocks; when generations diverge, copy the affected block. Extends prefix caching to multi-sample scenarios. (h) The Expert insight: PagedAttention is not "just a memory allocator" — it\'s a foundational primitive that enables (i) high concurrency (100-1000+ requests), (ii) prefix caching (30-80% cache hit rates), (iii) preemption (SLA-aware scheduling), (iv) parallel sampling efficiency. Together these enable modern serving economics ($2/M tokens vs $20-50/M naive). Understanding this mechanism is Expert-tier competence.

KV cache dominates serving memory. Naive contiguous allocation wastes 60-80%. PagedAttention treats it like OS virtual memory — fixed blocks, block tables, prefix sharing, near-zero fragmentation. Foundational modern primitive.
§ 03 — Continuous batching · speculative decoding · quantization · frameworks

Iteration-level
scheduling. Small
draft model verifies
in parallel.
FP8 + INT4
where it fits.

Beyond PagedAttention, three additional primitives specifically address the throughput, latency, and cost constraints of modern LLM serving: continuous batching (throughput), speculative decoding (latency), and quantization (memory + throughput + cost). Each has specific mechanics + specific fit; their composition is what modern frameworks (vLLM, SGLang, TensorRT-LLM, TGI) provide. (a) Continuous batching (Orca / vLLM): schedule per iteration rather than per request. Traditional "static batching" waits for all N requests to complete their generations before running the next batch of N — 30-70% of time wasted when requests have variable lengths. Continuous batching runs one forward pass over the current active batch; after each pass, requests that completed leave the batch (their KV cache blocks freed), new requests join. Handles the fundamental variability of request lengths gracefully. Prefill of a new request can interleave with decode of ongoing requests. Enables 50-70% GPU utilization for variable workloads vs 20-30% static. Foundational. (b) Speculative decoding (Leviathan et al. Google 2023; Chen et al. DeepMind 2023): leverage the fact that decode is memory-bound. Small "draft" model (e.g., LLaMA-1B for LLaMA-70B target) autoregressively generates N candidate tokens (typically N=4-8). Large "target" model processes those N tokens in a single forward pass (verifying their K/V + computing what the target model would have generated). Accept the longest matching prefix; reject the rest. Since decode is memory-bandwidth-bound (weights read once per token), verifying multiple candidates in parallel has similar cost to one — effective 2-3× latency reduction when acceptance rate is decent (60-80% typical). Standard for latency-critical workloads. (c) Quantization: reduce precision of weights and/or KV cache and/or activations. FP16→FP8 (H100 Transformer Engine): 2× memory, 1.5-2× throughput, ~1% quality loss. FP16→INT8 (SmoothQuant, LLM.int8()): 2× memory, 1.5-2× throughput, ~1-2% quality loss. FP16→INT4 (GPTQ, AWQ): 4× memory, 2-3× throughput, ~3-5% quality loss depending on method. Since decode is memory-bound: throughput scales roughly with 1/precision. Also apply to KV cache: FP16→FP8 KV cache halves memory footprint, enabling 2× longer contexts or 2× more concurrent requests.

// CONTINUOUS BATCHING · SPECULATIVE DECODING · QUANTIZATION · SIDE-BY-SIDE

THREE MODERN SERVING OPTIMIZATIONS · WHY EACH MATTERS CONTINUOUS BATCHING iteration-level scheduling STATIC (bad): Batch 8 · wait for slowest 30-70% GPU idle CONTINUOUS (good): Iter N: R1,R2,R3,R4,R5 Iter N+1: R2,R3,R4,R5,R6 Iter N+2: R2,R4,R5,R6,R7 R1 done · R6, R7 joined · dynamic MECHANISM: After each forward pass: → Completed leave batch → New arrivals join → Prefill + decode mix RESULT: GPU util: 50-70% Throughput: 3-5× static Foundational (Orca 2022) standard modern default SPECULATIVE DECODING draft + verify in parallel MECHANISM: Step 1: Draft (small model) Llama-1B generates 8 tokens Step 2: Verify (target model) Llama-70B one forward pass Step 3: Accept prefix 6/8 tokens match → advance 6 KEY INSIGHT: Decode is memory-bound Verifying 8 tokens ≈ 1 token (same weights read once) effective 2-3× speedup ACCEPTANCE RATE: 60-80% typical (chat) Higher: EAGLE, Medusa RESULT: Latency: 2-3× reduction critical for interactive QUANTIZATION reduce precision · memory + throughput PRECISION LEVELS: FP16 baseline · 2 bytes/param FP8 (H100 TE) · 2× · minimal loss INT8 (SmoothQ) · 2× · ~1% loss INT4 (AWQ, GPTQ) · 4× · ~3-5% loss WHY DECODE BENEFITS: Memory-bandwidth-bound Throughput ∝ 1/precision smaller weights = faster reads KV CACHE QUANTIZATION: FP8 KV cache: 2× longer ctx or 2× more concurrent RESULT: 2-4× throughput 2-4× memory savings standard modern discipline
Three modern serving optimizations that compose with PagedAttention for the full modern stack. Continuous batching (Orca 2022, vLLM 2023): schedule per model iteration rather than per request. Traditional static batching: batch N requests, run all forward passes together, wait for all to complete before scheduling next batch. Variable request lengths → GPU idle 30-70% of time. Continuous batching: after each forward pass, completed requests leave the batch; new requests join. Prefill for new requests can interleave with decode for ongoing ones. GPU utilization jumps from 20-30% (static) to 50-70% (continuous). 3-5× throughput improvement. Foundational Orca contribution, popularized by vLLM. Speculative decoding (Leviathan Google, Chen DeepMind 2023): leverage fact that decode is memory-bandwidth-bound. Small draft model (e.g., LLaMA-1B for LLaMA-70B target — 70× smaller, ~70× faster to run) autoregressively generates N candidate tokens (typically N=4-8). Large target model processes those N tokens in single forward pass — verifying their K/V and computing what target would have generated. Accept longest matching prefix; reject rest. Key insight: since decode is memory-bound (target model weights read once per forward pass regardless of tokens processed), verifying multiple candidates costs approximately same as one. If acceptance rate is 75%: effectively 6 accepted tokens per target forward pass instead of 1 → 6× theoretical speedup, ~2-3× practical after overhead. Extensions: EAGLE (feature-level auto-regression, higher acceptance), Medusa (multi-head decoding, no separate draft), lookahead decoding. Standard modern discipline for chat serving. Quantization: reduce weight/activation/KV cache precision below FP16 baseline. FP8 (H100 Transformer Engine): 2× memory savings, 1.5-2× throughput, ~1% quality loss — standard for H100 serving. INT8 (SmoothQuant addresses activation outliers, LLM.int8() addresses matmul precision): 2× memory, 1.5-2× throughput, ~1-2% quality loss. INT4 (GPTQ post-training quantization, AWQ activation-aware quantization): 4× memory, 2-3× throughput, ~3-5% quality loss depending on method + model quality. Since decode is memory-bandwidth-bound: throughput scales approximately with 1/precision. Applied to KV cache: FP8 KV cache halves memory footprint, enabling 2× longer contexts or 2× more concurrent requests. FP8 on H100 is the current sweet spot for most workloads. INT4 for extreme memory-constrained deployments. Standard 2024-2025 pattern. The composition: PagedAttention (KV memory) + continuous batching (throughput) + speculative decoding (latency) + quantization (cost + memory) = full modern stack. vLLM, SGLang, TensorRT-LLM, TGI compose these differently based on design tradeoffs. Understanding each mechanism + when it fits is Expert-tier competence.
i
Continuous batching.

Iteration-level scheduling. Requests join/leave batch dynamically. Prefill interleaves with decode. GPU util 50-70% vs 20-30% static. 3-5× throughput. Orca 2022 → vLLM standard.

ii
Speculative decoding.

Small draft model proposes N tokens; large target verifies in parallel. Decode memory-bound → verify cost ≈ single token. 60-80% acceptance → 2-3× latency. Standard for chat.

iii
Quantization.

FP8 (H100 TE): 2× · minimal loss. INT8: 2× · ~1% loss. INT4 (AWQ/GPTQ): 4× · ~3-5% loss. Decode is memory-bound → throughput ∝ 1/precision. Standard modern discipline.

iv
vLLM (Berkeley).

PagedAttention foundational. Continuous batching. Prefix caching. Most popular open-source serving. GitHub: vllm-project/vllm. Standard 2023+ default choice.

v
SGLang (Berkeley).

RadixAttention prefix caching. Structured generation (JSON, regex). Excellent for RAG + agent workloads. GitHub: sgl-project/sglang. Strong 2024 alternative to vLLM.

vi
TensorRT-LLM (NVIDIA).

Kernel-fused production stack. FP8 on H100 TE. Strong Triton Inference Server integration. Best NVIDIA-native perf. Standard for NVIDIA-native production. Closed source, NVIDIA-only.

The prefill vs decode phase separation (foundational architectural insight) is worth specific attention because it dictates every modern serving system\'s scheduler design. Consider the specific differences: (a) Prefill computationally: process entire N-token prompt at once. Matrix operations are (batch × N × hidden) × (hidden × hidden) = O(N × hidden²) per layer. Attention specifically is O(N² × hidden) — quadratic in prompt length. Compute-bound: matmul units fully utilized. TTFT (Time-to-First-Token) is dominated by prefill cost. Grows quadratically with prompt length. Long-context prefill (32K+ tokens) can take seconds. (b) Decode computationally: generate one token at a time. Matmul is (batch × 1 × hidden) × (hidden × hidden) — tiny per step. Attention is O(N × hidden) per step (attend to N cached tokens). Memory-bandwidth-bound: for each token, read full model weights + full KV cache from HBM into compute; compute takes microseconds but memory read dominates. Weights: 140GB FP16 for 70B; HBM bandwidth 3.35 TB/s → ~40ms to read weights per token. GPU compute severely underutilized (1-10% of peak matmul FLOPs). (c) Why batching helps decode dramatically: memory bandwidth is amortized across the batch. Reading 140GB of weights once serves the whole batch\'s decode step. Batch of 100 → same 40ms, 100 tokens produced → 2500 tokens/sec. Continuous batching + PagedAttention enable large batches. (d) Why prefill doesn\'t benefit as much from batching: prefill is compute-bound already; batching increases compute proportionally without free lunch. Also prefill dominates latency for interactive workloads — batch prefills of long prompts add TTFT for waiting requests. (e) Chunked prefill: split long prompts into chunks (say 512 tokens each); process chunks incrementally interleaved with decode steps for other requests. Amortizes long-prefill latency across many decode steps for others. Standard modern optimization. (f) Prefill/decode disaggregation (DistServe/Mooncake): at frontier scale, prefill and decode have different SLA targets (TTFT vs TPOT) and different hardware needs (compute-rich vs memory-rich). Solution: separate them across different hardware pools. Prefill instances: process incoming requests, produce KV cache. Transfer KV cache to decode instance. Decode instance: continuous decode of many requests. Adds inter-instance communication cost but enables independent scaling of each phase, matches SLAs. Standard for 100B+ MoE serving. Understanding this — that prefill and decode are fundamentally different problems requiring different optimization strategies — is Expert-tier competence.

The framework choice heuristic (mech items iv-vi) deserves specific attention because it\'s where production engineering decisions actually get made. Consider the specific tradeoffs: (a) vLLM: canonical modern serving framework. PagedAttention foundational contribution. Continuous batching. Prefix caching. Broad model support via HuggingFace integration. Popular for prototyping + production. GitHub 30K+ stars. Standard 2023+ default choice for open-source LLM serving. Weakness: RadixAttention (SGLang) does better prefix caching for RAG; TensorRT-LLM has better FP8 kernels on H100 for pure NVIDIA. (b) SGLang: newer Berkeley project. RadixAttention: prefix tree data structure for automatic prefix sharing detection (extends vLLM foundations). Structured generation: constrained decoding for JSON schemas, regex matches, tool use — critical for agent + RAG workloads. Zheng et al. 2024. Excellent for prompt-heavy workloads with high prefix overlap. Strong 2024 alternative to vLLM for specific workloads. (c) TensorRT-LLM: NVIDIA production stack. Kernel-fused (fused attention + matmul + activation). FP8 on H100 Transformer Engine. Best raw performance on NVIDIA hardware. Strong Triton Inference Server integration for production deployment. Closed source, NVIDIA-only. Standard for NVIDIA-native production requiring maximum throughput. (d) TGI (HuggingFace Text Generation Inference): HuggingFace\'s inference server. Easy deployment via HF ecosystem. Good compatibility with HF models. Less optimized than vLLM/TRT-LLM at peak but simpler ops. Standard for teams already in HF ecosystem. (e) DeepSpeed-Inference: Microsoft\'s inference. Strong MoE support. Composes with DeepSpeed training stack. Less popular than vLLM in 2024-2025 for new deployments but good for MoE-specific workloads. (f) llama.cpp: CPU + edge inference. GGUF format. 4-bit quantization. Standard for on-device serving. (g) Framework choice heuristic: default vLLM for general open-source serving; SGLang for RAG + agent workloads with structured output requirements; TensorRT-LLM for maximum throughput on NVIDIA-native production; TGI for HF ecosystem alignment; llama.cpp for edge. Choose based on workload + hardware + team + ecosystem alignment. Standard modern discipline.

Continuous batching for throughput. Speculative decoding for latency. Quantization for cost + memory. Prefill and decode differ fundamentally. vLLM / SGLang / TensorRT-LLM compose these. Standard modern stack.
§ 04 — Inference optimization explorer

Three primitives.
Three workload profiles.

Below: each of three inference optimization primitives (PagedAttention · Continuous batching · Speculative decoding + Quantization) evaluated against three workload profiles (7B chat @ high QPS · 70B RAG @ long context · 400B MoE @ mixed frontier). Watch how each primitive fits each workload — Continuous batching is IDEAL for chat (high concurrency canonical), PagedAttention is KEY for RAG (long-context KV memory dominates + prefix caching wins), Speculative + Quantization is IDEAL for MoE frontier (latency + cost critical at scale). Off-diagonals show partial fit — each primitive still helps, but with less leverage than its ideal workload. The takeaway: match optimization stack to workload characteristics; compose all three at production scale.

INFERENCE_OPTIMIZATION.SIM // m.65 lab
Workload profile →
// SERVING STACK · at current workload
// METRICS · MEMORY / THROUGHPUT / TTFT / TPOT / COST / FIT
Memory efficiency-
Throughput-
TTFT (Time-to-1st)-
TPOT (per token)-
Cost / M tokens-
Overall fit-
// VERDICT
Loading...
...
§ 05 — Where serving decays

Every regret is
fragmented KV, static
batching, or ignored
prefill/decode split.

The failure modes of LLM serving are specific mechanisms by which "we\'re serving Llama-70B on 8 H100s" turns into "we\'re at 15% GPU util paying $30 per million tokens." Each anti-pattern is a real production pattern; Expert engineers avoid them by using PagedAttention for KV management, continuous batching for throughput, speculative decoding for latency, quantization for cost, and treating prefill/decode as fundamentally different phases. Recognizing these saves months of "why is our serving so expensive" debugging.

// FIVE LLM SERVING ANTI-PATTERNS

i
The static batching (waiting for slowest)
"We\'re batching 8 requests together on our 70B serving. GPU utilization is 20%. Turns out one request generates 5000 tokens while the other 7 finish at 100 tokens — the 7 sit idle for 4900 tokens worth of decode time. We\'re wasting most of our compute."

Static batching (fixed-batch, wait-for-slowest) wastes 30-70% of GPU time when requests have variable lengths — which is always the case for real LLM serving. The specific fix is continuous batching (iteration-level scheduling): after each forward pass, completed requests leave the batch and new requests join. Specifically: (a) THE FUNDAMENTAL PROBLEM. Static batching groups N requests together at start; runs forward passes over batch; when all N complete, schedules next batch. But request lengths vary drastically — median chat completion 100-500 tokens, tail can be 5000-10000. When 7 requests complete at 100 tokens and 1 continues to 5000: those 7 GPUs sit idle for 4900 iterations. Total wasted GPU time: (5000-100) × 7 / (5000 × 8) = 86% of the slow request\'s time, 60% of total batch time. (b) THE CONTINUOUS BATCHING FIX. Iteration-level scheduling (Orca, vLLM): after each forward pass, examine which requests completed (hit stop token, reached max length). Freed slots immediately accept new requests from the queue. Requests of different generation lengths coexist naturally. The batch composition changes every iteration. GPU utilization jumps from 20-30% to 50-70%. Throughput 3-5× higher. Standard modern discipline. (c) THE PREFILL INTERLEAVING. New request arrives while decode is ongoing: modern schedulers (vLLM v0.5+, SGLang) interleave prefill of new request with decode of existing requests. Prefill is compute-bound, decode is memory-bound → they use complementary resources. Chunked prefill: split long prompts into smaller chunks to interleave more finely. Standard modern optimization. (d) THE VLLM API. from vllm import LLM, SamplingParams; llm = LLM(model="meta-llama/Llama-3-70b", tensor_parallel_size=8); outputs = llm.generate(prompts, sampling_params). Continuous batching enabled by default; server mode (vllm serve) handles concurrent HTTP requests. Standard modern pattern. (e) THE MEASUREMENT. Track GPU utilization (nvidia-smi during load); target 50-70% for well-tuned modern serving. Track requests-per-second, tokens-per-second, TTFT, TPOT. Alert on util drops below 40%. Standard modern discipline. Understanding this fix — that static batching is objectively wrong for variable-length workloads and continuous batching is the specific answer — is Expert-tier competence. Anti-pattern §05.i captures the failure to use iteration-level scheduling.

ii
The contiguous KV cache (fragmentation)
"We\'re running out of GPU memory serving Llama-70B RAG workload. Only 30 concurrent requests fit. But our math says the H100s have room for 200+. What are we missing?"

Contiguous KV cache allocation wastes 60-80% of GPU memory on internal fragmentation — allocating for max_seq_len per request when most requests only use a fraction. The specific fix is PagedAttention: manage KV cache in fixed-size blocks (16 tokens) like OS virtual memory pages, near-zero fragmentation, 4-8× more concurrent requests. Specifically: (a) THE ROOT CAUSE. When request arrives, system doesn\'t know final sequence length. Naive allocation: contiguous buffer for max_seq_len (typical 4K-32K). Request only uses 500-2K tokens → 60-80% of the buffer wasted. For LLaMA-70B on 8× H100 (320GB KV budget), 32K max sequence = 30 requests × 32K × 2.6MB/token = 2.5TB attempted vs 320GB available. Only 30 concurrent effectively; 60-80% of those buffers wasted. (b) THE PAGEDATTENTION FIX. Divide KV cache into fixed-size blocks (16 tokens per block). Physical block pool: pre-allocated free list of blocks. Per-request block table: maps logical token positions to physical block IDs. Growing sequence allocates blocks from pool on demand. When request completes: blocks returned to pool. Near-zero fragmentation (only ~50% average waste in last partial block per request, ~3% at scale). Memory efficiency 95%+. Enables 4-8× more concurrent requests. Standard vLLM contribution (Kwon et al. SOSP 2023). (c) THE PREFIX CACHING BONUS. Shared prompt prefixes (system prompts, RAG contexts, conversation history) → shared physical blocks. Two requests with same first 500 tokens: block table for both points to same physical blocks B100-B131. Blocks physically stored once. TTFT for cached prefix: milliseconds (skip prefill entirely). Standard vLLM prefix_caching_enabled=True. 30-80% cache hit rate typical in RAG workloads. Enormous compute + memory savings. (d) THE VLLM CONFIGURATION. llm = LLM(model="meta-llama/Llama-3-70b", tensor_parallel_size=8, enable_prefix_caching=True, block_size=16). Block size 16 is the default sweet spot. Prefix caching auto-detects shared prefixes across requests. Standard modern config. (e) THE SGLANG ALTERNATIVE. SGLang\'s RadixAttention uses radix tree structure for automatic prefix sharing detection — more sophisticated than vLLM\'s hash-based caching. Excellent for RAG + agent workloads with highly structured prompts. (f) THE MEASUREMENT. Track KV cache memory efficiency (used blocks / total blocks × block_size × ideal_usage). Target 90%+. Track prefix cache hit rate. Track concurrent request count. Standard modern discipline. Understanding this fix — that PagedAttention is the specific answer to "why can\'t I serve more concurrent requests" — is Expert-tier competence. Anti-pattern §05.ii captures the failure to use paged KV management.

iii
The ignoring speculative decoding for latency-critical
"Our chat interface TTFT is 300ms which is fine, but users complain about typing speed — generation is only 30 tokens/sec on our Llama-70B. That\'s about 15 words/sec which feels slow. Can we improve without hardware upgrade?"

Decode phase is memory-bandwidth-bound — GPU compute severely underutilized while HBM reads dominate. Speculative decoding exploits this by having a small draft model propose N tokens, then having the large target model verify all N in a single forward pass. Since decode is memory-bound, verifying N tokens costs approximately the same as verifying 1 → effective 2-3× latency reduction. Specifically: (a) THE MECHANISM. Small draft model (e.g., LLaMA-1B for LLaMA-70B target — 70× smaller, ~70× faster to run standalone) autoregressively generates N candidate tokens (typically N=4-8) very quickly. Large target model then processes all N candidate tokens in a single forward pass — verifying each token\'s K/V and computing what target would have generated. Accept longest prefix where candidates match target\'s greedy (or sampled) output. Reject rest, continue from accepted position. (b) THE KEY INSIGHT. Target model decode is memory-bandwidth-bound: reading 140GB of weights from HBM per token takes ~40ms; compute of matmul on 1 token vs N tokens takes microseconds either way. So verifying N tokens in one forward pass costs ~40ms (same as verifying 1). If acceptance rate is 75%: ~6 tokens accepted per verify → 6 tokens per 40ms = 150 tokens/sec vs 25 tokens/sec baseline. Practical speedup 2-3× after overhead (draft model time, rejection handling). (c) THE ACCEPTANCE RATE. Depends on draft-target model similarity. For LLaMA-1B / LLaMA-70B: typically 60-80% acceptance. Higher for constrained-output tasks (code, structured), lower for creative writing. Extensions: EAGLE (feature-level auto-regression from target hidden states, higher acceptance ~85%), Medusa (multi-head decoding on target model — no separate draft, learned decoding heads, ~2× speedup), lookahead decoding (Jacobi iteration, no draft model needed but lower speedup ~1.5×). (d) THE VLLM CONFIGURATION. llm = LLM(model="meta-llama/Llama-3-70b", tensor_parallel_size=8, speculative_model="meta-llama/Llama-3-1b", num_speculative_tokens=4). Standard modern config. TensorRT-LLM supports Medusa + EAGLE via built-in kernels. (e) THE FIT HEURISTIC. Speculative decoding: essential for latency-critical interactive workloads (chat interface, code completion). Marginal for batch workloads (throughput-focused — spec adds compute cost per token, batched decode already amortizes memory reads). Not helpful when decode is compute-bound (very short sequences with tiny batch sizes). Standard modern discipline. (f) THE MEASUREMENT. Track TPOT with and without spec; track acceptance rate; alert on rate drops (indicates draft-target divergence). Standard modern discipline. Understanding this — that speculative decoding is specifically effective because decode is memory-bound — is Expert-tier competence. Anti-pattern §05.iii captures the failure to use spec for latency-critical serving.

iv
The FP16 baseline serving (ignoring quantization)
"We\'re serving Llama-70B in FP16 on H100s. Cost is $12 per million tokens. Competitors are quoting $2-3. Where\'s the gap coming from?"

Ignoring quantization leaves 2-4× throughput on the table. Modern H100 serving typically uses FP8 (via Transformer Engine) for 2× throughput at ~1% quality loss; INT4 (via AWQ or GPTQ) for 4× throughput at ~3-5% quality loss. Since decode is memory-bandwidth-bound, throughput scales approximately with 1/precision — the specific mechanism that reduces cost per token. Specifically: (a) THE MEMORY-BANDWIDTH MATH. Decode phase reads full model weights from HBM per token per request. For LLaMA-70B FP16: 140GB weights / 3.35 TB/s HBM = 42ms per token per batch (weights amortized across batch). For FP8: 70GB weights / 3.35 TB/s = 21ms → 2× faster. For INT4: 35GB weights / 3.35 TB/s = 10.5ms → 4× faster. Throughput scales directly with 1/precision because decode is memory-bound. (b) THE FP8 ON H100. H100 Transformer Engine provides native FP8 matmul with automatic precision management (FP16 accumulators, FP8 weights/activations). Configurations: E4M3 for forward (4-bit exponent, 3-bit mantissa — better range), E5M2 for backward gradients. Quality loss ~1% for most models (calibrated). Standard 2024-2025 serving discipline for H100 deployments. vLLM: llm = LLM(model="...", quantization="fp8"). TensorRT-LLM has best FP8 kernel implementation. (c) THE INT4 VIA AWQ/GPTQ. Post-training quantization. GPTQ (Frantar et al. 2022): layer-wise Hessian-based error minimization; 4-bit weights. AWQ (Lin et al. 2023): activation-aware — protects weights corresponding to salient activation channels; typically ~1% quality improvement over GPTQ at 4-bit. Both maintain FP16 activations (weight-only quantization). Quality loss: 2-5% for well-calibrated models, up to 10% for aggressive settings. vLLM: llm = LLM(model="TheBloke/Llama-3-70B-AWQ", quantization="awq"). Standard for memory-constrained deployments. (d) THE KV CACHE QUANTIZATION. Beyond weights: quantize KV cache. FP8 KV cache halves memory footprint → 2× longer contexts or 2× more concurrent requests. INT8 KV cache: similar 2× savings, slight quality loss. Standard 2024+ pattern. vLLM: kv_cache_dtype="fp8". (e) THE COMPOSITION. Combine weight quantization (FP8/INT4) + KV cache quantization (FP8) + PagedAttention + continuous batching + speculative decoding for full modern stack. Cost drops from $10-15/M tokens (FP16 baseline) to $2-5/M tokens (fully optimized). (f) THE QUALITY-COST TRADEOFF. Task-dependent: (i) chat / general QA: FP8 losses undetectable; INT4 losses marginal; (ii) code generation: FP8 fine; INT4 shows some errors on complex code; (iii) math/reasoning: FP8 fine; INT4 shows accuracy drops; (iv) creative writing: subjective, hard to measure. Standard evaluation: benchmarks (MMLU, HumanEval, GSM8K) with quantized vs FP16 baseline. Choose precision based on quality budget + cost target. Standard modern discipline. Understanding this — that quantization is the specific lever for reducing serving cost, and that the tradeoff is quality vs cost — is Expert-tier competence. Anti-pattern §05.iv captures the failure to leverage quantization.

v
The not disaggregating prefill/decode at scale
"We\'re serving 400B MoE model at massive scale. TTFT SLA is 500ms, TPOT SLA is 30ms. But when a long-context user request arrives (32K prompt), it hogs the GPUs for 3 seconds during prefill — all other decodes stall. TTFT SLA violated for everyone."

Prefill and decode have fundamentally different characteristics: prefill is compute-bound with quadratic latency in prompt length; decode is memory-bandwidth-bound with linear per-token latency. At frontier scale (100B+ MoE), separating them across different hardware pools (prefill/decode disaggregation) enables independent SLA management and specialized hardware selection. Standard 2024+ pattern for frontier serving. Specifically: (a) THE MIXED-PHASE PROBLEM. Long-context prefill (32K tokens on 70B model) takes 2-3 seconds on H100. During that time, GPU is fully occupied — other requests\' decode stalls. Continuous batching helps for typical workloads but breaks down when prefill dominates. TTFT SLA for waiting requests violated. Standard failure of mixed-phase serving at scale. (b) THE DISAGGREGATION PATTERN. Separate physical machines: (i) PREFILL POOL — compute-rich H100s, optimized for burst matmul work; process incoming requests, produce KV cache; (ii) DECODE POOL — memory-rich H100s (larger HBM per GPU, higher HBM bandwidth), optimized for continuous decode. Between them: transfer KV cache via network. Router: sends new request to prefill pool, receives KV cache, forwards to decode pool. (c) THE DISTSERVE (Berkeley 2024) + MOONCAKE (Moonshot AI 2024) IMPLEMENTATIONS. DistServe: proves disaggregation improves both TTFT and TPOT at scale — prefill pool sizes independently of decode pool. Mooncake: production Chinese-language LLM (Moonshot) serving; uses RDMA for fast KV cache transfer between prefill and decode nodes; heavy KV cache offloading + prefix caching. Standard 2024-2025 frontier patterns. (d) THE KV TRANSFER COST. Between prefill and decode nodes: transfer full KV cache for request. For LLaMA-70B, 8K prompt: 8000 × 2.6MB = 20GB. At 400 Gb/s InfiniBand (50 GB/s bulk): 400ms transfer time. Significant overhead. Mitigations: (i) use PCIe P2P + RDMA for GPU-to-GPU direct transfer (100 GB/s+); (ii) compress KV cache in transit (INT8/FP8 quantization); (iii) overlap transfer with decode of first tokens; (iv) prefix cache hits avoid transfer entirely (shared prefix served from cache). Standard modern discipline. (e) THE SCHEDULER COMPLEXITY. Prefill/decode disaggregation requires more sophisticated scheduling: (i) prefill queue with priority (long prompts scheduled to avoid HOL blocking); (ii) chunked prefill (split long prompts, interleave with decode); (iii) prefill-decode ratio autoscaling (match load characteristics); (iv) failure recovery (KV cache transfer + decode node crash handling). Standard modern engineering. (f) THE FIT. Disaggregation: essential at 100B+ MoE scale with mixed prompt lengths; overkill for single-model chat serving where prompts are consistent. Standard 2024+ pattern for frontier labs (Anthropic, OpenAI, Google, DeepSeek, Moonshot). vLLM has experimental disaggregation support in 2024+; SGLang provides similar. Standard modern discipline. (g) THE MEASUREMENT. Track TTFT p50/p99 separately from TPOT p50/p99; track KV cache transfer latency; track prefill/decode pool utilization independently. Standard modern discipline. Understanding this — that prefill/decode disaggregation is the specific pattern for frontier-scale serving with mixed workloads — is Expert-tier competence. Anti-pattern §05.v captures the failure to disaggregate at scale.

The composite pattern across all five is that serving failure modes reflect specific engineering gaps in scheduling (static vs continuous), memory management (contiguous vs paged), latency optimization (missing spec decoding), cost optimization (ignored quantization), and phase separation (mixed prefill/decode). Static batching wastes GPU time on slow requests. Contiguous KV wastes memory on fragmentation. No speculative decoding leaves latency unfixed. FP16 baseline serving costs 4× more than optimized. Not disaggregating hurts SLAs at scale. Each has specific fixes: (a) continuous batching (Orca/vLLM iteration-level); (b) PagedAttention (16-token blocks + prefix caching); (c) speculative decoding (small draft + parallel verify); (d) FP8/INT4 quantization (weights + KV); (e) prefill/decode disaggregation at frontier scale. Getting LLM serving right is the specific engineering discipline that turns "our 70B serving is expensive and slow" into "we\'re serving Llama-70B on 8 H100s at 60% GPU utilization with 200ms TTFT, 40 tokens/sec TPOT, and $2/M tokens — competitive production economics."

Every serving regret is static batching wasting GPU time, contiguous KV wasting memory, missing speculative decoding, FP16 baseline paying 4× cost, or mixed prefill/decode violating SLAs at scale. Standard modern discipline avoids all five.
§ 06 — Eight words for the inference serving conversation

Vocabulary,
for the LLM serving case.

The terms that show up in every LLM serving design review, every vLLM config, every latency SLA discussion.

KV Cache
/keɪ vi kæʃ/
Cached K (key) and V (value) tensors per token per layer, avoiding recomputation during autoregressive decode. Size formula: 2 × layers × heads × head_dim × seq × batch × precision. For LLaMA-70B: ~2.6MB per token FP16. Dominates GPU memory at long context.
PagedAttention
/peɪdʒd əˈtɛnʃən/
KV cache management as fixed-size blocks (16 tokens) like OS virtual memory pages. Block table per request maps logical→physical. Near-zero fragmentation, 95%+ efficiency. Foundational vLLM contribution (Kwon et al. SOSP 2023).
Continuous Batching
/kənˈtɪnjuəs ˈbætʃɪŋ/
Iteration-level scheduling: requests join/leave batch dynamically after each forward pass. vs static batching (wait-for-slowest). GPU util 50-70% vs 20-30%. 3-5× throughput. Orca 2022 → vLLM standard.
Speculative Decoding
/ˈspɛkjələtɪv diːˈkoʊdɪŋ/
Small draft model proposes N tokens; large target verifies in single parallel forward pass. Decode is memory-bound → verify cost ≈ single token. 60-80% acceptance → 2-3× latency. EAGLE, Medusa extensions. Standard for chat.
Prefix Caching
/ˈpriːfɪks ˈkæʃɪŋ/
Shared prompt prefixes → shared physical KV blocks, reused across requests. Skip prefill for cached portion. TTFT drops from seconds to milliseconds. 30-80% hit rate typical. SGLang RadixAttention for automatic detection.
TTFT (Time-to-First-Token)
/ˌti ti ɛf ˈti/
Latency from request arrival to first output token. Dominated by prefill cost. Grows O(N²) with prompt length. Standard chat SLA: sub-second. Long-context RAG: seconds acceptable.
TPOT (Time-per-Output-Token)
/ˌti pi oʊ ˈti/
Latency per token during decode (streaming rate). Reciprocal of tokens/sec. Determined by memory bandwidth + batch size. Standard chat SLA: 20-50ms (20-50 tokens/sec, faster than human reading).
Prefill/Decode Disaggregation
/ˈpriːfɪl diːˈkoʊd/
Separate prefill (compute-bound) and decode (memory-bound) across different hardware pools. Independent SLA scaling; specialized hardware. DistServe (Berkeley) + Mooncake (Moonshot) 2024. Standard frontier pattern.
§ 07 — Knowledge check

Five questions.
The inference serving intuition.

Test the LLM serving understanding. Click an answer; explanation drops in instantly.

QUESTION 1 OF 5
Loading question...
Score: 0 / 5
5 / 5

Serving earned.

Perfect. PagedAttention, continuous batching, speculative decoding, quantization, prefill/decode disaggregation — the specific engineering for modern LLM serving infrastructure. Next: M.66.

§ 08 — The recap

Three ideas to
carry forward.

The composite understanding that turns "naive serving at 5% GPU utilization costing $50 per million tokens" into "vLLM-served 70B model at 60% GPU utilization with 200ms TTFT and $2 per million tokens — competitive production economics."

i

Prefill and decode differ fundamentally

Prefill is compute-bound (O(N²) attention over prompt); TTFT dominant. Decode is memory-bandwidth-bound (KV cache reads per token); TPOT dominant. Different optimization strategies for each. Chunked prefill interleaves with decode; disaggregation separates them at frontier scale. Standard modern discipline.

ii

PagedAttention + continuous batching are foundational

PagedAttention manages KV cache as 16-token blocks (near-zero fragmentation, 95%+ efficiency, prefix caching). Continuous batching schedules per iteration (requests join/leave dynamically, 50-70% GPU util). Together: 4-8× more concurrent requests, 3-5× throughput vs naive. vLLM standard. Standard modern discipline.

iii

Speculative decoding + quantization for latency + cost

Speculative decoding: small draft proposes N tokens, target verifies in parallel; 2-3× latency reduction. Quantization: FP8 (H100 TE), INT4 (AWQ/GPTQ) reduces memory-bound decode cost; 2-4× throughput. Compose with PagedAttention + continuous batching for full modern stack. Standard modern discipline.

↓ UP NEXT · PHASE J CONTINUES

M.66 — Observability
at scale.

The next Expert module. Beyond serving — the specific engineering that keeps distributed systems debuggable at scale. Distributed tracing (OpenTelemetry, Jaeger), metrics pipelines (Prometheus, VictoriaMetrics), log aggregation (Loki, Elasticsearch), continuous profiling (Pyroscope, Parca), SLO/SLI discipline, error budgets. How to instrument once and observe everywhere across microservices + ML systems.

Continue to Module 66 →