DeepSeek开源生产级推理框架DeepInfer:单集群一天处理155万亿token,这意味着什么?

1 阅读20分钟

DeepSeek 把跑线上服务的推理框架开源了,叫 DeepInfer。

官方给的说法是:单集群每天 155 万亿 token,谷电价下每张卡每小时收入 38 美元。我看到这组数字的第一反应是去翻代码,看看能不能对得上。

翻完之后感受有点分裂。一边是调度器和投机解码,确实写得好,值得逐行读;另一边是那张漂亮的架构图,上面有三个大块在这个仓库里根本不存在。

这篇按我读的顺序写。能对上源码的地方标了行号,对不上的地方也说了。

它只跑一个模型

DeepInfer 不是 vLLM 那种通用服务框架。模型注册表里只有一条 DeepseekV41ForCausalLM,默认 checkpoint 是 DeepSeek-V4.1-Flash-1017。

DeepInfervLLM / SGLang
支持模型一个几百个
入口形态离线 LLM.generate()OpenAI 兼容 HTTP API
硬件NVIDIA SM100 / 华为昇腾 950广泛的 GPU 型号
优化方式和 V4.1 的结构绑死通用抽象加插件

README 自己写了,最初是基于 vLLM 构建的,也参考了 SGLang 和 TensorRT-LLM。这话没错,但只说了一半。

Python 那层确实还留着 vLLM 的形状:LLM、EngineArgs、Sequence、SamplingParams,连注释都像。可 csrc/engine/ 底下的调度器、块管理、输入组装是重写的 C++,model_executor/models/v4_modules/ 里的模型结构也是为 CED、YOCO、Engram、DFlash 单独写的。

拿 vLLM 的壳,装了台为自家模型定制的发动机。这个比喻我觉得还挺准。

那张架构图,画的不是这个仓库

请添加图片描述

先看绿色那块,DeepSeek Recipe。它是协议层,把 Chat Completions、Responses、Messages 三种 API 的 JSON 统一成对话和 token 序列,再往引擎里送;引擎吐出来的 token 流也由它解析回各家协议的 SSE 响应。组件在另一个仓库 deepseek-recipe,不在 DeepInfer 里。

红色是 Entrypoint,请求入口。它会拿请求去查 KV cache 的前缀,只查元数据,走哈希链,然后决定这个请求该进 prefill 还是 decode。

黄框和橙框分别是 Prefill Service 和 Decode Service。前者吃没缓存的 prompt 算出 KV,后者一个 token 一个 token 地往外吐。每台机器内部还塞了一个 Expert-Parallel Load Balancer,管专家怎么分。

紫框是视觉编码器。图片先过 ViT 出 embedding 再进 prefill,多模态走 EPD 三阶段分离。

三个蓝色圆角框是三个负载均衡器,路由维度各不相同。VE 那个按图片 patch 数挑最闲的 GPU;Prefill 那个按上下文长度分四档(<16K、16–64K、64–256K、≥256K),按上一轮的算力配额动态分配;Decode 那个同时看请求数和总 KV 长度,短请求往并发低但 KV 长的卡上送。

最底下灰色的是 3FS 上的 KV 存储集群。粗蓝箭头是 cache 的读写,prefill 写完落盘,decode 按需拉。

整张图逻辑很顺。问题在于,红框的路由、三个蓝框、底下那层存储,这个仓库里都没有。

LLMEngine 里能翻到 init_pd_split()、do_save_kvcache()、send_processed_prompts() 这几个方法,点进去看,要么是 pass,要么是个默认实现。这是给内部系统留的扩展点,不是开源功能。

仓库分五层

mermaid diagram

具体到目录:

目录干什么规模
deepinfer/engine/引擎主循环、参数解析、统计日志6 个 py
deepinfer/worker/Worker、ModelRunner、CUDA Graph、CacheEngine10 个 py
deepinfer/model_executor/模型结构、算子、并行通信、EPLB24 + 33 + 30 + 30 个 py
deepinfer/ve/多模态预处理9 个 py
deepinfer/structure_output/结构化输出的编译与匹配5 个 py
csrc/engine/调度器、块管理、输入准备、采样准备约 20 个 cpp/hpp
csrc/graph_timer/CUDA Graph / 昇腾 profiler 计时4 个文件
deep_cluster/硬件探测、NUMA 绑定5 个 py
vendor/6 个 submodule:FlashMLA、DeepGEMM、DeepEP、DeepSelect 及昇腾版—

