跳转至

注意力机制(Attention Mechanism)

注意力机制是从 RNN 时代到 Transformer 时代的关键桥梁。它让模型在处理信息时,能动态聚焦于最相关的部分,而非平等对待所有输入。


1. 为什么需要注意力?

回顾 Seq2Seq 的瓶颈:编码器将整个输入序列压缩为一个固定长度的向量 \(\mathbf{c}\),解码器只能依赖这一个向量生成输出。

问题

当输入序列很长时,一个向量根本无法承载所有信息。翻译一句 50 词的长句,解码器到后面已经"忘了"前面的内容。

Attention 的核心思想:解码器在生成每个词时,不只看 \(\mathbf{c}\),而是回头看编码器的所有隐藏状态,并根据相关性分配不同的注意力权重。

类比

你在写英语翻译时,不是先把整句中文背下来再翻译。而是翻译到哪个词,就回头看对应的中文部分——这就是注意力。


2. 基础 Attention(Bahdanau Attention)

由 Bahdanau 等人在 2015 年提出,用于改进 Seq2Seq 机器翻译。

计算流程

第 1 步:计算注意力分数(Alignment Score)

对于解码器在时间步 \(t\) 的隐藏状态 \(\mathbf{s}_t\) 和编码器的第 \(j\) 个隐藏状态 \(\mathbf{h}_j\)

\[ e_{tj} = \text{score}(\mathbf{s}_{t-1}, \mathbf{h}_j) \]

第 2 步:Softmax 归一化为注意力权重

\[ \alpha_{tj} = \frac{\exp(e_{tj})}{\sum_{k=1}^{T_x} \exp(e_{tk})} \]

\(\alpha_{tj}\) 表示在生成第 \(t\) 个输出词时,应该关注输入序列第 \(j\) 个位置的程度。

第 3 步:加权求和得到上下文向量

\[ \mathbf{c}_t = \sum_{j=1}^{T_x} \alpha_{tj} \mathbf{h}_j \]

第 4 步:结合上下文向量进行解码

\[ \mathbf{s}_t = f(\mathbf{s}_{t-1}, y_{t-1}, \mathbf{c}_t) \]
graph TD
    subgraph 编码器隐藏状态
        H1[h₁] 
        H2[h₂] 
        H3[h₃]
        H4[h₄]
    end

    S[解码器状态 s_t] -->|计算分数| H1
    S -->|计算分数| H2
    S -->|计算分数| H3
    S -->|计算分数| H4

    H1 -->|α₁| C[上下文向量 c_t]
    H2 -->|α₂| C
    H3 -->|α₃| C
    H4 -->|α₄| C

    C --> OUT[解码输出 y_t]

注意力分数函数

不同的打分方式:

名称 公式 特点
加性注意力(Bahdanau) \(\mathbf{v}^T \tanh(\mathbf{W}_1 \mathbf{s} + \mathbf{W}_2 \mathbf{h})\) 灵活,参数多
点积注意力(Luong) \(\mathbf{s}^T \mathbf{h}\) 简单高效
缩放点积注意力 \(\frac{\mathbf{s}^T \mathbf{h}}{\sqrt{d}}\) ⭐ Transformer 使用

3. Self-Attention(自注意力)

基础 Attention 是解码器关注编码器(跨序列)。Self-Attention 则是序列中每个位置关注同一序列中的所有位置,捕捉序列内部的依赖关系。

关键区别

  • Attention:一个序列的元素关注另一个序列(如翻译时目标语言关注源语言)
  • Self-Attention:同一个序列的元素互相关注(如理解"它"指代前文的哪个名词)

QKV 框架

Self-Attention 将每个输入向量 \(\mathbf{x}_i\) 分别映射为三个向量:

\[ \mathbf{Q} = \mathbf{X}\mathbf{W}^Q, \quad \mathbf{K} = \mathbf{X}\mathbf{W}^K, \quad \mathbf{V} = \mathbf{X}\mathbf{W}^V \]
  • Query(查询):我想找什么信息?
  • Key(键):我包含什么信息?
  • Value(值):我要传递什么内容?

