五十五:Sarathi-Chunked Prefill¶
来源:http://mp.weixin.qq.com/s?__biz=MzYyNTk3Njg1NA==&mid=2247484710&idx=1&sn=b7090b17bfd8164c8fae50a9d8bba02e&chksm=f01eb65fc7693f4996f7354d0d3bdababa39885f8cca0c61b192291a18d886b09422016e3626#rd
1. 学习范围¶
本日主题是 Sarathi,重点是 chunked prefill、prefill 和 decode 的协同调度,以及如何减少 decode stall。
本日覆盖: - Sarathi 的定位和问题定义。
-
为什么长 Prefill 会阻塞 Decode。
-
Chunked prefill 的核心思想。
-
Piggyback decoding 的含义。
-
Stall-free schedule 的目标。
-
Chunk size、batch 形态和调度权衡。
-
与 DistServe、vLLM 的区别。
-
常见面试问题和生产化注意事项。
2. Sarathi 的定位¶
Sarathi 是一种 LLM 推理调度方案,核心目标是让长 prompt 的 Prefill 不再长时间独占 GPU,从而减少 Decode 等待和输出卡顿。
它的基本思路不是把 Prefill 和 Decode 完全分离,而是: - 把长 Prefill 切成多个 chunk。
-
在 chunk 之间穿插 Decode。
-
让每轮执行的 batch 更均衡。
-
尽量减少 Decode stall。
Sarathi 关注的是单个 serving 引擎内部的调度效率和 latency-throughput 平衡。
3. 为什么长 Prefill 会阻塞 Decode¶
如果一个请求有很长的 prompt,传统做法可能一次性把整个 Prefill 放进一个大 batch 执行。 问题是: - Prefill 可能持续很长时间。
-
Decode 请求在 batch 边界之外只能等待。
-
流式输出会出现停顿。
-
TTFT 和 TPOT 都可能恶化。
对于在线聊天、RAG 和长文档总结,这种阻塞尤其明显。
4. Sarathi 的核心思想¶
Sarathi 的核心是 chunked prefill:把长 prompt 的 Prefill 切成若干 chunk,每次只处理一部分 token,然后让 Decode 请求 piggyback 在这些 chunk 上一起执行。 可以理解为:
prefill chunk 1 + some decode tokens
prefill chunk 2 + some decode tokens
prefill chunk 3 + some decode tokens
5. Piggyback decoding¶
Piggyback decoding 指 Decode token 不单独开一轮,而是“搭载”在 Prefill chunk 的执行批次中一起跑。 它利用的事实是: - 大 chunk Prefill 已经占用了主要计算路径。
-
少量 Decode token 加进去的边际成本相对较小。
-
一次批次里兼顾两类 token,可减少空泡和切换开销。
因此,Piggyback decoding 的重点不是把 Decode 变成更快的单独任务,而是把它藏进更高效的混合批次中。
6. Stall-free schedule¶
Sarathi 希望构造一种尽量 stall-free 的 schedule,也就是让 Decode 不因长 Prefill 长时间停摆。 所谓 stall-free,并不是没有等待,而是尽量避免: - decode 阶段被长时间完全阻塞。
-
GPU 有效算力被低效空转。
-
batch 形态剧烈震荡。
理想情况下,每一轮都可以持续推进 Prefill 和 Decode。
7. Chunked prefill 的工作方式¶
Chunked prefill 会把一个长 prompt 分成多个连续块。 执行时: - 先处理前一个 chunk。
-
把已完成的中间状态写回 KV cache。
-
再处理下一个 chunk。
-
在 chunk 之间插入活跃请求的 Decode token。
这要求系统正确维护位置编码、注意力掩码和 KV 状态,但不会改变模型结果本身。
8. Chunk size¶
Chunk size 是 Sarathi 的关键参数。 影响包括: - 太大时,仍然会长时间阻塞 Decode。
-
太小时,chunk 切换频繁,调度和 kernel 开销变大。
-
不同 chunk size 会影响吞吐、TTFT 和 TPOT。
-
最优值与模型、硬件和请求分布有关。
chunk size 本质上是在“Prefill 连续性”和“Decode 及时性”之间做平衡。
9. 为什么 chunking 不是简单分片¶
Chunked prefill 不是把 prompt 随便切断。 它必须保证: - attention 依然能看到正确的历史上下文。
-
KV cache 按顺序增长。
-
位置编码一致。
-
中间 chunk 的计算结果可被后续 chunk 继续使用。
所以它是带状态的、严格正确的分段执行,而不是 token 级乱序处理。
10. Sarathi 的调度目标¶
Sarathi 的调度目标通常包括: - 降低 Decode stall。
-
保持较高 GPU 利用率。
-
提升整体吞吐。
-
控制 TTFT。
-
控制 P95/P99 延迟。
它不追求单一指标极致,而是找一个更平衡的批次形态。
11. Prefill 和 Decode 的共存¶
Sarathi 和 DistServe 的思路不同。 Sarathi 的思路是: - Prefill 和 Decode 仍然在同一个执行引擎内共存。
- 通过 chunking 和 piggybacking 让二者更好地穿插。
DistServe 则更偏向: - 把 Prefill 和 Decode 分离到不同资源池。
因此 Sarathi 是“同池协同调度”,DistServe 是“跨池解耦调度”。
12. 为什么混合批次更高效¶
单独跑 Decode 时 batch 往往较小,GPU 可能无法充分利用。 如果把 Prefill chunk 和 Decode 合在一起: - batch 更大。
-
kernel 启动次数更少。
-
计算更连续。
-
Prefill 的大矩阵乘法能够填满 GPU。
但前提是 Decode 不会被过度饿死,所以 chunk size 很关键。
13. 与 continuous batching 的关系¶
Sarathi 可以看作 continuous batching 的一个强化版本,重点是把长 Prefill 拆分并与 Decode 混合。 区别在于: - continuous batching 关注每个 step 动态增删请求。
- Sarathi 进一步关注长 Prefill 如何不拖死 Decode。
因此它更强调“调度结构的形状”。
14. 主要收益¶
Sarathi 可能带来的收益: - 减少 decode stall。
-
改善流式输出稳定性。
-
降低大 prompt 对小请求的干扰。
-
在保持较高吞吐的同时改善延迟分布。
-
更适合混合负载。
这些收益来自调度形态改变,而不是模型结构改变。
15. 主要代价¶
代价包括: - 调度逻辑更复杂。
-
chunk size 需要调优。
-
状态管理更复杂。
-
Prefill 被切块后可能增加调度开销。
-
如果负载不匹配,收益有限。
chunking 不是免费午餐,它把“长阻塞”换成“更复杂的混合调度”。
16. 对 TTFT 的影响¶
Chunked prefill 对 TTFT 的影响要分情况看。 可能改善: - 让 Decode 更快开始。
- 避免长 Prefill 独占 GPU。
也可能恶化: - 如果 chunk 太小或调度策略不佳,Prefill 总完成时间拉长。
- 首 token 相关路径可能变复杂。
因此不能只看局部;要看端到端 SLO。
17. 对 TPOT/ITL 的影响¶
Sarathi 的目标之一是让每个 decode token 的输出间隔更稳定。 它可能: - 减少长 Prefill 导致的 Decode 停顿。
-
改善 token 生成的连贯性。
-
让流式响应更平滑。
但如果 chunk 太大或 batch 太拥挤,Decode 仍可能受到影响。
18. 适用场景¶
Sarathi 更适合: - 长 prompt 与短 prompt 混合的在线服务。
-
需要流式输出的应用。
-
不想拆成独立 Prefill/Decode 集群的单引擎部署。
-
希望在同一个 GPU 池内优化调度的场景。
它尤其适合“长输入会拖慢所有人的服务”这种问题。
19. 与 vLLM 的关系¶
vLLM 解决的是 KV cache 管理和 continuous batching 等问题。Sarathi 则进一步关注如何通过 chunked prefill 和 piggyback decoding 改善混合批次调度。 两者可以看作关注层次不同: - vLLM 更偏推理服务框架与内存管理。
- Sarathi 更偏调度策略。
20. 与 DistServe 的关系¶
DistServe 通过物理分离 Prefill 和 Decode 来减少干扰。 Sarathi 则不分离,而是在同一个引擎里把长 Prefill 切块并和 Decode 交错执行。 所以: - DistServe 是架构级解耦。
- Sarathi 是调度级协同。
它们解决的都是 Prefill/Decode 干扰问题,只是路径不同。
21. 常见失败模式¶
常见失败包括: - chunk size 过大,Decode 仍然卡顿。
-
chunk size 过小,调度开销和 kernel 开销太高。
-
只看平均吞吐,忽略 P99。
-
长输出请求占据过多 decode slots。
-
负载变化后原先最优 chunk size 不再合适。
所以 Sarathi 需要压测驱动调优。
22. 评估方法¶
评估 Sarathi 时应关注: - tokens/s。
-
TTFT。
-
TPOT/ITL。
-
P95/P99 latency。
-
Decode stall 时间。
-
GPU 利用率。
-
不同 chunk size 下的曲线。
最好在长 prompt 占比不同的负载上分别测试。
23. 面试表达要点¶
面试中回答 Sarathi,建议先讲问题: - 长 Prefill 会阻塞 Decode。
- 在线流式服务不能接受长时间停顿。
再讲方法: - 把 Prefill 切成 chunk。
-
在 chunk 间 piggyback Decode。
-
让混合批次更均衡。
最后讲权衡: - 好处是减少 stall、提升延迟体验。
- 代价是调度更复杂、chunk size 需要调优。
24. 核心总结¶
Sarathi 的核心不是把 Prefill 和 Decode 分开,而是让它们在同一个执行引擎内更聪明地混跑。通过 chunked prefill 和 piggyback decoding,它减少了长 prompt 对 Decode 的阻塞,改善了流式输出的稳定性,并在吞吐和延迟之间找到更好的平衡。
25. 参考资料¶
-
SARATHI: Efficient LLM Inference by Piggybacking Decodes with Chunked Prefills: https://arxiv.org/abs/2308.16369
-
Sarathi-Serve GitHub: https://github.com/microsoft/sarathi-serve
-
DistServe: Disaggregating Prefill and Decoding for Goodput-optimized Large Language Model Serving: https://arxiv.org/abs/2401.09670
-
vLLM documentation: https://docs.vllm.ai/
预览时标签不可点<div class="