热路径基本都在 C++ 里。原因也简单:调度器每生成一个 token 就要跑一遍,decode 阶段每秒几十到上百 step,Python 那点开销会被放大到不能忍。scheduler.hpp 一千三百多行,全是每个 step 的必经之路。

一个请求怎么走完

mermaid diagram

入口在 deepinfer/entrypoints/llm.py 的 LLM.generate()。编码 prompt、逐条 add_request、循环 step(),就这三件事。

主循环是 llm_engine.py:860 的 step(),一次调用产出一批 token:

# llm_engine.py:881
with cpu_timer.record("schedule"):
    seq_metadata_list, scheduler_outputs = self.scheduler.schedule(
        self.sequence_metadata_pool
    )
# ... 处理 clone_states / so 状态 / 多模态 fetch ...
request_outputs = self._execute_model_async_step(seq_metadata_list, scheduler_outputs)

调度那步在 csrc/engine/scheduler.hpp:275。它要回答的是:这一步跑 prefill 还是 decode,跑哪些序列,每个序列跑多长的 chunk。

执行在 deepinfer/worker/worker.py:89。把调度结果变成 GPU 张量,forward,采样,异步模式下再把 post-process 推到下一轮。

源码里几个我想记下来的地方

调度器要投票

EngineType 有三种:PROMPT 只做 prefill,COMPLETION 只做 decode,NORMAL 两个都做。离线推理走的是最后一种,也对得上架构图里的 Prefill Service 和 Decode Service。

NORMAL 有个很实际的问题。一个 DP 组里所有 rank 必须做同一件事,rank 0 在 prefill、rank 1 在 decode,allreduce 就死锁了。

源码里的解法是投票,scheduler.hpp:295:

bool is_any_point = (decode_step != 0) && (decode_step % prefill_any_attempt_interval == 0);
bool is_all_point = (decode_step % prefill_attempt_interval == 0);
if (!is_any_point && !is_all_point) {
    return _schedule_decode(acquire);
}

bool want = (get_gpu_cache_usage() <= GPU_CACHE_PREFILL_WATERMARK) && _has_prefill_waiting();
bool do_prefill;
if (is_any_point) {
    // ANY:任一 rank 想做即触发
    do_prefill = (_dp_allreduce(want ? 0 : 1, c10d::ReduceOp::MIN) == 0);
} else {
    // ALL:全员想做才触发
    do_prefill = (_dp_allreduce(want ? 1 : 0, c10d::ReduceOp::MIN) == 1);
}

ALL 点每 prefill_attempt_interval 个 decode step 出现一次,要求全员都有 prefill 活,避免一个 rank 干活、其他 rank 陪跑。ANY 点间隔更短,任一 rank 有活就一起做,给孤立的那个 rank 兜底。

后面还有第二轮投票。want 只是看 waiting 队列非空,_schedule_prefill 仍可能因为 slot 满了、KV 块不够而空手而归。全组都空手就得转 decode,不然后面会陷入"做空 prompt step 把 decode_step 清零,下一步接着投票接着空手"的循环。

另外 GPU_CACHE_PREFILL_WATERMARK 是 0.9,缓存占用过了九成就不再接 prefill。

这段投票逻辑我没在别的解析文章里见过,但它是"分离部署"这套架构落到单机离线场景时最真实的妥协。

显存是切成块管的

csrc/engine/block_manager.hpp 的思路和操作系统管内存页差不多。显存切固定大小的 block,按需分配,引用计数,用完回收。

核心就三个方法:

int allocate();           // 从 free_blocks 链表取一个
void free(int block_id);  // 还回去
AllocStatus can_allocate_nolock(int to_allocate_blocks);

这么做的收益很直接。请求长短不一,不用预留连续显存;相同前缀可以共享物理 block;请求被抢占时只放 block,不搬数据。

每个序列要多少 block,scheduler.hpp:191 是这么算的:

return (seq.get_len() + seq.generation.stopping.max_tokens + block_size - 1) / block_size + 1;

prompt 长度加上最大生成长度,向上取整,再多留一个。

异步调度省的不是计算,是等待

官方叫它 zero-overhead batch scheduler。这个说法我看完代码后觉得得打个折。

原来的流水线是这样:

schedule(N) → forward(N) → sample(N) → [等 GPU 结果] → post-process(N) → schedule(N+1)
                                          ↑ GPU 在这里空转

