Skip to content
Posts en inglés. Usá el traductor del navegador para leerlos en tu idioma.
Featured

Optimize vLLM Performance: A Guide to Reducing LLM Tail Latency

Yammbo
· 4 min read
llm inference continuous batching chunked prefill p99 latency tail latency
Optimize vLLM Performance: A Guide to Reducing LLM Tail Latency

You've meticulously benchmarked your Large Language Model (LLM), and the initial metrics look promising: low p50 latency and high tokens per second. Yet, once real-world traffic hits, the p99 latency skyrockets, often becoming five to ten times worse than your controlled tests. This discrepancy often stems from the difference between clean benchmark conditions and the unpredictable nature of production loads, which include bursts of requests, a mix of short and very long prompts, and shared GPU resources. The primary culprit for this tail latency explosion is often a long prefill operation blocking concurrent token generation (decodes). This tutorial will walk you through the underlying causes and demonstrate how strategies like chunked prefill and intelligent scheduling can bring your LLM's tail latency back under control.

Understanding LLM Inference Phases: Prefill and Decode

To effectively optimize LLM inference, it's crucial to distinguish between the two primary phases of token generation: prefill and decode. Each phase presents unique computational challenges and resource demands.

Prefill Phase: Processing the Prompt

The prefill phase is responsible for processing the entire input prompt. This involves a single, forward pass through the model to establish the initial hidden states and Key-Value (KV) cache entries for the prompt. It is typically a compute-bound operation, meaning its performance is primarily limited by the raw computational power of the GPU, involving large matrix multiplications. A longer prompt directly translates to a more extensive and computationally intensive prefill. The prefill phase is often the largest contributor to the Time to First Token (TTFT), which is the delay before the first generated token is returned to the user. However, TTFT is also influenced by other factors like queue waiting times, scheduler overhead, and network round trips.

Decode Phase: Generating Subsequent Tokens

Following the prefill, the decode phase begins, generating one token at a time. This phase is memory-bandwidth-bound. Instead of heavy computation, it primarily involves shuffling weights and KV cache blocks in and out of GPU memory. The goal during decoding is to maintain low Inter-Token Latency (ITL) to ensure a smooth, continuous stream of generated tokens. Each decode step is relatively quick but happens frequently, making efficient memory access critical.

The fundamental problem arises when a long, compute-heavy prefill operation monopolizes the GPU, forcing all ongoing decode operations to pause. This pause, even if brief, significantly contributes to the p99 latency, causing a noticeable stutter in the user experience.

The Limits of Continuous Batching for Tail Latency

Continuous batching revolutionized LLM serving by moving beyond static, request-level batching. In static batching, requests were grouped, processed together, and no request could complete until the slowest one in the batch finished, leading to wasted GPU cycles and increased latency for faster requests.

Continuous batching, inspired by concepts like those in the Orca paper, addresses these inefficiencies by allowing the scheduler to dynamically re-evaluate the batch before every single step. This approach offers two key advantages:

  1. Immediate Completion: A request that finishes its generation can exit the batch immediately, freeing up its allocated memory and GPU resources instead of waiting for other slower requests to complete.
  2. Dynamic Admission: New waiting requests can be pulled into the batch as soon as there's available capacity, rather than being held in a queue until the entire current batch is drained.

While continuous batching significantly improves overall GPU utilization and average latency (p50), it doesn't fully resolve the tail latency (p99) issue, particularly when dealing with mixed workloads of varying prompt lengths. The critical gap is that continuous batching still tends to treat the prefill phase of a long prompt as one atomic, uninterruptible unit. When such a long prefill enters the batch, it can consume a significant amount of GPU time, causing all currently decoding sequences to stall. Users who were receiving a smooth stream of tokens suddenly experience a noticeable pause, directly contributing to the elevated p99 latency.

Implementing Chunked Prefill to Mitigate Stalls

The core idea behind chunked prefill is to break down a single, large prefill operation into multiple smaller, manageable