深入篇 30 / DeepInfer 专项精读 · 2026-11-08

DeepInfer:公开引擎边界与 C++ 调度链

从Python请求跟踪到C++ batch,并区分公开离线引擎与完整线上服务所需组件。

核心阅读 12–18 分钟练习另需 10–20 分钟前置:24、27;原课12

本课只拿下这一件事

从Python请求跟踪到C++ batch,并区分公开离线引擎与完整线上服务所需组件。

请求从Python进入C++的路径。公开版本仍有prompt/decode阶段选择,不照搬vLLM的所有抽象。
公开版本仍有prompt/decode阶段选择,不照搬vLLM的所有抽象。

先明确这份代码能代表什么

本地a679bb8的README把开源包定位为offline inference,列出DeepSeek-V4.1-Flash、NVIDIA SM100和Ascend950支持。它同时说明完整推理服务还需KV cache system、VE/Prefill/Decode disaggregation、DP副本负载均衡。仓库已有本地KV管理与部分hooks,所以不能反过来说“这里没有KV cache”。这节依据固定提交,不声称是所有未来版本的支持范围;你的4070 Ti按这份矩阵不做DeepInfer整栈实跑。

阶段选择与元数据

Python构造Sequence并交给scheduler.add_sequence;C++记录到达时间放入waiting。engine_type有PROMPT、COMPLETION、NORMAL;NORMAL会用DP投票决定本轮做prompt还是decode,某些rank可能需要空prompt step以保持集体操作一致。prefill受token预算、CP对齐、chunk检查点、容量与lookahead等约束。元数据中seqlen_k=cache.num_tokens+total_inflight_tokens+seqlen_q,必须把在途工作算进依赖。

用无异步的小例子建立基线

关闭MTP/ZOS,单DP、CP=1、KV充足。A prompt6、B prompt3、预算16:prefill q=[6,3]、k=[6,3],各采样一token后已提交长度=[7,4]、cache=[6,3]。下一轮decode q=[1,1]、k=[7,4]。再加入ZOS后要明确当前forward、上一轮postprocess、当前sample的顺序,不能把所有计数都归到同一轮。

注释不是实现证据的终点

decode段有一句注释说抢占最短输出请求,但代码按output_len降序排列,先推进尾部较短输出者,不足时取头部较长输出者抢占。例[2,7,5]排序为[7,5,2],先尝试2,必要时抢占7。以可执行语句为准,并在自己的读码记录里标注冲突。

FlopsEstimator确实被传给Scheduler,但此固定提交的calc_flops在已经形成调度结果后的log_stats分支调用,用于指标。部署QA中内部服务的时间/计算预算设计可作为背景,不能直接说公开循环正按FLOPs limit选batch。C++入口显式释放GIL可以减少该段Python约束,但收益必须实测,不能捏造CPU开销占比。

公开README划出的系统边界。缺完整KV服务不等于没有本地KV缓存;支持矩阵以固定提交README为准。
缺完整KV服务不等于没有本地KV缓存;支持矩阵以固定提交README为准。

数值练习:先算,再核对

沿add_request→C++队列→_schedule→metadata→Worker画五个框,每个框写出输入和输出。再用output_len=[2,7,5]手推一次容量不足的victim选择,核对注释与代码。

闭卷检索

不要回看正文。答错后先解释原因,再重新打开这一课。

把结论落到源码

  1. 找到pybind映射和C++add_sequence,说明请求进入哪个容器。
  2. 核对_schedule_decode排序比较函数、l/r索引及victim;再找calc_flops的调用上下文。

以下行号由本地 vendor 文件生成;上游链接固定完整 commit,离线摘录可直接打开。

优先阅读:固定 README边界 与 C++ decode调度。

速查:形状与公式 · 三框架映射 · 术语表 · 复习与实战路线 · 4070 Ti本地实验

记录你此刻能做到什么

只在当前浏览器保存自评;不会自动写成已掌握的 learning record。

随时追问老师。把“第 30 课 + 哪个公式 / 哪个张量 / 哪一行 + 你的推导”发给我,我们可以继续拆到每一步。