Deploying autoregressive Large Language Models (LLMs) in production environments presents extreme engineering challenges. Unlike traditional deep learning models where execution is compute-bound, autoregressive text generation operates in two distinct phases:
This guide details the state-of-the-art serving stack: PagedAttention virtual memory management, Continuous Batching (Orca), Speculative Decoding, and modern FP8 / AWQ Quantization methods.
+-----------------------------------------------------------------------------------------------------------------------+
| INFERENCE SERVING OPTIMIZATIONS |
+-----------------------------------------------------------------------------------------------------------------------+
| Technique | Primary Bottleneck Solved | Throughput / Latency Impact| Hardware Requirement |
+------------------------+----------------------------------------+----------------------------+------------------------+
| PagedAttention | KV-cache memory fragmentation | 2x - 4x Concurrency Uplift | Any Modern GPU (CUDA) |
| Continuous Batching | Static batching GPU idle bubbles | 5x - 10x Throughput Uplift | Dynamic scheduler (vLLM)|
| Speculative Decoding | Memory-bandwidth latency bound | 2x - 3x Time-To-First-Tok | Draft Model / Spec Head|
| FP8 / INT4 Quantization| HBM capacity & memory bus saturation | 2x Lower HBM footprint | NVIDIA Ada / Hopper |
| Chunked Prefill | Prefill inter-token latency spikes | Smooth P99 Decode Latency | TensorRT-LLM / vLLM |
+-----------------------------------------------------------------------------------------------------------------------+
In naive serving systems, GPU memory for the KV-cache is allocated contiguously based on the maximum possible sequence length (e.g., 8,192 tokens). Because actual request lengths vary wildly, 60\% - 80\% of GPU memory is wasted on internal and external fragmentation, capping server concurrency.
Inspired by virtual memory paging in operating systems, PagedAttention (Kwon et al., 2023) breaks the KV cache into fixed-size physical blocks (e.g., 16 or 32 tokens):
Logical KV Cache (Sequence 1):
[ Block 0: Tok 0-15 ] -> [ Block 1: Tok 16-31 ] -> [ Block 2: Tok 32-47 ]
| | |
v v v
Physical GPU HBM Blocks:
[ Phys Frame #42 ] [ Phys Frame #108 ] [ Phys Frame #15 ]
Traditional batching waits for an entire batch of requests to reach their termination token (<|endoftext|>). If Request A finishes in 20 tokens while Request B requires 800 tokens, the GPU spends 780 iterations computing padding for Request A.
Static Batching (Massive Waste):
Req A: [ Tok 1 ][ Tok 20 ][ PAD ][ PAD ][ PAD ][ PAD ][ PAD ] ... (Idle)
Req B: [ Tok 1 ][ Tok 20 ][ Tok 100 ][ Tok 400 ][ Tok 800 ] ... (Running)
Continuous Batching (Dynamic Iteration Scheduler):
Iteration t: [ Req A (Tok 1) ][ Req B (Tok 20) ][ Req C (Tok 5) ]
Iteration t+1: [ Req D (New!) ][ Req B (Tok 21) ][ Req C (Tok 6) ] <-- Req A evicts clean!
Autoregressive decoding generates exactly one token per memory-bandwidth pass over the model weights:
Speculative decoding pairs a large Target Model (M_T, e.g., Llama-70B) with a tiny Draft Model (M_D, e.g., Llama-1B):