# 前代 · CSA：4 倍压缩 + 闪电索引器

> 前代 V4-Flash 的压缩稀疏注意力：先把每 4 个 token 的 KV 压成一条，再用 FP4 的闪电索引器挑出 top-512——省两次，省的是不同的东西。V4.1 已改用 CSA2。

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

<Callout type="info">
  **本篇描述的是前代 DeepSeek V4-Flash（2026 年 4 月发布）的设计。** V4.1-Flash 已把它换成 [CSA2](https://daiw.net/manual/deepseek-v4-flash/csa2)：去掉了压缩时的重叠与绝对位置编码，索引器的 K 改为从主 KV 投影，并加入跨层复用。本篇保留初版要点，并按 V4 论文与 `config.json` 做了更正（见文中注明处）。
</Callout>

**CSA**（Compressed Sparse Attention，压缩稀疏注意力）是 V4 两种全局注意力之一。V4-Flash 的 43 层里，它占 **21 层**，与另一种机制 HCA 逐层交替 [1][2]。名字里的两个词各对应一次节省。

<Callout type="warn">
  **更正**：初版这里写的是“约 4/5 的注意力层用 CSA”，来自第三方拆解。V4 论文写明 CSA 与 HCA 是交替使用的，`config.json` 显示 V4-Flash 为前 2 层纯滑动窗口、之后 21 层 CSA 与 20 层 HCA 一层隔一层 [1][2]。排布细节见[CSA 与 HCA 怎么排](https://daiw.net/manual/deepseek-v4-flash/hybrid-ratio)。
</Callout>

## 第一次省：压缩

沿**序列维度**做 **4 倍**压缩：把每 4 个 token 的 KV 归并成一条“压缩条目”，之后的注意力在压缩条目的层面上进行 [1]。

V4 论文给出了具体做法：先算出两组 KV 和对应的压缩权重，再按“权重做 softmax、加上可学习的位置偏置”的方式加权求和，得到压缩条目。每条压缩条目其实取自 **8 个**原始条目，相邻条目的来源**互相重叠**，所以序列实际被压到约 1/4 [1]。这是一种学出来的加权池化。

1M token 压 4 倍，变成约 25 万条。缓存需求随之降到约 1/4。

代价当然存在：**块内的细节被抹平了**。4 倍是个相对保守的压缩率，正是为了把这种损失控制在可接受范围——对比 HCA 的 128 倍，这已经算温和。

## 第二次省：稀疏

压完还不算完。25 万条如果每个 query 都全算一遍，仍然贵。所以 CSA 的第二步是**只挑其中一部分来算**，这就是 Sparse。V4 论文说，这一步直接沿用 V3.2 的 DeepSeek 稀疏注意力（DSA）[1][3]。

## 闪电索引器

挑哪些，由一个专门的模块决定：**Lightning Indexer（闪电索引器）**。它用自己的一组低维 query 和压缩后的 key 打分，为每个 query 选出分数最高的 k 条；V4-Flash 的索引器有 64 个头、每头 128 维，**k = 512**（V4-Pro 为 1024）[1]。

拆开看这个设计的三层考虑：

**一、为什么要专门的索引器？** “哪些条目相关”，理论上算一遍完整注意力就知道了——但那正是要避免的开销。所以需要一个**便宜得多的近似打分器**：它不需要精确，只需要排序大致对。

**二、为什么用 FP4？** 因为它只做排序。V4 在后训练阶段对索引器的 QK 路径做了 FP4（MXFP4）量化感知训练，缓存、读取和乘法都在 FP4 下进行；索引分数再从 FP32 降到 BF16，top-k 选择提速 2 倍，召回率保持在 99.7% [1]。**把精度花在需要精度的地方。**

**三、代价是什么？** 索引器可能**选错**。某个关键条目被漏掉，模型就看不到它，而且不会报错——输出只是悄悄地差一点。这类失败是**静默**的，也是稀疏注意力这条路线的根本风险。

<Callout type="warn">
  静默失败是稀疏注意力最难评估的地方。标准基准很难测出“模型漏看了上下文里的第 43 万个 token”，除非基准专门为此设计（比如大海捞针或多轮指代检索）。看到“支持 1M 上下文”时，要额外关心它在长上下文检索类基准上的表现，而不只是看通用分数。
</Callout>

## 还有一条滑动窗口分支

初版没有提到的一点：CSA 的每个 query 只能看**之前的**压缩块，看不到自己所在块里的其他 token；而最近的 token 往往又最相关。所以 V4 给 CSA（和 HCA）都加了一条**滑动窗口分支**：每个 query 额外看最近 128 个未压缩 token 的 KV，和选出的压缩条目放在一起做注意力 [1]。另外，核心注意力采用所有查询头共享一份 KV 的 MQA 方式，还用了注意力汇（attention sink）和只作用于最后 64 维的部分旋转位置编码 [1]。

这条滑动窗口分支在 V4.1 里原样保留，还成了[有界重放](https://daiw.net/manual/deepseek-v4-flash/swa-bounded-replay)的主角。

## 两次节省是正交的

| | 省什么 | 损失什么 |
| --- | --- | --- |
| **压缩（4 倍）** | **缓存容量**——要存的东西少了 | 块内细节被抹平 |
| **稀疏（top-k）** | **计算与带宽**——每步要读、要算的少了 | 可能漏选相关条目 |

压缩不能替代稀疏：压完的 25 万条还是得存着，每步仍要决定读哪些。稀疏也不能替代压缩：只算 top-k 不代表可以不存其余的，下一个 query 可能要选到别的条目。

<Callout type="info">
  **更正**：初版把“压缩主攻 10% 的缓存、稀疏主攻 27% 的 FLOPs”挂在 V4-Flash 名下。这两个百分比是 V4 论文给 **V4-Pro** 的；V4-Flash 在 1M 上下文下相对 V3.2 是 **10% 的单 token FLOPs 与 7% 的 KV 缓存** [1]。
</Callout>

## CSA 与 DSA 的关系

DeepSeek 在 V3.2 时期就有 **DeepSeek 稀疏注意力（DSA）** 这条线 [3]。CSA 可以看作它的下一步：**DSA 在原始序列上做稀疏，CSA 先压缩再稀疏。** 多出来的这层压缩，把稀疏选择的搜索空间也缩小了 4 倍——索引器要排序的候选从 100 万降到 25 万，它自己的开销也跟着降。

到了 V4.1，这条线又往前走了一步：CSA2 让大部分层不再各自选，而是复用前面某一层选好的结果（见 [CSA2](https://daiw.net/manual/deepseek-v4-flash/csa2)）。

下一篇讲另一种机制——它走的是完全相反的极端。👉 [前代 · HCA：128 倍压缩后再做稠密注意力](https://daiw.net/manual/deepseek-v4-flash/hca)

## 参考文献

- [1] DeepSeek-AI. “DeepSeek-V4: Towards Highly Efficient Million-Token Context Intelligence.” 2026-04. [arXiv:2606.19348](https://arxiv.org/abs/2606.19348) —— 第 1 节（V4-Pro 与 V4-Flash 各自的效率数字）、第 2.3 节（CSA 的重叠压缩、闪电索引器、滑动窗口分支、注意力汇、部分 RoPE）、第 4.2.1 节（V4-Flash 与 V4-Pro 的注意力设置）、第 5.2.1 节（索引器的 FP4 量化感知训练）。
- [2] Hugging Face：[deepseek-ai/DeepSeek-V4-Flash 的 config.json](https://huggingface.co/deepseek-ai/DeepSeek-V4-Flash/blob/main/config.json) —— `compress_ratios`：逐层的 4 与 128 交替。
- [3] DeepSeek-AI. “DeepSeek-V3.2: Pushing the Frontier of Open Large Language Models.” 2025-12. [arXiv:2512.02556](https://arxiv.org/abs/2512.02556) —— DeepSeek 稀疏注意力（DSA）。
