In the LLM serving pipeline, what is the difference between the prefill phase and the decode phase?
- Prefill processes all input tokens in parallel and is compute-bound, while decode generates one token at a time and is memory-bandwidth-bound
- Prefill loads the model weights into GPU memory and is I/O-bound, while decode runs the forward pass and is compute-bound for every generated token
- Prefill tokenizes the input string into token IDs using the vocabulary, while decode converts output token IDs back into readable text
- Prefill allocates GPU memory for the entire output sequence up front, while decode fills that memory one token at a time during generation
Why
The serving pipeline has two main computational phases. Prefill processes the entire input prompt in a single batched forward pass, running matrix multiplications across all input tokens in parallel, which saturates GPU tensor cores and makes it compute-bound. Decode then generates output tokens one at a time autoregressively, where each step reads the full model weights and the growing KV cache from GPU high-bandwidth memory but performs relatively little arithmetic per byte loaded, making it memory-bandwidth-bound. Loading model weights happens before serving begins, not during prefill. Tokenization and detokenization are separate CPU-bound stages that take less than a millisecond and are never the bottleneck. GPU memory for the KV cache is allocated before prefill, not as a pre-allocated output buffer. Understanding this distinction matters because optimizations target different phases: prefix caching and prompt compression reduce prefill time, while quantization and batching improve decode throughput. On an A100 with Llama 3 8B, prefill runs at roughly 14,000 tokens per second while decode produces about 100 tokens per second per sequence.