DeepInfer 深度分析报告:拆解 DeepSeek 的开源推理引擎
分析对象:deepseek-ai/DeepInfer(2026-10-20 开源,Apache 2.0)与 deepseek-ai/deepseek-recipe
分析方法:全量克隆源码(含 6 个算子库子模块,约 19 万行代码)逐模块精读,结合官方部署 QA 文档、技术报告与公开报道交叉验证
报告日期:2026-10-20
0. 摘要:一句话与十个判断
一句话:DeepInfer 不是又一个 vLLM 分叉,而是 DeepSeek 把"怎么用商品化硬件把一个千亿参数 MoE 模型跑成 155 万亿 token/天的生意"这件事的完整工程答案,第一次以可编译、可复现的形式摊在了所有人面前。
通读全部源码与官方文档后,本报告给出十个核心判断:
- 引擎本体约 7 万行 Python/C++,加 6 个算子库子模块约 19 万行,相对 vLLM(50 万+ 行)是刻意保持的精简形态——它没有做通用推理框架,只做 DeepSeek 模型的极致服务。
- TileLang 是这个框架真正的灵魂:绝大多数关键算子(采样、变换、元数据准备)用 TileLang DSL 编写,
cuda/与asc/双后端同构实现,跨平台是"写一次 DSL、编两张卡",而不是两套代码硬凑。 - V4.1 Flash 是"编码器-解码器混合(CED)+ 稀疏索引注意力 + SWA"的组合架构,模型代码(
v4_modules/)揭示了大量未见于技术报告的结构细节:indexer 注意力、C2 压缩边界状态、MXFP8 量化的 SWA KV。 - SWA Bounded Replay(内部代号 YOCO)是全文最精妙的机制:利用滑动窗口注意力的局部性,把缓存未命中的重算成本从"与上下文长度×层数成正比"压到常数 128 token,解码器侧重放更是把总 prefill 计算量近乎砍半。
- 推测解码已进入"按边际收益调度验证算力"的阶段:DSpark 用 Confidence Head 预测每个 draft token 的接受率,动态挑选验证子集,官方数据是验证 token 数省 30%、生产工作点吞吐 +4~7%。
- 确定性是特性而非性能:批不变推理(batch-invariant)与确定性采样被做成一等公民开关,这是给 Agent 时代"同请求同结果"的可复现性需求准备的。
- 开源的是核心引擎,不是完整在线服务:KV 缓存存储、三级负载均衡、E/P/D 分离部署留在内部,但官方 QA 文档把设计细节几乎全盘托出,"代码开源 + 架构白皮书"的组合拳前所未有。
- 昇腾支持是真投入而非门面:DeepEP-Ascend、DeepGEMM-Ascend 子模块合计 3.2 万行,
asc/后端覆盖全部关键 TileLang 算子,构建链完整(CANN 9.2)。 - deepseek-recipe 用 Rust 重写了 API 接入层(约 2.5 万行),解决的是一个被低估的安全与一致性问题:特殊 token 注入防护 + 三协议(Chat Completions/Responses/Messages)统一编解码。
- 这份开源的真实杀伤力在于成本透明:每卡每小时 38 美元收入(谷电价)、155 万亿 token/天单集群吞吐、每 GPU 14.4 TB 逻辑缓存配比——DeepSeek 第一次把推理业务的经营账本连同代码一起公开。
1. 背景与定位:为什么开源的是"中间层"
1.1 大模型竞争的战场转移
大模型的能力边界由模型本身划定,但如何以合理成本向海量用户提供服务,取决于一个长期未被公众了解的中间层:推理框架。训练决定模型"学有所成",推理决定模型"为人所用"。当 Agent 应用让单请求的输入从几百 token 膨胀到几十万 token(代码、文档、历史对话、工具返回不断累积),推理系统的效率就直接决定了 AI 服务的算力成本与电力消耗,进而决定了定价空间和商业模式的可行性。
这个中间层的门槛在于:它不是单机推理程序,而是"内核、通信、调度、缓存管理相互咬合的集群系统"。官方 QA 文档开篇即点明:性能优化必须落在具体部署条件上——用什么芯片、硬件怎么组织、计算怎么分布、算过的结果怎么复用。这四个问题,恰好对应 DeepInfer 开源代码的四大板块。
1.2 DeepSeek 的开源脉络:从算子到引擎的三级跳
DeepInfer 不是孤立事件,而是一条三年期开源路线的收口:
- 2025 年 2 月开源周:FlashMLA(注意力内核)、DeepEP(MoE 专家并行通信库)、DeepGEMM(矩阵乘法内核)、3FS/DualPipe 等基础设施组件,首次公开"训练+推理底座"的积木;
- 2025-2026 年:TileLang 编译工具链、DeepSelect(MoE 路由选择算子)陆续开源;面向昇腾的 DeepGEMM-Ascend 与 DeepEP-Ascend 发布,双平台算子库成形;与北大联合开源 DSpark 投机解码框架(2026 年 6 月);
- 2026 年 10 月 20 日:DeepInfer 引擎本体 + deepseek-recipe 编解码组件开源,把积木组装成机器,并宣布"未来新模型的推理代码也将持续在此更新"。
这条路径的选择颇有深意:先开放最难复制、最无争议的内核(算子),再开放组织算子的引擎。模型权重人人可下,但"怎么把模型跑便宜"的知识一直锁在各大 lab 内部——DeepInfer 开的是这把锁。
1.3 交付边界的诚实声明
README 开宗明义:本次发布提供离线推理及大规模服务所需的核心能力,完整在线服务还需自行补齐三样东西——KV 缓存系统、VE/Prefill/Decode 分离部署、跨副本负载均衡。官方进一步说明:KV 缓存管理与负载均衡组件"与内部基础设施深度耦合,故暂未完全开源",但作为补偿,发布了一份持续更新的部署 QA 文档,把这两块的设计思路白纸黑字写了出来。
这个"代码 + 白皮书"的组合交付,比纯粹的代码开源更聪明:拿不到的代码可以从文档里复刻,拿得到的代码可以直接编译运行。
2. 生产系统全景:155 万亿 token/天是怎么跑出来的
在进入代码之前,必须先建立生产系统的完整图景——DeepInfer 的每一行代码都是为这张架构图服务的。以下内容主要来自官方部署 QA 文档与知乎技术博客。
2.1 三大设计目标
V4.1 Flash 推理系统从设计之初确立了三个目标:
- 支持多厂商加速器:在不同硬件平台运行,并充分发挥各平台性能(对应代码里的双后端体系);
- 围绕商品化硬件组织 prefill 与 decode:普通 8 卡机做 prefill,普通 64–128 卡超节点做 decode(对应代码里的并行配置与拓扑绑定);
- KV 缓存保留 72 小时以上:为上下文复用提供更长窗口,削减命中时的重复 prefill 计算(对应 3FS 存储体系与 SWA Bounded Replay)。
2.2 E/P/D 分离架构
整体形态是 E/P/D(Vision Encoder / Prefill / Decode)分离部署 + 专职存储节点:
- Prefill:EP2–8 / DP2–8,用 HBM 允许的最小 EP/DP;
- Decode:EP64–128 / DP64–128(Wide-EP),用硬件允许的最大 EP/DP;
- VE(视觉编码器):单卡实例即可,建议用更便宜的卡;
- TP 与 CP 暂不使用。
Wide-EP 对 decode 的价值:大幅减少 MoE 专家部分的每步内存搬运,配合好的 EPLB 有效提升 TPS。官方给出 EP8 vs EP64 的对比基准,结论是"扩展域内 Mega MoE 是通用解"——无论 EP 大小或批大小,Mega MoE 都显著快于非融合 MoE。
多模态部署采用 EPD 分离,视觉编码器每卡一个实例,图像按机器粒度路由——prefill 机随机挑一台"每 GPU 一个视觉编码器"的机器,再把图交给该机当前处理 patch 数最少的 GPU,patch 数直接由 (宽/patch_size) × (高/patch_size) 算出。
2.3 存储体系:把 KV 缓存当数据资产管理
KV 缓存按三类介质分级管理,这张表是理解整个系统的钥匙:
| 内容 | 介质 | 副本策略 | 管理方 |
|---|---|---|---|
| 在飞 block KV + 状态 KV | 推理 GPU 显存 | — | Prefill/Decode 实例 |
| SWA KV 缓存 | 本机内存 | 单副本,不进 3FS | Prefill/Decode 实例,跨机命中走 400G VLAN |
| 分页 block KV 缓存 | 专用 3FS 存储集群 | 无应用层副本,靠 3FS 自身冗余 | kvcache-store |
关键设计取舍:block KV(主 KV + indexer K)放专用 3FS 集群而非分层存储,为的是任何 prefill 机器都能命中任意前缀,避免"前缀亲和"与"负载均衡路由"打架;同时让存储节点与计算节点独立扩缩容——计算节点的故障率比存储节点高一个数量级以上,解耦后 KV 缓存不受计算节点故障牵连。
容量与配比的量化数据:每台 KV 缓存存储服务器建议 20 块 30.73 TB SSD,提供至少 40 GB/s 读、5 GB/s 写,容量需保住 24 小时数据;每 GPU 对应约 14.4 TB 逻辑容量(物理需求更大);3FS 用 10+2 纠删码,读请求同时发给 11 个存储节点、凑齐 10 个响应即可解码返回;GC Worker 按节点部署,LRU 策略周期驱逐,磁盘水位以下兜底。TTL 策略按流量分型:Agent 流量 3 天,聊天机器人流量 7 天——聊天流量的命中长尾更重,少量 KV 被反复读,TTL 定 3 天会让聊天流量损失 0.5%–1% 的命中率。
缓存开销的"藏进流水线"三板斧:匹配在 Entrypoint 以 CHECK 角色对本地 kvcache-store 做纯元数据的哈希链前缀匹配(命中长度必须在路由前算出,藏不掉);取 KV由独立进程异步把 KV 从 3FS 搬进主机共享内存;换入(shared memory → HBM)在引擎进程内的线程执行,目标是让逐层 H2D 传输与正向计算重叠——由于 CUDA copy engine 做不好 KV 块的细粒度拷贝,换入用 GDR 实现:RDMA 网卡直接打满 PCIe 带宽,一个 SM 都不占。
2.4 四级负载均衡:用统计和求解器代替启发式
负载均衡是没开源但讲得最细的部分,一共四个均衡器:
- EPLB(专家并行均衡):每 GPU 在负责的专家之外持若干冗余专家(热门专家的副本),按最近 N 步的专家负载统计、每 M 步重分配一次,专家权重在 NVLink
symm_mem内洗牌。Prefill 配置:每 GPU 4 个冗余专家起步、100 步统计窗、每 1000 步重分配,实测moe_lb(最慢 rank / 均值)= 1.074(EP4DP4)/ 1.045(EP2DP2);Decode 配置:每 GPU 1 个冗余专家起步、1000 步统计窗、每 10000 步重分配,EP64 下折算每 GPU 7 个专家(不含共享专家),实测moe_lb= 1.090。 - Prefill 负载均衡:按总上下文长度把请求分成 4 档(<16K / 16–64K / 64–256K / ≥256K),各档引擎数按上一轮算力配额需求占比动态再分配;DP 组之间按剩余算力配额拉活——因为任何引擎都能命中任意前缀,不需要前缀亲和路由;GPU 内部 FIFO 出队,但每次 prefill 步的 chunk 大小不是定值而是解出来的:给每步一个时间预算(
compute_quota_limit,纳秒),用拟合的二次成本模型cost(q, c)(q = 序列 token 数,c = 已算好的前缀长度)预测步耗时,在 32768 token 预算内解出恰好花完剩余时间预算的最大 q。预算本身还会被 DP 组内 all-reduce MIN 进一步压低。 - Decode 负载均衡:在所有 decode 实例的所有 GPU 间均匀路由,同时平衡两个维度——请求数(决定每步批大小)与总 KV 长度(决定注意力成本)。启发式:短请求发给低并发但 KV 总量大的卡,长请求发给 KV 总量小的卡(细节见 DualPath 组内调度算法)。
- VE 负载均衡:机器粒度随机选机 + 机内最小 patch 数选卡。
整体效果:相对完美均衡的离线基准,线上能打到约 80%。
2.5 弹性与容错
- 自动扩缩容:prefill 按"未命中缓存的 token 数"定机器数,decode 按在跑请求数调整,调整限速且有上下界;长尾请求会在大 EP 部署中浪费资源,对策是 decode 引擎(CE)收到停机通知后进入 1 分钟宽限期,未完成请求连同 KV 缓存一次性转发给其他 CE 续跑。
- 冗余配额:两种形态——池内备而不用的整机作为扩容库存;在线实例始终多于计算需求,配额利用率高于 0.8 时禁止缩容。
- 重启耗时:分钟级。容错靠 PE/CE 配额冗余 + 请求级重路由,不靠单引擎重启快。
- EP 故障切换:大 EP 下实例内所有 GPU 是一个通信域,单卡故障即整实例不可用;重启时平台按当前健康 GPU 重新确定 EP 大小,实例"拿到几张卡就用几张"。
2.6 低精度计算版图
QA 文档明确了 FP4 的三个落点:
- 主 KV:per-16、e4m3——类似 NVFP4 但不带全局 scale;
- Indexer KV:per-32、ue8m0,MXFP4;
- MoE 路由专家权重:per-32、ue8m0,MXFP4。
SWA KV 的落盘格式是 MXFP8,528 B/token,每序列落盘 state_size_to_disk = 20 层 × 134 token × 528 B = 1,415,040 B——这个数字后面解释 YOCO 机制时会反复出现。
2.7 经营账本
单集群服务吞吐 155 万亿 token/天,整体收入 每 GPU 小时 38 美元(按谷电价)。官方还给出效率参照:线上系统达到完美均衡离线基准的约 80%;开源版内核与内部版端到端性能差距最多 5%(FlashMLA 开源版缺一个手写 SASS 优化,decode 内核慢 5%–10%)。
这些数字合起来是一份罕见的"推理业务财报":它让全行业第一次可以用真实数据校准"大模型服务到底赚不赚钱、边际成本长什么样"。
3. 全景架构与代码地图
3.1 分层结构:一条清晰的五层栈
从 entrypoints 到硬件,DeepInfer 的代码组织成五层,每层职责单一:
┌─ entrypoints/llm.py ──── LLM 类:用户 API(离线批量接口)
├─ engine/ ──────────────── LlmEngine:调度循环、统计、profiling(1029 行)
│ ↓ 控制面:shm_broadcast 共享内存消息队列
├─ worker/ ──────────────── Worker/ModelRunner:设备侧执行、CUDA Graph、cache_engine
│ ↓
├─ model_executor/ ──────── models/(deepseek.py + v4_modules/)、layers/、
│ input_metadata/、parallel_utils/、eplb/
│ ↓
├─ tilelang_ops/ ────────── 43 个 TileLang 融合算子 × cuda/asc 双后端
└─ vendor/ + csrc/ ──────── FlashMLA/DeepGEMM/DeepEP/DeepSelect + C++ 分配器/调度辅助
横切面上还有三块独立板卡:deep_cluster/(NUMA 探测与绑定,零加速器依赖)、npu_ops/(昇腾 import 补丁层)、structure_output/(xgrammar 结构化输出)。
3.2 规模与构成
| 板块 | 规模 | 构成 |
|---|---|---|
| 引擎本体 | 218 个源文件,约 7 万行 | Python 为主,csrc 约 5,900 行 C++ |
| tilelang_ops | 顶层 37 文件 + 双后端各 43 个 *_tl |
全部 TileLang DSL |
| vendor 子模块 | 约 12.1 万行 | DeepGEMM 3.4 万 / FlashMLA 2.9 万 / DeepGEMM-Ascend 2.0 万 / DeepEP 1.8 万 / DeepEP-Ascend 1.1 万 / DeepSelect 0.8 万 |
| deepseek-recipe | 约 2.5 万行 | Rust 2.2 万 |
3.3 vLLM 血统:诚实的继承清单
README 致谢栏写明"最初主要构建于 vLLM 之上,另受 SGLang 与 TensorRT-LLM 启发"。代码里的痕迹可量化:grep "Derived from vLLM" 命中 22/218 个文件(约 10%)——cache_engine.py、shm_broadcast.py、config、sampler、engine-worker 分层这些骨架承自 vLLM(英文注释),而 deep_cluster/、parallel_utils/(CP 相关)、eval/、examples/sweep/ 是全新代码(中文注释)。两代代码的注释语言分界线,本身就是一份"哪些是遗产、哪些是新写"的地质剖面图。
继承之外的三处深度改造值得点名:一是 engine–worker 通信放弃了 vLLM 的多进程消息总线,全部控制消息走共享内存环形缓冲(详见 §4);二是 KV 布局层按 V4.1 的压缩 KV/SWA/状态槽彻底重写,块内 token 数按压缩比折算而非单一 block_size;三是调度器把批组织下沉到 C++(csrc/engine/pybind_scheduler.cpp)并支持 forward 期间 CPU 预调度(详见 §4)。
3.4 三条设计主线
通读全库,三条主线贯穿所有模块,理解了它们就理解了 DeepInfer 的一切取舍:
- 模型–系统协同设计:不为通用性留抽象。模型结构(V4.1 Flash 的 CED 混合架构)直接决定引擎的缓存布局、调度策略与算子形态,
prepare_v4_decode_metadata.py这类以具体模型命名的文件就是宣言。代价是模型一换代、代码大动,官方以"新模型推理代码持续在 DeepInfer 更新"来兑现这个承诺。 - 算子 DSL 化:性能关键的大算子(GEMM/注意力/通信/TopK)交给 vendor 四库,长尾融合算子统一用 TileLang 编写,一份逻辑编译双平台(详见 §6)。
- 控制面与数据面分离:控制消息走共享内存(低延迟),大张量走 NCCL;批调度走 CPU(可异步),采样决策下沉 GPU(绕开 ZOS 滞后,详见 §7)。凡是"CPU 慢半拍会拖累 GPU"的地方,都做了下沉或预取。
4. 引擎与调度架构:ZOS——"零开销"三个字是认真算过账的
4.1 主循环:一步之内的流水线
对外接口只有离线入口 LLM(entrypoints/llm.py),构造经 LLMEngine.from_engine_args,generate 循环调 step()。LLMEngine.step() 一步之内依次发生:C++ scheduler.schedule() 选批并顺手回收已结束序列 → 有 fork/清零需求时在当前 CUDA stream 上执行 clone_and_zero_states_and_blocks → 进入 worker 的三段式执行——Forward → Post_process(上一步) → Sample(worker.py)——→ GPU 采样完成后两个回调把控制权拉回引擎:pre_sampler_sync_fn(释放延迟释放队列、保存 KV、泵结构化输出匹配器、落账序列)与 post_process_fn(处理输出、用实测 forward/sampler 耗时反哺调度器的估时模型、构建输出对象)。注意第三点:调度器是自校正的——每步的真实耗时都成为下一步选批决策的输入。
所有权管理同样精心:每步输出由 C++ RequestOutputPool 持有、下一步自动回收;SequenceMetadata 用完即还池。调度决策、对象生命周期全部 C++ 化,Python 只在步边界出现。
4.2 ZOS:异步零开销批调度
zos = Zero-Overhead Scheduling(csrc/engine/zos.hpp/cpp + README "zero-overhead batch scheduler" 互证)。目标:CPU 的批组织时间被 GPU 执行完全掩盖,默认开启(PROMPT 引擎除外)。实现不是口号,是三个机制的叠加:
- 后处理挪位:ZOS 下本步只 forward + sample,上一步的 post-process 推迟到本步 forward 完成之后——CPU 的记账工作与 GPU 的前向重叠。
- 时序错位的 GPU 修正:异步调度下,CPU 在 step N+1 组织批次时,step N 的采样结果还没回来。DeepInfer 的解法是让 CPU 带着一步滞后继续调度,由 GPU 端自我修正:C++
prepare_zos_inputs产出 pinned 内存上的remap映射(新批第 i 条接续上批第 j 条,−1 表示新序列)与修正后的序列长度,H2D 非阻塞拷贝,GPU 端update_metadata_for_sampling_zos原地刷新元数据。有重叠时甚至只填充 fresh 行的 input_ids,续写行复用图内常驻张量。 - 同步点拆除:
execute_sample的代码注释用大写写着 "must NOT contain any cuda synchronize"——张量释放经DeferredRelease延到下一步 forward 期间,has_unfinished_requests在 CPU 组上 all_reduce,调度全程 CPU 常驻不碰 GPU 同步。
选批策略本身在 C++ Scheduler::schedule():prefill 逐条装填、可按 chunk 续切;decode 走 LCFS + 按已生成长度降序 + 块不足时抢占输出最短者。最有特色的是 SchedulerOutputs 里每条的 seqlens_q 被显式标注为"异步 varlen 场景下的乐观估计"——连本步 forward 要算多久,都是调度器估算并交 GPU 乐观执行的(与 §7 的置信度调度联动)。
4.3 CUDA Graph 与对象池
CudaGraphRunner 的批次大小取 2 的幂加固定间隔,共享 graph 内存池与 graph stream,ZOS 下输入张量常驻显存、图内原地复用——"源张量在 ZOS 下共享设备张量存储"。图内还埋了事件探针(C++ graph_timer.GraphHandle)供耗时统计。DFlash 有独立的 graph runner。另一处 C++ 化的深水区是 object_pool.hpp:对回收的 py::object 做 placement-new 复用——Python 对象的分配开销也在被优化之列。
4.4 引擎–worker 通信:共享内存控制面 + NCCL 数据面
driver worker(CP rank 0)内,engine 与 worker 同进程,回调直连(EngineCallbacks);非 driver worker 由 daemon 进程拉起(先 expose_all_gpus_to_cuda_driver,set_pdeathsig(SIGKILL) 保证父死子随),进入死循环 start_slave_worker_loop():从共享内存 MessageQueue(shm_broadcast.py,ShmRingBuffer 单写多读环形缓冲)收 (method, kwargs) 反射调用。控制元数据走共享内存,大 CUDA 张量走 NCCL 组通信,显式分流。停机顺序也处理了已知坑:barrier → 关 userbuffer → barrier → 销毁进程组,注释引用 pytorch#115388 解释 NCCL graph 内分配导致的销毁挂死。
4.5 C++ 侧的 KV 准入与抢占
block_manager.hpp(243 行)的空闲块表是侵入式双向链表,下标 0 保留作 null 哨兵;分配三态 OK/LATER/NEVER,NEVER 直接硬报错。序列级状态与 KV 块分离(state_manager 管 state_id),fork 时记录 (旧,新) 克隆对与半写块,GPU 端一次 kernel 完成克隆+清零,unpin 经 DeferredRelease 延后。抢占语义有讲究:ZOS 在途被抢占的序列本步输出作废跳过记账;stop_preempted_request 默认开启,COMPLETION 引擎强制开启——无 prefill 通道的引擎没有重算退路,只能停。
4.6 小结:vLLM 的壳,全新的核
vLLM 的命名骨架(EngineArgs/LLMEngine/Worker/ModelRunner/CudaGraphRunner/ShmRingBuffer)全部保留,但 Python Scheduler/V1 EngineCore 被整体替换为 C++ Scheduler + C++ 对象池 + MTP varlen 乐观选批 + ZOS 重叠。README:140 的一句话说明了产品边界:"This release does not include an online-serving wrapper"——纯离线栈,调度器为吞吐而生,不为在线 SLO 而生。这个定位选择让 ZOS 可以做得激进:离线场景丢一批请求的延迟无关紧要,吞吐才是唯一货币。
5. 模型结构与执行层:V4.1-Flash 的解剖报告
5.1 注意力:MLA 血统 + 稀疏索引器 + SWA 的三合一
主注意力容器 LoraRopeCompressFlashMHAAutoRecomp 自述"MLA + compressed KV + sparse indexer":保留 MLA 血统参数(q_lora_rank/kv_lora_rank),但远不是 vLLM 标准 MLA。三个正交机制叠加:
- KV 压缩:
Compressor产出 norm 后、RoPE 前的压缩 KV 供索引器使用,同时把 RoPE 后的值写入主 KV cache;压缩比仅支持 C1/C2,C2 用state_cache增量压缩,prefill/decode 双 kernel。 - lightning-indexer 式稀疏注意力:
MQAIndexer持有索引头配置与topk_tokens,以relu(q@k)·weights打分,经 DeepSelect topk 在压缩 KV 上选块,另有候选块两阶段筛选。量化策略明确分工:主 KV 用 MXFP8,索引器 Q/K 恒为 FP4(加载日志自证:"Main KV: MXFP8; Indexer QK: FP4")。这是 V4.1 成本模型的关键:注意力不扫全量 KV,索引器只扫压缩 KV、注意力只算 top-k 选中的块。 - SWA 分支:KV 以 e4m3/ue8m0 经融合核(norm+RoPE+Hadamard+cast+store 一步完成)写入环形
swa_cache。
在此之上是 YoCo 截断(forward 在 n_prefill_layer 边界切 consumer/mask 视图)与跨层共享拓扑:SharedLayerTopology 把 share-kv/share-index/share-index-K 三张 layer map 归一化,并校验粒度链 index-topk ⊆ index-K ⊆ KV——共享粒度逐层递减、不能倒挂。
5.2 MoE 与 EPLB:四级专家计数
专家计数语义写在文件头:logical(gate 选择域)→ extra(冗余副本)→ physical(=logical+extra,被 ep_size 整除)→ local(=physical/ep_size)。Gate 断言 sqrtsoftplus 打分 + noaux_tc 选择,Wgate 恒 bf16,带 text/image 两份 FP32 纠偏 bias。权重是 FP4-QAT checkpoint(e2m1 + packed ue8m0 scale,代码断言"Only support FP4-QAT checkpoint"),分组 GEMM 走 psum 布局;可选 mega-MoE 融合路径(gate 也进 tile_kernels)。EP 通信:DeepEP userbuffer 异步 dispatch(async_with_compute_stream=True),combine 与 shared expert 计算重叠。
EPLB 运行时按"同布局分组"为各层建 balancer(层数含 MTP),重排策略 rebalance_experts_global:滑窗 token 统计 → 贪心冗余复制(tokens+arange*1e-4 微扰破平)→ 跨 step 贪心装箱最小化最大 rank 负载。调度节奏:默认 30 步一个周期、首次重排提前到 1/4 周期(冷启动阶段热点最猛)、prefill 可推迟到其结束后立即触发(prefill 中途换专家映射代价太大);到期时 all_reduce 统计 → 重算映射 → 原位 shuffle 权重。
5.3 DFlash:层数与提议数解耦的 draft 模型
V4.1 的 MTP 实体叫 DFlash,设计上"MTP 层的层数和预测个数解耦":num_nextn_predict_layers 个 draft 层,每步提议数由 DEEPINFER_USE_NEXTN_DECODE 控制(默认 5)。两个结构细节值得展开:一是 draft 的输入特征来自主模型的多个目标层(projection: hidden×N → hidden,目标层由 dspark_target_layer_ids 指定)——draft 不只看最后一层 hidden,而是取主干多层特征拼接投影,信息量更大;二是末层带 MarkovGPTHead(一阶马尔可夫 logits 修正)与 AcceptRatePredictor,加上逐 token 的 ConfidenceHead,draft 侧自带一整套自我评估仪表。draft 滑窗与主模型严格一致以共用 SWA cache 布局;解码整体进 CUDA graph replay。
5.4 input_metadata:一份 metadata 的三种视图
InputMetadata 是 dataclass 继承树(V4 子类叠 YoCo/DFlash mixin,VL 再叠多模态字段),三条设计线:紧凑索引前移——C++ prepare 只给紧凑 pivot,forward 开头才展开完整索引(sparse 核要求 128 对齐);prefill/decode 同字段异语义——shape 注释按两态分写;视图化——CP 镜像、YoCo compact/mask、DFlash 定长步幅三种视图都是 copy.copy 浅拷贝,换字段指针而不复制大张量。这是"一处数据、多方消费"在 Python 侧的轻量解法。
5.5 权重装载:从 name-mapping 到物理重排
与 vLLM 分野最大的地方。vLLM 是 name-mapping 逐权重加载;DeepInfer 是三段式:build_model_on_meta 元设备建容器 → 逐参数 materialize 上 GPU(packed FP4 专家层再过 process_moe_weight)→ from_model_cfg 转运行时布局——权重按 kernel 需求物理重排(转置连续化、scale factor 布局变换、FP4 packing),而非改名映射。模型注册表只有一个 arch:DeepseekV41ForCausalLM(VL 是其子类),默认 checkpoint deepseek-ai/DeepSeek-V4.1-Flash-1017。单一模型、深度协同——整个执行层没有为"通用性"留任何余地,这是立场而非缺陷。
5.6 小结
模型结构层的三个关键词:混合(MLA 血统 + 稀疏索引 + SWA + YoCo 四种注意力机制分工覆盖长短上下文)、FP4 原生(权重 FP4-QAT、索引 Q/K FP4、主 KV MXFP8——精度按信息价值分层投放)、确定性(断言密布,凡是可配置的歧路口都收死为单一选择)。它不像一个框架的模型定义,更像一份可执行的结构论文。
6. TileLang 算子层:跨平台的真正答案
6.1 分工:vendor 四库管大头,TileLang 管长尾
TileLang 在 DeepInfer 中不承担主力算子:GEMM 走 DeepGEMM、注意力走 FlashMLA、TopK 走 DeepSelect(DSA indexer 与采样共用,官方称较 torch.topk 快 2–20 倍)、MoE 通信走 DeepEP。TileLang 只写这四者覆盖不了的数据面小算子——全库共 43 个 *_tl 内核,典型如 fused_sample:单 kernel 完成"温度→LSE→top-p/k 过滤→log-softmax→按 seq_seed 采样→MTP 拒绝采样"整条链路。选型逻辑在代码里看得见:这类算子需要块级原子操作、基数直方图、跨核同步等"比 Triton 低的控制力 + 比 CUDA C++ 高的生产力",TileLang 恰好卡在这个位置。
6.2 三层结构与同名契约
跨平台组织是一个三层结构:
- 顶层
tilelang_ops/*.py(约 37 个文件):平台无关的公共 API +*_ref参考实现 + pytest 测试三合一。生产代码只 import 顶层。 ops.py动态分发:按DEEPINFER_ACCELERATOR环境变量决定 importcuda/还是asc/子包,并重导出*_tl符号;启动期一条硬契约断言——符号冲突直接报backend symbol collision。cuda/与asc/双实现:两后端各 43 个*_tl,几乎一一对应(仅 CUDA 多一个离群检测核)。
必须澄清一个容易被 README 误导的认知:cuda/ 与 asc/ 不是同一份 DSL 的两次翻译,而是两种方言。CUDA 侧用标准 tilelang.language + TMA/warp 原语;昇腾侧用 tilelang.ascend.language + SIMD 内建(vcmp/vadd 谓词合并、BRC 广播),手写 UB(统一缓冲)字节预算——如 asc/norm.py 里 num_stages = min(5, (248*1024 - fixed_bytes)//per_stage_bytes) 这类对片上内存的显式管理,还有跨核 flag 同步的注释。跨平台是"同一份算子语义、两套刻意特化的实现",靠同名符号契约和参考实现对拍("沿用参考实现的分块,保持归约顺序一致")来保证数值一致,而不是靠可移植抽象。
6.3 三个关键算子的语义澄清
- compress.py:压缩的是 V4 DSA 索引器的压缩 KV——按
compress_ratio∈{1,2}把 score/latent 压缩并增量更新state_cache,输出 bf16kv_compressed喂给稀疏索引器。这是理解 V4.1 注意力成本模型的关键:索引器不扫全量 KV,只扫压缩后的 KV。 - get_kv_index.py:生成
kv_ca_index(compressed attention 索引),把 (offset, len) 展开成 token 索引表,decode 时经 block_tables 解析分页地址,供稀疏注意力取址,再与 SWA 全量索引拼接。 - prepare_cp_mirror.py:CP 即 context parallel;"mirror" 指每个 CP rank 本地镜像构造压缩 token 的全局视图——单 kernel 产出
mirror_cp_index/reverse_index/ks/ke四组索引,reverse_index 回传给 compress 闭环。CP 在生产中不用于 decode(QA 文档),但离线长上下文场景靠它切分。
6.4 构建体系与昇腾的真实成色
DEEPINFER_ACCELERATOR=nvidia|ascend 贯穿整条构建链:build.sh 分流、Makefile 提供 build-nvidia/build-ascend 双目标、vendor 脚本在昇腾侧自动换用 DeepEP-Ascend/DeepGEMM-Ascend、requirements 双轨(NVIDIA:torch 2.13+cu132;昇腾:torch-npu 2.13.0rc1;公共:tilelang 0.1.15 + tile-kernels 2.1.0——后者是昇腾 TileLang 运行时)。setup.py 按 accelerator 选 NpuExtension/CUDAExtension,产物同名 deepinfer._C,按 <accelerator>-<arch> 分目录存放,双平台产物可以在同一棵目录树共存。
npu_ops/ 则暴露了迁移的中间态:它劫持 builtins.__import__,把 CUDA-only 的 deep_select.topk、flash_attn 调用换成 torch.topk/torch_npu.npu_fusion_attention,代码里留着"待替换"的 TODO。这说明昇腾支持是"全部关键路径已跑通、个别路径还在从通用实现换专用核"的状态——真投入,但未完工。
6.5 小结
工程纪律是这个板块最大的护城河:43 核同名契约 + 启动期冲突断言、缺核时仅在昇腾侧优雅跳过(CUDA 侧视为 bug 直接抛)、顶层 ref + pytest + benchmark 三合一让跨平台数值一致性可验证。短板也很诚实:抽象止于"符号同名"(scale factor dtype CUDA 用 int32、昇腾用 int16,注释自认);asc/fused_transform.py 注释提及内部引擎分支血统(hai-llm/tile_kernels),暴露迁移痕迹;两侧各有独有算子未收敛。结论:这是"一致接口契约 + 两套特化实现"的务实主义,不是教科书式的可移植抽象——但对"把一个模型在两种硬件上都跑快"这个具体目标,它是对的。
7. 投机解码与采样:把验证算力当成稀缺资源来调度
7.1 DSpark 完整链路:从 draft 到接受
推测解码的 draft 模型是 DFlash(models/mtp/dflash.py),即 NextN/MTP 模块:单步 decode_forward 一次产出最多 5 个 draft token(DEEPINFER_USE_NEXTN_DECODE 默认 5)。关键增件是 ConfidenceHead——一个 ReplicatedLinear(n_embed+markov_rank → 1) 小头,docstring 直书"Predict the acceptance probability of each draft token":每个 draft 步独立温度,逐步输出 confidence_rates,随 token 一起写入 MTPPredictInfo。draft 侧有自己的 CUDA Graph runner(DFlashCudaGraphRunner),按 batch-size 集合捕获,padding 用 noise_token_id,replay 后 narrow(req_cnt) 裁掉。
存储上,MTPInfoPool 提供 slot 化的稳定 GPU 存储(pool_rows=(max_num_seqs+1)*nextn,slot 0 留给 padding),经专用 TileLang 核写入 token_ids/logprobs/confidence,跨 step 的写后读依赖由同 stream 保证。
验证与接受准则实现在融合采样核里(fused_sample.py):对每个验证位计算 residual = relu(target_probs − exp(draft_logprobs − penalty)),接受概率 accept = clamp(1 − Σresidual, 0),随机数由 seq_seed 派生的哈希均匀值产生;逐位判定接受,首个拒绝位按 residual 分布重采样,其后该请求所有行作废(前缀接受语义);全接受则续采 fresh token。随后 get_accept_result 施加 golden 覆盖与停止标记。
7.2 置信度调度验证(Confidence-Scheduled Verification)
这是 DSpark 的核心创新,实现在 csrc/engine/mtp_varlen.hpp。要解决两个问题:一是固定长度验证对每个请求都验证全部 5 个 draft,低接受概率的 token 白耗验证算力;二是异步调度下时序错位——schedule(N+1) 执行时 step N 的 confidence 还没算回来。
解法分两层。CPU 层:MTPVarlen::schedule 维护两个接受率队列——算总验证预算(best_bsz)用 N−2 轮的 rates、分配每请求验证长度用 N−1 轮(专门的双计数器处理 ZOS 滞后一轮的时序);把请求按接受率降序排列后,在 decode 延迟曲线(_decode_perf_curve,decode_perf_cache.py 落盘的 batch_size→ms 画像)上最大化 throughput = expected_tokens/(baseline + slope×graph_size + sampler_ms),取最优前缀子集。GPU 层:逐请求长度不由 CPU 定死,而由 TileLang 核 compute_seqlens_q_by_confidence_rates 现算——cumprod 累乘接受率、全局排序取 top-k、融合 remap scatter 直写 pinned buffer。CPU 只定总预算,GPU 算明细,正好绕开"confidence 未回"的时序洞。
官方生产数据给出回报:每步验证 draft 数从 5.00 降到 3.2–4.4(省 30% 验证算力),平均接受长度几乎不变(3.29 vs 3.20),60 并发/rank 吞吐 +5.4%,96 并发 +11%。
7.3 批不变与确定性采样:可复现性作为一等公民
Batch-invariant(仅 NVIDIA)要让同一 prompt 在不同 batch 组合下逐位一致,代码关闭了三处非确定性来源:FlashMLA 的 split-KV(按动态 batch 决定归约分解,是 batch 依赖的根源,关闭后走固定归约树)、DeepGEMM/tile-kernels 的确定性算法模式、MoE 通信的多 SM 分块累加(allow_multiple_reduction=False)。代价明码标价:放弃 split-KV 的长上下文性能、确定性 GEMM 更慢、通信禁多归约。
确定性采样 = 批不变数值底座 + 采样流确定。采样核以 (seq_seed, sample_position) 为种子,经 SplitMix64 散列派生均匀随机数再逆 fp64 CDF——docstring 明言"independent of batch size and row order"。draft 与 target 流用质数偏移分离,验证接受判定用第三条独立流。注意它与 varlen MTP 互斥(README 规定确定性需 DEEPINFER_ENABLE_MTP_VARLEN=0):动态验证长度由调度与 GPU 修正决定,天然不可复现。
7.4 结构化输出:编译与掩码的标准答案,加两处巧思
structure_output/ 基于 xgrammar:JSON schema/regex/EBNF 三种约束分别编译(compile_json_schema(strict_mode=True) 等),带编译缓存(缓存上限注释里标注了 CVE-2025-32381 的 OOM 风险与 kill switch)。运行时在 logits 计算期间异步备好 token bitmask,验证前按 step inplace 应用。两处巧思:一是与 MTP 耦合——MAX_ROLLBACK_TOKENS = nextn+2 为 draft 回滚预留预算,编译完成后用 replay_tokens 逐个 accept_token 恢复 matcher 状态;二是编译异步化,独立线程池 + CPU affinity 的 submit/pump 模式,编译不阻塞调度器。
7.5 小结
这一层的设计哲学可以概括为一句话:验证算力是稀缺资源,要按边际收益分配。从 ConfidenceHead 预测接受率,到延迟曲线上解最优验证子集,再到 GPU 侧现算明细绕开时序洞,全链路都在做同一件事——让每一个花在验证上的 FLOP 都有最高的期望回报。而批不变与确定性采样,则是给 Agent 时代"同请求同结果"的审计需求预付的工程成本。
8. 缓存管理与 SWA Bounded Replay:开源版最精巧的机制
8.1 双管理器:主 KV 与 SWA 状态是两套配额、同批准入
C++ 侧的 block_manager.hpp 是纯分配策略:双向链表空闲块表 + 引用计数钉住语义,分配状态三态 OK/LATER/NEVER(NEVER 直接硬报错)。关键结构在 SequenceManager:尾部持有两个 BlockManager——block_manager(分页 KV 块)与 state_manager(SWA state 槽位),双锁按序获取后 try_allocate_seq 原子地同时检查两者。也就是说,主 KV 与 SWA 状态各自有独立配额,但准入是原子的一票——避免"块够而槽不够"的半准入状态。
Python 侧 cache_engine.py(文件头自注"Derived from vLLM; modified by DeepSeek")是内存布局工程:一整块 uint8 大 buffer 按层切视图——SWA 走 as_strided 环形布局;压缩主 KV 为 FP4/MXFP8 的 [data|scale] 交错(V4.1 每 token 288B/528B);indexer K 独立成 ica_cache。StateBlock 定义每序列定长状态槽:[stored: SWA][dropped: YOCO consumer SWA | 压缩状态]——需要落盘的在前,运行时保留但不落盘的在后;PE→CE 传输两部分都带,落盘只截 state_size_to_disk 前缀。压缩状态不落盘的理由写在注释里:"压缩窗口边界天然对齐 128 落盘粒度,无跨界依赖"。
8.2 YoCo:You Only Cache Once 的架构兑现
模型配置 n_prefill_layer < num_hidden_layers 即启用 YoCo:V4.1 的前 20 层是 producer,全量计算压缩块 KV 只缓存一次;后段 consumer 层的块 KV 不再缓存——由共享 hidden 投影生成(yoco_swa_share_hidden:consumer 层的 kv_swa 从首个 consumer 层的 attn-norm 共享 hidden 投影而来,与 QA 文档"decoder 层的块 KV 由最后 encoder 层 hidden 投影"互相印证)。缓存侧的对应动作是:consumer SWA 层被划入 dropped 区域,直接从持久化预算中删除。"只缓存一次"不是口号,是字节级的布局决策。
8.3 Bounded Replay 的数学:为什么 128/140 个 token 就够
官方定义:重放从位置 s 开始时,位置 i 的 query 只对 max(s, i−127) 到 i 的 key 计算——重算代价是常数,与上下文长度和层数无关。代码里的可见域公式(prepare_tensor_input_v4.cpp 的 yoco_swa_visibility)逐项对应:abs_lo = clamp(max(位置−窗口+1, 矩形下界, 有效下界), 0, 位置+1)。
两个正确性保证:窗口已完整落入保留段的尾部 token,可见域等于精确滑窗,产出与全量计算逐位一致;跨界 token 的产出是近似的,但它们只用于生成末窗 KV、不进前缀缓存,误差不扩散。
数字闭环:decode 未来只需要最近 window_size=128 个 token 的 SWA KV;swa_block_size = window + DEEPINFER_MAX_BACKTRACKING_TOKENS,后者 = nextn+1 = 6(MTP 回退预留)→ 134 = QA 文档的"20 层 × 134 token × 528B"。引擎侧硬约束 keep_tokens ≥ window + backtracking(C++ TORCH_CHECK 强制),保证回退 6 个 token 后滑窗仍完整。这就是 README 里"保留后缀必须覆盖 SWA 窗口加最大回溯长度"的代码出处,也解释了默认值 KEEP_TOKENS=140 ≥ 134 的余量。
命中与重算策略:最大命中长度 L−134;先查块 KV 得 L1(128 的倍数),再看 [L1−128, L1) 区间有无 SWA 缓存——有则命中 L1,无则退一块、重算末 128 token。两种截断模式:mask 产 full 布局的可见性 pivots(全量 query 照算,矩形外整行屏蔽);compact 产 gather 索引,物理删除截断区 query——省下 consumer 层算力,生产默认 compact。官方还附了一个 1057 行的等价性验证器 yoco_equiv.py:L1 秒级比对索引/可见域/存储槽,L2 上真 8 卡 checkpoint 比 logprob + top-K + DFlash confidence——把"近似重放 ≡ 全量计算"做成可执行断言。
Decoder 重放是隐藏的大招:CED 架构下 decoder 层块 KV 由末 encoder 层 hidden 投影而来,精确重建需末 2560 token 过 20 层 decoder;改为每 chunk 只重算末 128 后,官方说法是"几乎减半 prefill 计算"。
8.4 开源版与生产版的接缝
生产独有、开源无实现的部分:kvcache-store 服务、3FS 集群、入口 hash-chain 前缀匹配、KV 异步搬运、GDR 换入、SWA 内存目录 + 400G VLAN 跨机拉回、PE/CE 弹缩与故障转移。但代码留了清晰的接缝:KVSTORE_GRAIN=128 落盘粒度断言 + select_state_slice_to_store/load_state_to_cache 落盘回装钩子(环形布局按 % block_size 重排)、DEEPINFER_PREFILL_STORE_EXTRA_STATE 开关、PE→CE 全量 state 传输参数、kvstore 视角的 block size 公式(inference 大小 + prefill 多存 128 + YoCo extra)——多存一段保证 128 粒度下多轮命中。两处易混淆的文件顺带澄清:decode_perf_cache.py 是 decode 延迟曲线的磁盘缓存(供调度画像),refresh_offline_decode_ppl.py 是 PPL 测试黄金文件的刷新器,都与 KV 缓存管理无关。
8.5 小结
SWA Bounded Replay 是整份开源中算法与工程咬合最紧的部件:注意力局部性(数学)→ YoCo 层切分(架构)→ 状态槽分区(布局)→ 128 粒度落盘(存储协议)→ 等价性验证器(质量保障),五层环环相扣。它把"缓存未命中"这个在线服务的头号成本项,从与上下文长度成正比压到常数——对一个 72 小时缓存留存、Agent 长上下文为主的业务,这一项就值得单独开会源公告。
9. 集群、硬件与工程质量:被低估的 deep_cluster 与诚实的基准
9.1 deep_cluster:社区框架普遍缺失的那一层
deep_cluster/ 是独立于引擎的集群硬件包,回答"进程该绑哪个 NUMA、用哪张网卡"。设计上刻意零加速器运行时依赖:GPU 发现走 /proc/driver/nvidia/gpus 拿 PCI bus 再读 sysfs 的 numa_node,NVML 用 ctypes 加载全程不建 CUDA context;昇腾侧正则解析 /sys/class/ubcore 的 udma 条目、扫 /dev/davinci* 设备节点,NUMA 拿不准时降级解析 npu-smi 拓扑再与 lscpu 求交,最后还有经验公式兜底。绑定动作是硬核的:ctypes 调 libnuma 同时设 CPU 亲和与 set_mempolicy(MPOL_BIND) 内存落位,避免 HBM 搬运跨 NUMA;which_numa 同时支持按 GPU 序号或按 mlx5_* IB 卡定位——部署假设直白写着"超节点内 GPU 与 RDMA 网卡 NUMA 成对"。这套逻辑真正被引擎调用(worker 初始化时 _bind_numa(local_rank),失败时警告"内存落位退化为 first-touch"),且通过 _root/_environ 注入做到无 GPU 单测。对比社区框架普遍把 NUMA 绑定丢给运维脚本,这是一层被低估的完成度。
9.2 控制面与并行拓扑
engine→worker 的控制平面是共享内存环形缓冲(shm_broadcast.py,标注 Derived from vLLM):driver worker 的 engine 进程把 (method, kwargs) 经 CPU 组广播,slave worker 死循环收消息反射调用——调度元数据走共享内存,大张量才走 NCCL,显式分流。清理顺序都有讲究:停机时 barrier→关 userbuffer→barrier→再销毁进程组,注释引用 pytorch#115388 解释 NCCL 在 CUDA graph 内分配的依赖会导致销毁挂死。
并行配置三层:ParallelConfig 校验整除关系(含 V4.1 多模态记忆模块专属的 engram_parallel_size 组);进程组用 einops 表达式声明 rank 布局(DP "(replica dp cp) -> (replica cp) dp"、EP "(edp ep) -> edp ep"),可读性远超手工索引算术;EPLB 策略做物理↔逻辑专家映射,配合 DeepEP V2.5 的冗余专家 NVLink 权重预热。注意批不变模式与专家重排互斥(关多归约的代价)。
9.3 评测与基准:证明"跑的就是官方协议"
eval/ 的定位不是刷榜而是自证:AIME 2026(30 题 × 32 采样)、GPQA Diamond(198 × 8)、HLE(2500 题,2158 文本 + 342 图 × 1),参考值 99.9%/93.4%/42.6%,README 明说这是"部署配置正确性的 sanity check"。工程上两阶段解耦——generation 批量落盘原始输出,scoring 可换 judge 重打分不重跑推理;三个基准默认走 LLM judge,judge prompt 是详尽的确定性评分规则(代数/数值/集合/单位等价);HLE 强制走官方协议(</think> 前缀不截断送审),拒绝 rule 判分时要求给出完整理由。言下之意很清楚:开源框架跑的数字,与产出模型报告的那套内部评测协议是同一套。
examples/sweep/run_sweep.sh 复现 README 的 Pareto 图(prefill 扫 batch 4096–65536、decode 扫请求数 8–256),方法论相当专业:合成前缀先 prefill 出 KV 再 fork 整批请求(断言缓存命中数相等);稳态测量窗剔除负载均衡 flush 步(只统计 flush-clean 区间,配合强制负载均衡开关保证窗内有真值);指标落原始量、换算留给消费方;每点换 MASTER_PORT 躲 TCPStore TIME_WAIT。这种"测量卫生学"让性能数字可信。
9.4 工程质量总评
- 测试:19 个测试文件对 218 个源文件,数量少但质量好——环境变量 autouse 快照恢复、硬件层无 GPU 单测、EPLB 策验结构自反不变量、共享内存覆盖 double-
__del__。短板:调度器/引擎层零集成测试,关键路径靠断言兜底。 - 类型与门禁:全量现代类型注解,但只配 ruff、无 mypy/pyright,无类型门禁。
- 错误处理:fail-loud 风格统一,大量中文报错把后果说清("内存落位退化可能导致 H2D 性能下降")。
- 最欠:几十个
DEEPINFER_*环境变量旋钮散布各处、无集中文档与校验,可发现性差;64 卡 decode 这类大集群行为只能靠 benchmark 脚本自证。
综合评价:这是一个"内核精致、外围诚实"的代码库——核心路径(调度、采样、缓存、算子)达到生产级完成度,配套(测试门禁、配置文档)保持着"内部工具刚整理出来见人"的朴素。
10. 生态位分析:DeepInfer 在推理框架版图中的位置
10.1 与三大主流框架的对照
| 维度 | vLLM | SGLang | TensorRT-LLM | DeepInfer |
|---|---|---|---|---|
| 定位 | 通用推理引擎 | 通用+前端编程 | NVIDIA 极致性能 | DeepSeek 模型极致服务 |
| 模型广度 | 数百个 | 数十个 | 广泛 | 当前 1 个(V4.1 Flash) |
| 硬件 | 多厂商 | 多厂商 | NVIDIA 专属 | NVIDIA SM100 + 昇腾 950 |
| 代码规模 | 50 万+ 行 | 30 万+ 行 | 30 万+ 行 | 引擎 7 万行 |
| 血统 | 原生 | 基于 vLLM 演化 | 独立栈 | 基于 vLLM 演化 |
三点值得展开。第一,"通用性"是刻意放弃的。vLLM 支持数百模型,代价是每个模型都要在通用抽象下折损性能;DeepInfer 只支持一个模型家族,因此可以把批调度、元数据布局、算子融合全部按 V4.1 Flash 的形状硬编码到极致——prepare_v4_decode_metadata.py 这类以具体模型命名的文件就是明证。这不是框架的退步,而是"模型-系统协同设计"(model-system co-design)路线对"通用框架"路线的胜利宣言:模型结构变化时,推理代码跟着一起重写(官方承诺新模型推理代码持续在 DeepInfer 更新),而不是迁就旧抽象。
第二,跨平台打法不同。TensorRT-LLM 选择 NVIDIA 深度绑定,vLLM/SGLang 的多硬件靠社区适配层。DeepInfer 的答案是 TileLang:用 Python DSL 写算子,一份逻辑编译出 CUDA 与 Ascend 两套内核,抽象成本被压缩在 DSL 一层。这条路此前只有昇腾生态自己走过,如今被 DeepSeek 用在自家框架上反向验证。
第三,开源的完整度不同。vLLM/SGLang 开源的是"框架",DeepInfer 开源的是"框架 + 内核 + 部署知识(QA 文档)+ 经营数据",唯独扣住了与内部基础设施耦合的存储与调度组件——这是一种"开放核心"(open core)策略,但配合白皮书式的文档,实际扩散的知识量远超一般开源。
10.2 对不同人群的价值
- 企业部署者:拿到的是可编译、可复现的 V4.1 Flash 私有化部署基座。配合 deepseek-recipe,第三方部署能获得与官方 API 完全一致的编解码行为——这对"我把应用从官方 API 迁到自建集群,输出必须逐字节一致"的需求(Agent 应用尤其敏感)是硬保障。
- 推理系统工程师:这是近年最完整的一份"生产级推理系统教材"。从异步调度、CUDA Graph 管理到投机解码验证调度,每个模块都有真实生产流量的背书,而非论文原型的 toy implementation。
- 国产算力生态:昇腾后端覆盖全部关键算子路径,等于一份"如何在昇腾上跑 SOTA MoE 推理"的参考实现,其示范意义超出 DeepInfer 本身。
- 竞品与研究者:38 美元/卡/小时的收入数据、80% 的均衡效率、5% 的开源性能差距,给行业提供了第一批可校准的基准点。
10.3 局限与风险
客观地说,当前版本有四条明确边界:
- 功能边界:无 KV 缓存存储系统、无三级负载均衡、无 VE/P/D 分离部署编排。拿它搭"离线推理"简单,搭"在线服务"需要相当的自研投入——官方把这部分定义为留给社区的作业。
- 模型边界:只支持 V4.1 Flash。想在 DeepInfer 上跑 Llama 或 Qwen 的团队可以死心,这不是它的设计目标。
- 硬件边界:NVIDIA 侧仅支持 SM100(B200/B200 Max 一代),没有 Hopper 支持;昇腾侧要求 950。消费级与上一代数据中心卡均不在射程内,这会显著抬高社区复现门槛。
- 单点依赖:模型-系统协同设计是双刃剑——模型结构一换,代码就要大动。"新模型推理代码持续开源"的承诺意味着这条赛道会一直跟着 DeepSeek 的发版节奏走。
11. 行业影响:这份开源真正改变什么
11.1 推理成本军备竞赛公开化
DeepInfer 开源之前,头部 lab 之间的推理优化是暗战:各家都知道别人有高招,但看不到代码。现在牌桌上的牌翻开了——投机解码怎么调度验证、缓存未命中怎么止损、负载怎么配平,全部有据可查。可以预期的是:开源推理框架(vLLM/SGLang)社区会在数周内吸收其中可移植的设计(异步调度模式、置信度调度验证、SWA 重放),全行业推理成本的斜率将被压低一档。
11.2 "模型开源"的内涵被重新定义
2025 年开源周开放的是部件,2026 年 10 月开放的是整机图纸加经营数据。当"开源一个模型"变成"开源模型 + 引擎 + 算子 + 编解码器 + 部署白皮书 + 单位经济模型",其他开源模型厂商的"开放"标准被被动抬高了。这对被迫跟随的厂商是压力,对使用者和整个生态是纯收益。
11.3 昇腾生态的成人礼
DeepEP-Ascend、DeepGEMM-Ascend、asc/ 全套 TileLang 后端、CANN 9.2 构建链——一个 SOTA 级 MoE 模型的完整推理栈在昇腾上跑通并开源,这是国产算力软件生态第一次以"对等平台"而非"移植目标"的身份出现在顶级开源项目里。QA 文档里"支持多厂商加速器"位列三大设计目标之首,不是姿态,是架构事实。
11.4 普惠叙事的工程支撑
「为善与众行之,为巧与众能之」——公告里的这句话常被当作姿态解读,但配上代码看是实指:让智能以更低价格触达更广人群的具体路径,就是把"推理"这个成本大头的技术门槛打下来。当更多团队能用商品化硬件(8 卡机 + 64–128 卡超节点)高效部署大模型,推理服务的供给曲线会整体右移,价格随之下降。开源在这里不是慈善,是通过扩大生态位来降低自身供应链成本的商业策略——但客观效果上,它是普惠的。
12. 附录
12.1 仓库规模速览
| 板块 | 规模 | 备注 |
|---|---|---|
| 引擎本体(deepinfer/ + deep_cluster/ + csrc/ 等) | 348 个 tracked 文件,约 7 万行 | Python 为主,csrc 约 5,900 行 C++ |
| 其中 deepinfer/ 包 | 46,353 行 Python | 218 个源文件 |
| vendor 子模块合计 | 约 12.1 万行 | DeepGEMM 3.4 万、FlashMLA 2.9 万、DeepGEMM-Ascend 2.0 万、DeepEP 1.8 万、DeepEP-Ascend 1.1 万、DeepSelect 0.8 万 |
| deepseek-recipe | 约 2.5 万行 | Rust 2.2 万(tokenizer + 会话协议) |
| 测试 | 19 个测试文件 | 无集成测试;调度/引擎层靠断言兜底 |
| 文档 | doc/inference_deployment_qa.md 312 行 | 本报告 §2 生产数字的主要来源 |
浅克隆 footprint:主仓库 8.5 MB,含 6 个 submodule 约 21 MB(含 .git 共 638 MB)。
12.2 关键环境变量速查(按主题)
| 主题 | 变量 | 作用 |
|---|---|---|
| 平台 | DEEPINFER_ACCELERATOR |
nvidia / ascend,贯穿构建与运行时 |
| 投机解码 | DEEPINFER_ENABLE_MTP_VARLEN |
1 = 置信度调度变长验证 |
DEEPINFER_USE_NEXTN_DECODE |
最大 draft 长度,默认 5 | |
| YoCo | DEEPINFER_YOCO_PREFILL_TRUNCATION_MODE |
off / mask / compact(生产用 compact) |
DEEPINFER_YOCO_PREFILL_KEEP_TOKENS |
默认 140(≥ 窗口 128 + 回溯 6 + 余量) | |
| 确定性 | DEEPINFER_BATCH_INVARIANT |
1 = 批不变(仅 NVIDIA) |
| 采样 | SamplingParams.seq_seed |
确定性采样的种子(需关闭 varlen) |
| 结构化输出 | DEEPINFER_XGRAMMAR_DISABLE_CACHE / DEEPINFER_XGRAMMAR_CACHE_LIMIT_BYTES |
编译缓存开关与上限 |
| 调度 | DEEPINFER_ZERO_OVERHEAD_SCHEDULING |
ZOS 开关(NORMAL/COMPLETION 默认开) |
DEEPINFER_CUDAGRAPH_BATCH_SIZE_INTERVAL |
graph 批间隔(含 DFLASH 版) | |
| EPLB | DEEPINFER_EXPERT_REARRANGEMENT_STEP_INTERVAL |
重排周期,首排提前 1/4 |
| 缓存 | DEEPINFER_PREFILL_STORE_EXTRA_STATE |
落盘额外 state(kvstore 接缝) |
| 杂项 | DEEPINFER_ENFORCE_EAGER / DEEPINFER_DFLASH_ENFORCE_EAGER |
禁 graph |
DEEPINFER_JIT_CACHE_DIR 族 |
TileLang/DeepGEMM/DeepEP JIT 缓存目录 |
环境变量是这份开源最大的可用性欠账:几十个旋钮散布在 environ.py 与各模块,无集中文档、无校验清单,只能读代码发现。
12.3 方法与证据说明
本报告的结论来自三层证据:① 直接阅读仓库源码(所有 file:line 引用均为 2026-10-20 浅克隆实测);② 官方部署 QA 文档 doc/inference_deployment_qa.md 的生产数字(155T tokens/日、$38/GPU-hour、E/P/D 拓扑、DSpark 收益等);③ 六路并行深读交叉验证——引擎调度、模型执行、TileLang 跨平台、投机解码与采样、缓存与 YoCo、集群评测与工程质量各自独立成篇后汇编。未能覆盖的部分如实声明:cache_engine.py 的部分分支、vendor 四库内部实现、recipe 的 Rust 细节未逐行审读。
12.4 参考资料
- 仓库:https://github.com/deepseek-ai/DeepInfer
- 默认 checkpoint:https://huggingface.co/deepseek-ai/DeepSeek-V4.1-Flash-1017
- 官方技术说明(知乎):https://zhuanlan.zhihu.com/p/2095560295930508953
- 官方公众号长文:https://mp.weixin.qq.com/s/X41mKH4Ds-VXUAnK6M8Eww
- 媒体报道:36 氪、IT 之家、C114、搜狐科技对开源事件与商业数据的综合报道
本报告由深度代码审读生成,完成后归档至 Knowly 与 ima 知识库。数据截止 2026-10-20。