读 disaggregation 源码树:prefill、decode 与 transfer backend#
这章解决什么问题#
代码导读前面已经把入口、协议、scheduler、bench_one_batch.py 和 observability 树都拉回主线了,但还有一棵很容易让读者直接迷路的源码树没有被正式导读:python/sglang/srt/disaggregation/。这里面同时有:
prefill.pydecode.pyencode_receiver.pycommon/base/fake/mooncake/nixl/mori/ascend/
如果不把这棵树的阅读顺序讲清楚,它很容易看起来像一堆传输后端杂糅在一起。
为什么这层值得专门成章#
因为 disaggregation 在整本书里已经不是边角料了:
- 调度章节已经写了 bootstrap/prealloc/transfer 队列
- RequestStage 章节已经写了 transfer 相关阶段
- 扩展与调试章节也写了 disaggregation 排障工作流
既然它已经进入主线,那么代码导读也应该给它一条清晰的源码阅读路径。
一张图:这棵树不是横向散开的,而是有层次的#
这张图解决的理解障碍是:很多人第一次看 disaggregation/ 目录时,只能看到很多 backend 名字,却看不出主干层次。
flowchart TD
Root["disaggregation/"] --> Core["prefill.py / decode.py / utils.py"]
Root --> Base["base/ / common/"]
Root --> Backend["fake / mooncake / nixl / mori / ascend"]
Root --> Encode["encode_receiver.py / encode_server.py"]这张图比纯文字多解释的一点是:backend 不是主线的起点,真正更稳的入口是 prefill.py / decode.py 与 base/common。
最稳的阅读顺序是什么#
建议按这个顺序:
- 先读
utils.py里与 disaggregation mode、transfer backend 相关的抽象 - 再读
prefill.py和decode.py - 再读
base/conn.py与common/conn.py - 最后再按需要深入具体 backend,例如
mooncake/conn.py或nixl/conn.py
这样读的好处是:你先建立主线,再读变体,而不是一开始就被某个 backend 的实现噪音淹没。
为什么 prefill.py 和 decode.py 是真正的主线#
因为这里最接近“系统真正要做什么”:
- prefill 侧怎样准备 KV / bootstrap / transfer
- decode 侧怎样接 KV / prealloc / waiting / forward
也就是说,这两个文件回答的是角色分工;而具体 backend 文件回答的是“角色之间怎么传”。
如果一开始就先看 mooncake/conn.py 这种大型 backend 文件,你会更容易先记住 transport 细节,而不是系统角色。
base/ 与 common/ 为什么值得在 backend 之前看#
因为它们定义了 backend 共用的连接、poll、KVArgs、staging 等抽象。更准确地说:
base/更像接口与最小共同模型common/更像 backend 共享实现与 staging 逻辑
这样读的收益很明显:后面看具体 backend 时,你知道哪些是共性,哪些是特性。
为什么 mooncake/conn.py 看起来特别大#
因为它不仅实现 transport,还承接了:
- staging
- bootstrap room
- session 追踪
- transfer queues
- failure / timeout 处理
这说明它不是一个“只负责发数据”的小模块,而是一个更接近端到端后端实现的运行时组件。也正因为这样,本章才更强调不要把它当作第一入口。
encode_receiver.py / encode_server.py 为什么也应该纳入阅读路径#
因为 encoder disaggregation 是这棵树里的另一条正式主线。它解释的不是 decode KV transfer,而是多模态或 encoder 侧的数据转运逻辑。把它们拉进来,代码导读才不会把 disaggregation 误写成“只有 prefill/decode KV cache”的故事。
这层和调度 / 维护章节怎样回扣#
这棵树天然会和前面章节形成强回扣:
- 调度与内存:看队列与 transfer 阶段
- RequestStage:看 bootstrap / transfer 的时间切片
- 扩展与调试:看 placement / transfer / backend 失衡如何落到这棵树
这就是为什么它值得单独导读,而不是只在需要时临时 grep。
这一层最容易出现的误判#
1. 把 backend 文件当成主线入口#
这样最容易丢掉系统角色分工。
2. 以为 disaggregation 只是 transport 层#
实际上它已经影响排队、时间线、请求角色和故障模式。
3. 只盯一个 backend#
你会更难区分共性设计和 backend 特性。
如果你要顺着这棵树真正读进去,先怎么走#
建议按这个顺序:
utils.pyprefill.pydecode.pybase/conn.pycommon/conn.py- 具体 backend(例如
mooncake/conn.py)
小结#
这一章真正想补齐的,是代码导读里对另一棵大树的稳定入口:
- 不是从最大 backend 文件开始
- 而是先从角色主线、再到共享抽象、最后到具体 backend
到这里,代码导读对 disaggregation/ 这棵树也不再是空白。
叶王 © 2013-2026 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。