线性注意力(Linear Attention)是一类改写注意力计算顺序的方法,它把标准注意力里 softmax(QKᵀ)V 的相似度函数换成可拆分的核函数,让总计算量从随序列长度平方增长(O(N²))降到线性增长(O(N))。
标准注意力贵在哪
标准注意力(softmax attention)要求每个 token 和历史上所有 token 两两打分,序列长度 N 对应 N×N 个分数矩阵:长度翻倍,计算量翻四倍,生成时还要把之前所有 token 的 Key/Value 缓存在显存里。
麻烦的根源是 softmax 拆不开。相似度写成 exp(q·k) 之后,query 和 key 粘在一起,没法先把 key 汇总好。
线性注意力的做法是换一个能拆的相似度:用特征映射 φ 把 q、k 各自映射后做点积,φ(q)·φ(k)。这样求和符号就能挪位子:
```
输出 = φ(q)·(Σ φ(kᵢ)vᵢᵀ) / φ(q)·(Σ φ(kᵢ))
```
括号里那个 Σ φ(kᵢ)vᵢᵀ 与当前 query 无关,尺寸是 d×d 的固定小矩阵,所有 query 共用。
打个比方:标准注意力像每来一个新同事,都让他把全公司每个人挨个问一遍"你跟他熟吗"——人越多越慢。线性注意力像公司维护一本固定厚度的"通讯录摘要",不管有多少人,信息先汇总进这本册子,新人只翻册子。册子厚度不变,所以人再多,翻册子的时间也不变。
在因果(causal)场景下它还能写成递推:每读入一个 token,就把状态更新一次;生成下一个词时只读一眼状态,不必回看历史。这本质上是一个 RNN 式的循环结构。
和容易混淆的邻居比一比
| softmax 注意力 | 线性注意力 | |
|---|---|---|
| 训练总量 | O(N²d) | O(Nd²) |
| 生成每步 | 读全部历史缓存,O(N) | 读固定状态,O(1) |
| 缓存占用 | 随长度线性涨 | 固定大小 |
| 检索精度 | 能精确定位任一历史 token | 只能从压缩摘要里回忆 |
| 数学性质 | 精确 | 近似 |
另外两组对比:AI 词典:FlashAttention">FlashAttention 常被归到"高效注意力"里,但它不改变数学结果,只优化显存读写,仍然是精确的 O(N²);线性注意力改的是公式本身。稀疏注意力、滑窗注意力则是少比一些,形式还是两两打分,属于另一条路线。
对从业者的意义
值得用的场景很明确:超长序列(长文档、日志流、基因序列)、流式生成、端侧设备、显存吃紧的推理服务。状态大小固定,意味着显存不随对话变长而膨胀,这是很实在的工程优势。
代价也要说清楚:把整段历史压进一个固定大小的状态,是信息瓶颈。token 一多,状态里各项互相干扰,早期内容被稀释甚至覆盖。表现上通常是"抓得住大意,抓不住细节"——让它概括一篇长文没问题,让它准确说出第 300 段里那个具体数值,就明显不如标准注意力。表达力同样打折:固定状态相当于容量有限的记忆,复杂的长程依赖容易记混。
因此工程上常见混合方案:多数层用线性注意力省成本,少数层保留全注意力负责精确召回。选型时先问一句任务要不要"大海捞针"式的精确检索——要,就偏标准注意力;只是把握主旨、处理超长输入,线性注意力更划算。具体框架支持哪些注意力后端、怎么开,以各自的官方文档为准。
