首页 / 资讯中心 / 文章详情

05.4.1 · DeepInfer Prefill 详解:小 EP、按时间预算切 chunk 与 SWA Bounded Replay

05.4.1 · DeepInfer Prefill 详解:小 EP、按时间预算切 chunk 与 SWA Bounded Replay ★ FEATURED ARTICLE
GitHub: https://github.com/geekchow/deepseek-v41-flash-inference-guide背景本文选自开源学习指南《DeepSeek V4.1 Flash 大规模推理部署实践》。全书用一个贯穿示例串联编程 Agent 通过 Messages 协议发起第三轮请求上下文 10 万 token、带一张截图、以edit_file工具调用结束文中的“第 N 步”即指该示例中的步骤完整场景见 04 贯穿示例。你在哪里DeepInfer 子系统第 1 篇贯穿示例的第 ④截图编码和第 ⑤预填充。读完本文你将知道prefill 实例的并行配置、两种 SWA Bounded Replay编码器侧、解码器侧的精确定义与收益、视觉编码如何接入以及 prefill 的实测吞吐。1. 角色回顾负责计算未命中后缀的 KV重建缺失的 SWA KV把新 KV 写回 3FS 并传给 decode。配置普通 8 卡机器EP2–8 / DP2–8在显存允许的前提下用最小的 EP/DP减少通信不用 TP / CP。出现在示例④⑤。2. 内部设计2.1 为什么 prefill 用小 EPprefill 每步处理成千上万个 token矩阵乘已经足够“胖”算力是瓶颈没必要靠扩大 EP 来增大批反而 EP 越大all-to-all 通信越多。所以“显存放得下就行”EP 越小越好。2.2 SWA Bounded Replay核心定义传统做法如果某段前缀的 SWA KV 缺失要精确重建它就得把窗口内的 token 逐层重算——而每层的输入依赖上一层输出窗口效应逐层叠加精确重建需要回溯的长度随层数增长。Bounded Replay 的做法只重算最近 128 个 token并把注意力窗口截断在重放段内。从位置s开始重放时位置i的 query 只与[max(s, i − 127), i]范围内的 key 计算得到一个近似的SWA KV。下图回答精确重建与有界重放分别要算多少。替换为Bounded Replay最后 128 token窗口截断在段内代价为常数与长度和层数无关精确重建解码器侧最后 2,560 token逐层跑 20 个解码器层结果重算代价变为常数与上下文长度和层数都无关。这是一个“用极小近似换大量算力”的工程取舍V4.1 论文摘要把“持久化 KV 降到 V4-Flash 的约 1/8”直接归功于 SWA Bounded Replay。近似对输出质量的影响官方 QA 未给出数字开源仓库提供了 mask / compact 两种截断实现的等价性校验见 2.4。2.3 两处使用位置场景做法收益编码器侧前缀命中但 SWA KV 缺失命中长度只看 Block KV把命中前缀的最后 128 token 与未命中后缀一起前向重放段只重建 SWA KVBlock KV 原样复用既不重算也不覆写SWA KV 可以只存单副本在本机内存丢了也只多算 128 token解码器侧每次 prefillCED 结构中 prefill 只在编码器层计算解码器层的 Block KV 由最后一个编码器层隐状态投影得到只剩解码器 SWA KV要逐层算。精确重建需要最后 2,560 token 跑 20 个解码器层改为只对 prompt 最后 128 token 在解码器层重算结果只给 decode 用、不进前缀缓存prefill 总计算量接近减半2.4 开源版里的开关# V4.1 默认配置exportDEEPINFER_YOCO_PREFILL_TRUNCATION_MODEcompactexportDEEPINFER_YOCO_PREFILL_KEEP_TOKENS140# 保留后缀需覆盖 SWA 窗口 128 最大回退长度140 而不是 128保留后缀必须覆盖SWA 窗口 最大投机回退长度。命中策略中的 134 128 6同样考虑了回退。mask与compact两种截断模式输出等价可用examples/yoco/yoco_equiv.py验证L1 级只比对元数据单卡、秒级、不加载权重L2 级在 8 卡上用固定 teacher-forcing 轨迹逐元素比对 logprob 与 top-K。2.5 视觉编码VE接入部署上是 EPD 分离VE 单卡一个实例推荐便宜的卡引擎侧CPU 预处理由MultimodalProcessor工作进程异步完成不在单步关键路径上GPU 侧流程为 pad → ViT → downsample → aligner产生的 embedding 填入 prompt 中image占位处开源benchmark.py --prompt_mode image时 ViT 与 LLM 在同一引擎内没有做分离。2.6 实测吞吐EP4DP438432 个专家上下文 131,072开启解码器 Bounded Replay140 token。点标签为每 DP rank 的 prefill 批大小。每 rank 批大小token单步时延未命中输入吞吐token/秒/卡4,096~70 ms~60,0008,192~115 ms~71,50016,384~200 ms~81,50032,768~375 ms~87,00065,536~730 ms~89,50032,768 之后吞吐几乎不再增长、时延翻倍——这正是 Prefill LB 把单卡 chunk 上限定为32,768的原因。3. 交互契约对端输入输出Prefill LB请求 命中长度 本步时间预算—KVCache Storage命中块GDR 逐层换入、SWA 快照本地或 400G 拉回新的完整块写回 3FSVE Service图像 embedding—Decode Service—Block KV SWA KV同一条 P→D 路径4. ⚓ 回到示例第 ④ 步截图prefill 引擎在 prompt 中看到image占位经 VE LB 交给一张 VE 卡该卡做 pad → ViT → downsample → aligner返回对应数量的图像 token embedding填入占位位置。这些图像 token 也计入L 100,000。第 ⑤ 步预填充假设命中正常96,896这一步内部依次发生换入96,896 token 的 Block KV 从共享内存经 GDR 逐层进入 HBM与下面的计算重叠SWA 快照1.35 MiB从 D-17 拉回。编码器层前向只对 3,104 个未命中 token 计算注意力能看到全部 100,000 token 的 Block KV。MoE 部分 4 卡 EP由 EPLB 均衡。解码器层不对 3,104 个 token 全部算 SWA而是只对 prompt最后 140 个 tokenKEEP_TOKENS140在解码器层重放窗口截断在段内得到 decode 所需的近似解码器 SWA KV——它不进前缀缓存。落盘新的完整块写入 3FS⌊100,000 / 128⌋ 781块第 758–781 块24 块覆盖到 99,968为新增。SWA 存储位置prefill 结束后存储位置 ⌊(100,000 − 1) / 128⌋ × 128 99,968写入本机内存并登记到 Entrypoint 目录。交给 decodeBlock KV SWA KV 经 P→D 路径发送。粗略耗时以 87,000 token/秒/卡的满载吞吐估算3,104 token 本身只需几十毫秒量级实际 TTFT 主要由排队、换入和 P→D 传输决定。媒体转述的线上平均首 token 约 0.4 秒。变体D-17 宕机命中回退到 96,768第 2 步变为“最后 128 个命中 token 3,104 个未命中 token”一起前向那 128 个 token 只重建编码器侧 SWA KVBlock KV 不重算不覆写。5. 故障行为情况行为SWA KV 缺失编码器侧 Bounded Replay多算 128 token显存不足调大 EP2 → 4 → 8这是“最小 EP”原则的边界prefill 实例故障请求级重路由到其他 PEPrefill Engine靠 PE 配额冗余而非缩短单实例重启时间重启为分钟级截图过多 / 过大VE 按 patch 数均衡VE 吞吐可用examples/sweep/ve_sweep.py单独测上一篇05.4 DeepInfer 总览 下一篇05.4.2 Decode 返回概念地图 返回专栏目录
阅读完成 · 觉得有帮助?
咨询建站