DeepSeek-V4.1-Flash 架构解析:KV Cache 压缩的极限在哪里

DeepSeek-V4.1-Flash 的技术报告副标题是 “Pushing the Limits of KV Cache Compression”——整篇论文的野心写在脸上:把 KV Cache 压到极致,把长上下文 Agent 负载的部署成本打下来。552B 骨干 + 196B 条件记忆,prefill 每 token 只激活 8B 参数,全局 KV 压到 890 字节/token(约 V4-Flash 的 1/4、V1 的 1/437),持久化 KV 压到 V4-Flash 的约 1/8。本文按报告第 2 章(架构)和第 3 章(推理系统)的顺序,把六个核心设计串成一条线:CED、CSA2、SWA Bounded Replay、Single-Pass mHC、FP4 主 KV、DSpark 与 Engram,最后算一笔总账。数字口径除标注外均来自论文原文,部分以 vLLM 实现/HF config 佐证。


1. 全景:一张表和一个劈半动作

项 数值
骨干参数 552B(MoE,1 共享 + 384 路由专家,激活 6 个,专家中间维 2304)
Engram 条件记忆参数 196B(单独计,不计入骨干)
激活参数 prefill 每token 8B / decode 每token 16B
层数与结构 40 层 = 20 层因果编码器 + 20 层解码器(CED)
隐维度 5120,64 查询头 × 头维 512;q_lora 1280,输出侧 8 组 × o_lora 1024
上下文长度 100 万 token(64K 起步稀疏注意力训练,34T token 处扩到 1M)
预训练语料 45T token(文本:多模态 = 7:1)

一句话概括架构:把一个标准 Transformer 从中间劈开——前 20 层当"因果编码器"处理全部输入,后 20 层当"解码器",其全局 KV 不再自己算,而是从编码器最后一层的隐状态投影出来;再叠加跨层 KV 共享、FP4 缓存与滑窗,完成上面那组压缩数字。

2. CED:编码器算一半,解码器借结果

Agent 工作流中频繁的工具调用产生大量 prefill 请求,KV 未命中时 prefill 计算是主要开销。CED(受 YoCo 启发)的目标是砍掉一半 prefill 计算:对全局注意力,解码器各层(l>L/2l > L/2)的 KV 条目不来自本层隐状态 HlH_l,而是由编码器最后一层隐状态经逐层独立投影直接算出:

Cl=HL/2⋅WlKV,Zl=HL/2⋅WlZC_l = H_{L/2} \cdot W^{KV}_l, \quad Z_l = H_{L/2} \cdot W^{Z}_l

C 是 KV 条目,Z 是对应压缩权重。投影是一次线性变换,相比"一整层 Transformer(注意力+FFN)"开销可忽略,后半层几乎免费拿到全局 KV。序列长度 N≫nwinN \gg n_{win} 时 prefill 复杂度从 O(NL)O(NL) 降到约 O(NL/2)O(NL/2)——这就是 prefill 激活 8B、decode 激活 16B 的来源。

两点澄清:每个解码层的注意力照常进行、KV 有得读,变的只是计算来源;部署配置下上式进一步塌缩——实际只有解码器第一个 Full 层(层 20)执行投影并落缓存,层 21–39 直接读这一份(HF config 佐证:kv_source_layer_ids = [2, 8, 14, 20],且这次投影与该层 Q 投影融合成单个 GEMM,vLLM 的 fused_wqa_wkv)。

SWA 维持逐层常规计算,保住局部特征的计算深度;代价是解码器 SWA 需要重放过程,见第 4 节。

3. CSA2:三个维度同时压缩

3.1 三个乘性维度

长上下文的 KV 开销可以沿三个维度相乘式压缩:条目大小(GQA 减 KV 头、MLA 共享 latent)、序列维度(每 m 个 token 压成 1 条)、层维度(部分层复用其他层的缓存/索引)。既有工作各占一维,CSA2 三个同时吃满。相对 V4 的 CSA:压缩比 m 的每条主 KV 不再去掉重叠与绝对位置编码;indexer K 不再从隐状态单独压缩,而是直接由主 KV 条目投影——少一条管线,且索引器与注意力读到逐位对应的内容。

