想象你办一场新生破冰晚会,要让 100 位同学互相认识。常规做法是两两握手,于是 100×99÷2 约等于 5000 次握手;如果来了 1 万人,握手次数直接破亿。Transformer 的注意力机制也是这样:每个 token(可以理解为一个词或一个“同学”)都要和序列里所有 token 交换信息,计算量随序列长度平方增长。为了高效处理长文本,研究者想出了各种“晚会改造方案”:随机特征近似像给每人发几张随机性格标签,靠标签估算彼此相似度;低秩分解像选几位学长学姐汇总全场印象再分发;广义线性注意力像一边聊天一边更新全局印象,不需要保留完整的握手记录;而 Flash Attention 则是重新布置晚会场地,让同学们少跑腿。这些方案统称为 Linear Attention 变体,是高效 Transformer 家族中的关键成员。
掌握这些变体,你就能在超长序列的 Transformer 训练与部署中,把时间和内存从平方级降到线性级。这是做大模型长文本工程、推理优化和高效架构设计的基本功。
目录
可视化演示
展示MMoE架构中多专家网络与多门控的协作机制,包括任务级门控路由与专家共享,直观理解多任务学习中的专家分配策略。
本节配有交互动效(进入视口后自动加载,约 3KB)。
MMoE多门控专家网络 共享专家:多个专家网络学习不同特征子空间 多门控:每个任务拥有独立门控网络进行专家路由 软路由:门控输出权重分布,加权融合专家输出 y_k = Σ g_k(x)_i · f_i(x); g_k = Softmax(W_k · x) MMoE实现多任务间的专家共享与差异化路由
注意力瓶颈:两两握手的爆炸
回到破冰晚会。如果要求每位新生都必须和全场所有人逐一握手,那 10 个人的晚会只需 45 次握手,100 人就要 4950 次。Transformer 的自注意力机制正是如此:序列里每个 token 都要和其他所有 token 计算相似度,因此需要构造一个 N×N 的注意力矩阵,N 是序列长度。当输入是 10 万 token 的长文档时,这个矩阵有百亿个元素,显存直接爆炸。
这种“两两握手”虽然能捕捉任意两个位置的关系,但代价极高。标准注意力的公式可以写成:
所以,所有 Linear Attention 变体的目标都是改造这场“两两握手”,让晚会即使来再多人也能高效完成破冰。
- 查询、键、值投影将输入分别映射成 Q(查询)、K(键)、V(值),就像每个同学先写下自己的“自我介绍卡”,并准备好想打听的话题。
- 点积相似度每个查询与所有键做点积,数值越大表示两者越“聊得来”。
- 缩放除以 $\sqrt{d_k}$,防止点积过大导致 softmax 落在饱和区,梯度变小。
- 归一化与加权softmax 把每行变成一个概率分布,再用这些概率对 V 加权求和,得到最终输出。
Kernel视角:把握手换成相似度标签
如果两两握手太累,能不能让每人提前填写几张“性格标签”,然后通过标签内积估算彼此的关系?这正是核技巧(Kernel Trick)的思路。softmax 注意力本质上可以看成一个核函数:它在衡量两个 token 的相似度,而这个相似度可以被写成某个特征空间中的内积。
所谓“线性化”,就是找到一个人造特征映射 $\phi$,使得 softmax 的相似度近似等于两个特征向量的内积。一旦做到这一点,我们就不需要显式构造 N×N 的矩阵,而是可以先计算 $\phi(K)^\top V$,再用 $\phi(Q)$ 去乘,把乘法顺序变成“先合并键值,再逐行查询”,从而把复杂度降下来。
核视角就像给每位同学发了一套标准化的“性格标签”,从此大家不用逐一见面,只要交换标签就能估算合不合拍。
- 左侧的 softmax 相似度原始注意力中,第 i 个查询和第 j 个键之间的相似度是 softmax 的结果,范围在 0 到 1。
- 右侧的特征内积$\phi$ 把原始向量映射到更高维空间,两个高维向量的内积可以近似原来的相似度。
- 约等于的意义用近似代替精确,换来的是可以改变矩阵乘法顺序的“运算自由”。
- 特征映射选择不同变体的差异,就在于 $\phi$ 怎么设计——随机采样还是学习得到。
随机特征近似:发随机性格标签
Performer 提出的 FAVOR+ 方法,选择用随机特征来构造 $\phi$。它给每个 token 生成一组“随机性格标签”:先用高斯分布随机采样一些投影向量 $\omega$,再经过指数变换得到特征。只要采样的随机方向足够多,特征内积的期望就能逼近原始 softmax 核。
为了保证估计更稳定,FAVOR+ 还使用了正交随机特征,让不同采样方向尽量不重复。这样,尽管我们做的是近似,但近似偏差可以被控制。由于 $\phi(Q)$ 和 $\phi(K)$ 都是 N×d 的矩阵,整个注意力的计算可以在不生成 N×N 中间矩阵的情况下完成,内存从 $O(N^2)$ 变成 $O(N)$。
随机特征越多,估计越准确,但特征维度 m 也会增加计算量。所以 Performer 的调参重点,是在“标签数量”和“晚会速度”之间找到平衡。
- 随机投影向量从标准正态分布中采样一个向量 $\omega$,相当于随机选一个“性格维度”。
- 指数变换$\exp(\omega^\top x)$ 把点积结果变成非负值,模仿 softmax 的非负性质。
- 二阶矩修正减去 $\|\omega\|^2/2$ 是为了让随机特征的期望恰好等于某个高斯核,数学上可以证明无偏。
- 归一化系数$\frac{1}{\sqrt{m}}$ 让多个随机特征的均值保持稳定,$m$ 越大近似越准。
低秩分解方案:学长学姐当代表
与随机特征不同,Linformer 走的是另一条路:在序列长度这个维度上做低秩投影。直观理解:晚会上不需要每个人都亲自去认识 100 位同学,可以请 K 位学长学姐分别和所有人聊一遍,把综合印象带回来,然后大家只和这 K 位学长学姐交流。
形式化地说,Linformer 将原本 N×N 的注意力矩阵压缩成 N×K,其中 K 是远小于 N 的固定值。它通过学习矩阵 $P$,把 K 和 V 的序列长度投影到 K 维,使每个查询只和 K 个“汇总代表”计算注意力。这样时间和内存都是 $O(NK)$,当 K 固定时就是线性复杂度。
低秩分解假设自注意力矩阵本身有冗余,就像晚会上很多人的信息高度重合。这个假设在自然语言里通常成立,但在某些需要精确逐点对应的任务上会有误差。
- 键的低秩投影用投影矩阵 $P_k$ 把原始 N×d 的 K 压缩为 K×d,K 是代表数量。
- 查询与压缩键的相似度每个查询只和 K 个代表向量计算相似度,而不是和全部 N 个键。
- 值的低秩投影用另一个投影矩阵 $P_v$ 压缩 V,得到 K 组“综合印象”。
- 最终加权用相似度权重对压缩后的值加权,还原成 N×d 的输出。
广义线性注意力:边聊边更新印象
如果说前面几种方法还在模仿 softmax,那广义线性注意力干脆“掀桌子”:直接去掉 softmax,用一个核特征映射替代相似度计算。这样注意力公式变成特征内积的加权和,并且可以通过改变乘法顺序,把复杂度真正降到线性。
更进一步,在自回归生成场景中,我们可以用递推的方式维护一个全局印象矩阵 $S$:每读入一个新 token,就把它的键值对“累积”进 $S$;每个查询输出时,只需要拿着查询特征去点乘当前 $S$。这就像晚会主持人每见一个人就在心里更新一份“对全场的印象表”,新同学来问问题时,主持人直接给出最新总结。
递推让“晚会”真正变成流水席:来一个人,主持人更新一次印象;随时有人提问,随时可以回答。这是流式推理和低延迟应用的关键能力。
- 累积键值记忆每个新 token 的键特征 $\phi(k_t)$ 与值 $v_t$ 做外积,加到旧记忆上。
- 查询读取记忆当前查询的特征 $\phi(q_t)$ 与记忆矩阵 $S_t$ 相乘,得到加权后的输出。
- 累积归一化常数$z_t$ 记录到目前为止所有键特征的累加和,用来把输出拉回合理尺度。
- 除法归一化将输出除以 $\phi(q_t)z_t$,避免不同长度序列的特征尺度漂移。
效果速度权衡:没有免费的午餐
各种变体都很美好,但它们都牺牲了一些东西。随机特征近似用 m 维采样控制精度;低秩分解用 K 个代表压缩信息;广义线性注意力则放弃了 softmax 的锐利分布。这些近似带来的误差,在某些任务上可以忽略,在另一些任务上却很致命。
从复杂度看,变革是明显的:
没有免费午餐的意思是:如果你的序列只有几十个 token,用线性注意力反而不划算;只有序列很长、显存吃紧、或需要流式输出时,这些变体才真正发光。
- 标准注意力复杂度$O(N^2)$ 来自构造 N×N 注意力矩阵,每个查询都要比较所有键。
- 线性注意力复杂度$O(N)$ 来自先合并键值,再用查询去读取,不再形成 N×N 中间矩阵。
- 箭头含义这只表示计算复杂度的优化,不代表完全无精度损失。
- 隐含条件实际还要乘上特征维度 d 或代表数量 K,所以常数项可能较大。
与 Flash Attention 关系:两种晚会改造思路
Flash Attention 常被误认为是线性注意力的一种,其实它是另一种维度的优化。线性注意力改变的是算法复杂度,把两两握手变成汇总交流;Flash Attention 则不改复杂度,它重新“布置晚会场地”:把注意力矩阵切成小块,在计算一小块时就让数据留在片上快速缓存里,减少和外部显存的反复读写。
因此,Flash Attention 的计算复杂度仍是 $O(N^2)$,但显存占用从 $O(N^2)$ 降为 $O(N)$,速度提升来自 IO 优化。它和线性注意力并不冲突:一个降低算法复杂度,一个降低访存开销。
实际工程中,两者甚至可以被结合使用。选型时不需要把它们看作对手,而要看瓶颈在“计算量”还是“访存开销”。
- 线性注意力定位改变计算流程,使复杂度随 N 线性增长。
- Flash Attention 定位保留完整注意力矩阵,但通过分块避免把整块矩阵都搬进搬出。
- IO 优化含义减少高带宽内存读写,充分利用片上缓存。
- 显存优势即使复杂度没降,显存占用也从 N² 降到 N,能训练更长的序列。
应用与选型:按需选择晚会方案
说了这么多,到底怎么选?先看序列长度。如果序列只有几百,标准注意力或 Flash Attention 足够;如果序列上万甚至十万,线性注意力才显出价值。再看任务类型:Performer 的随机特征适合需要保留近似 softmax 特性的场景,比如蛋白质序列建模;Linformer 的低秩投影适合长文本摘要,因为这类文本有大量冗余;广义线性注意力的递推优点适合流式生成、在线推理。
工程上还要注意一点:线性注意力的实现并不像公式那么简单,数值稳定性、归一化方式、特征维度都需要反复调试。一个务实的做法是在同一套代码里同时实现标准注意力和几种线性变体,用真实数据评估精度和速度,而不是凭感觉选型。
最终,高效 Transformer 的实践不是记住某个变体最牛,而是读懂任务需求,像选择晚会方案一样,选出最合适的那一款。
- 分子含义序列长度和流式需求越大,线性化的收益越高。
- 分母含义精度要求越高,近似方法的容错空间越小。
- 正比关系两边力量对比,决定了你在工程中最终选择哪种注意力。
- 工程直觉这并非严格公式,而是提醒你权衡不同维度的需求。
AI 应用场景
长文本摘要中的 Linformer
阶段:模型架构优化 / 训练加速
解决的问题:传统 Transformer 处理 1 万字以上的文档摘要时,注意力矩阵太大,显存和训练时间都不可接受。Linformer 通过低秩投影,把注意力矩阵从 N×N 压缩为 N×K,使长文档训练成为可能。
具体案例:某新闻聚合平台需要对平均 8000 字的新闻稿生成摘要。使用 Linformer 后,单条样本的显存占用下降约一个数量级,训练吞吐提升了 4 倍,摘要质量与标准 Transformer 接近。
蛋白质序列建模中的 Performer
阶段:长序列特征提取
解决的问题:蛋白质序列长度可达数万甚至数十万,标准注意力无法直接处理。Performer 用随机特征近似 softmax 核,在线性复杂度下保留核函数的表达能力。
具体案例:某生物计算实验室将 Performer 嵌入蛋白质二级结构预测模型,对长度超过 5 万 token 的序列做全局建模,最终在保持预测精度的前提下,把最长序列训练时间从几天缩短到几小时。
流式对话生成中的 Linear Attention
阶段:推理部署 / 在线服务
解决的问题:对话机器人需要边接收输入边生成回复,标准注意力每次都重新计算历史信息,延迟高。线性注意力的递推状态让模型每一步只更新一个记忆矩阵,自然支持流式推理。
具体案例:某智能客服系统将生成模型换成线性注意力 Transformer,同时保留对话历史记忆。实测单轮回复延迟降低 60%,长对话中也不再随时间线性增加计算量。
Python 演示
import numpy as npimport time def standard_attention(Q, K, V): d = Q.shape[-1] scores = (Q @ K.T) / np.sqrt(d) scores = np.exp(scores - scores.max(axis=-1, keepdims=True)) weights = scores / scores.sum(axis=-1, keepdims=True) return weights @ V def linear_attention(Q, K, V): phi = lambda x: np.maximum(x, 0) + 1 Q_phi = phi(Q) K_phi = phi(K) KV = K_phi.T @ V Z = K_phi.sum(axis=0) out = Q_phi @ KV denom = Q_phi @ Z[:, None] return out / denom if __name__ == '__main__': np.random.seed(0) N, d = 256, 64 Q = np.random.randn(N, d) K = np.random.randn(N, d) V = np.random.randn(N, d) out_s = standard_attention(Q, K, V) out_l = linear_attention(Q, K, V) print('shape:', out_s.shape, out_l.shape) print('mean abs diff:', np.abs(out_s - out_l).mean()) for name, fn in [('standard', standard_attention), ('linear', linear_attention)]: t0 = time.time() for _ in range(10): fn(Q, K, V) print(name, 'time:', round(time.time() - t0, 4))
scores = (Q @ K.T) / np.sqrt(d)计算所有查询和键的点积相似度,并缩放防止 softmax 饱和。scores = np.exp(scores - scores.max(axis=-1, keepdims=True))对分数做平移后再指数,得到稳定的未归一化权重。weights = scores / scores.sum(axis=-1, keepdims=True)按行归一化,得到标准注意力的软最大权重。phi = lambda x: np.maximum(x, 0) + 1构造一个简单的非负核特征,用来模拟线性注意力中的 φ。KV = K_phi.T @ V先合并键和值,避免显式生成 N×N 的注意力矩阵。denom = Q_phi @ Z[:, None]计算线性注意力的归一化分母,防止输出尺度漂移。
常见误区
误区我刚学高效 Transformer,看到“线性”和“Flash”都出现在长文本优化里,以为它们是一回事,都是把复杂度变成 O(N)。
正解它们走的是两条完全不同的优化路线。线性注意力通过核技巧或低秩分解,真正把算法复杂度从 O(N²) 降到 O(N)。Flash Attention 仍然计算完整注意力,复杂度还是 O(N²),但它通过分块和 IO 优化降低显存占用与访存时间。可以简单记:线性注意力是“少算”,Flash Attention 是“快取”。
为何常见:两者常出现在同一篇长文本高效 Transformer 的文章里,而且都能提升速度、降低显存,初学者容易把结果当成原因。
误区Linformer 只是把 K 和 V 投影到更小的维度,信息量变少了,但文本里有冗余,所以损失应该为零。
正解低秩分解本质上假设注意力矩阵可以被 K 个基向量表达,这是一个近似。K 越小误差越大,长序列或超低频关键信息下尤其明显。论文中的实验显示,在合适 K 下误差可接受,但不是“无损”。
为何常见:因为自然语言中确实存在大量冗余,很多文章也强调“文本冗余使低秩假设成立”,容易被引申成“没有损失”。
误区我以为只要把 softmax 从注意力公式里拿掉,计算量自然就变成 O(N),这就叫线性注意力。
正解仅仅去掉 softmax 还不够,你还需要确定权重函数的形式,并且要让它能写成特征内积;之后还要改变矩阵乘法顺序,先算 φ(K)^T V,再用 φ(Q) 去乘,才能真正避免 N×N 矩阵。最后往往还需要归一化分母来保持数值稳定。
为何常见:公式看起来就是“QK^T 再乘 V”,初学者只看到 softmax 是显式构造矩阵的环节,忽略了后续运算顺序才是复杂度降低的关键。
误区既然线性注意力复杂度低,那所有长文本任务都应该无脑换成线性注意力,速度肯定更快。
正解任务还要看精度和瓶颈。比如某些长文本关系抽取需要精确的逐对交互,近似注意力会丢失重要细节。如果序列长度只有几百,线性注意力的额外特征变换开销可能比标准注意力还大。Flash Attention 等硬件感知方法在中等长度下往往更划算。
为何常见:看到“线性”两个字,容易忽略常数项和精度损失,也容易忽略 IO 开销才是某些场景的真正瓶颈。
面试题
Q1. 标准自注意力的计算复杂度随序列长度 N 如何增长?
- A.线性级 O(N)
- B.平方级 O(N²)← 正确答案
- C.对数级 O(logN)
- D.常数级 O(1)
答案:B。标准注意力需要生成 N×N 的相似度矩阵,每个查询都要与所有键计算点积,因此是 O(N²)。线性注意力的目标就是把这个平方关系改写成线性级。
Q2. Softmax 注意力能被核技巧近似的基础是什么?
- A.相似度可写成特征内积← 正确答案
- B.数据必须服从高斯分布
- C.序列长度必须足够大
- D.必须使用 GPU 训练
答案:A。核技巧的核心是把某种相似度函数看成高维特征空间中的内积。只要 softmax 能被 φ(x) 的内积近似,就能改变运算顺序,所以“可写为内积”是关键前提。
Q3. Performer(FAVOR+)主要采用什么特征?
- A.随机正交特征← 正确答案
- B.哈希碰撞特征
- C.低秩投影特征
- D.卷积滑动窗口特征
答案:A。Performer 用随机特征映射近似 softmax,并特别使用正交随机特征来减小近似方差。低秩投影是 Linformer 的做法,卷积窗口和哈希碰撞是其他类别的方法。
Q4. Linformer 降低复杂度的核心操作是?
- A.对序列维度做低秩投影← 正确答案
- B.随机丢弃注意力头
- C.把 softmax 改成 ReLU
- D.将词向量维度减半
答案:A。Linformer 通过学习矩阵把键和值的序列长度从 N 投影到 K,使注意力矩阵变成 N×K,从而把复杂度降到 O(NK)。它并没有替换 softmax。
Q5. 线性注意力递推形式的主要优势是?
- A.支持流式增量计算← 正确答案
- B.自动获得稀疏注意力
- C.完全消除近似误差
- D.无需任何归一化操作
答案:A。线性注意力把历史信息累积进状态矩阵 S,每个新查询只需读取当前状态,所以天然支持流式推理。它仍有近似误差,也需要归一化分母。
Q6. 下列哪个方法不属于线性注意力变体?
- A.Performer
- B.Linformer
- C.Longformer← 正确答案
- D.Linear Transformer
答案:C。Performer 基于随机特征,Linformer 基于低秩投影,Linear Transformer 是广义线性注意力。Longformer 使用稀疏窗口和全局 token,主要思想是稀疏化,不是线性化。
Q7. Flash Attention 与 Linear Attention 的关键区别是?
- A.前者优化 IO,后者降低复杂度← 正确答案
- B.前者无需 softmax,后者保留 softmax
- C.前者依赖随机投影,后者依赖低秩矩阵
- D.两者在数学上完全相同
答案:A。Flash Attention 通过分块和重计算减少显存读写,没有改变 O(N²) 的算法复杂度。Linear Attention 通过改变计算流程把复杂度降为 O(N),二者是不同维度的优化。
Q8. 哪些方法通过核特征映射实现线性化?
- A.Performer← 正确答案
- B.Linformer
- C.Linear Transformer← 正确答案
- D.Flash Attention
答案:AC。Performer 用随机特征映射近似核,Linear Transformer 用可学习或固定的核特征替换 softmax。Linformer 是低秩投影,Flash Attention 是 IO 优化,两者都不是核特征映射。
Q9. 在哪些场景下线性注意力比标准注意力更合适?
- A.超长序列训练← 正确答案
- B.流式在线推理← 正确答案
- C.需要精确注意力权重
- D.极短序列小模型
答案:AB。超长序列下 N² 内存不可接受,线性注意力是刚需;流式推理能利用递推状态。需要精确注意力权重时应保留标准注意力或使用 IO 优化,极短序列下线性注意力的额外开销可能不划算。
Q10. 线性注意力数值不稳定的常见来源有哪些?
- A.分母可能趋于零← 正确答案
- B.递推累积误差← 正确答案
- C.随机特征方差过大← 正确答案
- D.学习率必须非常大
答案:ABC。线性注意力用累加和作分母,如果特征非负性设计不好,分母会趋近零;递推方式会把误差一路累积;随机特征方差过大会让近似波动剧烈。学习率不是数值不稳定的直接来源。