Chunked Prefill 深度调优平衡首字延迟与生成吞吐的黄金切片步长在大促长文本多轮对话、智能客服知识库检索RAG以及代码辅助等复杂业务场景中推理集群经常面临一种极端的“负载撕裂”一方面大量在线交互请求正在进行逐 Token 的流式生成Decode 阶段对**序列间延迟Inter-Token Latency, ITL**有着严苛的平稳性要求如波动不得超过 30ms另一方面突发的长 Prompt 请求如 4K ~ 16K Tokens不定期涌入如果系统采用传统的整包 Prefill 策略GPU 会在长达 150~300ms 内全量投入该长文本的矩阵乘计算导致所有处于 Decode 阶段的请求发生剧烈的“停顿等待Hiccup”用户端打字机效果严重卡死。**切片预填充Chunked Prefill**技术的出现彻底重塑了大模型调度器的执行范式。它将一个庞大的 Prompt 按照固定步长切分为多个 Chunk与正在运行的 Decode 请求无缝交错执行。本文深入微架构计算开销探讨如何调优切片步长以达成吞吐与平稳性的极致平衡。传统 Prefill 阻塞 vs Chunked Prefill 交错调度对比: 1. 传统无切片调度 (Decode 被动遭长 Prefill 阻断): Step 1 (40ms) : [ Decode 128 seqs ] Step 2 (220ms!) : [ Long Prefill 8192 Tokens 独占 GPU ! 造成严重 ITL 顿挫 ] Step 3 (40ms) : [ Decode 128 seqs (恢复生成) ] 2. Chunked Prefill 调度 (固定 Chunk 步长交错流水): Step 1 (45ms) : [ Decode 128 seqs ] [ Chunk 1 (1024 Tokens) ] Step 2 (46ms) : [ Decode 128 seqs ] [ Chunk 2 (1024 Tokens) ] Step 3 (45ms) : [ Decode 128 seqs ] [ Chunk 3 (1024 Tokens) ] Step 4 (45ms) : [ Decode 128 seqs ] [ Chunk 4 (1024 Tokens) - 完成 Prefill ]切片预填充的微观算力与访存权衡Chunked Prefill 的核心原理在于通过算力与访存的算子融合填补 GPU 的空闲执行单元Decode 序列天然是访存受限Memory-Bound计算小、读取大GPU 的 Tensor Core 计算单元利用率通常低于 25%Prefill 切片是计算密集型Compute-Bound将一个 1024 Tokens 的 Chunk 塞入同一个 Batch 中能够将矩阵乘维度拉大将 Tensor Core 利用率瞬间拉升至 80% 以上步长选择的博弈步长过小如 256矩阵乘计算粒度不够GPU 计算核心未充分预热算子启动Kernel Launch与小 GEMM 的固定开销占比过高导致整体 Prefill 总耗时被拉长步长过大如 4096单步计算时间过长Decode 序列的 ITL 延迟毛刺重新显现切片失去平滑抖动的意义。实测对账矩阵8 卡 H100 SXM5 80GB70B 模型在 512 并发下不同 Chunk Size 对比在 512 并发背景流量下针对 8192 Tokens 长 Prompt 输入对比不同 Chunk Size 的性能指标Chunk 切片步长 (Tokens)单步 Step 平均耗时Decode P99 ITL 抖动8K Prompt 首字耗时 (TTFT)单卡总吞吐 (Tokens/s)GPU 算力利用率 (MFU)未开启切片 (Baseline)35ms (Decode) / 280ms (Prefill)285.0 ms (严重顿挫)280 ms1,82054.2%Chunk Size 25638.5 ms18.2 ms (极度平稳)1,230 ms (过慢)1,98061.5%Chunk Size 51241.0 ms21.5 ms650 ms2,34072.8%Chunk Size 1024 (黄金平衡)44.5 ms25.0 ms (完全达标)360 ms2,680 (47.2%)83.5% (算力吃满)Chunk Size 204858.0 ms48.5 ms290 ms2,71084.2%实测数据显示Chunk Size 1024在保持 P99 ITL 低于 25ms 平稳红线的同时将整机吞吐提升了 47.2%首字延迟360ms亦处于完全可接受范围。切片注意力Chunked Attention状态维护与 KV Cache 写入在实现 Chunked Prefill 时模型并非每次切片都从头计算而是必须维护连续的 KV Cache 链条# Chunked Prefill 调度与分步前向核心逻辑示意 class ChunkedPrefillRunner: def __init__(self, model_runner, chunk_size1024): self.runner model_runner self.chunk_size chunk_size def step_chunked_forward(self, active_decode_reqs, pending_prefill_req): # 1. 提取当前处于 Decode 阶段的 Tokens decode_tokens [req.get_last_token() for req in active_decode_reqs] # 2. 截取新请求的一个 Chunk prefill_chunk_tokens [] is_last_chunk False if pending_prefill_req is not None: prefill_chunk_tokens pending_prefill_req.fetch_next_chunk(self.chunk_size) is_last_chunk pending_prefill_req.is_all_chunks_consumed() # 3. 拼接混合 Batch mixed_batch_tokens decode_tokens prefill_chunk_tokens # 4. 执行混合注意力 Kernel (Decode 读取历史 KV, Chunk 执行 Causal Attention 并追加 KV) output_logits self.runner.execute_mixed_step( mixed_batch_tokens, decode_countlen(decode_tokens), prefill_chunk_sizelen(prefill_chunk_tokens) ) # 5. 更新请求状态 if is_last_chunk: pending_prefill_req.transition_to_decode_phase() return output_logits大促生产级参数配置建议在 vLLM 与 SGLang 生产部署中启用并固化以下参数# vLLM 启用 Chunked Prefill 配置 python3 -m vllm.entrypoints.openai.api_server \ --model /models/Meta-Llama-3-70B-Instruct \ --tensor-parallel-size 8 \ --enable-chunked-prefill true \ --max-num-batched-tokens 8192 \ --max-num-seqs 512 \ --gpu-memory-utilization 0.95# SGLang 启用切片配置 python3 -m sglang.launch_server \ --model-path /models/Meta-Llama-3-70B-Instruct \ --tp 8 \ --chunked-prefill-size 1024 \ --max-running-requests 512 \ --port 30000通过将切片大小精准锁定在 1024 Tokens推理引擎得以在大促高并发的复杂混合场景中彻底消灭长文本请求引发的延迟顿挫让在线生成流如丝般顺滑。