返回博客列表

DeepSeek 开源 DeepInfer:155 万亿 Token/天,靠的是「不重算」

2026-10-21T10:30:00+08:00
DeepSeekDeepInfer推理框架LLMMoEKV Cache

DeepSeek 开源 DeepInfer:155 万亿 Token/天,靠的是「不重算」

155 万亿 Token/天是一份缓存命中率的成绩单,不是一份算力的成绩单。

DeepSeek 把支撑线上服务的推理框架 DeepInfer 开源了,Apache 2.0,一周不到 1.2 万 star。官方给的核心数字是单集群日服务 155 万亿 Token。

这个数字最容易被读错。它不是「算了 155 万亿 Token」,而是「服务了 155 万亿 Token」——中间隔着一个 96% 的 KV 缓存命中率。把这条线捋清楚,整个框架的设计选择就都讲得通了:为什么 Prefill 只需要 8 卡、Decode 却要 64 卡起,为什么要把 PB 级缓存搬到独立存储集群,为什么敢只重算 128 个 Token 就宣称 Prefill 计算量减半。

我把仓库里的 README、部署 Q&A、benchmark 与 eval 文档都读了一遍,顺便做了几处数量级校验。有几处数字互相印证得漂亮,也有一处对不上。

本文提纲

  1. 先把数字对齐:155 万亿 Token/天 是什么量级
  2. 非对称并行:为什么 Prefill 用 8 卡,Decode 用 64 卡
  3. 把 KV 缓存赶出 HBM:100PiB 3FS 的赌注
  4. SWA 有界重放:用 128 个 Token 换掉 2,560 个
  5. DSpark:把验证算力当预算来分配
  6. 藏在两行环境变量里的事:异步调度与 batch 不变性
  7. 双栈不是移植:一套 TileLang,两套 kernel
  8. deepseek-recipe:被低估的另一半
  9. 该怀疑的地方
  10. 如果你要动手:能抄的三件事

一、先把数字对齐:155 万亿 Token/天 是什么量级

一串官方数字先摆出来:单集群 155 万亿 Token/天,平均每请求输入 77K Token,首字延迟约 400ms,生成阶段 230 Token/s、写代码场景可达 300 Token/s,KV 缓存命中率 96%,Prefill 的有效吞吐因此从 6 万 Token/s 提升到 150 万 Token/s。另外 Q&A 里还有一个很少被引用的:按谷时电价算,GPU 每小时收入 38 美元。

先做除法。

155 万亿 ÷ 86400 秒 ≈ 每秒 1.79 亿 Token(1.79M tok/s)。再除以平均输入 77K:约 20 亿次请求/天,折合 2.3 万 QPS。这个量级意味着 77K 的平均输入不是「有些请求很长」,而是整个流量形态就是长上下文——绝大多数 Token 是输入,输出只占很小一块。

于是关键一步来了:96% 的命中率意味着真正过 GPU 的新 Token 只有 4% 左右,也就是约 6.2 万亿/天 ≈ 每秒 7,200 万 Token 的真实预填充。如果按 KV 容量反推卡数(100PiB ÷ 每卡 14.4TB 逻辑容量 ≈ 7,100 张),分摊下来是每卡每秒约 1 万 Token 的预填充——这正好落在 SM100 单卡预填充的合理区间内。这三个数字是自洽的,说明 155 万亿不是营销口径,而是「命中 + 重算」两部分的真实加总。

再看 400ms 首字。77K Token / 0.4s ≈ 每秒 19 万 Token 的等效预填充速率。单台 8 卡 Prefill 机的裸算力做不到这个数,差了一截。所以 400ms 这个成绩的本质不是「算得快」,而是「几乎不用算」——96% 的前缀已经在 3FS 里躺着了,Prefill 机做的是从远端把 KV 拉回来 + 补最后几千个 Token。这条推论构成了后面所有架构取舍的前提。