类比:图书馆检索

  • Query = 你的搜索关键词
  • Key = 每本书的索引/标题
  • Value = 每本书的实际内容

搜索时,你用 Query 和每个 Key 做匹配,找到最相关的几本书(注意力权重),然后阅读它们的内容(Value 的加权和)。

缩放点积注意力

\[ \text{Attention}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{Softmax}\left(\frac{\mathbf{Q}\mathbf{K}^T}{\sqrt{d_k}}\right)\mathbf{V} \]

其中 \(d_k\) 是 Key 的维度。

为什么要除以 \(\sqrt{d_k}\)

\(d_k\) 很大时,\(\mathbf{Q}\mathbf{K}^T\) 的值会很大,Softmax 之后分布会极度尖锐(一个位置接近 1,其余接近 0),梯度几乎为 0。除以 \(\sqrt{d_k}\) 使方差回到 1,让 Softmax 的输出更平滑。

计算过程图解

假设序列长度为 4,每个位置的向量维度为 \(d_k\)

       Q (4×d_k)  ×  K^T (d_k×4)  =  注意力分数 (4×4)

       ┌─────┐    ┌──────┐         ┌─────────────┐
       │ q₁  │    │k₁ k₂ k₃ k₄│         │ q₁·k₁  q₁·k₂ ...│
       │ q₂  │  × │            │    =    │ q₂·k₁  q₂·k₂ ...│
       │ q₃  │    │            │         │ ...              │
       │ q₄  │    └──────┘         │ q₄·k₁  ...      │
       └─────┘                      └─────────────┘

       → Softmax → × V (4×d_v) → 输出 (4×d_v)

每一行代表一个位置对所有位置的注意力分布。第 \(i\) 行告诉我们:位置 \(i\) 应该关注序列中哪些位置。


4. 多头注意力(Multi-Head Attention)

一个 Self-Attention 只能学习一种"关注模式"。多头注意力让模型同时从多个角度关注信息。

\[ \text{MultiHead}(\mathbf{Q}, \mathbf{K}, \mathbf{V}) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h)\mathbf{W}^O \]
\[ \text{head}_i = \text{Attention}(\mathbf{Q}\mathbf{W}_i^Q, \mathbf{K}\mathbf{W}_i^K, \mathbf{V}\mathbf{W}_i^V) \]

直觉理解

多头注意力就像多个平行的审阅者

  • 头 1 可能关注语法关系(主语-谓语)
  • 头 2 可能关注指代关系("它"→"猫")
  • 头 3 可能关注位置邻近关系

最后把所有审阅者的意见综合起来。

参数量分析

假设模型维度 \(d_{\text{model}} = 512\),头数 \(h = 8\)

  • 每个头的维度:\(d_k = d_v = d_{\text{model}} / h = 64\)
  • 每个头有 3 个投影矩阵:\(\mathbf{W}^Q, \mathbf{W}^K, \mathbf{W}^V \in \mathbb{R}^{512 \times 64}\)
  • 输出投影:\(\mathbf{W}^O \in \mathbb{R}^{512 \times 512}\)
  • 总参数量:\(3 \times 8 \times 512 \times 64 + 512 \times 512 = 4 \times 512^2 = 1,048,576\)

计算量和单头 Attention(全维度)相同,但表达能力更强。


5. 位置编码(Positional Encoding)

Self-Attention 的计算是排列不变的——打乱输入顺序,输出不会变。但序列的顺序很重要!

"猫 吃 鱼" 和 "鱼 吃 猫" 的 Self-Attention 结果完全一样(如果不加位置信息)。

位置编码给每个位置注入顺序信息

正弦位置编码(Sinusoidal)

原始 Transformer 使用的方案:

\[ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \]
\[ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \]
  • 不同位置的编码向量是唯一的
  • 可以泛化到训练时没见过的序列长度
  • 相对位置信息可以通过线性变换表达

可学习位置编码

直接为每个位置学一个向量(BERT、GPT 系列使用):

