25.5k Star 的 DeepInfer 怎么扛住3万亿参数

这周对写服务端的人有两条消息,一条在 GitHub,一条在财报里。

GitHub 上那条是 DeepSeek 把自家推理框架开源了,仓库叫 DeepInfer,10 月 16 日建仓,二十天 25.5k Star、3.1k Fork。README 里写得很清楚:这是支撑 DeepSeek 大规模生产服务的推理框架,开源版放出离线推理的核心能力。

财报里那条是微软不再续签从甲骨文租的 AI 算力,理由是那批服务器的英伟达卡代际太老,不符合当前规格。而甲骨文披露过,用了约四年的 GPU 续约价格比原合同高 20%。

两条消息其实指向同一个工程问题:模型越来越大,硬件换代越来越快,中间那层推理框架要同时兜住两侧的变化。

这篇不聊估值,只聊代码和架构。


DeepInfer 到底解决了什么

先看支持的模型和硬件,这两项决定它的适用边界。

模型目前只支持 DeepSeek-V4.1-Flash,硬件支持 NVIDIA SM100 和华为昇腾 950 NPU。这个组合本身就说明它是为超大规模 MoE 模型调的,不是通用推理引擎。

功能清单里几个设计值得逐条拆:

并行策略。Attention 层走 DP,配均衡的 CP;MoE 走 EP 加 EPLB 做专家负载均衡。3 万亿参数的模型,专家数量多到单机能放下的部分很有限,EPLB 的作用是在线感知各专家的负载并把热点专家重新分布,避免某几张卡被压死。

DSpark 与置信度调度验证。用草稿 token 加速解码,再用置信度估计决定验证哪些位置。开关是 `DEEPINFER_ENABLE_MTP_VARLEN=1`,`DEEPINFER_USE_NEXTN_DECODE` 控制最大草稿长度,默认 5。

SWA 有界重放。这个设计我很喜欢。长上下文场景下,decoder 的 prefill 会被反复重算,开销巨大。它只重放一个有界后缀,把工作量砍掉。默认配置是 `DEEPINFER_YOCO_PREFILL_TRUNCATION_MODE=compact` 加 `DEEPINFER_YOCO_PREFILL_KEEP_TOKENS=140`,保留的后缀必须覆盖 SWA 窗口加最大回溯长度。

异步调度。CPU 侧的批调度和设备执行重叠,默认开启,属于零开销批调度的常规做法,但真要做到"零开销"需要在锁和队列上抠很多细节。

batch-invariant 推理。这是我觉得最被低估的特性。同一段 prompt,放在不同 batch 组合里跑,结果必须一致。开 `DEEPINFER_BATCH_INVARIANT=1`(仅 NVIDIA)。

确定性采样。相同输入 token、相同采样参数,输出完全相同。需要同时开 batch-invariant、关掉 `DEEPINFER_ENABLE_MTP_VARLEN`,并给 `SamplingParams` 传固定的 `seq_seed`。

为什么这两条重要?做过线上推理的都懂:batch 一变,logits 就会有微小差异,采样一放大,输出就跑偏。评测复现不了、线上问题抓不住、A/B 实验对不齐,全是这个原因。

结构化输出。支持正则、JSON schema、EBNF 语法约束,通过 `SamplingParams` 的 `so_args` 传。

底层 kernel 用的是 FlashMLA、DeepGEMM、DeepEP、TileKernels、DeepSelect,加自定义 TileLang 算子。架构基于 vLLM,README 里也承认参考了 SGLang 和 TensorRT-LLM。

依赖环境:Linux、GCC 13 以上、Python 3.12、CUDA 13(NVIDIA)或 CANN 9.2(昇腾)。


上手:编一个,跑一个

编译入口只有一个环境变量切换后端。

```bash

建一个干净的 Python 3.12 环境后

export DEEPINFER_ACCELERATOR=nvidia # 昇腾用 ascend

./build.sh

```

跑离线推理,默认会拉 HuggingFace 上的 `deepseek-ai/DeepSeek-V4.1-Flash-1017`,本地已有权重就指过去,省一次下载。

```bash

export DEEPINFER_HF_MODEL_DIR=/data/models/DeepSeek-V4.1-Flash-1017

python examples/offline_inference.py

```


一个能直接用的 batch-invariance 验证脚本

README 说了这个特性,但没给验证方法。线上要真信它,得自己量。

下面这个脚本打任何 OpenAI 兼容端点都能用(DeepInfer 起服务后,或 vLLM、SGLang 都行),思路是把同一条 prompt 分别放在单条请求、2 条批、8 条批里跑,比较输出哈希。

```python

import hashlib

import os

import sys

from openai import OpenAI

client = OpenAI(

base_url=os.getenv("BASE_URL", "http://127.0.0.1:8000/v1"),

api_key=os.getenv("API_KEY", "EMPTY"),

)

PROMPT = "用一句话解释什么是 MoE 的专家并行,不要超过 40 字。"

SEED = 42

def one(n_repeat: int) -> liststr:

"""把同一条 prompt 复制 n 份发出去,返回每份的文本。"""

resp = client.chat.completions.create(

model=os.getenv("MODEL", "deepseek-v4.1-flash"),

messages={"role": "user", "content": PROMPT} for _ in range(n_repeat),

temperature=0.0,

seed=SEED,

max_tokens=64,

)

return c.message.content.strip() for c in resp.choices

def digest(s: str) -> str:

return hashlib.sha256(s.encode()).hexdigest():12

baseline = one(1)0

print(f"single {digest(baseline)} {baseline}")

ok = True

for n in (2, 8, 16):

outs = one(n)

uniq = {digest(o) for o in outs}

dup_within = len(uniq) == 1

match_base = outs0 == baseline

flag = "OK" if (dup_within and match_base) else "MISMATCH"

if flag != "OK":

ok = False

print(f"batch={n:<3} 内部一致={dup_within} 与单条一致={match_base} {flag}")

sys.exit(0 if ok else 1)

```

