# SWA 有界重放：SSD 上只剩八分之一

> 滑动窗口缓存不再写进 SSD，缺了就只重算最后 128 个 token。这个部署层面的取舍让持久化缓存缩到前代的约 1/8，代价是恢复出来的状态只是近似。

- 作者：David（道雾轩）
- 专栏：DeepSeek V4.1 Flash 深度解析（https://daiw.net/manual/deepseek-v4-flash.md）
- 最后更新：2026-09-19
- 原文：https://daiw.net/manual/deepseek-v4-flash/swa-bounded-replay
- 转载与引用：请注明出处并附原文链接（https://daiw.net/about/copyright）

前两章讲的是**全局 KV**：跨越整个上下文、随长度增长、运行时常驻 HBM 的那部分缓存。每一层还有另一份缓存：最近 128 个 token 的**滑动窗口 KV（SWA KV）**。窗口长度固定，它的大小与上下文长度无关，看起来无关紧要——直到你要把缓存**存下来**。

## 持久化缓存是什么

DeepSeek 的服务会把算过的前缀 KV 持久化，供后续相同前缀的请求复用，这部分叫**持久化 KV 缓存**，受 SSD 和主机内存容量约束 [1]。V4 时代的做法是 [1]：

- 全局 KV 与 SWA KV 分开管理，都按 LRU 淘汰；
- 全局 KV 整段存储，命中就复用整个前缀；
- SWA KV 只在两个位置存档——提示词末尾和输出末尾，方便重新生成和多轮对话从那里接着算；
- SSD 上的持久化缓存配得足够大，典型负载下两类缓存都能驻留 **72 小时以上**。

问题在于：虽然每个存档点只存 128 个 token 的窗口，但它**不压缩**，而且每层一份。报告说在 V4 的部署里，**SWA KV 占了持久化缓存将近一半的容量**，多轮、每轮很短的对话尤其浪费 [1]。

## 为什么存 SWA KV 不划算

报告的判断是：持久化存 SWA KV“既昂贵又低效”，因为它的访问模式和持久化缓存的长保留策略不匹配 [1]。全局 KV 有长尾复用——同一份长文档可能几天后还会被问；SWA KV 只在一个活跃会话内几分钟的时间窗里被复用，会话结束或进入下一轮就没用了。

那干脆不存、缺了就重算？V4 的技术报告提过这种“零 SWA 缓存”方案，但**精确重算很贵**：滑动窗口的依赖会逐层累积，第 $l$ 层窗口里的状态依赖第 $l-1$ 层更早的位置，要精确恢复 $L$ 层的窗口状态，就得把最近“层数 × 窗口长度”个 token 重新前向一遍。报告说这在生产环境里代价高得不可接受 [1]。

## V4.1 的做法：只重放 128 个 token

V4.1 改了两件事 [1]：

1. **SWA KV 不再进持久化缓存**，改放在一个分布式内存池里，池子取自每台机器 10% 的主机内存，存活时间只有几分钟，过期即回收给新会话。报告说在真实负载下，这种高周转足以覆盖绝大多数并发活跃会话。全局 KV 仍留在持久化缓存里，保证至少 72 小时。
2. **缺了就有界重放**：少数请求会遇到“全局 KV 命中、SWA KV 已被淘汰”。这时只重放缓存前缀的**最后 128 个 token**，和未缓存的后缀一起处理；重放的 token 只重新生成 SWA KV，全局 KV 直接复用、不重算也不覆盖。

具体做法是把滑动窗口截断在重放段内：从位置 $s$ 开始重放时，位置 $t$ 的 query 只看 $\max(s, t-127)$ 到 $t$ 之间的窗口 [1]。报告把它称为这套设计的“基石”：**一次灾难性的缓存缺失，变成一次便宜的、温和的降级**。

同一个技巧用在两处：