\[ \mathbf{x}_i' = \mathbf{x}_i + \mathbf{p}_i, \quad \mathbf{p}_i \in \mathbb{R}^{d_{\text{model}}} \]
  • 表达能力更强(不受固定公式限制)
  • 但最大序列长度固定(超出训练长度需要外推)

旋转位置编码(RoPE)

LLaMA、Qwen 等现代大模型使用的方案:

\[ \text{RoPE}(\mathbf{q}, m) = \mathbf{R}_m \mathbf{q} \]

其中 \(\mathbf{R}_m\) 是一个旋转矩阵,将位置信息编码为向量的旋转角度。

核心优势:位置信息融入 Q 和 K 中,使得 \(\mathbf{q}_m^T \mathbf{k}_n\) 只依赖于相对位置 \(m - n\)


6. Attention 的掩码(Mask)

Padding Mask

序列长度不同时需要 padding,padding 位置不应该被关注:

序列:    [我, 爱, DL, <PAD>, <PAD>]
掩码:    [ 1,  1,  1,    0,     0 ]

将 padding 位置的注意力分数设为 \(-\infty\),Softmax 后变为 0。

Causal Mask(因果掩码)

用于自回归生成(GPT 等),每个位置只能看到自己和之前的位置,不能"偷看"未来:

\[ \text{Mask} = \begin{pmatrix} 0 & -\infty & -\infty & -\infty \\ 0 & 0 & -\infty & -\infty \\ 0 & 0 & 0 & -\infty \\ 0 & 0 & 0 & 0 \end{pmatrix} \]

加到注意力分数上后,再做 Softmax:

位置 1 只能看位置 1
位置 2 能看位置 1, 2
位置 3 能看位置 1, 2, 3
位置 4 能看所有位置

7. Attention 的变体与优化

标准 Self-Attention 的计算复杂度是 \(O(n^2 d)\),当序列长度 \(n\) 很大时(如 100K tokens),计算量和显存开销都难以承受。

常见优化方法

方法 核心思想 复杂度 代表
标准 Attention 全量计算 \(O(n^2)\) 原始 Transformer
稀疏 Attention 只关注部分位置(局部 + 全局) \(O(n\sqrt{n})\) Longformer、BigBird
线性 Attention 用核函数近似 Softmax \(O(n)\) Performer
Flash Attention IO 优化,减少显存读写 \(O(n^2)\) 但更快 ⭐ Flash Attention 2/3
分组查询注意力 (GQA) 多个 Q 头共享 K/V 减少 KV 缓存 LLaMA 2/3、Gemma
滑动窗口 Attention 只关注邻近窗口内的 token \(O(nw)\) Mistral

Flash Attention

Flash Attention 不改变 Attention 的数学计算,而是优化了 GPU 显存访问模式

  • 避免在高带宽显存(HBM)中存储完整的 \(n \times n\) 注意力矩阵
  • 使用分块计算(Tiling):将 Q、K、V 分块,在 SRAM 中完成计算
  • 减少 HBM 读写次数,速度提升 2~4 倍,显存降低数倍

GQA(Grouped Query Attention)

标准多头注意力中,每个头有独立的 Q、K、V。GQA 让多个 Q 头共享同一组 K/V 头

方法 Q 头数 K/V 头数 推理 KV 缓存
MHA \(h\) \(h\)
GQA \(h\) \(h/g\) 减少 \(g\)
MQA(极端) \(h\) 1 最小

这在大模型推理中极为重要,因为 KV 缓存是显存占用的主要来源之一。


8. 从 Attention 到 Transformer

注意力机制的发展历程:

graph TD
    A[Seq2Seq 瓶颈<br>固定长度上下文向量] --> B[Bahdanau Attention 2015<br>解码器关注所有编码器状态]
    B --> C[Self-Attention<br>序列内部互相关注]
    C --> D[Multi-Head Attention<br>多角度并行关注]
    D --> E[Transformer 2017<br>完全基于注意力的架构]
    E --> F[BERT / GPT / ViT<br>预训练 + 微调范式]

Transformer 详细内容

Transformer 的完整架构(编码器-解码器、前馈层、层归一化等)请参阅 Transformer。本页重点介绍注意力机制的原理和演进。