跳转到内容

Attention:让每个位置选择上下文

直觉版:一边生成,一边”看重点”

Section titled “直觉版:一边生成,一边”看重点””

注意力机制解决的问题是:当模型处理一个 token 时,应该重点参考哪些上下文?翻译”it”时可能要看前面的名词,回答问题时要看相关证据。注意力权重就是一组会随输入变化的分数,表示当前 token 对其他 token 的依赖强弱。

行表示正在更新的 token,列表示它关注的上下文 token;颜色越深,权重越高。

query \ key语言模型关注上下文生成答案
1.000.000.000.000.000.000.00
语言0.250.750.000.000.000.000.00
模型0.120.380.500.000.000.000.00
关注0.080.240.280.400.000.000.00
上下文0.050.180.220.250.300.000.00
生成0.040.120.200.180.260.200.00
答案0.030.100.220.120.230.180.12

注意力机制核心流程图:

graph TD
A[输入序列 X] --> B[投影层: W_Q, W_K, W_V]
B --> C[Query矩阵 Q]
B --> D[Key矩阵 K]
B --> E[Value矩阵 V]
C --> F[计算相似度: QK^T/√d_k]
D --> F
F --> G[Softmax归一化]
G --> H[注意力权重 A]
H --> I[加权求和: AV]
E --> I
I --> J[输出: 上下文表示]

Bahdanau 注意力先在序列到序列模型中证明了”动态查找上下文”的价值;Transformer 进一步把自注意力变成核心计算单元,让所有位置可以并行建立依赖关系。

实现上,每个 token 会投影成 Query、Key、Value。Query 和 Key 点积得到相似度,经过 softmax 变成权重,再对 Value 加权求和。多头注意力把这个过程复制多份,让不同头学习语法、指代、位置或任务相关模式。

自注意力的主要代价是序列长度平方级:长度翻倍,注意力矩阵大约变为四倍。因此推理系统会使用 KV cache 复用历史 Key/Value;长上下文模型会结合稀疏注意力、分块、滑窗或更高效 kernel。理解这个瓶颈有助于解释为什么上下文窗口很贵。

示例代码:简化的自注意力实现

Section titled “示例代码:简化的自注意力实现”
可运行示例
import numpy as np

def softmax(x):
    """数值稳定的 softmax"""
    exp_x = np.exp(x - np.max(x, axis=-1, keepdims=True))
    return exp_x / np.sum(exp_x, axis=-1, keepdims=True)

def scaled_dot_product_attention(Q, K, V):
    """
    计算缩放点积注意力
    Q, K, V: [seq_len, d_k]
    返回: [seq_len, d_k]
    """
    d_k = Q.shape[-1]
    # 计算注意力分数
    scores = np.matmul(Q, K.T) / np.sqrt(d_k)
    # 应用 softmax 得到注意力权重
    attention_weights = softmax(scores)
    # 对 V 加权求和
    output = np.matmul(attention_weights, V)
    return output, attention_weights

# 示例
seq_len, d_k = 4, 8
Q = np.random.randn(seq_len, d_k)
K = np.random.randn(seq_len, d_k)
V = np.random.randn(seq_len, d_k)

output, weights = scaled_dot_product_attention(Q, K, V)
print("注意力权重形状:", weights.shape)  # (4, 4)
print("输出形状:", output.shape)  # (4, 8)
print("每行权重和:", weights.sum(axis=1))  # 每行和为 1.0

研究版:注意力模式的可解释性

Section titled “研究版:注意力模式的可解释性”

研究上,注意力权重本身能否解释模型的决策?早期工作认为注意力提供了”模型在看哪里”的透明信号,但后续研究表明,注意力分布与特征重要性并非简单对应——模型可以在高注意力权重区域保持输出不变,反之亦然。

更深的研究方向包括:多头注意力中不同头的专业化分工(语法头、位置头、 rare token 头);注意力模式的动态演化(深层 vs 浅层);以及注意力与梯度-based 归因方法之间的关系。理解这些有助于设计更稀疏、更高效、更可解释的注意力变体。

🔬 开放研究问题

该领域的关键问题与研究方向:

  1. 注意力权重本身能否可靠解释模型决策?注意力分布与特征重要性的关系如何准确刻画?
  2. 多头注意力中不同头的专业化分工如何量化?是否存在通用的"语法头"、"位置头"模式?
  3. 如何设计更稀疏、更高效、更可解释的注意力变体以降低计算成本?

本文引用论文

  • Attention Is All You Need — Ashish Vaswani et al. (2017)

    Transformer 架构的奠基之作。作者完全用注意力机制替代了 RNN/CNN,提出多头自注意力与位置编码, 在机器翻译任务上大幅超越此前所有模型。今天所有主流 LLM 的底层架构都源于此论文。

  • Neural Machine Translation by Jointly Learning to Align and Translate — Dzmitry Bahdanau et al. (2014)

    注意力机制的开山之作(在 Transformer 之前)。作者发现 Seq2Seq 的固定长度瓶颈向量限制了翻译 质量,提出让解码器在生成每个词时都能"回顾"编码器的所有隐状态,动态分配注意力权重。 这个思想直接演化为 Transformer 的自注意力。

  • Effective Approaches to Attention-based Neural Machine Translation — Minh-Thang Luong et al. (2015)

    系统化地比较 global vs local attention、不同打分函数(dot / general / concat),是后人讲 "attention score 是怎么算的" 时最常引用的工程化版本。

  • Sequence to Sequence Learning with Neural Networks — Ilya Sutskever et al. (2014)

    Seq2Seq 架构(编码器-解码器)的奠基之作。通过两个 LSTM 的"压缩-生成"结构,首次让神经网络 能够进行变长序列到变长序列的转换,在机器翻译上取得突破性进展,也直接启发了后来 Transformer 的编解码器设计。

  • Neural Machine Translation in Linear Time — Nal Kalchbrenner et al. (2016)

    用扩张卷积做 seq2seq,把序列建模从"必须 RNN 顺序计算"中解放出来;和同期 ConvS2S 一起是 Transformer 之前"并行序列建模"的最强尝试。