1.6 长上下文与高效注意力¶
本章你将学到
- 为什么标准注意力在序列长度 \(T\) 上的计算量和显存都是 \(O(T^2)\),以及这两种开销分别在哪里“咬人”。
- FlashAttention 如何通过分块(tiling)加在线 softmax,在不存储 \(T \times T\) 矩阵的情况下计算精确的注意力(本章给出推导)。
- 在短序列上训练的模型如何扩展到长序列:位置插值、NTK-aware 缩放和 YaRN。
- 更便宜的注意力模式:滑动窗口、局部/全局交错,以及 attention sink。
- 亚二次复杂度的替代方案:线性注意力、状态空间模型(Mamba)、gated delta rule、混合模型和稀疏注意力(NSA/DSA)。
为什么重要¶
长上下文让模型能够阅读一整个代码库、一份合同,或者智能体数小时的工具调用记录。但 1.3 中的注意力要把每个 query 与每个 key 都比较一遍。对于序列长度为 \(T\) 的单个头,分数矩阵 \(QK^\top\) 有 \(T^2\) 个元素。上下文翻倍,这部分工作就变成四倍。当 \(T = 131{,}072\)(128K)时,一个头的分数矩阵有 \(1.7 \times 10^{10}\) 个元素,在 BF16 下占 32 GiB,而这还只是一层中的一个头。即使算力够用,朴素地存储这个矩阵也不现实。本章讲两类解决办法:让精确注意力在硬件上高效运行(FlashAttention),或者改变注意力本身,让它不再是二次的(窗口、线性注意力、SSM、稀疏注意力)。本章还会讲,对于位置编码(RoPE,见 1.4)只训练到某个长度的模型,如何扩展它的上下文长度。
直觉¶
- FlashAttention: 朴素注意力的问题与其说是算术,不如说是数据搬运:把一个巨大的矩阵写进慢速的 GPU 显存,再读回来。FlashAttention 以能放进高速片上存储的小块(tile)来计算注意力,从不把那个大矩阵写出去。让这一切成为可能的窍门,是一种可以增量计算的 softmax:每次处理一块 key。
- 上下文扩展: RoPE 把位置编码成旋转角度。一个训练到 8K token 的模型从没见过 8K 之后的位置所产生的角度。插值类方法把长位置重新压缩回模型熟悉的角度范围。
- 更便宜的模式: 大多数 token 大多数时候只需要附近的上下文。让大部分层只看一个局部窗口,再保留少数几层做全注意力,负责远距离检索。
- 线性注意力 / SSM: 不再保留每一个过去的 key 和 value,而是保留一个固定大小的摘要(一个状态矩阵),每个 token 更新一次,就像 RNN。每个 token 的内存变成常数,但摘要是有损的,所以对远处细节的精确回忆会变差。混合模型把两者结合起来。
工作原理¶
注意力的开销¶
对于一层,有 \(h\) 个头、头大小为 \(d_h\)(因此 \(h d_h = d\)),序列长度为 \(T\):
- 计算: \(QK^\top\) 和 \(AV\) 各花 \(2 T^2 d\) FLOPs,所以前向传播中每层是 \(4 T^2 d\)(利用因果掩码可省去约一半)。该层其余部分(投影、FFN)的开销为 \(O(T d^2)\)。一旦 \(T\) 超过 \(d\) 的几倍,注意力就占主导。
- 显存(训练): 朴素实现会为反向传播存储 \([B, h, T, T]\) 的注意力概率。
- 显存(推理): KV cache 随 \(T\) 线性增长(见 1.4),而且每个解码步都必须读取它的全部内容。
FlashAttention:分块与在线 softmax¶
GPU 有容量大但速度慢的主存(HBM,几十 GB,带宽几 TB/s),以及每个流式多处理器(SM)上容量很小但速度很快的片上 SRAM(几百 KB)。朴素注意力把 \(S = QK^\top\) 写入 HBM,读回来做 softmax,再写出 \(P\),然后为了算 \(PV\) 再读一次。FlashAttention(Dao et al., 2022)把 \(Q\) 切成行块,把 \(K, V\) 切成列块,每次把一个 tile 载入 SRAM,并直接累加输出。障碍在于 softmax 需要整行才能归一化:\(\mathrm{softmax}(s)_j = e^{s_j} / \sum_{j'} e^{s_{j'}}\)。解决办法就是在线 softmax。
推导在线 softmax。 为了数值稳定,softmax 总是减去最大值后再计算:\(\mathrm{softmax}(s)_j = e^{s_j - m} / \ell\),其中 \(m = \max_j s_j\),\(\ell = \sum_j e^{s_j - m}\)。假设我们已经处理了第一块分数,持有它的统计量 \(m^{(1)}, \ell^{(1)}\) 以及未归一化的输出 \(o^{(1)} = \sum_{j \in \text{chunk 1}} e^{s_j - m^{(1)}} v_j\)。第二块到来,其局部最大值为 \(\tilde m\)。新的全局最大值是 \(m^{(2)} = \max(m^{(1)}, \tilde m)\)。每个旧的项都是相对于 \(m^{(1)}\) 算的;要把它改写成相对于 \(m^{(2)}\) 的形式,需要乘以 \(e^{m^{(1)} - m^{(2)}}\),因为 \(e^{s_j - m^{(1)}} e^{m^{(1)} - m^{(2)}} = e^{s_j - m^{(2)}}\)。于是
处理完最后一块之后,精确的注意力输出就是 \(o / \ell\)。用大白话说:维护一个滚动的最大值、一个滚动的分母和一个滚动的加权和;每当最大值增大,就把旧的累加器按相应系数缩小。无论 \(T\) 多大,每个 query 行只需要 \(O(1)\) 个额外的数。
对于反向传播,FlashAttention 每行只存储 \(m\) 和 \(\ell\)(而不存 \(T \times T\) 的概率),并在需要时重新计算 \(P\) 的各个 tile。重新计算增加了 FLOPs,但去掉了主要的内存搬运,所以整体更快。结果就是显存为 \(O(T)\) 的精确注意力。FlashAttention-2 改进了跨序列和跨 warp 的并行化;FlashAttention-3 针对 Hopper GPU(异步内存拷贝、warp 特化、FP8)。kernel 的细节见 第 3 部分。
扩展上下文窗口¶
在很长的序列上做预训练代价高昂,所以模型大多在 4K–8K token 上训练,然后在长文档上做一小段继续训练来扩展长度。使用 RoPE 时,位置 \(m\) 上的第 \(i\) 对维度旋转角度为 \(m\theta_i\),其中 \(\theta_i = b^{-2i/d_h}\)(见 1.4)。设训练长度为 \(L\),目标长度为 \(L' = sL\),其中 \(s\) 是缩放因子。
- 位置插值(PI)(Chen et al., 2023):用位置 \(m / s\) 代替 \(m\),等价于把每个频率都除以 \(s\):\(\theta_i' = \theta_i / s\)。所有角度都保持在训练过的范围内。代价是:用来区分相邻 token 的高频维度对也被压缩了 \(s\) 倍,所以相邻位置更难区分。一次短暂的微调(Chen et al. 报告约 1,000 步)就能恢复大部分质量。
-
NTK-aware 缩放: 改为调整底数,使高频几乎不变,而最低频率恰好被插值 \(s\) 倍。最低频率是 \(\theta_{d_h/2-1} = b^{-(d_h-2)/d_h}\)。要求 \((b')^{-(d_h-2)/d_h} = b^{-(d_h-2)/d_h} / s\),得到
\[ b' = b \cdot s^{d_h/(d_h - 2)} . \]用大白话说:把底数增大到比 \(s\) 稍多一点。这样插值是不均匀地分摊的:快的维度对完全不插值,最慢的完全插值。(这个名字来自关于神经正切核(NTK)的论证,涉及如何学习高频。) - YaRN(Peng et al., 2023)把这种划分按频率显式地做出来。对第 \(i\) 对维度,计算它的波长 \(\lambda_i = 2\pi / \theta_i\) 以及比值 \(r_i = L / \lambda_i\)(它在训练长度内完成了多少整圈旋转)。转了很多圈的维度对(\(r_i > \beta\))在训练中已经见过所有角度:保持不动。转不满一圈的一部分(\(r_i < \alpha\))的维度对必须插值:除以 \(s\)。介于两者之间的,用一段斜坡做线性混合。论文对 Llama 模型取 \(\alpha = 1\),\(\beta = 32\)。YaRN 还会把注意力 logits 乘以一个温度因子 \(\sqrt{1/t} = 0.1 \ln s + 1\),以抵消远距离上注意力分布变平的现象。它只需少量继续训练就能达到长上下文,Qwen、DeepSeek-V3、Kimi K2 和 gpt-oss 都在使用。
另一个互补的手段,是从一开始就用较大的底数训练(Llama 3 使用 \(b = 500{,}000\)),并安排专门的长上下文训练阶段,长度逐步增加。
滑动窗口与局部/全局注意力¶
滑动窗口注意力(SWA) 让每个 token 只关注前面的 \(W\) 个 token。每层的计算量降为 \(O(T W)\),每层的 KV cache 上限为 \(W\) 项。信息传播的距离仍然可以超过 \(W\):堆叠 \(L\) 层窗口注意力后,感受野最多可达 \(L \cdot W\) 个 token,就像堆叠的卷积一样。Mistral 7B 使用 \(W = 4096\)。
实际中,纯 SWA 会损失精确的远距离检索,所以模型会把局部层和全局层交错排列:Gemma 2 以 1:1 交替;Gemma 3 每 1 个全局层配 5 个局部层(窗口 1024);gpt-oss 则让全注意力与 128 token 的带状(窗口)注意力交替。只有全局层才需要完整长度的 KV cache。
Attention sink¶
softmax 的权重之和必须为 1,即使某个头没有任何值得关注的内容。模型学会把这些多余的注意力倾倒在最前面的 token 上,因为每个位置都能看到它们。Xiao et al.(2023)把它们称为 attention sink,并指出:如果滑动窗口缓存把最开头的 token 驱逐出去,模型就会崩溃;而保留最前面 4 个 token 加一个最近窗口(StreamingLLM),则能让生成在非常长的流上保持稳定。gpt-oss 把这点内建进了模型:每个头有一个可学习的 sink logit,它给 softmax 的分母增加一项,让该头把概率质量放在“什么都不关注”上,而不是放在某个任意的 token 上。
线性注意力¶
把 query \(t\) 的因果注意力写成 \(o_t = \sum_{j \le t} \mathrm{sim}(q_t, k_j)\, v_j / \sum_{j \le t} \mathrm{sim}(q_t, k_j)\),其中 \(\mathrm{sim}(q, k) = e^{q \cdot k / \sqrt{d}}\)。线性注意力(Katharopoulos et al., 2020)把指数换成特征映射的点积,\(\mathrm{sim}(q, k) = \phi(q)^\top \phi(k)\),其中 \(\phi\) 为正值函数(如 \(\mathrm{elu}(x) + 1\))。于是,利用结合律,
用大白话说:整个历史被压缩进一个 \(d_v \times d_k\) 的矩阵 \(S_t\)(外加一个向量 \(z_t\)),每个 token 只需往里加一个外积来更新。推理内存与 \(T\) 无关(常数),就像 RNN;训练仍然可以并行(或分块)进行。它的弱点是:\(S_t\) 是固定大小的和,旧信息永远不会被移除,key 之间会相互干扰。对很久以前的具体事实的回忆因此会退化。
状态空间模型与 Mamba¶
一个(离散化的)状态空间模型通过隐状态 \(h_t\) 把输入序列 \(x_t\) 映射为输出:
其中 \(\bar A_t\) 控制状态如何衰减,\(\bar B_t\) 控制输入如何写入,\(C_t\) 控制状态如何被读出。经典 SSM 使用固定(时不变)的矩阵,这使得基于卷积的训练很快,但无法根据内容决定记住什么。Mamba(Gu & Dao, 2023)让 \(\bar B_t\)、\(C_t\) 和步长(进而包括衰减 \(\bar A_t\))成为输入 token 的函数:模型可以有选择地保留或遗忘信息。它用硬件感知的并行扫描(parallel scan)来训练,解码时每个 token 只需 \(O(1)\) 内存。Mamba-2(Dao & Gu, 2024)证明了这种递推的一个受限形式,等价于一种带衰减掩码的线性注意力(“状态空间对偶”),从而可以做对矩阵乘法友好的分块训练。
Gated delta rule¶
线性注意力是往状态里加上 \(v_t k_t^\top\)。可以把 \(S\) 看作一个联想记忆:用(单位范数的)key 去读取,得到 \(S k\)。而 delta rule 则是把记忆朝目标值修正:它先读出当前的预测 \(S_{t-1} k_t\),然后只写入误差,
其中 \(\beta_t \in (0, 1]\) 是可学习的、依赖输入的写入强度。当 \(\beta_t = 1\) 时,更新之后恰好有 \(S_t k_t = v_t\):存放在 key \(k_t\) 下的旧值被替换,而不是叠加。Gated DeltaNet(Yang et al., 2024)加入了衰减门 \(\alpha_t \in (0, 1)\),在上下文发生变化时可以迅速遗忘一切:
用大白话说:先遗忘一点(门控),再精确覆盖这个 key 所指向的内容(delta),然后写入新的关联。这样既保持了固定大小的状态,又比普通线性注意力有好得多的上下文内回忆能力。
混合模型¶
线性/SSM 层提供廉价的长上下文;softmax 注意力提供精确的检索。混合模型把大部分线性层与少量全注意力层堆叠起来。MiniMax-01 把 lightning(线性)注意力与每隔八层一层的 softmax 注意力交错排列;Qwen3-Next 大约每 3 个 Gated DeltaNet 层配 1 个全注意力层;Jamba 和 NVIDIA 的 Nemotron-H 把 Mamba 层与注意力层混合使用。KV cache 只在那少数几个全注意力层里增长。
稀疏注意力¶
稀疏注意力不去近似注意力,而是在过去 token 的一个被选中的子集上计算精确的 softmax 注意力。原生稀疏注意力(NSA)(DeepSeek, 2025)为每个 query 结合了三条分支:对压缩后的块摘要做注意力(对全部内容的粗略视图)、对利用这些摘要选出的得分最高的块做注意力(在重要之处看细节),以及滑动窗口(局部上下文),并由可学习的门控混合。它是端到端训练的,并且被设计成让选中的块在内存中连续,从而保持 GPU kernel 的效率。DeepSeek-V3.2 的 DeepSeek Sparse Attention(DSA)用一个轻量的“索引器(indexer)”低成本地为过去的 token 打分,然后只对 top-\(k\) 做注意力。一个相关的思路是 Differential Transformer:保持稠密注意力,但把它算成两个 softmax 图之差,抵消共模的“注意力噪声”,改善长上下文检索。
代码¶
25 行写出 FlashAttention 的前向传播。 这就是算法本身,用纯 PyTorch 写成(所以并不快);代码会与朴素注意力做对照检查。
import math, torch
def naive_attention(q, k, v): # q, k, v: [T, d](单头,无掩码)
s = q @ k.T / math.sqrt(q.shape[-1]) # [T, T] 完整物化
return torch.softmax(s, dim=-1) @ v
def tiled_attention(q, k, v, block=16):
"""FlashAttention 风格的前向:用在线 softmax 在 K/V 块上流式处理。
从不物化 [T, T] 矩阵;每个 query 行额外的状态只有 (m, l)。"""
T, d = q.shape
scale = 1 / math.sqrt(d)
out = torch.empty_like(q)
for i in range(0, T, block): # 每个 query 块(对应一个 GPU thread block)
qi = q[i:i + block] * scale # [b, d]
m = torch.full((qi.shape[0], 1), -float("inf")) # 分数的滚动最大值
l = torch.zeros(qi.shape[0], 1) # exp(score - m) 的滚动和
acc = torch.zeros(qi.shape[0], d) # 滚动的未归一化输出
for j in range(0, T, block): # 让 K/V 块流经“SRAM”
s = qi @ k[j:j + block].T # [b, b],只含这个 tile 的分数
m_new = torch.maximum(m, s.max(-1, keepdim=True).values)
p = torch.exp(s - m_new) # tile 的概率(未归一化)
c = torch.exp(m - m_new) # 旧统计量的缩放因子
l = l * c + p.sum(-1, keepdim=True)
acc = acc * c + p @ v[j:j + block]
m = m_new
out[i:i + block] = acc / l # 最后只归一化一次
return out
torch.manual_seed(0)
q, k, v = (torch.randn(100, 32) for _ in range(3))
print(torch.allclose(naive_attention(q, k, v), tiled_attention(q, k, v), atol=1e-5)) # True
线性注意力:并行形式 = 递推形式,外加 gated delta rule。
import torch
import torch.nn.functional as F
def phi(x): # 正值特征映射(Katharopoulos et al.)
return F.elu(x) + 1
def linear_attention_parallel(q, k, v): # 每个都是 [T, d];因果,训练风格
A = phi(q) @ phi(k).T # [T, T] 相似度(不做 softmax)
A = torch.tril(A) # 因果掩码
return (A @ v) / A.sum(-1, keepdim=True)
def linear_attention_recurrent(q, k, v): # 推理风格:每步 O(1) 状态
d_k, d_v = q.shape[1], v.shape[1]
S = torch.zeros(d_v, d_k) # 状态:sum_j v_j phi(k_j)^T
z = torch.zeros(d_k) # 归一化项:sum_j phi(k_j)
outs = []
for t in range(q.shape[0]):
S = S + torch.outer(v[t], phi(k[t]))
z = z + phi(k[t])
outs.append(S @ phi(q[t]) / (z @ phi(q[t])))
return torch.stack(outs)
def gated_delta_recurrent(q, k, v, alpha, beta):
"""S_t = alpha_t * S_{t-1} (I - beta_t k_t k_t^T) + beta_t v_t k_t^T ; o_t = S_t q_t"""
S = torch.zeros(v.shape[1], k.shape[1])
outs = []
for t in range(q.shape[0]):
kt = F.normalize(k[t], dim=0) # 单位范数的 key 让更新保持稳定
S = alpha[t] * (S - beta[t] * torch.outer(S @ kt, kt)) + beta[t] * torch.outer(v[t], kt)
outs.append(S @ q[t])
return torch.stack(outs)
torch.manual_seed(0)
T, d = 50, 16
q, k, v = (torch.randn(T, d) for _ in range(3))
print(torch.allclose(linear_attention_parallel(q, k, v),
linear_attention_recurrent(q, k, v), atol=1e-5)) # True
o = gated_delta_recurrent(q, k, v, alpha=torch.full((T,), 0.95), beta=torch.full((T,), 0.5))
# 把 delta rule 当作联想记忆:把同一个 (key -> value) 写两次不会累加。
S = torch.zeros(d, d)
key, val = F.normalize(torch.randn(d), dim=0), torch.randn(d)
for _ in range(3):
S = S - torch.outer(S @ key, key) + torch.outer(val, key) # beta = 1, alpha = 1
print(torch.allclose(S @ key, val, atol=1e-5)) # True:精确回忆
如果用普通线性注意力把同一对写三次,读出来会是该值的 \(3 \times\);delta rule 读出来则恰好等于原值。
实例演算¶
手算在线 softmax。 某个 query 的分数为 \(s = (1, 2 \mid 4)\),切成长度 2 和 1 的两块,标量值为 \(v = (10, 20 \mid 30)\)。
- 第 1 块:\(m^{(1)} = 2\),\(\ell^{(1)} = e^{1-2} + e^{0} = 1.3679\),\(o^{(1)} = e^{-1} \cdot 10 + 1 \cdot 20 = 23.679\)。
- 第 2 块:局部最大值为 4,所以 \(m^{(2)} = 4\),缩放因子为 \(e^{2-4} = 0.1353\)。
- \(\ell^{(2)} = 1.3679 \times 0.1353 + e^{0} = 1.1851\);\(o^{(2)} = 23.679 \times 0.1353 + 30 = 33.205\)。
- 输出 \(= 33.205 / 1.1851 = 28.02\)。
直接验算:\(\big(e^{-3} \cdot 10 + e^{-2} \cdot 20 + 30\big) / \big(e^{-3} + e^{-2} + 1\big) = 33.205 / 1.1851 = 28.02\)。完全一致。
局部/全局交错的显存。 考虑一个假设的模型:62 层,16 个 KV 头,头大小 128,BF16 缓存,128K 上下文。每层中,每个被缓存的 token 占 \(2 \times 16 \times 128 \times 2 = 8192\) 字节。
- 62 层全部为全局:每个序列 \(62 \times 8192 \times 131{,}072 = 62\) GiB。
- 10 个全局层 + 52 个窗口为 1024 token 的局部层:\(10 \times 8192 \times 131{,}072 + 52 \times 8192 \times 1024 \approx 10.0 + 0.4 = 10.4\) GiB。
约 6× 的缩减,这就是 Gemma 3 从 Gemma 2 的 1:1 模式改为 5:1 并采用较短窗口的原因。
上下文扩展的数字。 从 32K 扩展到 128K,意味着 \(s = 4\)。取 \(d_h = 128\)、\(b = 10{,}000\),NTK-aware 缩放给出 \(b' = 10{,}000 \times 4^{128/126} \approx 40{,}890\)。YaRN 的注意力温度因子为 \(0.1 \ln 4 + 1 \approx 1.139\)。
实践中的做法(2025–2026)¶
- FlashAttention 风格的 kernel 已经无处不在,训练和 prefill 都用它;没有人再去物化注意力矩阵。在 PyTorch 中,
F.scaled_dot_product_attention会自动选择这类 kernel。 - 128K 的上下文长度已是开源前沿模型的标配(Llama 3、DeepSeek-V3、配合 YaRN 的 Qwen3、gpt-oss、Kimi K2、Gemma 3),通常的做法是先短上下文预训练,再分阶段扩展到长上下文。Llama 3 分六个增量阶段完成了到 128K 的长上下文训练。
- 减小 KV cache 是主要的架构抓手:GQA/MLA(见 1.4)加上局部/全局交错(Gemma 3、gpt-oss)。
- 混合模型正在进入前沿模型(MiniMax-01、Qwen3-Next、Nemotron-H),而可训练的稀疏注意力(DeepSeek-V3.2 中的 NSA、DSA)则是在长距离上保持精确 softmax 注意力的主要替代方案。
- 上下文并行(把一个序列切分到多块 GPU 上,例如 Ring Attention)是百万 token 训练能放进显存的办法;见 1.8。
常见误区¶
- “FlashAttention 是一种近似。” 它是精确的(至多存在浮点运算顺序不同带来的差别);它改变的是内存访问模式,而不是数学。
- “FlashAttention 让注意力变成线性的。” 显存变成了 \(O(T)\),但计算量仍然是 \(O(T^2)\)。
- 声称的上下文 ≠ 可用的上下文。 模型可能接受 128K token,却仍然无法利用中间部分的信息。请在你需要的长度上,用检索和推理任务来评测。
- 在推理时更改 RoPE 缩放,却与训练不匹配。 插值方法在配合它们设计时所用的继续训练时效果最好(甚至只有那时才有效);设置必须与检查点的配置一致。
- 期望线性注意力像 softmax 注意力那样回忆。 固定大小的状态无法存储无限多的事实;这正是混合模型保留部分全注意力的原因。
- 把最开头的 token 从滑动缓存中驱逐,会让依赖 attention sink 的模型崩溃。
本章要点¶
- 注意力的计算量是 \(O(T^2)\);朴素实现的显存同样是 \(O(T^2)\),FlashAttention 通过分块和在线 softmax 消除了后者。
- 在线 softmax 维护滚动的最大值、分母和输出,每当最大值增大,就按 \(e^{m_{\text{old}} - m_{\text{new}}}\) 缩放。
- 上下文扩展就是重新缩放 RoPE 的频率:均匀缩放(PI)、通过底数(NTK)、或按频段分别处理并加上温度(YaRN)。
- 局部窗口与少量全局层交错,可以大幅削减 KV cache;attention sink 让窗口缓存保持稳定。
- 线性注意力、SSM 和 gated delta rule 用固定大小的状态取代不断增长的 KV cache;混合模型和可训练的稀疏注意力则把效率与精确检索结合起来。
自测¶
FlashAttention 在反向传播中多做了 FLOPs,为什么仍然能加速?
注意力受限于内存搬运,而不是算术。在高速 SRAM 里重新计算 tile,比把 \(T \times T\) 矩阵写入 HBM 再读出来更便宜。
在线 softmax 中,如果新一块的最大值比滚动最大值小,会发生什么?
\(m\) 保持不变,于是缩放因子 \(e^{m_{\text{old}} - m_{\text{new}}} = 1\),旧的累加器不变;新的项直接加进去即可。
一个模型有 32 层,每层的滑动窗口为 4096。信息最多能向最后一个 token 传播多远?
最多约 \(32 \times 4096 = 131{,}072\) 个 token,因为每一层最多能把信息移动一个窗口的距离。实际上,经过多次跳转后信息会退化,这就是为什么要保留全局层。
为什么 PI 在短距离上比 NTK/YaRN 差?
PI 把所有频率都除以 \(s\),包括用来区分相邻 token 的高频,所以局部位置分辨率下降了 \(s\) 倍。NTK/YaRN 几乎不动高频,只对低频做插值。
当同一个 key 被写入两次、对应不同的值时,delta rule 与线性注意力有什么不同?
线性注意力把两个值都加进去,所以读出来是它们的和。delta rule(取 \(\beta = 1\))会用第二个值替换第一个,因为它只写入目标值与当前读出值之间的差。
延伸阅读¶
| 论文 | 为什么读 |
|---|---|
| FlashAttention — Dao et al., 2022 | 对注意力分块,使 \(T \times T\) 矩阵从不触及 HBM;精确、更快、显存 \(O(T)\)。 |
| Online normalizer calculation for softmax — Milakov & Gimelshein, 2018 | FlashAttention 的在线 softmax 所依据的单遍 softmax 归一化方法。 |
| FlashAttention-2 — Dao, 2023 | 在 warp/thread block 之间更好的工作划分;比 v1 快约 2×。 |
| FlashAttention-3 — Shah et al., 2024 | 针对 Hopper:异步(TMA、warp 特化)与 FP8。 |
| Extending Context Window of LLMs via Positional Interpolation — Chen et al., 2023 | RoPE 的位置插值,以及它为什么优于外推。 |
| YaRN: Efficient Context Window Extension — Peng et al., 2023 | 按频率(“NTK-by-parts”)重新缩放 RoPE,加上注意力温度;应用广泛。 |
| Ring Attention with Blockwise Transformers — Liu et al., 2023 | 把序列切分到多个设备上,并让 K/V 块沿环传递:上下文并行的基础。 |
| Mistral 7B — Jiang et al., 2023 | 在一个强大的小模型里使用带滚动 KV cache 的滑动窗口注意力。 |
| Gemma 2 — Gemma Team, 2024 | 局部/全局交错注意力与 logit 软截断(soft-capping)。 |
| Efficient Streaming Language Models with Attention Sinks — Xiao et al., 2023 | 发现了 attention sink;StreamingLLM 保留起始 token 加一个窗口。 |
| Transformers are RNNs (Linear Attention) — Katharopoulos et al., 2020 | 核化注意力及其递推形式,如上文所推导。 |
| Mamba: Linear-Time Sequence Modeling with Selective State Spaces — Gu & Dao, 2023 | 依赖输入的 SSM;训练 \(O(T)\),推理时每个 token 的内存为 \(O(1)\)。 |
| Transformers are SSMs (Mamba-2) — Dao & Gu, 2024 | SSM 与线性注意力之间的状态空间对偶;更快的基于矩阵乘法的算法。 |
| Gated Delta Networks — Yang et al., 2024 | 线性注意力的门控加 delta rule;以混合形式用于 Qwen3-Next。 |
| MiniMax-01: Scaling Foundation Models with Lightning Attention — MiniMax, 2025 | 第一个前沿规模的混合线性注意力 MoE(456B),上下文最长达 1M–4M。 |
| Native Sparse Attention (NSA) — Yuan et al. (DeepSeek), 2025 | 与硬件对齐、可训练的稀疏注意力;V3.2 中 DeepSeek Sparse Attention 的前身。 |
| Differential Transformer — Ye et al., 2024 | 把注意力写成两个 softmax 图之差,抵消注意力噪声。 |