3.2 三种静态模式与部署配置

每层静态指定 Full / Reindex / Reuse 三种模式之一,区别只在于 main KV、indexer K、Top-K 索引从哪来:

模式 main KV + indexer K Top-K 索引 开销
Full 本层自己算 全量打分,产出新索引 最重
Reindex 复用最近 Full 层 自己的 indexer Q 对共享 K 重新打分 中
Reuse 复用最近 Full 层 复用最近产索引层的索引 最轻

部署配置(HF config 佐证):层 0–1 纯 SWA(m=0);编码器层 2–19 压缩比 m=2(3 组 × 6 层,Full 在 2/8/14,其余全 Reuse);解码器层 20–39 m=1(5 组 × 4 层:首组 1 Full + 3 Reuse,其余 4 组各 1 Reindex + 3 Reuse)。m=1 的含义值得咀嚼:解码器放弃序列维度压缩、保留逐 token 粒度,把压缩收益改从层维度共享(全解码器只有 1 份全局 KV)与 FP4 精度里拿——这是 V4.1 相对 V4(C4/C128)最大的思路转变。

m=0 的常见疑问:头两层只看 SWA 窗口 128,长上下文是不是"彻底没了"?不是——上下文不靠每层各自看见,而靠分工:层 0–1 把每个 token 加工为局部特征写入残差流,特征向上进入 H₂₀ 被压缩为全局缓存条目,远距离 query 在高层 CSA2 里按需检索。即"低层局部加工 → 残差流运输 → 高层全局检索"。

Z(压缩权重)的计算:kv-source 层对每 token 隐状态做两个并行投影——wkv 产出 512 维 latent,wgate 产出 512 维门控分数;按 m 分组后组内做逐通道 softmax 加权求和(每个通道有自己的组内混合权重,不是标量门)。池化后 RMSNorm → 无 RoPE 版本 → 压缩 RoPE(theta=160000)→ FP4 量化入缓存。m=1 时整条门控路径不存在——解码器层 20 的缓存条目就是 wkv 投影 + RMSNorm,论文式(1)的 Z 是 m>1 的一般形式。

3.3 分层稀疏索引器:16384 → 2048 → 512 的漏斗

超长上下文下索引器给全上下文打分是 decode 的主要计算瓶颈。分层索引器用四级漏斗解决(仅解码器):

  1. 建池——唯一一次全量过滤:解码器第一个 Full 层(层 20)对全部可见位置打分,为自己的注意力选出 Top-512;同一份分数顺手完成块级候选选择——位置按 8 个一组分块,每块取块内最大索引分(块 max 是上界,强相关块不会被漏),选出最高的至多 2048 块,展开为至多 2048×8 = 16384 个候选位置,构成共享候选池
  2. 池内过滤——4 次,常数开销:4 个 Reindex 层(24/28/32/36)用自己的 indexer Q 只对池内候选重新打分,各自选出 Top-512——深层索引器的每查询开销从"正比于上下文长度"变为常数
  3. 纯继承——15 个 Reuse 层:不做任何打分。每个 decode step 的索引账 = 1 次全量打分 + 4 次池内打分 + 15 次继承
  4. 旁路与边界:滑窗最近 token 不经漏斗,展开池块后直接并入尾部,最新上下文不因块未攒满而丢失

时序澄清(容易读错):top-2048 与 top-512 是同一次打分、同一处的两次并行 Top-K(位置级取 512 自用、块级取 2048 展开建池),不是"先选 512 再基于 512 建池"。每个 decode step 各走一遍。该机制在 post-training 引入且训练/推理一致——deeper indexer 在与推理相同的搜索域上被优化。

4. SWA Bounded Replay:按生命周期分治

4.1 为什么 SWA 不值得持久化