| | 编码器 SWA 有界重放 | 解码器 SWA 有界重放 |
| --- | --- | --- |
| 什么时候用 | 全局 KV 命中、编码器的 SWA KV 缺失 | 每次预填充都用 |
| 重放多少 | 缓存前缀的最后 128 个 token | 提示词的最后 128 个 token |
| 得到什么 | 让前缀缓存只依赖全局 KV，SWA KV 从持久化缓存里拿掉 | 解码器的 SWA KV，只用于接下来的解码，不进前缀缓存 |
| 解决什么 | 存储 | 计算（配合 [CED](https://daiw.net/manual/deepseek-v4-flash/ced) 把预填充砍掉近一半） |

## 1/8 是怎么乘出来的

报告给的解释是两个相乘的因素 [1]：

- 持久化缓存**不再存 SWA KV**——在 V4 的部署里它占将近一半，这一项让体积几乎减半；
- 留下来的全局 KV，经过 CSA2 与 FP4 再压到 V4 的 **1/4**。

两者相乘，同样负载下持久化缓存约为 V4 的 **1/8**。官方公告的对应说法是：对 HBM 的需求减少到 1/4，对 SSD 的需求减少到 1/8 [2]。

## 代价：近似，而且与命中位置有关

**重放出来的状态是近似的。** 被截断的窗口看不到重放段之前的内容，所以恢复出的 SWA KV 与完整前向并不数学等价。报告为此给了两条理由 [1]：

- 已有研究表明，滑动窗口的**有效感受野**远小于理论上的“层数 × 窗口”；
- 他们的实验显示，这种近似对回答质量的影响“几乎可以忽略”；解码器那一侧还在后训练时模拟了同样的重放，让模型提前适应。

还有一个不那么显眼的后果：报告明确说，未缓存后缀算出来的全局 KV 与 SWA KV **取决于缓存命中的位置**，不同命中位置之间并不数学相同 [1]。换句话说，同一段对话，缓存命中在哪里，模型内部的状态就可能略有不同。对需要严格复现的场景（例如回归测试、评测），这是一个值得记下的变量。

<Callout type="warn">
  “影响可以忽略”是**官方口径**，报告没有公开对应的数字。报告在局限性一节也把“缓存恢复边界处的 SWA 状态重建”列为需要继续压测的方向 [1]。另外，这一章讲的全是 DeepSeek 自己的服务端部署策略：自托管时是否持久化、怎么重放，取决于你用的推理引擎是否实现了同样的机制。
</Callout>

## 和账单的关系

官方公告在介绍缓存压缩时特意说：Agent 场景里，缓存命中的费用往往占比较高，KV Cache 的压缩大幅降低了这类任务的成本 [2]。V4.1-Flash 上线时的缓存命中价比前一天的 V4-Flash 低了约 57%（见[规格总表](https://daiw.net/manual/deepseek-v4-flash/spec-sheet)）。价格怎么定是商业决策，但方向与“存得更少”一致。

第一部分到此结束。下一部分转向主干：MoE、残差流与两个新加的组件。👉 [1 + 384 选 6](https://daiw.net/manual/deepseek-v4-flash/moe)

## 参考文献

- [1] DeepSeek-AI. “DeepSeek-V4.1-Flash: Pushing the Limits of KV Cache Compression.” 2026-09. [arXiv:2609.19969](https://arxiv.org/abs/2609.19969) —— 第 1 节（全局 KV 与 SWA KV、持久化缓存的定义）、第 3.2.1 节（V4 的持久化缓存管理、SWA KV 占比、72 小时、10% 主机内存池）、第 3.2.2 节（编码器与解码器 SWA 有界重放、截断规则、非数学等价的说明）、第 6 节（局限性）。
- [2] DeepSeek. “DeepSeek-V4.1-Flash 发布.” 2026-09-10. [api-docs.deepseek.com/zh-cn/news/news260910](https://api-docs.deepseek.com/zh-cn/news/news260910) —— “对 HBM 的需求减少到 1/4，对 SSD 的需求减少到 1/8”与缓存命中费用的说法。
