📦 GitHub: https://github.com/geekchow/deepseek-v41-flash-inference-guide
你在哪里:已知问题与定义,现在一次性铺开整片领域。
读完本文你将知道:8 个核心概念(按依赖顺序)、7 个关键组件各自“负责什么 / 知道什么 / 刻意不做什么”,以及它们如何协同把一个请求变成一个回答。此处不讲内部实现。
3.1 领域映射:从问题到概念
| # | 现实问题 | 系统概念 | 一句话定义 | 为什么是这个抽象 |
|---|---|---|---|---|
| C1 | prefill 和 decode 脾气相反 | EPD 分离 | 视觉编码(VE,Vision Encoder)、预填充(P)、解码(D)部署在不同机器池,各自扩缩容 | TTFT 与 TBT 可以分别优化;各阶段选各自最优并行度和硬件 |
| C2 | MoE 权重太大、decode 访存瓶颈 | Attention DP + MoE EP(Wide-EP) | 注意力按数据并行(#DP = #EP),专家按专家并行切到多卡;decode 用 EP64–128 | EP 越宽,每卡要读的专家权重越少,批越大,矩阵乘效率越高 |
| C3 | 缓存要省、要大、要可靠 | 分层 KV 缓存 | 三类:在途 KV(显存)、SWA KV(本机内存,单副本)、Block KV(3FS 集群,分页) | 不同 KV 体积与复用价值差异巨大,分层存放成本最低 |
| C4 | 多轮请求大量重复前缀 | 前缀命中与命中策略 | 用哈希链对前缀做元数据匹配;命中长度由 Block KV 决定,最后一块是否重算由 SWA KV 决定 | 任意 prefill 机器可命中任意前缀,路由不必考虑亲和 |
| C5 | SWA 缓存缺失时重算代价随层数和长度增长 | SWA Bounded Replay | 只重放最近 128 个 token、并把注意力窗口截断在重放段内,得到近似 SWA KV | 重算代价变为常数;持久化 KV 降到 V4-Flash 的约 1/8 |
| C6 | 请求长短悬殊,按“请求数”均衡不准 | 计算配额(compute quota) | 用拟合的二次代价模型 cost(q, c) 把请求换算成纳秒级时间预算,按预算调度和均衡 | 均衡的是“算力时间”,而不是“请求个数” |
| C7 | 固定长度投机解码浪费验证算力 | DSpark 变长验证 | 草稿模型一次出 5 个 token,置信度头(Confidence Head)预测每个的接受率,只验证边际收益最高的前缀 | 验证 token 数减少约 30%,接受长度几乎不变 |
| C8 | 三种 API 协议、控制 token 注入风险 | 统一 Conversation + 特殊 token 区间 | 所有协议先转成同一个 Conversation,再渲染出 prompt 和“哪些字节是真正的特殊 token” | 一套模板服务三种协议;用户文本中的同名字符串只能是普通文本 |
依赖关系:C1 → C2(分离后才能各选并行度)→ C3/C4(有了分离和多副本,缓存必须共享)→ C5(共享缓存只存 Block KV,SWA 缺失时怎么办)→ C6(请求换算成算力才能均衡)→ C7(decode 侧再提速);C8 横跨入口和出口。
3.2 关键组件:从概念到组件
下图回答:系统的物理分层长什么样(官方架构图)。

黑色箭头为请求流,蓝色粗箭头为 KV 缓存流。
| # | 组件 | 负责(Owns) | 知道(Knows) | 刻意不做(Does not do) |
|---|---|---|---|---|
| K1 | deepseek-recipe | 协议 JSON ↔ token 序列 + 采样参数;输出 token 流 ↔ 协议流式事件 | 各协议字段语义、V4/V4.1 模板、特殊 token 表、tokenizer | 不推理、不发 HTTP、不执行工具、不算 logprobs |
| K2 | Entrypoint | 请求入口;前缀命中长度计算;选择 prefill 路由;回收 decode 结果 | 本地 kvcache-store(CHECK 角色)的哈希链元数据;SWA KV 位置目录(按 key 分片) | 不搬运 KV 数据本身(只看元数据) |
| K3 | KVCache Storage(kvcache-store + 3FS) | 持久化 Block KV;按 LRU 回收过期缓存 | ~100 PiB SSD 上每个块的位置;10+2 纠删码分组 | 应用层不做副本、不做 TTL 判断(全交给 3FS GC) |
| K4 | 负载均衡器族(Prefill LB / Decode LB / VE LB / EPLB) | 把请求分配到 DP 副本;把专家分配到 GPU | 各引擎剩余计算配额、并发数、KV 总长度、专家近期负载 | 不考虑前缀亲和(缓存是全局共享的) |
| K5 | Vision Encoder Service | 把图片编码成 embedding 交给 prefill | 每卡正在处理的 patch 数 | 不参与文本 prefill;单卡即可,用便宜卡 |
| K6 | Prefill Service(DeepInfer 实例,EP2–8) | 计算未命中后缀的 KV;执行 SWA Bounded Replay;把 KV 写入 3FS 并传给 decode | 本批请求的命中长度、换入的 KV 块、时间预算 | 不做长时间生成;不用 TP(Tensor Parallelism,张量并行)/ CP(Context Parallelism,上下文并行) |
| K7 | Decode Service(DeepInfer 实例,Wide-EP 64–128) | 逐步生成 token;DSpark 投机解码;结构化输出掩码;把 decode 产生的 KV 也落盘 | 在途 KV、每请求每草稿 token 的接受率、语法自动机状态 | 不做 KV offload(decode 不受缓存容量约束) |
这 7 个组件就是第 5 章深潜的目录(K5–K7 同属 DeepInfer,合并为一个子文件夹)。
3.3 协同一览:快乐路径
下图回答:一个请求从 JSON 进来到 JSON 出去,依次经过谁、带着什么数据。
两条最重要的非快乐路径(机制留到深潜):
- SWA KV 缺失:Block KV 命中了,但 SWA KV 所在机器不可达 → 命中长度回退一个块(128 token)并重放 → 见 05.2 Entrypoint 与 KV 存储。
- Decode 实例下线 / GPU 故障:1 分钟宽限期后把未完成请求连同 KV 一次性转给其他实例;EP 规模按健康 GPU 数重新确定 → 见 05.5 弹性与容错。
3.4 质量检验
现在你应该能在白板上画出:入口(recipe + Entrypoint)→ 三类均衡器 → 三类服务池 → 共享存储,并说出每个组件为什么必须存在——即使还不知道任何一个组件的内部细节。
下一篇:04-running-example.md — 贯穿示例 | 返回:00 总览
📚 返回专栏目录
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/PhilZhou/article/details/168962920