每层 SWA 窗口 128,SWA KV 以 FP8 存储(对量化敏感,不随主 KV 降 FP4)。V4 部署中 SWA KV 约占持久缓存容量一半,但只在两个点缓存(prompt 末尾、output 末尾各留 128 条),复用只发生在分钟级会话窗口内,会话结束即死——与持久缓存 72 小时的长留存策略根本不匹配:贵且低效。

4.2 精确重建为什么是 5120——"楼梯"式感受野

V4 曾提出 Zero SWA Caching(缺了就精确重算),但精确恢复需要 L×n_win = 40×128 = 5120 token 的完整前向。SWA 的 K/V 本身便宜,贵在隐状态的跨层依赖:第 l 层位置 i 的值由第 l−1 层窗口 [i−127, i] 构成——每往深一层,所需历史的左边界再扩一个窗口,形成楼梯:

层 精确重建所需历史
40(目标) [p−127, p]
39 [p−254, p]
⋮ 每降一层再扩一个窗口
1(底座) [p−5119, p] ≈ 40×128

正常 prefill 不付这笔账(楼梯被逐位置计算摊销),只有断点冷启动重建时才显形。

4.3 Bounded Replay:只重放 128 个

重放只取前缀最后 n_win=128 个 token 过全部 L 层,补出各层 SWA 缓存的最后 128 个槽位;重放期间滑窗左边界截断到重放起点。近似性:重放段靠前的 token 历史被砍短(越靠后越精确,最后一个 token 精确);重放过程中新算的全局 KV 直接丢弃不覆盖缓存。代价从 5120 骤降到 128,且与上下文长度无关。

三种方案成本对照(10,000 token 前缀已缓存全局 KV,新 turn 50 个 token):

方案 SWA 补齐代价
V4:持久化 SWA、命中 0(但持续占持久缓存)
精确重建 5120 token 过 40 层 ≈ 新 token 的 100 倍
Bounded Replay 128 token 过 40 层 ≈ 新 token 的 2.6 倍

两种 Replay 分工:Encoder 版面向存储(全局 KV 命中而 SWA 缺失时重放兜底,SWA 彻底退出持久缓存,体积约砍半,改存每机 10% host DRAM 的分钟级 TTL 池);Decoder 版面向计算(每次 prefill 把最后 128 个 token 的编码器输出喂过解码器 20 层,所得 SWA 仅供 decode 不缓存——支撑"prefill ≈ 编码器-only")。训练适配是共同底座:post-training 期间模拟同样的 replay;LMSYS serving 实测开启 decoder replay 后 prefill 提速 1.56×、AIME 评测零差异。

5. Single-Pass mHC:把 A 错位一层

mHC 在相邻块间维持 n 条残差流(n = hc_mult = 4):

Xl+1=BlXl+ClFl(AlXl)X_{l+1} = B_l X_l + C_l F_l(A_l X_l)

三组系数 (Al,Bl,Cl)(A_l, B_l, C_l) 由系数预测器 H(Xl)H(X_l) 从当前流算出。V4 的三 kernel 实现因数据依赖串行执行,含 pre-norm 总激活访存 (4n+4)d(4n+4)d,是理论下界 (2n+2)d(2n+2)d 的两倍。卡点在 AlA_l:它需要扫完整 hidden 维的归约,而输入混合在本层内就要用它——每个 tile 算完只能等全维归约,然后重读 XlX_l。

Single-Pass 把输入混合系数错位一个块:

Xl+1=BlXl+ClFl(Al−1Xl)X_{l+1} = B_l X_l + C_l F_l(A_{l-1} X_l)

层内循环变成层间接力:XlX_l 的每个 tile 算完可立即同时用于输入混合、系数预测累加和 RMS 平方和累加,一次遍历完成。部署侧 Mega-mHC kernel 把残差更新、输入混合、系数预测融合进单个 kernel,精确达到 (2n+2)d(2n+2)d 的理论下界——激活访存减半,decode 访存受限场景直接转化为时延收益。语义代价是"本层用上一层的混合权重"(相邻层流演化平滑,近似为一阶滞后),实验损失可忽略。vLLM 对应 mhc_pre_delayed_tilelang + MHC_PRE_NORM_KERNEL,Sinkhorn 迭代 20 轮。

