📋 目录
- 一、DSpark 到底做了什么
- 二、那张被讲反的三档数据
- 三、SWA 的 128 与 140:两个都对,指的不是一回事
- 四、MoE 负载均衡:80% 和 9% 这两个数
- 五、异步调度:zero-overhead 是个修辞
- 六、这些数字怎么用
- 七、结语
一、DSpark 到底做了什么
先说清这项技术本身,否则后面的数字没有参照系。
投机解码(speculative decoding)的思路是:用一个小的"草稿模型"一次猜出好几个 token,再让主模型一次性验证这批猜测。猜对的 token 全部采纳,猜错的丢弃重算。因为验证是并行做的,而生成是逐字的,中间省下的时间就是收益。
DeepSeek 在 DeepInfer 里把这套东西叫 DSpark,特点是验证长度不是固定的,而是调度出来的。
官方 README 的描述是:DSpark 与置信度调度验证,用草稿 token 加速解码并用置信度估计来调度验证。开启方式是设置DEEPINFER_ENABLE_MTP_VARLEN=1,DEEPINFER_USE_NEXTN_DECODE控制最大草稿长度(默认 5)。
关键在"置信度估计"这四个字。草稿模型猜出来的 5 个 token 里,第 1 个几乎肯定对,第 5 个大概率不对。如果每次都固定验证 5 个,就会在高拒绝率的位置浪费算力。DSpark 用一个 Confidence Head 预测每个候选 token 的接受概率,根据预期收益分配验证预算——某条请求的后缀接受概率低了,就少验证几个,把算力让给更划算的请求。
源码层面这个逻辑更具体:csrc/engine/mtp_varlen.hpp用了启动时采集的 Decode 性能曲线,加上运行时前向和采样耗时估计,比较不同图规模下的单位时间预期收益。这个估计不把一次离线画像当成永远正确——运行时用实际执行反馈修正,因为上下文长度和请求构成都在变。
同时它和异步调度共享一个必须保持的时序约束:异步执行下,CPU 规划下一轮调度时,上一轮的置信度可能还没回来。强行同步等待就丢掉了调度重叠。DeepInfer 的做法是 CPU 先定总预算,GPU 再用更新的信息细化每个请求的验证长度。
这套设计是有代价的。置信度预测器如果过度自信、性能曲线如果过期,优化器都可能稳定地选错工作点——而且看起来更快。
这张图的重点在最后一步:**收益不是均匀分布的,它随并发上升。**这就是为什么同一个技术会同时有 -1.5% 和 +11.0% 两个数。
二、那张被讲反的三档数据
官方技术报告和部署问答里,DSpark 动态验证与固定验证 5 个(fixed-five)的对照数据是这样的:
| 每 rank 并发序列数 | 固定验证 5 个 | DSpark 动态验证 | 变化 | 每用户 token/s(动态) |
|---|---|---|---|---|
| 16 | 4,891 | 4,816 | -1.5% | 301 |
| 60(生产工作点) | 13,730 | 14,466 | +5.4% | 241 |
| 96 | 16,817 | 18,660 | +11.0% | 194 |
这张表是整个 DeepInfer 发布里信息量最大的一张,因为它同时告诉了三件事。
第一件事:DSpark 在低并发下是负收益。16 并发时吞吐下降 1.5%。这不是测量噪声,是机制决定的——草稿模型本身要花算力,验证预算的分配也要花调度成本,人少的时候摊不平。
第二件事:官方自己给出的"生产工作点"是 60 并发,对应 +5.4%。中文传播里最常见的说法是"提升 4~7%“或"提升约 6%”,这两个数字都来自这一行——4~7% 是官方对生产工作点的区间表述,6% 是 +5.4% 的四舍五入。**这个数字只在 60 并发附近成立。**把它写成"DSpark 能提升 6% 吞吐",就丢了"在什么负载下"这个前提。
第三件事:收益随并发上升,而单用户体验随并发下降。看最后一列:并发从 16 涨到 96,每用户的 token/s 从 301 掉到 194。DSpark 赚的是吞吐,不是体验。它恰好在单用户速度本来就在下降的那个区间开始生效。
这一点对做 Agent 服务的团队最要紧。如果你的业务是"少量用户、超长会话",并发常年停在个位数,DSpark 那一项基本是净亏;如果是"大量短请求、高并发",收益才显现。
还有一个被广泛引用的数字需要单独处理:有资料称 DSpark 让每用户生成速度提升 60%85%(DeepSeek-V4-Flash)、57%78%(V4-Pro)。这个数字说的是相对 MTP-1 生产基线的用户侧生成速度,而 4~7% 说的是相对固定验证的集群吞吐。**两个都是官方数字,但基线不同、口径不同、度量的东西也不同。**把它们放在一起说"提速 6% 到 85%"是错的。
另外,官方自己给的接受率假设是固定 75% 的草稿接受率,而这个数在官方 Decode Pareto 曲线的解读中被明确标注为"假设值而非实测值"。接受率还会随任务漂移——代码、自然语言、结构化 JSON、长推理、多语言文本,草稿质量不可能一致。
三、SWA 的 128 与 140:两个都对,指的不是一回事
DeepInfer 里有两项技术特别容易被中文报道混为一谈,因为它们都跟"token"有关,但一个是 128,一个是 140。
SWA Bounded Replay(有界重放):当滑动窗口注意力的缓存未命中时,机制上只重算提示词末尾有限的一段后缀,而不是全量重算。
官方技术报告的说法是:只重算最近 128 个 token,这让成本基本与上下文长度和层数无关,decoder 侧的版本使总 prefill 计算量近乎减半。
而 DeepInfer README 里的默认配置是:
export DEEPINFER_YOCO_PREFILL_TRUNCATION_MODE=compact export DEEPINFER_YOCO_PREFILL_KEEP_TOKENS=140140。
这两个数字不矛盾。滑动窗口本身是 128 token,而保留的后缀必须覆盖滑动窗口加上最大回溯长度——DSpark 的草稿机制要回溯,被拒的草稿 token 需要重新计算,多留 12 个 token 正是为这个。
所以正确的表述是:**机制上只重算最近 128 个 token,配置上保留 140 个 token 后缀。**报道里只写其中一个都不算错,但不写清另一个就是信息缺失——如果你按 128 去估算显存和算力,会低估。
这个机制的收益确实很大,因为它把"上下文越长、prefill 越贵"这条曲线压平了。DeepSeek 官方的说法是"成本与上下文长度无关"。对处理长文档、长代码库的场景,这个价值很直接。
有个具体的例子能把这条机制的威力说清楚。按 890 字节/token 的 KV 压缩比算,一段 131,072 token 的上下文,完整 KV cache 是 116.7 MB。把这段 KV 从 prefill 节点搬到 decode 节点,按官方建议的每 8 GPU 约 400 Gbps 互联算,需要大约 2.3 毫秒。
而两小时后用户追问一句、带上同样的前缀加一句短的:第 1 步,deepseek-recipe 按已知特殊 token 位置并行分段编码请求,入口对 KV 元数据做哈希链前缀匹配再路由;第 5 步,如果 1.4 MB 的 SWA 快照还在,除了最后 134 个 token 之外的内容全部复用,快照不在的话重放 128 个 token。
**输出是:这次追问只需要为几百个 token 付 prefill 成本,而不是 131,072 个。**这就是 SWA 有界重放加上 72 小时缓存的价值——它把"多轮对话"从成本悬崖变成了平摊。
这里有个值得单独记的对比。890 字节/token 是 V4.1-Flash 的水平,而按同样的算法,DeepSeek-V3 的 MLA cache 约 70 KB/token,是前者的 79 倍。模型侧把 KV 压到 1/79,引擎侧把重算压到 128 个 token——这两件事叠加起来,才让"百万 token 上下文 + 多轮追问"这个组合在成本上成立。
还有一组相关的官方数据也值得看:Block KVCache 按 128 Token 切块,存入独立的 3FS 分布式文件系统(约 100 PiB SSD,峰值聚合读取带宽约 10 TiB/s、写入约 850 GiB/s);SWA KVCache 只留在机器内存中、不做持久化,线上保留时间约 180 秒、命中率超过 98%。设计目标是缓存不活跃后保存 72 小时以上。
也就是说 128 这个数字在系统里出现了两次,但含义不同:一次是 SWA 窗口大小(也正好是 Block KV 的切块粒度),一次是 SWA KV 的驻留时长(180 秒)。
四、MoE 负载均衡:80% 和 9% 这两个数
DeepSeek 的模型是 MoE(混合专家)架构,384 个路由专家加 1 个共享专家,每个 token 选 6 个。热门专家会被频繁调用,导致"某几张卡忙死、其他卡闲着"。
DeepInfer 内置的 EPLB(专家并行负载均衡)每 10000 步动态重排专家副本,官方说线上最忙的卡只比平均负载高 9%,整体达到理想均衡状态的 80%。
这两个数字要一起读。80% 意味着还有 20% 的不均衡没有被消除——这是官方自己给的上限,不是"已完全均衡"。9% 是最差卡相对平均的偏差,也不是"所有卡都均匀"。
有意思的是,vLLM 在吸收 DeepInfer 的内核后把这个数字改写得更激进:其工程博客提到,decode 侧 Wide-EP 配合 EPLB,把目标模型的负载均衡度从 0.35 提到 0.94;规模化之后 CPU 开销接管瓶颈,仅 NIXL push(KV 数据推送式传输)一项修复就把单 GPU 吞吐从 141K 提到 440K tokens/s。
**0.35 到 0.94,对应 DeepSeek 官方口径的 80%。**这说明两件事:一是 DeepSeek 的 80% 是个真实但可超越的水平;二是 vLLM 在通用框架里用更通用的机制做到了更好——因为它有 DeepInfer 没开源的那层调度自由。
这也回答了一个问题:开源 DeepInfer 之后,竞争对手会把它吃进去,而吃了之后可能做得更好。框架开源不保证框架作者最优,它保证框架作者的方法被传播。
五、异步调度:zero-overhead 是个修辞
DeepInfer 把异步调度描述为"零开销批调度器"(zero-overhead batch scheduler)。README 说它默认开启,让 CPU 批调度与设备执行重叠。
这句话需要按字面拆开。
同步推理循环是:调度、前向、采样、同步、后处理,然后进入下一步。当设备还在采样、CPU 还在读结果准备下一批时,GPU 可能无事可做。随着 kernel 变快,原来不可见的 Python 与 C++ 记账和对象管理变成每步的固定开销。
"零开销"要读作尽量隐藏这笔开销,而不是 CPU 的工作消失了。DeepInfer 的 Worker 逻辑是:启动当前前向,在设备运行时处理上一轮结果,然后启动当前采样,CPU 与 GPU 作为流水线并行推进。落后的序列长度和请求映射由设备侧的元数据修正路径修复,避免每步全同步一次只为了拿最新结果。
这个设计的实际收益依负载而定。官方 README 自己也说了,实际收益取决于负载特征和系统配置。
**再叠加一件官方很少强调的事:批不变推理和确定性采样都是 NVIDIA only。**而且它们与 DSpark 互斥——确定性采样要求DEEPINFER_ENABLE_MTP_VARLEN=0(关掉草稿解码)并传固定的seq_seed;而 DSpark 恰恰要开启这个变量。
也就是说:同一套代码里,"可复现"和"更快"这两件事,目前不能同时要。
这对需要结果可复现的场景(Agent 工具调用、代码生成、离线评测)是硬约束。第三方分析也提醒过,DeepInfer 没有发布确定性与非确定性并行的成本对照表,所以这个取舍的代价目前无法量化——需要在自己的负载上实测。
这张图讲的是一件在工程里很常见、但很少被明说的事:**很多"性能优化"实际上是拿确定性换的。**你在评估一项优化技术时,如果只看到它的收益曲线、不看它禁掉了什么,就会把一个不该上的功能上了生产。
六、这些数字怎么用
把前面五节的数字收成一张可以直接拿去做决策的表:
| 技术 | 官方数字 | 生效条件 | 不生效的场景 |
|---|---|---|---|
| DSpark 动态验证 | -1.5% / +5.4% / +11.0% | 16 / 60 / 96 并发 | 低并发(个位数到十几)净亏 |
| SWA 有界重放 | prefill 计算量近乎减半 | 长上下文、缓存未命中 | 短上下文收益小 |
| 96% 前缀缓存命中 | prefill 从 6 万 → 150 万 tokens/s | 前缀重复率高 | 每次都是全新 prompt |
| EPLB 专家均衡 | 最忙卡高于均值 9%,达理想均衡 80% | MoE 大规模部署 | 小规模部署无意义 |
| 异步调度 | 与硬件细节相关 | CPU 记账开销占比高的场景 | — |
| 批不变推理 | 不受 batch 组成影响 | 结果需可复现 | 与 DSpark 互斥,且仅 NVIDIA |
三个可以直接拿去用的判断:
**第一,任何"提速 X%"的说法,先问在什么并发下测的。**DSpark 的三档数据就是最好的模板——同一个技术,三个并发点,符号都不一样。
第二,官方自己公布的"负收益点"比"最高收益点"更有信息量。-1.5% 那个数告诉你这套机制的启动门槛在哪。
**第三,能力之间会互相排斥。**确定性 vs 投机解码,是这类系统里最典型的一对。评估一项技术时,要连同它会禁掉什么一起看。
顺带把这次发布里几个流传很广、但我一概没有引用的数字列出来。按这个栏目的规矩,查不到可确认口径的精确数字,宁可不写:
| 流传数字 | 处理方式与理由 |
|---|---|
| “DSpark 提速 6%~85%” | 6% 是 60 并发点的 +5.4%,85% 是相对 MTP-1 基线的每用户生成速度,两者基线不同,不可并列 |
| “SWA 只重算 128 个 token” | 机制上是,配置上默认保留 140(需覆盖 SWA 窗口 + 最大回溯长度),只写一个会低估开销 |
| “DSpark 使线上吞吐提升 4~7%” | 官方限定在"其生产工作点约 60 并发"的前提下,不是任意环境的保证 |
| “DeepInfer 负载均衡已达理想状态” | 官方口径是"达到理想均衡的 80%",且最忙卡仍高于均值 9%,不是完全均衡 |
| “草稿接受率 75%” | 官方在 Decode Pareto 曲线解读中标注为假设值而非实测值,且接受率随任务类型漂移 |
| “DeepInfer 吞吐优于 vLLM/SGLang 达数十个百分点” | 三方对照硬件跨代(SM100 vs GB200/GB300)、并行度不同(EP64DP64 vs DEP32),vLLM 侧未重跑 DeepInfer,只对照了公布的图表 |
这六条里,最容易被忽略的是最后一条。vLLM 是用自己实测的曲线去对照 DeepInfer 公布的图表数字,而 DeepInfer 的 README 只有两张 PNG,没有单卡吞吐绝对值,也没有 vLLM 基线。所以"谁更快"这个问题,严格说目前没有第三方独立复现的答案,只有各方的口径对齐声明。
如果你要自己测,测什么才有用
既然官方的数字都带边界,那在自己环境里测的时候,测法本身决定了结论有没有用。四个要点:
**第一,扫并发区间,不要只测一个点。**至少覆盖 8、16、32、64、96 这几档。只测一个点的风险是:你测到的那个点可能是这条曲线的最低点,也可能是 DSpark 收益最大的点,结论会完全相反。DSpark 的三档数据就是最直接的教训。
**第二,同时记录每用户 token/s,不要只看集群总吞吐。**这两条曲线方向相反:吞吐随并发上升,每用户速度随并发下降。只报吞吐,会得到一个技术上正确、业务上错误的结论。
**第三,固定语料,别用随机 prompt。**接受率随任务漂移,代码、自然语言、结构化 JSON 的草稿质量不一样。你用自己业务里的真实请求分布去跑,才能测出对你有效的那个数。
**第四,把"关掉优化"的基线也测一遍。**DSpark 的官方对照是"动态验证 vs 固定验证 5 个",不是"开 vs 关"。如果你的目标是评估要不要上 DSpark,那基线应该是完全关掉的版本——两者差的才是真实收益。
有一点官方自己都提醒了:接受率的预测值和实际值需要按任务分桶持续对账,同时把预算算法误差、采样时间、草稿时间和尾延迟放在一起记录。一个过期了性能曲线加上一个过度自信的预测器,会让优化器稳定地选错工作点,而且看起来更快。
对领码 SPARK 融合平台的映射
这三条判断落到企业数据平台,指向的是同一件事:把"性能"和"可复现"当成两个可独立选择的维度,而不是一个笼统的"更快的系统"。
**其一,可复现性要能被记录,而不是靠约定。**上面那条"确定性与 DSpark 互斥"的现实,在企业里对应一个更常见的问题:同一个 Agent 任务,跑两次结果不一样,出了问题无法定位是模型行为、prompt 差异还是数据变化。领码的平台侧要能把一次 AI 调用绑定的模型版本、prompt 模板版本、授权数据版本、以及当时的策略配置记成一条可回溯的记录链——不是为了追求逐 token 一致,而是为了在不一致发生时能定位到是哪一层变的。
**其二,权限判定要跟着数据走。**推理层把数据送出去的那一刻,系统边界的保护就断了。全域守卫要做的是把"谁在什么域能看什么"做成一张能查询、能追溯的表,让数据被送往推理侧时,授权状态是明确的、可审计的。
**其三,把可复现要求前置成治理要求。**治理中心要在调用发生之前就记录"这次任务需不需要可复现",从而在策略上提前决定走哪条路径——是关掉投机解码换稳定,还是接受波动换吞吐。这个选择不该由运维在压测时临时发现,只能在设计时就定下来。
一句话:引擎层的性能是参数,治理层的可复现是契约。参数可以调,契约必须先定。
七、结语
这一轮 DeepInfer 开源的中文解读,普遍只取了最好看的那几个数:155 万亿、38 美元、96%、提速 6%。但官方技术报告里信息密度最高的,恰恰是那些不那么好看的数——16 并发下的 -1.5%、均衡度 80% 而非 100%、128 与 140 的区别、以及确定性与投机解码互斥。
**一家公司愿意把自己的负收益点、自己的取舍、自己的功能互斥写进公开文档,这本身就是这次开源最值得信任的信号。**比起宣传材料里的漂亮数字,这些带着边界的数字更接近真实的生产系统。
所以下次看到一个新的推理优化技术被介绍时,建议按三个问题问一遍:在什么负载下测的?它会禁掉什么?官方有没有给出不适用的场景?
你手上有哪个推理服务是"结果必须可复现"的?你更愿意为了稳定性关掉那些提速的技术,还是接受波动换吞吐?这个取舍你们是怎么定的?评论区说说,我按场景给一组判断依据。