MoE 路由、expert dispatch 与执行侧证据#
这章解决什么问题#
执行模型前面的章节已经把主生成循环、采样、输出尾部、hidden states 和 routed experts 的旁路返回语义讲了出来,但如果系统底层是 MoE 模型,仍然还有一层很关键的执行现实没有被单独说透:
- token 到底怎样被路由到专家
- 专家选择结果怎样在执行层继续传播
- request 级
return_routed_experts和 runtime 级 expert distribution record 为什么是两条不同但相连的链
如果没有这一章,读者虽然知道“可以返回 routed experts”,却仍然很难回答:
- 这些专家 id 从哪里来
- 它们是在执行链哪个位置被捕获
- 为什么同一条执行链上既会有 request-level 旁路返回,又会有全局 recorder
为什么这层值得单独成章#
因为它正好站在执行模型一个很有价值的位置:
- 不是单纯 API surface 的字段
- 也不是单纯维护端点
它真正属于:
- 执行层自己在做路由和 dispatch
- 然后把部分证据向外暴露
这非常像优秀系统书应该强调的一类结构:某个能力先在 runtime 内部自然存在,后来才被做成可返回、可记录、可运维控制的外部能力。
一张图:MoE 路由证据在执行链里如何分叉#
这张图解决的理解障碍是:很多读者会把专家路由看成“模型内部黑盒”,或者反过来只把它当成一个输出字段。源码其实已经把它分成了两条并行证据链。
flowchart LR
Router["moe/topk.py\nselect experts"] --> Dispatch["token dispatcher / moe runner"]
Dispatch --> Main["main forward result"]
Router --> Capture["routed_experts_capturer"]
Router --> Record["expert_distribution recorder"]
Capture --> Proc["scheduler_output_processor_mixin"]
Proc --> Ret["request-level returned experts"]
Record --> Dump["runtime-level record / dump"]图比纯文字多解释的一点是:同一份专家选择结果,在执行层里会自然分出两条下游:
- 面向单请求返回
- 面向全局运行时记录
topk.py 为什么是这条线的第一阅读入口#
如果你想读 MoE 执行语义,最稳的起点不是一头扎进某个 token dispatcher,而是先读:
python/sglang/srt/layers/moe/topk.py
因为这里会把:
topk_weightstopk_ids
真正产出来,而且在 _post_process_topk_ids(...) 之后,会显式调用:
get_global_expert_distribution_recorder().on_select_experts(topk_ids=topk_ids)
这说明专家选择并不是纯局部中间值,而是已经被系统正式当成可观察执行证据。
为什么专家选择一产出就会进入 recorder#
这是一个很重要的设计判断:
- 如果你只在后面某个更晚阶段再去“猜”专家分布,信息已经不再完整
- 在 top-k 选择刚产出时记录,才最接近执行事实
因此这条 recorder 链的本质不是调试附加项,而是执行侧最原生的观测点。
从技术书角度看,这很值得强调,因为它说明上游把专家选择当成正式运行时事实,而不是可有可无的 debug 材料。
routed_experts_capturer.py 在解决什么问题#
如果 recorder 是 runtime-level 的全局记录器,那么:
routed_experts_capturer.py
更像 request-level 的局部证据容器。
它的核心动作是:
- 在 device buffer 上按 layer 捕获
topk_ids - 在 forward 结束后同步到 host buffer
- 再通过
req_to_token_pool和req_pool_idx把某个请求对应的 routed experts 切出来
这非常关键,因为它说明 request-level routed experts 返回并不是“在 API 层重新拼”,而是执行层先主动为后续请求级索引保留了一份缓冲。
为什么 req_to_token_pool 会再次出现#
这恰好回扣了前面调度与内存部分的核心观点:只要某个执行侧证据需要最后回到“单请求视角”,系统往往还是要借:
req_to_token_poolreq_pool_idx
去把 batch 级或 token 级状态重新切回请求级视图。
因此 routed experts 这条线再次证明:
ReqToTokenPool不只是 cache 索引账本- 也是很多执行侧附加证据回到单请求视角时的桥梁
request-level 返回与 runtime-level recorder 的边界#
这两条线虽然都围绕 experts,但职责并不相同。
request-level 路由证据#
它主要对应:
return_routed_expertsreq.routed_expertsscheduler_output_processor_mixin.py- 最终经
TokenizerManager被 base64 编进meta_info
这条线更适合回答:
- 这个请求在这次运行里到底选了哪些专家
runtime-level expert distribution record#
它主要对应:
ExpertDistributionRecorderwith_forward_pass(...)with_current_layer(...)start_record()/stop_record()/dump_record()
这条线更适合回答:
- 在一段时间窗口里,系统整体的专家分布和 dispatch 是否平衡
优秀技术书在这里必须主动把两者拆开。否则读者会把它们都当成“专家路由可视化”,却不知道一个是单请求证据,一个是全局运行时统计。
ExpertDistributionRecorder 为什么不像普通 logger#
eplb/expert_distribution.py 里的 recorder 很值得认真看,因为它不是简单地写日志。它有明确的生命周期动作:
start_record()stop_record()dump_record()
还有明确的上下文入口:
with_current_layer(...)with_forward_pass(...)disable_this_region()
这说明它更像一个:
- 运行中启停的全局采集器
而不是一个永远打开的轻量 logger。
这也正是为什么相关 HTTP / Engine 控制端点必须存在:因为这条 recorder 链本来就被设计成可以在运行中打开和关闭。
token dispatcher 与 expert distribution 为什么天然绑定#
从 deepep.py 等 token dispatcher 路径可以看到,某些更深的 expert dispatch 行为还会继续调:
on_deepep_dispatch_normal(...)on_deepep_dispatch_low_latency(...)
这说明 expert distribution record 不只想知道“选了谁”,还想知道:
- dispatch 到各 rank / expert 的真实分布怎样
这比 request-level routed_experts 又更进一步,说明它关注的是更全局的 dispatch 健康度,而不只是单请求解释性。
为什么这章和 5.16 不重复#
5.16 的重点是:
- hidden states / routed experts 作为旁路返回语义怎样附着进输出对象
这一章的重点是:
- routed experts 这份证据在执行层是怎样被产生、捕获和双向分流的
换句话说:
- 5.16 讲“怎么返回”
- 5.17 讲“为什么有这些返回,以及它们在执行侧从哪里来”
这一层最容易出现的误判#
1. 以为 return_routed_experts 就等于 expert distribution record#
一个偏 request-level,一个偏 runtime-level。
2. 以为 routed experts 是输出阶段后处理时临时算出来的#
真正的捕获点在执行层的 expert 选择与 dispatch 周围。
3. 以为这条链只对调试有意义#
对 MoE 运行时来说,它同样直接关系到 dispatch 平衡、分析与维护。
如果你要顺着源码读这条 MoE 证据链,推荐顺序是什么#
建议按下面顺序:
layers/moe/topk.pylayers/moe/routed_experts_capturer.pyeplb/expert_distribution.pyscheduler_output_processor_mixin.py- HTTP / Engine 上的 expert distribution 控制端点
这样读,你先看到“证据从哪里产生”,再看到“证据怎样被捕获”,最后才看到“证据怎样被对外暴露或导出”。
工程收益与代价#
收益:
- 单请求和全局窗口都能得到专家路由证据
- 执行层不需要为每个消费场景重算专家选择
- MoE 运行时的解释性和可运维性都更强
代价:
- 缓冲和序列化成本会上升
- recorder 生命周期要被控制好,否则开销可能很大
- 用户很容易把 request-level 和 runtime-level 两套证据混为一谈
小结#
这一章真正要补齐的,是执行模型里一条此前还散在多处的 MoE 主线:
- top-k 专家选择先在执行层自然发生
- 然后分出 request-level routed experts 返回链
- 以及 runtime-level expert distribution record 链
到这里,执行模型就不只会讲“生成怎样推进”,也开始更完整地覆盖“MoE 模型的专家路由怎样成为执行证据和运行时控制面的一部分”。
叶王 © 2013-2026 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。