课程 12 · DeepInfer

把调度器下沉到 C++

DeepInfer 是 DeepSeek 的生产推理框架,2026 年 10 月开源。README 说它「最初建立在 vLLM 之上」——但打开源码你会发现,它把 vLLM 最核心的那一层重写了。

约 50 分钟 源码:deepinfer/engine/llm_engine.py · csrc/engine/ 前置:08–11

2026-11-08 源码校正

本页已按本地固定commit修正相关描述。三框架对照 · 带行号的离线证据 · 核查与勘误详情。

1它是什么

维度事实(来自 README 与源码)
定位支撑 DeepSeek 大规模生产服务的推理框架,开源版提供离线推理
支持模型DeepSeek-V4.1-Flash(默认权重 DeepSeek-V4.1-Flash-1017)
硬件NVIDIA SM100(Blackwell)· 华为 Ascend 950
环境Linux · GCC ≥ 13 · Python 3.12 · CUDA 13
许可Apache 2.0
状态README 明确:KV cache 系统、PD 分离、跨副本负载均衡不在本次开源范围
你的 4070 Ti 跑不了它

SM100 是 Blackwell 数据中心卡,AD104(4070 Ti)的 sm_89 不在支持列表里;内核栈(FlashMLA / DeepGEMM)也是为 SM100 编译的。所以 DeepInfer 只能读、不能跑——这反而是好事:你会更专注在设计上。

2和 vLLM 到底是什么关系

README 的致谢写得很清楚:

“DeepInfer was originally built primarily on vLLM, with additional inspiration from SGLang and TensorRT-LLM.”

但「最初建立」不等于「现在还是」。对照代码你会发现三处根本性改动:

vLLM v1DeepInfer
调度器Python(scheduler.py 3869 行)C++(csrc/engine/scheduler.hpp,pybind 暴露)
注意力内核可插拔 backend(FlashAttention / FlashInfer / Triton…)FlashMLA(DeepSeek 自研,MLA 专用)
MoE 通信通用 all-to-allDeepEP + EPLB(专家负载均衡)
投机解码draft model / EAGLE / n-gramDSpark + confidence head(见第 14 课)

3分层:Python 壳,C++ 核

entrypoints/                 # 离线推理入口
  └─ engine/llm_engine.py    # 1029 行:请求生命周期、worker 管理、输出处理
       └─ deepinfer._C.engine
            ├─ Scheduler      # C++:schedule / add_sequence / process_outputs
            ├─ BlockManager   # C++:块分配
            └─ FlopsEstimator # C++:估算 FLOPs,用于当前log_stats指标
       └─ worker/model_runner.py   # 前向 + 采样
       └─ model_executor/models/   # DeepSeek V4 架构、MoE、MTP

_create_scheduler() 里能直接看到这个跨界[llm_engine.py L307]:

def _create_scheduler(self) -> Scheduler:
    return Scheduler(
        self.cache_config.block_size,
        self.block_manager,
        self.state_manager,
        self.tokenizer.eos_token_id,
        PG.cpu_data_parallel_group() if envs.DEEPINFER_ZERO_OVERHEAD_SCHEDULING else PG.data_parallel_group(),
        self.scheduler_config,
        self.yoco_truncate_len,
        self.cache_config.lookahead_tokens,
        ...
        FlopsEstimator(self.model_metadata, yoco_mode=..., keep_tokens=...),
        ...
    )

该固定提交确实向Scheduler传入FlopsEstimator,但calc_flops在已形成调度结果后的log_stats分支调用,用于指标。公开prefill循环按token、对齐、chunk与容量等约束组批。部署QA的内部服务时间/计算预算设计应单独理解,不能当作此公开循环的现行实现。见源码证据。

为什么值得用 C++ 重写调度

这条路径的启示

nano-vllm → vLLM 是「把逻辑写对」;vLLM → DeepInfer 是「把逻辑挪到更低的层」。同一套概念(预算、块、抢占),实现语言从 Python 换到 C++,具体性能收益仍由算法、实现和硬件测量决定。

4内核栈:三件套

vendor/ 下直接内置了五个仓库:DeepEP、DeepGEMM、DeepSelect、FlashMLA(以及 Ascend 版本)。它们分别解决:

项目解决什么对应到前面课程
FlashMLAMLA(多头潜在注意力)的高效 kernel第 10 课的 attention backend
DeepGEMMFP8 矩阵乘,MoE 分组 GEMM——
DeepEPMoE 的 all-to-all 通信(NVLink / RDMA)第 05 课的通信原语
DeepSelectREADME列出的内核依赖;具体职责需查其主源不凭名称推断

这一层是 vLLM 与 DeepInfer 差距最大的地方:vLLM 追求「支持所有硬件与模型」,DeepInfer 只服务一个模型家族 + 两种硬件,所以可以把每个 kernel 都压到极限。

5你能用它做什么

跑不了,但可以:

6练习 A · 对照阅读

打开 vendor/deepinfer/csrc/engine/scheduler.hpp,找出下面三件事分别在哪个方法里(不用读懂实现,找到函数名即可):

  1. 把请求加入等待队列
  2. 一次调度决策
  3. 处理模型输出、更新请求状态
展开:参考答案

① add_sequence;② schedule;③ process_outputs。三个名字与 vLLM 的 add_request / schedule / update_from_output 一一对应——概念没变,只是换了语言和封装。

7练习 B · 闭卷测验

8面试复述卡

「DeepInfer 和 vLLM 有什么不同?」

展开:30 秒版本

「它最初建立在 vLLM 之上,但核心被重写了:调度器和块管理下沉到 C++,注意力用自研 FlashMLA,MoE 通信用 DeepEP 加 EPLB 做专家负载均衡,投机解码是 DSpark 加置信度头。它的取舍是只服务 DeepSeek V4 系列和两种硬件,所以每个 kernel 都能为单一模型极限优化;vLLM 反过来,用可插拔 backend 换通用性。」

贡献练习:先做可复现的映射/状态测试或文档纠错,再与维护者确认范围。README缺失项代表系统集成边界,不代表维护者已承诺接收任何相关PR。