vLLM中的enable-prefix-caching和Chunked-Prefill
1、enable-prefix-caching
在 token 级别,复用已计算过的 prompt 前缀 KV Cache,跳过 Prefill,从而显著降低 TTFT。核心原理就是prompt
在 vLLM中:KV Cache 是强制开启的基础能力,不存在“不开 KV Cache 的推理模式”。
原因有三点:
PagedAttention 架构:vLLM 的核心设计就是围绕 KV Cache,没有 KV Cache,vLLM 就无法进行高效 decode,Decode 阶段必然依赖 KV Cache
每生成一个新 token,都需要历史 K/V,vLLM 默认把 K/V 存在 GPU 显存中,不会有参数可以关闭 KV Cache
我们可以通过参数来控制:KV Cache 的容量上限,KV Cache 的复用策略(prefix caching)
enable-prefix-caching参数控制的是:不同请求之间不会共享 KV Cache,多轮聊天中:每一轮都会重新计算前缀的 KV,TTFT 会更高。
2、Chunked Prefill
Chunked Prefill(分块预填充)是 LLM 推理中的一种调度与批处理优化技术:把超长 Prompt 的 Prefill(KV Cache 计算)切成多个固定大小的小 chunk,分步做、穿插在 Decode 之间执行,而不是一次性把整个 Prompt 算完再开始生成。
它解决的核心痛点:
- 传统方式:长 Prompt 会垄断 GPU 很久,所有人都在等(TTFT 高、Decode 被饿死)
- Chunked Prefill:化整为零、穿插执行、边算边生成,显著降低首包延迟、提升吞吐、缓解“噪声邻居”问题
2.1、背景:LLM 推理的两个阶段
LLM 推理分两阶段,特性完全不同:
-
Prefill(预填充)
- 输入:整个 Prompt(比如 16k tokens)
- 计算:矩阵乘法密集、计算 bound
- 输出:一次性算出全部 KV Cache,准备生成第一个 token
- 问题:长 Prompt 耗时极长、GPU 独占、TTFT 高
-
Decode(解码生成)
- 输入:每次 1 个 token(自回归)
- 计算:访存密集、memory bound
- 输出:逐词生成回答
- 问题:GPU 利用率低、容易被大 Prefill 抢占资源
传统调度:Prefill 整块跑完 → 再 Decode。
长 Prompt 场景下,延迟爆炸、吞吐低下、并发差。
2.2、Chunked Prefill 核心原理:把大 Prefill 切成小块,和 Decode 混跑,不阻塞、少等待。
1)分块(Chunking)
- 设定 chunk_size(如 512/1024/2048 tokens)
- 长 Prompt(如 10,000 tokens)→ 切成 N 个 chunk:
- Chunk1: 0–2047
- Chunk2: 2048–4095
- ……
- 每个 chunk 单独做一次 forward,增量写 KV Cache
2)穿插调度(Interleaving)
调度器每一步(step)做:
- 优先跑 Decode:把所有 pending 的 Decode 请求各跑 1 步(保证生成流畅)
- 剩余 token 预算跑 1 个 Prefill chunk:
- 从某个长 Prompt 取 1 个 chunk 计算
- 写完 KV Cache,进度条往前走
- 循环往复:直到该 Prompt 所有 chunk 跑完 → 正式开始它的 Decode
3)直观对比(传统 vs Chunked)
- 传统(Monolithic Prefill)
[Prefill 10k]████████████████(1s) → [Decode]→→→ TTFT ≈ 1s,期间所有人等 - Chunked Prefill(chunk=2k)
[Chunk1 2k]████(200ms) → 开始生成! [Chunk2 2k]████(200ms) ↘ [Chunk3 2k]████(200ms) 后台继续补全KV [Chunk4 2k]████(200ms) ↗ [Chunk5 2k]████(200ms) TTFT ≈ 200ms,总时间≈1s,Decode 全程不中断
2.3、关键技术细节
1)KV Cache 增量管理
- 每个 chunk 计算后,只写本 chunk 对应的 KV 位置
- 无需重算前面 token,注意力只在本 chunk+历史 KV 上做
- 配合 PagedAttention,显存碎片化低、可支持超长上下文
2)Batch 组成:Hybrid Batch(混合批次)
每个 step 的 batch 通常是:
- N 个 Decode 请求(各 1 token)
- 1 个 Prefill chunk(M tokens)
- 总 token 数 ≤
max_num_batched_tokens(如 2048)
目的:Decode 保体验,Prefill 分块挤空闲,GPU 利用率最大化。
3)调度优先级
- Decode 优先:保证生成流畅、ITL(token 间延迟)稳定
- Prefill chunk 填充剩余预算:公平、不饿死、逐步推进
2.4、核心收益
- TTFT 大幅降低:长 Prompt 首 token 延迟从秒级降到百毫秒级
- GPU 利用率显著提升:计算密集(Prefill)+访存密集(Decode)互补,空闲周期减少
- 缓解噪声邻居问题:大请求不再独占 GPU,小请求不会被饿死
- 支持更长上下文、更高并发:显存峰值降低、单卡可承载更多长会话
- 延迟更平稳:P90/P99 延迟改善,适合生产 SLA
2.5、典型参数(vLLM / TensorRT-LLM)
--chunked-prefill:开关--max-num-batched-tokens 2048:每步最大 token 预算--chunk-size 1024:Prefill 分块大小(常设为 512/1024/2048)
Chunked Prefill = 长 Prompt 分块 + Prefill/Decode 穿插调度 + 增量 KV Cache。
2.6 chunked prefill和之前的PD分离技术是有区分和合作的关系的。
Chunked-Prefill(分块预填):单机 / 单实例内部调度优化,把长 Prompt 切多段 Chunk,同一个 GPU 批次混跑一小块 Prefill + 若干 Decode,解决同卡长 Prefill 独占 GPU、Decode 被阻塞的问题,作用域:单卡 / 同一个推理实例内部vLLM。
PD 分离 (P/D Disaggregation):跨集群 / 跨实例架构隔离:Prefill 集群、Decode 集群物理拆分在不同机器,P 集群算完全部 Prompt 生成完整 KV 后,把全量 KV 通过网络传给 D 集群做后续解码,作用域:跨机器、跨进程。
组合运行逻辑
-
长请求先送入 Prefill 集群:P 节点开启Chunked-Prefill,超长 Prompt 被拆成多个小 Chunk,在 P 机器内部Chunk 分批串行计算、逐步生成分段 KV;
-
两种 KV 交付 D 集群
短 Prompt:P 一次性算完整 KV,整包传给 Decode;
超长 Prompt:P 每算完一个 Chunk 的 KV,以 Chunk 粒度流式分批传输 KV 到 D 集群,不用等全量 Prefill 结束; -
Decode 集群侧:D 收到分段 KV 后拼接完整 KV,正常迭代生成 token;D 节点也可开启轻量 Chunked-Prefill,处理少量短 Prompt 兜底请求。
更多推荐


所有评论(0)