跑法很简单:

```bash

pip install openai

BASE_URL=http://127.0.0.1:8000/v1 MODEL=deepseek-v4.1-flash python check_batch_invariance.py

```

脚本返回非 0 就说明这个端点没做到 batch-invariant。注意 temperature 必须设 0,否则比的是采样噪声不是框架行为。另外 `seed` 参数只是让服务端有机会对齐,真确定性还得靠框架自己开 `DEEPINFER_BATCH_INVARIANT=1`。

我拿 vLLM 默认配置试过,batch 从 1 涨到 8 时输出就开始飘,这不是 bug,是浮点累加顺序变了。所以这个检查有实际意义。


另一条线:算力租约的账,比框架更难算

回到微软那条新闻。它给的工程信号是:卡的有效寿命,正在短于合同周期。

四年前买的卡,今天续约要涨价 20%,同时被大客户判定"不符合规格"。这两件事同时成立,说明算力市场已经分层:新卡按性能定价,旧卡按稀缺定价。

对做技术选型的人来说,这意味着 TCO 模型得改。以前按五年折旧摊,现在得按三年算,还要把"第三年开始降级使用"写进去。

一个粗糙但能用的估算脚本:

```python

def tco(card_price: float, cards: int, years: int, kwh_price: float,

watts_per_card: float, utilization: float,

tokens_per_hour_per_card: float) -> dict:

"""单卡 TCO 摊到每百万 token 的成本。"""

capex = card_price * cards

hours = years * 365 * 24 * utilization

power = watts_per_card / 1000 * hours * kwh_price * cards

机房、网络、运维按电费的 1.8 倍粗估

opex = power * 1.8

total_tokens = tokens_per_hour_per_card * hours * cards / 1e6

return {

"total_cost_usd": round(capex + opex, 0),

"total_m_tokens": round(total_tokens, 0),

"cost_per_m_token": round((capex + opex) / total_tokens, 4),

}

for yrs in (3, 5):

print(yrs, "年折旧:", tco(30000, 64, yrs, 0.12, 700, 0.65, 120000))

```

跑出来的差异会很明显。以 64 张单价 3 万美元的卡、电价 0.12 美元/度、单卡 700W、利用率 65%、每卡每小时 12 万 token 这组假设为例:按五年摊,每百万 token 成本约 10 美元;按三年摊,涨到约 15.9 美元,涨幅接近六成。而收入端的推理单价还在往下走。这就是前面说的那笔账。

框架层面的应对其实只有一个方向:提高单位算力的有效吞吐。DeepInfer 那些设计(EPLB、DSpark、SWA 重放、异步调度)本质都在做同一件事,把每一张卡的利用率往上抬。抬得动的部分,就是折旧加速吃掉的那部分。


给做选型的人几句实话

第一,别只看 benchmark 里的吞吐峰值。峰值通常在 batch 拉满、序列长度固定的理想条件下测出来,线上很少是这个形状。

第二,把确定性当成一项功能来验收。有评测、有对账、有回归测试的业务,输出漂移带来的排查成本远高于多花的那点算力。

第三,硬件代际要写进架构假设。如果框架强依赖某种卡的新特性(比如 SM100 的特定指令),换代时迁移成本会很高。DeepInfer 同时支持 SM100 和昇腾 950,这个双栈设计本身就是一种风险对冲。

第四,MoE 的负载均衡不要等上线再调。EPLB 这类机制在流量平稳时看不出价值,一旦某个专家被热点请求打爆,整机吞吐会断崖式下跌。


聊两句

两个问题想问实际操作过的朋友:

  1. 你们线上跑 MoE 模型时,专家负载不均导致的尾部延迟有多严重?是靠框架自动均衡,还是自己在路由层做限流?

  2. 团队做算力 TCO 时,折旧按几年算?有没有人把"第三年后降级跑小模型"这条路真的算进模型里?

我个人倾向于按三年算,宁可保守。财报可以按五年写,业务不能。

有更好的验证脚本思路也欢迎扔到评论区,尤其是怎么在流式输出场景下量确定性,我还没找到特别干净的测法。

相关推荐
Linye21 分钟前
为什么让 AI 修个小 Bug 却把底层全重写了?聊聊 Coding Agent 的最小修改边界
人工智能·架构
Agent世界24 分钟前
cookie 判据会撒谎:CDP 登录态保活的五个实测坑
后端·自动化运维
林小帅25 分钟前
【笔记】Prisma v7 + SQLite TS2305 及连锁 TS7006 问题
前端·javascript·后端
王中阳Go29 分钟前
你那条三跳链路的单跳超时,是按压测的 p95 定的,还是拍出来的?
人工智能·后端·架构
时光不老杰31 分钟前
03 Netty 双通道长连接层
后端
1360967572336 分钟前
报错指的地方,往往不是坏的地方:47 次故障的定位方法
后端
Gopher_HBo40 分钟前
cpuprof.go开关、缓冲区与记账
后端
ting94520002 小时前
Databox MCP Connectors 技术深度解析:协议架构、集成原理与企业落地实践
人工智能·架构
特立独行的猫A3 小时前
13MB 单文件、一条命令变服务:把仓颉写的 cjh 内嵌进你的应用,当它的 AI 大脑
java·后端·python