最后一处印证更有意思。Q&A 里 DSpark 那张 benchmark 表,conc=60 那一行的估算吞吐是每 rank 13,730 Token/s;除以 60 个并发序列,得到 每人 228.8 Token/s——和官方宣传的 230 Token/s 是同一个数。换句话说,公开的 benchmark 表格就是按生产工况(每 rank 约 60 条并发序列)算出来的,那个 230 不是实验室峰值。写代码场景的 300 Token/s 也能对上更靠上的行:代码的 draft 接受率更高,折算下来接近 conc=96 那一行的 18,660 Token/s/rank ÷ 60 ≈ 311。

这种「官方数字能在源码仓库的表格里找到出处」的情况不多见,值得先给一分信任。

二、非对称并行:为什么 Prefill 用 8 卡,Decode 用 64 卡

架构的骨架是一张很不常见的配置表:

flowchart LR
    C["Client
Chat / Responses / Messages"] --> R["deepseek-recipe
protocol to tokens"] R --> E["Entrypoint
prefix hash match"] E --> V["Vision Encoder
1 GPU"] E --> P["Prefill Engine
8 GPUs, EP 2-8 / DP 2-8"] V --> P P <--> S[("3FS KV Store
100 PiB, TTL 3-7 days")] P --> D["Decode Engine
64-128 GPUs, Wide-EP"] S <--> D D --> K["DSpark
confidence scheduled verify"] K --> E classDef c fill:#FF6B6B,stroke:#764ba2,stroke-width:2px,color:#ffffff classDef r fill:#4ECDC4,stroke:#764ba2,stroke-width:2px,color:#1a1a1a classDef p fill:#45B7D1,stroke:#764ba2,stroke-width:2px,color:#ffffff classDef d fill:#96CEB4,stroke:#764ba2,stroke-width:2px,color:#1a1a1a classDef s fill:#FFEAA7,stroke:#764ba2,stroke-width:2px,color:#1a1a1a classDef k fill:#DDA0DD,stroke:#764ba2,stroke-width:2px,color:#1a1a1a class C,V c class R,E r class P p class D d class S s class K k linkStyle default stroke:#764ba2,stroke-width:2px
阶段 并行度 选型原则
Prefill EP2–8 / DP2–8 用 HBM 装得下的最小 EP/DP
Decode EP64–128 / DP64–128(Wide-EP) 用现有卡能给的最大 EP/DP
Vision Encoder 单卡一实例 用便宜卡就够
TP / CP 不使用 —

同一个模型,两个阶段用差了一个数量级的并行度,这是全文最值得琢磨的地方。

原因是两个阶段的瓶颈根本不是一个东西。Prefill 一次要吃几千到几万个 Token,矩阵乘的 batch 维度足够大,算术强度高,属于算力受限。这时 EP 越大,专家分散在越多卡上,All-to-All 通信代价越高,而算力利用率提升有限——所以官方说「用 HBM 能装下的最小 EP」。反过来说,Prefill 机的目标不是省显存,是别让通信把算力吃掉。

Decode 每个请求每步只算一个 Token,batch 再大,MoE 那部分的权重读取量也不会摊薄——每步都要把参与计算的专家权重从 HBM 搬进 SM。这是访存受限。Wide-EP 的作用就是把专家摊到 64 甚至 128 张卡上,让每张卡每步只需要读一小撮专家权重,单步访存直接降一个数量级。Q&A 里那张 EP8 vs EP64 的对比图就是这个意思。

代价写在后面:EP64 意味着 64 张卡在同一个通信域里,一张卡挂了整个实例不可用。官方的处理方式不是缩短重启时间(他们明说重启是「分钟级」),而是重启时按「当前还能用的健康卡数」重新决定 EP size——实例拿到几张卡就按几张卡跑。这种「结构性地接受降级」的做法比追求高可用更符合大规模集群的现实。

EPLB 的配置差异也很说明问题。Prefill 每卡留 4 个冗余专家、100 步统计窗口、1000 步重排一次,实测 moe_lb(最慢 rank / 平均)1.074(EP4DP4)/ 1.045(EP2DP2)。Decode 只留 1 个冗余专家(EP64 时四舍五入成每卡 7 个专家,不含 shared expert),1000 步统计窗口、10000 步重排,moe_lb 1.090。统计窗口长 10 倍、重排频率低 10 倍,是因为 decode 的专家负载分布稳定得多,频繁 shuffle 只会扰动稳态。

门槛也在这里写明:1P + 1D 就能部署,但推荐 decode 用 EP64 以上,所以最小的高效部署单元是 64 卡 Prefill + 64 卡 Decode,128 卡起。 这一条基本决定了谁能真的用上这套东西。

三、把 KV 缓存赶出 HBM:100PiB 3FS 的赌注

绝大多数推理框架把前缀缓存放在本机内存或本地盘,做成分层结构。DeepInfer 反过来:把 paged block KV cache 全部扔进一个独立的 3FS 全闪集群。

理由在 Q&A 里说得很直白,也是我觉得整个系统最漂亮的一个取舍:如果缓存留在本地,路由就必须考虑 prefix 亲和性——哪个机器上有你要的前缀,请求就得发给谁。而这样一来,负载均衡就没法只按算力余量来分。 集中式存储把缓存从「机器的属性」变成「集群的属性」,于是任何一台 Prefill 机都能命中任何前缀,调度器可以只看配额。

这是一笔用存储带宽买调度自由度的交易。账目也算得清楚:约 100PiB SSD、逻辑容量每卡约 14.4TB、存储服务器推荐 20 × 30.73TB SSD(单机 614TB)、每台至少 40GB/s 读 5GB/s 写、10+2 纠删码(同组容忍两个节点同时故障,读时向 11 个节点发请求,任意 10 个响应即可解码)、每存储节点跑一个 GC Worker 按 LRU 在水位线下回收。TTL 是 agent 流量 3 天、chatbot 流量 7 天。

TTL 这个细节值得单独说。官方承认,3 天 TTL 会让 chatbot 流量损失 0.5%–1% 的命中率,因为 chatbot 的命中长尾特别重——「少量 KV 被读非常多次」。这是个非常具体的成本项:多留 4 天的存储,换回 1% 的命中率。而 1% 命中率在 155 万亿的基数上就是 1.55 万亿 Token/天的重算量,按前面每卡 1 万 Token/s 折算,相当于几千张卡。这笔账算下来,7 天 TTL 显然是划算的,框架里也留了按流量类型分 TTL 的机制。

隐藏成本在工程细节里:

  • 匹配在 Entrypoint 用哈希链做前缀匹配,只查元数据。但命中长度必须在路由前算出来,所以这一步无法隐藏。
  • 拉取由独立进程异步做,从 3FS 搬进主机共享内存。
  • 换入(swap-in,共享内存 → HBM)用 GDR 而不是 CUDA copy engine。原因官方直接写了:CUDA 拷贝引擎对 KV block 这种细粒度拷贝性能很差,所以改走 RDMA 网卡,把 PCIe 带宽打满且不占 SM。

最后这条是我读源码级文档时最想鼓掌的一处。绝大多数团队遇到「KV 从主机内存搬到显存慢」,第一反应是调大 block、合并拷贝,而他们直接换了一条数据通路。这类决定只有真在 100PiB 规模上跑过的人才做得出来。

顺带一个看着别扭的地方:存储服务器的选型建议是「总容量足以保存 24 小时数据」,但 TTL 是 3–7 天。两个口径对不上,可能是「单机 24 小时」的抽屉式表述,也可能是 GC 水位线之外还有余量。文档没有解释,这里存疑。

Prefill 的负载均衡也值得抄一手。请求按上下文长度分四档(<16K / 16–64K / 64–256K / ≥256K),每档拥有的引擎数量按上一轮的计算配额需求动态重新分配;单卡内部不固定 chunk 大小,而是给每个 prefill step 一个时间预算(纳秒级),用拟合出来的二次成本模型 cost(q, c) 反解出「在 32768 Token 上限内、正好花完剩余时间」的最大 q,最后再在 DP 组内做一次 all-reduce MIN 收敛预算。官方给的整体效果是:达到完美均衡离线 benchmark 的约 80%。

80% 这个数字很诚实。它等于承认了在线调度和离线跑分之间有 20% 的差距,而这个差距是队列、抖动、失败重路由共同造成的,不会消失。

四、SWA 有界重放:用 128 个 Token 换掉 2,560 个

如果说 3FS 那套是「用存储换调度」,SWA 有界重放就是「用近似换算力」。

问题出在架构上:V4.1 是 CED(compressed encoder-decoder)结构,decoder 层的 block KV cache 是从最后一层 encoder 的隐状态投影出来的,所以只有 decoder 的 SWA KV cache 需要逐层计算。而要精确重建它,得把最后 2,560 个 Token 重新跑过 20 层 decoder。

他们的做法是只重算最后 128 个 Token。具体地,从位置 s 开始重放时,位置 i 的 query 只对 max(s, i-127) 到 i 这个区间的 key 做注意力。文档自己用的词是「approximate SWA KV cache」。

为什么这个近似站得住?因为 SWA(sliding window attention)本来就是滑窗——超出窗口的 key 根本不参与注意力。窗口外的信息被截掉,在语义上不构成错误;重放段内每个 query 看到的是「自己的 128 窗口 ∩ 重放段」,越靠近重放起点的 query 窗口越不完整,这才是真正的误差来源。误差影响的是重放段最前面那几十个位置,而这段结果只用于 decode、不进入前缀缓存,误差不会向后传播累积。

收益很直接:decoder 层的预填充从 2,560 × 20 层降到 128 × 20 层,官方说总预填充计算量近乎减半。同一套机制还用在 encoder 侧——当前缀命中了但 SWA 缓存缺失时,只重算命中前缀的最后 128 个 Token,block KV 原样复用,不算也不覆盖。

配套的存储设计抠得很细:SWA 缓存只存在 128 的整数倍位置,每个序列占一个固定大小的 StateBlock,里面分「要存的 SWA 区」和「丢弃区」(YOCO consumer 层 + 压缩边界累加器)。V4.1 真正落盘的只有 20 层 × 134 Token × 528 B = 1,415,040 B/序列,528 B/Token 是 MXFP8 的 SWA KV 格式。decode 阶段在显存里另开一块副本区,每跨一次 128 边界就把当前窗口复制过去;复制位置最多越界 5 个 Token,正好被 slot 环缓冲多出来的 6 个位置吸收。

命中策略一句话能说完:命中长度由 block KV 决定,最后一块要不要重算由 SWA KV 决定——SWA 没命中就退一个 block 重算。所以长度为 L 的输入,最大命中长度是 L − 134(128 窗口 + 6 个投机回溯位)。

顺便说低精度:主 KV 用 per-16 的 e4m3(类似 NVFP4 但去掉全局 scale),indexer KV 用 per-32 ue8m0 的 MXFP4,MoE 路由专家权重也是 per-32 MXFP4。这三处是「能不能跑得省」的关键,也解释了为什么 100PiB 能装下这么多人的 KV。

五、DSpark:把验证算力当预算来分配

投机解码的常规做法是固定 draft 长度(比如每次 5 个),然后整批验证。问题是不同请求、不同位置的 draft 接受概率差别很大,固定长度等于把验证算力平均撒在一个分布极不均匀的场地上。

DeepInfer 的 DSpark 用了一个 Confidence Head 预测每个 draft Token 的接受率,然后在调度时把验证算力分配给「边际收益最高」的那些 Token:先按期望接受率排序,再挑出使有效吞吐最大的前缀子集去验证。生产环境 draft 模型一次出 5 个 Token,实际只验证其中一部分。

效果表如下(EP64/DP64 benchmark 数据):

并发(seq/rank) 固定 5 验证长度 动态验证长度 固定 5 接受长度 动态接受长度 动态 vs 固定收益
16 5 4.44 3.32 3.24 −1.5%
32 5 3.65 3.25 3.17 +1.6%
48 5 3.94 3.30 3.26 +3.6%
60 5 3.58 3.30 3.21 +5.4%
72 5 3.24 3.29 3.12 +6.7%
96 5 3.24 3.30 3.15 +11.0%

整体每步验证的 draft Token 数少了约 30%(5.00 → 3.2–4.4),而平均接受长度几乎不变(3.29 vs 3.20)。也就是说省下来的是纯浪费。

但请把注意力放在第一行和最后一行。并发 16 时动态验证是负收益(−1.5%),并发 96 时是 +11%。 这条曲线说明 DSpark 不是无条件更好:低并发下 GPU 本来就有空闲,省验证算力换不来吞吐,反而多了调度开销;只有并发堆到每卡 60 条以上,验证算力才真正成为瓶颈,动态分配才开始赚钱。这是一个只在生产工况下才成立的优化,跟前面 230 Token/s 对应的正是同一行数据。

异步调度下这里有个很硬的工程问题:跑 schedule(N+1) 的时候,第 N 步的 confidence 还没从 GPU 回来,CPU 侧只能先定总预算。所以每个请求的具体验证长度是在 GPU 上用 TileLang kernel 现算的——累积乘积、全局排序取 top-k、再加一个融合的 remap scatter,结果写回 pinned buffer。把「依赖未来信息」的决策推迟到 GPU 上做,这是异步流水线里很难绕开的一手。

六、藏在两行环境变量里的事:异步调度与 batch 不变性

README 里有一段很容易被跳过的 feature 列表,但实际上藏着两个信号。

第一个是异步调度(零开销批调度器)。decode 一步的流程是 schedule(N) → forward(N) → sample(N) → post-process(N),其中调度和后处理都是纯 CPU 逻辑,而 post-process(N) 之前要等 sample(N) 的 GPU 结果——于是 GPU 在 post-process 和 schedule(N+1) 期间是空转的。他们的做法是让 CPU 在 GPU 跑 forward(N) → sample(N) 的同时跑 schedule(N+1) → launch_forward(N+1) → post-process(N-1) → launch_sample(N+1)。文档里明说思路借鉴了 SGLang 和 NanoFlow,不算原创,但工程落地是完整的。

第二个更值得说:batch-invariant inference(批不变性)和确定性采样,都用一行环境变量打开,而且都标注了 NVIDIA only。

  • DEEPINFER_BATCH_INVARIANT=1:同一个请求,不管和哪些请求拼在一个 batch 里,输出完全一致。
  • 确定性采样:DEEPINFER_BATCH_INVARIANT=1 + DEEPINFER_ENABLE_MTP_VARLEN=0 + 固定 seq_seed,相同输入必得相同输出。

为什么这件事重要到要写进 feature 列表?因为这是推理框架能不能参与训练闭环的分界线。RL 训练要拿 rollout 数据算梯度,如果同一个 prompt 因为 batch 组成的偶然差异给出不同采样结果,「这批数据变好是因为模型进步还是因为 batch 变了」就永远说不清。同理,线上 A/B、回归测试、badcase 复现,全都依赖「同输入同输出」这个前提。

而它为什么只能在 NVIDIA 上开,原因也很实在:批不变性要求矩阵乘的归约顺序固定,而 split-k 之类的算子会按 batch 规模改变切分方式,同一行数据的累加顺序随之改变,浮点结果就差最后几位。这需要在 kernel 层面把归约结构钉死。Ascend 侧显然还没做到这一步。

这一点在 eval 目录里被落到制度上:tests/models/offline_decode_ppl.json 存了按平台/工况分开的 PPL 基线,逐样本精确比对;一旦数值变了,必须用 refresh_offline_decode_ppl.py 显式刷新基线,等于承认「这是一次有意的数值变更」。这比「跑一遍 benchmark 差不多就行」严格得多,也是把推理框架当基础设施而不是脚本在维护的标志。

参考成绩:AIME 2026 Pass@1 99.9%、GPQA Diamond 93.4%、HLE-Full 42.6%。AIME 是 30 题 × 32 采样共 960 个 rollout,99.9% 意味着只错了 1 个。另外文档提到 rule-based judge 和 LLM judge 在这 960 个 rollout 上判定完全一致——这反过来给规则判分背书了。

不过要泼一盆冷水:这三个数字是 V4.1 模型的能力,不是推理框架的能力。它们的作用是「部署正确性的哨兵」,不是「DeepInfer 有多强」的证据。把 eval 表格当成框架的功劳是常见误读。

七、双栈不是移植:一套 TileLang,两套 kernel

README 里 Ascend 950 只是一行「支持的硬件」。翻文件树才知道工作量在哪:deepinfer/model_executor/layers/tilelang_ops/ 下面 cuda/ 和 asc/ 两个目录是一一镜像的——flash_mla_utils、fused_sample、store_kv_cache、swa_index、schedule_mtp_varlen……每个算子两边各一份。

而且 ASC 版本普遍更大:

算子 CUDA 版 Ascend 版
fused_transform.py 35 KB 49 KB
norm.py 15 KB 24 KB
fused_sample.py 29 KB 45 KB
sampler.py 19 KB 39 KB
store_kv_cache.py 10 KB 16 KB

这不是巧合。同一套 TileLang DSL 写出来的算法,在 NPU 上往往要显式描述同步、切分和搬运,Code 自然更长。「国产卡适配」的真实形态不是「把 CUDA 代码翻译一遍」,而是「用一套 DSL 写两遍,让两份实现各自演化」。 代价是双份维护,收益是算法语义对齐——两边的算子名和参数是同一套,调优才能共用一套方法论。

配套的 kernel 全是自家孩子:FlashMLA、DeepGEMM、DeepEP、TileKernels、DeepSelect,加自研 TileLang kernel。官方还顺手交代了一个「开源版和内部版的差距」:FlashMLA 缺一个手调的 SASS 优化,导致 decode kernel 慢 5%–10%,端到端最多差 5%。

这句话信息量很大:你在这份代码上复现出来的性能,本来就不是线上性能。差 5% 听起来不多,但它是「你永远追不平」的 5%,因为缺的那块不在仓库里。

八、deepseek-recipe:被低估的另一半

同一批开源的另一个仓库 deepseek-recipe 只有 1500 多 star,但我认为它对第三方开发者的实际价值高于 DeepInfer 本体。

它是一个 Rust 库加 Python 绑定(MIT 协议,pip install deepseek-recipe,或 cargo add deepseek-recipe@0.2),干的事是:把 Chat Completions、Responses、Anthropic Messages 三种 API 请求统一转成一个 Conversation 格式,用同一套模板渲染成 DeepSeek 模型的 prompt,编码成 Token,再把模型输出解析成事件(正文、思维链、工具调用)回流成各协议的流式响应。请求转换、prompt 编码、输出解析全在 Rust 里做。

其中有一个设计我认为所有自建推理服务都该抄,而它被讲成了一个「格式问题」,实际是安全问题:

构建 prompt 时,显式插入的特殊 Token 及其位置会被记录下来,编码时直接映射成对应 Token ID;而普通文本用基础词表编码。用户在输入、工具结果、工具调用参数里写的 <|User|>、<|image|> 这类字符串,会被编码成普通的 Token 序列——从而阻止文本注入控制 Token 影响模型行为。

输出侧同理:识别 </think> 的结束和 DSML 标签里的 |DSML|,都是靠 Token ID 判断的。模型用普通 Token 拼出同样文字时,那只是字面内容,不会获得「结束思考」或「触发工具调用」的能力。

这解决的是什么?是提示注入里最难防的一类:控制 Token 注入。只要你的服务端是「字符串拼接 prompt」,用户就能通过写几个尖括号伪造对话角色。绝大多数自建部署栽在这上面而不自知,因为接口返回「看起来正常」。DeepSeek 把它做进了编码层,而不是做在输入校验里——这才是根治。

另外两个工程点:分段并行编码(特殊 Token 的边界在构建 prompt 时已知,所以中间的普通文本段可以独立并行做 BPE,再按原序拼接,长上下文请求的 tokenization 延迟明显下降);跨 chunk 流式解析(一个 UTF-8 字符或 DSML 标签可能被切在两个 Token chunk 里,用状态机 + 增量 KMP 保留匹配进度,工具参数按边界直接吐 JSON 片段,不用构造完整对象再序列化)。

还有个容易被忽略的一致性细节:max_tokens 未指定时的默认值——非思考模式 8192、思考模式 65536、思考模式 + max effort 131072。这类默认值就是「第三方部署和官方 API 行为一致」的具体含义。

九、该怀疑的地方

前面夸了不少,该泼的冷水也不能省。

第一,开源的不是那个 155 万亿的系统。 README 自己列了一张表:「构成完整推理服务所必需、但本次未包含」——KV 缓存系统、VE/Prefill/Decode 分离、DP 副本间的负载均衡。而 Q&A 又明说 KV 缓存管理和负载均衡「与内部基础设施强耦合,代码尚未完全开源」,只给了知乎博客讲设计。换句话说,那 155 万亿 Token/天的成绩,恰好长在这三块没开源的部件上。 开源的是一台引擎,不是一个服务。想照着搭一套自己的,你得自己补缓存、补分离、补均衡——而这三样正是最难的部分(本文第三、四节讲的取舍,全在未开源范围内)。

第二,它只支持一个模型。 仓库明确写 Supported models: DeepSeek-V4.1-Flash,默认 checkpoint 是 DeepSeek-V4.1-Flash-1017。它没有 vLLM 那种「换个 config 就能跑 Llama/Qwen」的通用性,v4_modules/ 里全是 V4.1 专属结构(engram、hc、yoco、dflash)。这是一个为自家模型定制的引擎,不是通用推理框架。 拿它去跑别的模型是不现实的。

第三,复现门槛高到大多数人只能看。 4 卡 Prefill + 64 卡 Decode、SM100、CUDA 13、GCC ≥ 13、Python 3.12、CANN 9.2(昇腾),还要先 vendor 一堆 kernel 再 ./build.sh。README 的性能图注明测在「4 卡 Prefill、64 卡 Decode,各自在同一个 scale-up 域内」。这不是个人能验的东西。

第四,官方数字之间有一处对不上。 按 100PiB ÷ 14.4TB/卡 ≈ 7,100 卡,乘 24 小时乘 38 美元,日收入约 648 万美元,除以 155 万亿 Token,得到约 $0.042/百万 Token。而 DeepSeek 公开 API 的缓存命中输入价是 $0.07/百万、输出 $1.10/百万。差了 2–25 倍。可能的解释有三种:真实 GPU 数远大于 7,100(100PiB 不是卡数的约束);$38 是「谷时电价」口径下的收入而非定价;或者 155 万亿里绝大部分是命中缓存、几乎不计费的 Token。我倾向于第三种解释,但这三种都没法从公开材料里验证。所以那个 $38 只能当量级参考,别拿去建模。

第五,96% 命中率是流量形状的产物,不是技术水平的产物。 官方说 chatbot 流量有「很重的命中长尾」,TTL 从 3 天延到 7 天就是为了它。换一个业务——比如每请求都是全新长文档的文档问答、或者多轮但每轮都换语料的 agent——命中率会掉到个位数。把这个 96% 当基准去规划自己的容量,会算出完全错误的卡数。

第六,昇腾侧只有「能跑」,没有「跑得好」。 全仓库找不到一个 Ascend 的性能数字,没有 EP8/EP64 的对比图,没有 moe_lb 实测,只有双份 kernel 和 ASCEND_LAUNCH_BLOCKING 这类调试开关。代码存在 ≠ 性能对等,这一点必须分清。

第七,开源版比内部版慢。 FlashMLA 缺那个手调 SASS,decode kernel 慢 5–10%,端到端差最多 5%。加上「内部 draft 模型更新一些」「kernel 库大体相同但 indexer 和 mega 系列有差异」这些描述,能看出公开版本是「追平到 95% 的版本」。

第八,一些小处的近似和负收益,官方都写了,但容易被只看 headline 的人忽略。 SWA 有界重放是「近似」重建;DSpark 在低并发(conc=16)是 −1.5%;在线负载均衡只到离线完美均衡的 80%;重启是分钟级而不是秒级。

十、如果你要动手:能抄的三件事

把上面拆完,能拿走的东西其实不多,但都很硬。

一、把前缀缓存从「机器的属性」变成「集群的属性」。 这是全文最有迁移价值的判断。只要缓存绑在本地,路由就永远要在「算力均衡」和「缓存亲和」之间做取舍;把缓存集中到独立存储,调度器就能只看配额。但要先算清带宽账:官方给的参考是每 8 卡配 400 Gbps 互联,且 P/D 跨机房时可靠性会打折(光缆会被施工挖断,这个理由写得很实在)。中小规模未必需要 3FS 这种量级,对象存储 + 本地 SSD 二级缓存也能拿到大部分收益,关键是别让亲和性污染路由。

二、别用一套并行度服务两个阶段。 Prefill 取「HBM 装得下的最小 EP」,Decode 取「卡数允许的最大 EP」,这个非对称是物理决定的,不是调参偏好。哪怕你只有 8 张卡,也可以拆成 4P + 4D 分别调并行度,而不是一个 8 卡实例硬扛两个阶段。

三、batch 不变性 + 逐样本 PPL 门禁。 这条任何规模都能抄,而且立刻有用。给自己留一份「固定输入 → 逐样本 PPL/输出」的基线文件,任何 kernel、并行度、精度改动后跑一遍精确比对,数值变了就当成一次需要签字确认的变更。这件事的成本是一个下午,收益是以后每次优化你都知道自己到底改了什么。

不能抄的也要说清楚:SWA 有界重放依赖 V4.1 的 CED/YOCO 架构,你的模型没有 SWA + 压缩边界的话,这套「只重算 128 个」无从谈起;DSpark 需要一个训练好的 Confidence Head;Wide-EP 需要 64 卡起步的通信域。这三样都是「模型架构 + 规模」共同决定的,不是框架层的通用技巧。

那现在能用的是什么?如果你只是想接一个 DeepSeek 模型的兼容 API,deepseek-recipe 是今天就能 pip install 的那半个——MIT、Rust 内核、三种协议互通、特殊 Token 注入防护是白送的。如果你在做一个几十卡规模的推理服务,读 Q&A 里的负载均衡和 KV 存储两节,比读代码收益高。如果你在等一个「开箱即用的 DeepSeek 推理方案」,那这次开源还差三块拼图。

DeepSeek 说「未来模型的推理代码和后续性能工作会继续在 DeepInfer 开源」。按这个节奏,这份代码更像是给行业的一份设计说明书 + 可运行的引擎内核,而不是一个交付品。155 万亿 Token/天 是真实的,但它由很多没开源的部分托着——这一点,README 自己承认得挺坦率。

参考文档与链接

你手上的推理服务,prefix 命中率是多少?如果不到 50%,你其实在为一个缓存设计问题持续付卡钱。评论区聊聊你的数字,觉得有收获点个赞。


作者: itech001
来源: 公众号:AI人工智能时代(the-ai-era)
网站: https://www.theaiera.top/ 关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

本文首发于 AI人工智能时代,转载请注明出处。

分享给朋友