异步之后,GPU 跑 forward(N) 和 sample(N) 的时候,CPU 同时在跑 schedule(N+1)、启动下一轮 forward、处理上一轮的 post-process。等待那段被填掉了。

但 CPU 的开销没消失。事件同步、元数据处理、资源回收都还在,只是从"GPU 等 CPU"变成了"CPU 躲在 GPU 执行时间里"。

第三方那篇解析说得更直白:零开销是设计目标,不是事实。我同意。

对应开关是 DEEPINFER_ZERO_OVERHEAD_SCHEDULING。

DSpark 卖的是验证算力

普通投机解码很粗暴:草稿模型一次吐 5 个,大模型并行验,接受几个算几个。

但每个草稿 token 被接受的概率差很多。固定验 5 个,等于把算力平均撒在一堆低概率 token 上。

DSpark 加了个 Confidence Head,预测每个草稿位置的接受率,再决定验几个。入口在 csrc/engine/mtp_varlen.hpp:150:

void schedule(const std::vector<std::shared_ptr<Sequence>> &scheduled,
              std::vector<int> &seqlens_q) const {
    ...
    // 维护两个 queue,一个用于计算 best_bsz,一个用于计算 seqlen_q
    std::vector<std::pair<float, int>> acc_queue_for_bsz;
    std::vector<std::pair<float, int>> acc_queue_for_seqs_q;

把每个草稿位置按置信度排队,枚举验证规模,挑单位时间产出最大的那个。

产出怎么估?两个运行时估计器。ForwardRuntimeEstimator(mtp_varlen.hpp:48)拿最近观测到的 forward 耗时去修正启动时 profile 的那条曲线;SamplerRuntimeEstimator(mtp_varlen.hpp:20)用滑动窗口中位数,优先取同一请求数下的样本,样本不够再回退到全局。

这里有个特别容易写错的地方,注释里写得很清楚:

// 需要保证 confidence_{i+1, ..., nextn} 不影响 draft_token_i 是否被验证。
// 假设此时在第 N 轮,我们期望使用 N-2 轮的 next_n_token_accept_rate 去计算 best_bsz;
// 并使用 N-1 轮的 next_n_token_accept_rate 去分配每个请求的 seqlen_q

两个约束叠在一起。空间上,后面位置的置信度不能反过来影响前面位置要不要验,不然逻辑就自相矛盾。时间上,异步流水线里第 N 轮调度时第 N-1 轮的结果还没回来,所以 batch 规模用 N-2 轮的接受率估,每个请求的验证长度用 N-1 轮的估。

为了不漏账,每个请求带 schedule_cnt 和 process_cnt 两个计数器,配一个断言:

TORCH_CHECK(mtp.process_cnt <= mtp.schedule_cnt && mtp.schedule_cnt <= mtp.process_cnt + 1, ...);

差值为 0 说明前后配对,用 N-1 轮的数据;差值为 1 说明最新一次 forward 还没产生接受率,得再往回退一轮。

官方数据是:验证长度从固定 5 降到 3.2 到 4.4,平均接受长度基本没变(3.29 对 3.20),生产工作点大概 60 并发每 rank,吞吐提了 4% 到 7%。

打开开关 DEEPINFER_ENABLE_MTP_VARLEN=1,最大草稿长度由 DEEPINFER_USE_NEXTN_DECODE 控制,默认 5。

EPLB 盯的是最忙的那张卡

MoE 的毛病是专家热度不均。有的专家天天被路由到,有的基本闲着,最后所有卡一起等最慢的那张。

EPLB 的思路是给热门专家加冗余副本。eplb/policy.py 分两步走:先按最近 N 步的 token 负载决定复制谁,再用贪心把 physical 副本摆到各 rank 上。

第二步的目标函数有个细节我觉得挺关键:它盯的是历史最忙的 rank,不是长期平均负载。看平均会漏掉尾延迟,而卡住整批的就是尾延迟。

冗余副本数还要求能被 ep_size 整除:

def resolve_num_extra_experts(num_routed_experts, min_num_extra_experts, ep_size):
    """取不小于下限、且使 num_physical_experts 能被 ep_size 整除的冗余 expert 数。"""
    padding = -(num_routed_experts + min_num_extra_experts) % ep_size
    return min_num_extra_experts + padding

重排的动作是 expert_model_parallel_shuffle_inplace,通过 NVLink 的 symmetric memory 直接搬权重,不走网络。

效果官方给的是 prefill moe_lb 1.074(EP4DP4)和 1.045(EP2DP2),decode 1.090。这个指标是最慢 rank 除以平均值,1.0 是完美。

YOCO 的 140 不是截断

V4.1 的层分两种:真正做 prefill 计算的 Encoder 层,和复用前面状态的 Consumer 层(YOCO,You-Only-Cache-Once)。

麻烦出在 KV cache 命中时。如果只命中了 block KV,SWA(滑动窗口注意力)的 KV 是缺的。朴素做法是整段重算,可 YOCO 下重建 decoder 状态要把最后 2560 个 token 跑过 20 层,太贵。

实际做法是只重算最后 128 个 token,并且把注意力窗口截在重放段里面。官方原话是:

replaying from position s, the query at position i is computed only against keys in the range max(s, i−127) to i

滑动窗口本来也只看最近 127 个位置,重算更早的没意义。这样重算成本变成常数,跟上下文长度和层数都无关。

README 里给的配置是:

DEEPINFER_YOCO_PREFILL_TRUNCATION_MODE=compact
DEEPINFER_YOCO_PREFILL_KEEP_TOKENS=140

这个 140 我看到过好几种误读,最常见的是"上下文被砍到 140 个 token"。完全不是。它是特定 decoder 路径的后缀重放长度,不截断用户输入,也不缩模型 cache。

约束是 keep_tokens >= window_size + max_backtracking_tokens。投机解码要回滚,回滚长度得留够窗口历史。默认 nextn=5 时回溯余量是 6,下限就是 134,示例里取 140 多留了几个 token 的余量。

一套逻辑,两套算子

支持昇腾不是"能跑起来"这么简单,两套 kernel 都做了优化。

deepinfer/model_executor/layers/tilelang_ops/
├── cuda/     30 个 .py   # CUDA 版 TileLang 算子
└── asc/      30 个 .py   # 昇腾版,一一对应

采样、融合采样、KV 读写、SWA 索引、DFlash、结构化输出、压缩、gather、norm,都能找到对应的两份。上层靠 PLATFORM 判断走哪套,模型结构、调度、并行通信共用。

底层 kernel 库也是双份 submodule:FlashMLA、DeepGEMM、DeepEP、DeepSelect,加上 DeepGEMM-Ascend 和 DeepEP-Ascend。

这块我觉得是这次开源对国内团队最实在的部分。算法逻辑一份,硬件适配两份,CUDA 和 Ascend 的差距能压到最小。

确定性和结构化输出

Batch-invariant 说的是同一份输入换个 batch 组合,结果得完全一样。这件事难在 GPU 上的 reduction、矩阵乘法分块、FP8 量化粒度都会随 batch 形状变,不同 batch size 下的 logits 可能数值上就有差。

DEEPINFER_BATCH_INVARIANT=1 打开,目前只支持 NVIDIA。tests/models/test_batch_invariant.py 的验证方法是先整批生成一条轨迹,再单独重放同一条轨迹,比对 token、logprob 和 top-logprobs。

注意它验证的是沿固定轨迹的数值一致性,不是任意随机跑都输出一样。

确定性采样更严格,要求相同输入 token 加相同采样参数出相同输出。需要三个条件一起:

DEEPINFER_BATCH_INVARIANT=1
DEEPINFER_ENABLE_MTP_VARLEN=0
# 并且给 SamplingParams 传固定的 seq_seed

关掉变长验证,是因为动态的验证长度本身就会改变执行路径。

结构化输出用的是 xgrammar,requirements.txt 里锁的 0.2.2,支持正则、JSON Schema 和 EBNF。它是编译和推理解耦的:schema 先编译成语法自动机,有专门的 SO builder 进程异步跑,DEEPINFER_SO_BUILDER_CPUS 控并发;推理时每个 decode step 推进自动机,算出合法 token 集合,生成 bitmask 打到采样上。

llm_engine.py:913 附近还有段守卫:最后一个 prefill chunk 的 SO 状态如果不对,直接把请求判死,免得整个调度循环卡住。

三张性能图,和四个容易踩的误读

官方给了三张图,都有价值,但不能当跨框架对比的结论用。

请添加图片描述

第一张是 prefill。配置写在图上方:EP4DP4 | 384+32 experts | context 131,072 | Decoder Bounded Replay (140 tokens)。横轴是一个 prefill step 的耗时,纵轴是非缓存输入吞吐(tokens/s/GPU),点上的数字是每个 DP rank 的 token 数。

从 4096 加到 32768,吞吐从 60000 涨到 87000 附近。再从 32768 加到 65536,吞吐只到 89000,延迟却从 380ms 涨到 730ms。

这就是 chunked prefill 的拐点。再往上加批量,等于拿延迟换几乎为零的吞吐。社区里默认的 max_num_batched_tokens=32768 和这个拐点是对得上的。 请添加图片描述

第二张是 decode。EP64DP64 | 384+64 experts | context 131,072 | nextn=3 fixed | per-token acceptance 75% → τ=3.25。横轴是单用户生成速度,纵轴是每卡吞吐,点上的数字是每个 DP rank 的并发请求数,不是总数。

换算是这么回事:

τ = 1 + nextn × acceptance_rate        # 1 + 3 × 0.75 = 3.25
per_user_tokens_per_s = avg_SPS × τ
tokens_per_s_per_gpu  = avg_SPS × requests_per_DP_rank × τ / CP

并发从 8 加到 256,每卡吞吐从 2500 涨到 26000,单用户速度从 325 掉到 105。很标准的吞吐延迟权衡。

请添加图片描述

第三张把 EP8DP8 和 EP64DP64 叠在一起。同样的单用户速度下,EP64 的每卡吞吐高出一大截。单用户 250 tokens/s 时,EP8 大概 6000 tokens/s/GPU,EP64 有 15000。

原因不难想。Wide-EP 把专家摊到更多卡上,每步要读的权重总量不变,但每张卡读的部分少了。MoE 这部分本来就是 memory-bound,少读就快。再叠上 EPLB 把负载压平,TPS 就上去了。代价是更多的卡、更大的通信域、更难的故障恢复。

四个误读,我觉得值得单独列一下。

路由是受控的。DEEPINFER_FORCE_LOAD_BALANCE=1 配 Gate 的 force_random,测的是干净的性能上界,不是真实流量的热点分布。

测量窗是挑过的。跳过 warmup,跟 MoE 统计 flush 冲突的区间直接丢,正式 sweep 关 profiler。这些做法本身合理,但意味着数字是最佳稳态,不是平均体验。

请求是构造出来的。共享前缀 fork 加未缓存后缀,prefill 和 decode 分开测,不是冷缓存下的随机 HTTP 流量。

没有对照组。官方没给同配置的 vLLM 或 SGLang 数据,所以这三张图证明不了 DeepInfer 比谁快,只能说明它自己的扩展性。

decode 那张图还有一层:吞吐是按 75% 接受率换算的,脚本里明确拒绝 MTP_VARLEN=1 的数据,怕重复计算。所以它也证明不了 DSpark 在真实流量下能赚多少。那个数据得看官方 Q&A 里 60 并发下的表格,+5.4%。

别人怎么看

最完整的一篇源码分析是 aik8s.run 的《DeepInfer 架构与源码深度解析》,作者锁在首个 commit d585e65 纯读码,没跑 GPU,这点它自己交代了。里面几个判断我核对过,站得住:

EP64DP64 不是 4096 张卡,进程组复用 rank,CP=1 时 DP 可能直接被默认成 EP。零开销是目标。DSpark 的收益来自给验证工作定价。YOCO 的 140 是特定路径的后缀重放。EPLB 第二阶段盯最忙 rank。官方图表的四个前提。质量数据是上游参考值。硬件范围比宣传窄,H20、L20、RTX PRO 5000 Blackwell 都不在官方配置里,后者是 compute capability 12.0,和 SM100 的 10.0 不是一回事。构建会污染已有的 vLLM 环境,强制装 torch==2.13.0+cu132 和 NCCL 2.32.3,在同一个环境里做对比实验等于白做。

关于"缺 KV cache",它也讲清楚了:cache_engine.py 管的是引擎内部的 KV,压缩注意力、索引 cache、SWA 环形状态、跨层复用,这些都在;缺的是跨实例那一层的命名、定位、传输、共享和生命周期。

Hacker News 那条主贴有 2310 分,885 条评论,但讨论重心基本不在技术上,在钱上。有人算推理是赚的,有人提醒推理赚钱不等于 AI 生意赚钱,训练和研究还在烧,模型还会过期。也有人担心开源权重加一堆推理服务商会把价格打穿。

有个实操反馈挺有意思:V4.1 Flash 单看大概 300 tokens/s,但做 agentic 任务只快 25% 到 50%,因为思考轮次和跑命令都变多了。

中文媒体基本是通稿转述。多出来的一个数字是外部估算的毛利率 82% 到 96.94%,取决于缓存命中率和 GPU 租价。推算,不是官方说法。

开源的边界

这节可能是全文最实用的。仓库能跑的,和架构图画着的,差得比想象中多。

开源了没有
离线 LLM.generate() 批量推理OpenAI 兼容的 HTTP 服务
C++ 调度器 + 分页 KV + 抢占跨实例 KV cache 存储(3FS)
单机 / 多机 EP、CP、DPEPD 三阶段分离部署
EPLB 专家负载均衡Prefill / Decode / VE 三个负载均衡器
DSpark 投机解码 + 置信度调度自动扩缩容、故障转移
SWA bounded replay前缀路由器
多模态 VE + ViT多副本间的请求路由
结构化输出运维体系:指标、告警、限流、鉴权
双后端算子—

还有一点容易被忽略。官方 Q&A 里那套 cost(q, c) 二次代价模型,用算力预算反解 chunk 大小,在仓库里搜不到。我 grep 过 compute_quota、cost_model,都没有。它属于没开源的 Prefill Load Balancer。

仓库里真正约束分块的是这几个东西:max_num_batched_tokens、prefill_max_sum_seqlen_k、block manager 的可用块数,还有那个 0.9 的水位线。别在 csrc/ 里找代价模型,它不在。

我会怎么用它

如果你的场景是 SM100 或者 Ascend 950 上跑 V4.1-Flash,而且做的是离线批量推理,比如数据清洗、合成、评测、批量改写,这东西可以直接用。

如果你想研究生产级推理引擎长什么样,想抄它的调度和解码设计,更值得读。它把"验证工作定价"这件事摊开写了,这个思路能搬到任何投机解码实现里。

但如果你要一个 OpenAI 兼容的服务去接前端、接 Agent,不行。要跑 Llama 或 Qwen,不行。在 H100、H20 或者消费卡上,不行。要多租户、限流、鉴权、计费,都不行。

想补齐的话,至少得自己写 HTTP 服务层,处理协议、流式、取消、超时和背压;得做请求路由,按输入长度、decode 在途负载和缓存位置来分;得补跨实例 KV cache 的命名、传输和生命周期;多副本之间还得有负载均衡;最后是 TTFT、TPOT、排队时间、专家负载这些指标。

工程上要做的事不少。

上手

构建环境必须是 Linux、Python 3.12、GCC 13 以上。

export DEEPINFER_ACCELERATOR=nvidia   # 或 ascend
./build.sh

NVIDIA 要 CUDA 13,昇腾要 CANN 9.2。build.sh 会装 Python 依赖、把 NCCL 强制重装成 2.32.3、编译六个 vendor 库和 deepinfer._C 扩展。

这句提醒再说一遍:用全新的 Python 3.12 环境,装进已有的 vLLM 环境会改 torch 和 NCCL 版本。

跑第一个例子:

python examples/offline_inference.py --ep 8

--ep 8 是示例值,不是最低要求。默认模型会自动下到 HF cache,也可以用 DEEPINFER_HF_MODEL_DIR 指本地目录。

读码的话,我建议这个顺序:先看 examples/offline_inference.py 里怎么调用,再看 entrypoints/llm.py,然后钻进 llm_engine.py:860 的 step()。把这条主循环抓住之后,再去 scheduler.hpp:275 看调度,去 worker.py:89 看执行。投机解码单独看 mtp_varlen.hpp:133,模型怎么搭起来看 v4_modules/builder.py。

别从第一行开始读。这仓库更像浏览器的渲染引擎,不是业务代码,C++ 那层是排版引擎,Python 是上层 API,算子库是合成器。

最后说个我自己的感受。DeepInfer 最有价值的地方不是"又一个推理框架",而是它把一套完整生产系统里的协同设计露出来了:验证算力怎么定价,专家负载怎么压平,cache 怎么在多个阶段之间流转。这些在论文里通常只有结论,这里能看到代码。

至于那个 155 万亿的数字,它背后还有 KV 存储、负载均衡和分离部署三块没公开。仓库给你的是发动机,不是整车。


参考:

文中的架构图和三张性能曲线来自 DeepInfer 官方仓库 doc/images/,版权归 DeepSeek-AI。源码引用对应首个公开 commit d585e65。