6. Engram 与 DSpark

Engram(条件记忆):把"记忆"从计算中解耦——用 N-gram 哈希({2,3,4} 阶 × 8 哈希头)查 196B 的超大规模 embedding 表,查得的记忆向量按门控注入残差流,挂在第 1、14 层。嵌入用动量更新 + Sinkhorn 平衡优化(仅需动量缓冲,无需 Adam 的状态显存)。训练时表按行切分到专用进程组整批预取;推理时确定性寻址支持从 host 内存后台 RDMA 预取,与第一个 Transformer 块的计算重叠。图像 token 不参与 n-gram 也不注入条件记忆,n-gram 链在图像边界处打断。

DSpark(推测解码):3 个 Transformer 块的草稿 + Markov 头(rank 256)建模草稿 token 依赖 + 置信度头预测逐位置接受概率,调度器按请求动态选验证长度、最大化系统吞吐。V4.1 取消了 V3/V4 的 MTP,DSpark 是唯一推测解码方法。部署约束很有意思:PD 分离时必须双池同开——因为 prefill 池传给 decode 池的不止主模型 KV,还有 prompt 末尾 5 个 noise 槽(dspark_noise_token_id=128799)、3 个草稿块各自的 KV、目标层的注意力输入隐状态,双方记账必须逐位一致;单开一侧会导致位置错位 5 或草稿头读到空 KV。收益集中在低并发/延迟敏感场景,大 batch 下固定步开销不再回本。

7. FP4 主 KV:先证界,再省位

项 设置
格式 E2M1 + 每 16 通道一个 E4M3 scale(类 NVFP4,省掉二级全局 scale)
量级安全论证 格式上限 448×6=2688;RMSNorm 权重幅值≈1,512 维 KV latent 的 L2 范数 ≤ √512≈22.6,RoPE 保范,训练实测最大幅值约 10——余量充足
时机 RoPE 之后量化(写入缓存时);先 RoPE 再量化只带来边际精度提升且增加 decode 开销
计算侧 注意力前反量化——FP4 只省存储、不要求原生 FP4 矩阵乘,跨硬件兼容

注意区分:专家权重的 MXFP4(32 通道 UE8M0 scale)与 KV cache 的 FP4(16 通道 E4M3 scale)是两套格式。缓存布局 448B NoPE + 128B RoPE + 8B scale = 584B/token,576B 对齐分页。

8. 总账:890 B/token 与 1/8 是怎么来的

全局 KV(常驻 HBM)= CSA2 跨层共享 × FP4:

  • V4-Flash 基线 → 共享后约为其 1/2 量级(条目数骤减:编码器 3 份、解码器 1 份)
  • × FP4/FP8(再减半)→ 合计约 1/4,即 890 B/token,1M 上下文 < 1 GB

持久化 KV(常驻 SSD/host)= 去掉 SWA × 全局压缩:

  • SWA 约占 V4 持久缓存一半 → 去掉后 ≈ 1/2
  • × 全局 KV 的 1/4 → 合计 ≈ 1/8

对应地 decode FLOPs 从 4K 到 1M 上下文仅增长 1/4(近常数),prefill 复杂度 O(NL/2)O(NL/2)——架构 × 缓存精度 × 部署策略三个层面联合压低了计算、存储与带宽三本账。

回看六个设计,单项都是已有技术的组合,但组合的口径统一:凡是生命周期长于会话的(全局 KV),往死里压;生命周期短于会话的(SWA),干脆不存。这个按生命周期分治的存储哲学,比任何单项技术都更值得记住。

参考

  • DeepSeek-AI 技术报告《DeepSeek-V4.1-Flash: Pushing the Limits of KV Cache Compression》(2026-09)
  • HF 仓库 deepseek-ai/DeepSeek-V4.1-Flash(inference/ 目录,vLLM 实现佐证)