Skip to content

Transformer 面试必考:自注意力机制详细拆解 + 为什么它比 RNN 更适合长序列?

2260 字约 8 分钟

transformerattentioninterview

2026-06-16

面试官:"请详细解释 Transformer 模型中的自注意力机制是如何工作的?它为什么比 RNN 更适合处理长序列?" 如果你能流畅答出下面这些内容,这一题就是满分。


一、自注意力机制如何工作?

1. 直观理解:让每个词看到整个句子

假设输入一句话: "The cat sat on the mat because it was tired." 我们希望模型理解"it"指代的是"cat"。

  • RNN:需要从第一个词一步步读到最后一个词,把信息压缩在一个隐状态里,距离越远越容易丢失。
  • 自注意力:让"it"直接看到句子中所有其他词,并自动分配注意力权重——对"cat"权重很高,对"mat"权重很低。

这就是自注意力的核心思想:每个词与序列中所有词计算相关性,再汇总信息


2. 核心计算:缩放点积注意力(带形状推导)

每个输入词被投影为三个向量:

  • Query(Q):代表"我当前在找什么"。
  • Key(K):代表"我手里有什么信息标签"。
  • Value(V):代表"我实际要贡献的信息内容"。

设输入序列长度为 nn,每个词的嵌入维度为 dmodeld_{model}。 注意力运算中 Q、K 的维度为 dkd_k,V 的维度为 dvd_v(通常 dk=dvd_k = d_v)。

步骤 1:线性投影

  • 输入矩阵 XX 的形状:(n,dmodel)(n, d_{model})
  • 可学习的权重矩阵:
    • WQW^Q 形状:(dmodel,dk)(d_{model}, d_k)
    • WKW^K 形状:(dmodel,dk)(d_{model}, d_k)
    • WVW^V 形状:(dmodel,dv)(d_{model}, d_v)
  • 得到三个矩阵:

    Q=XWQ形状(n,dk)K=XWK形状(n,dk)V=XWV形状(n,dv)Q = XW^Q \quad \text{形状} (n, d_k) \\ K = XW^K \quad \text{形状} (n, d_k) \\ V = XW^V \quad \text{形状} (n, d_v)

步骤 2:计算注意力分数

用 Query 和所有位置的 Key 做点积:

Scores=QKT\text{Scores} = QK^T

  • QQ 形状 (n,dk)(n, d_k)KTK^T 形状 (dk,n)(d_k, n) → 结果形状 (n,n)(n, n)
  • 每个元素 scoreij\text{score}_{ij} 表示位置 ii 对位置 jj 的原始关注程度。

步骤 3:缩放

除以 dk\sqrt{d_k} 防止点积过大:

Scaled Scores=QKTdk\text{Scaled Scores} = \frac{QK^T}{\sqrt{d_k}}

形状仍为 (n,n)(n, n)

步骤 4:Softmax 归一化

对每一行做 softmax,得到注意力权重矩阵 AA

Aij=exp(scoreij/dk)k=1nexp(scoreik/dk)A_{ij} = \frac{\exp(\text{score}_{ij}/\sqrt{d_k})}{\sum_{k=1}^n \exp(\text{score}_{ik}/\sqrt{d_k})}

形状仍为 (n,n)(n, n),每一行的权重之和为 1。 此时 AijA_{ij} 表示位置 ii 从位置 jj 获取信息的比例。

步骤 5:加权求和

用注意力权重对所有 Value 向量加权求和:

Attention(Q,K,V)=AV\text{Attention}(Q, K, V) = A \cdot V

  • AA 形状 (n,n)(n, n)VV 形状 (n,dv)(n, d_v) → 结果形状 (n,dv)(n, d_v)

每个位置的输出都动态融合了整个序列的上下文信息。


3. 多头注意力:不同子空间的同时关注(带形状推导)

单头只能捕捉一种关系。Transformer 使用多头注意力,让模型从多个角度同时学习。

  • 设定头数 hh,每个头的 Q、K 维度 dk=dmodel/hd_k = d_{model} / h,V 维度 dv=dmodel/hd_v = d_{model} / h

  • 对每个头 ii,有独立的投影权重:

    • WiQW_i^Q 形状:(dmodel,dk)(d_{model}, d_k)
    • WiKW_i^K 形状:(dmodel,dk)(d_{model}, d_k)
    • WiVW_i^V 形状:(dmodel,dv)(d_{model}, d_v)
  • 计算每个头的注意力:

    headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)

    每个 headi\text{head}_i 的形状为 (n,dv)(n, d_v)

  • 将所有头的结果拼接:

    Concat(head1,,headh)\text{Concat}(\text{head}_1, \dots, \text{head}_h)

    由于 h×dv=dmodelh \times d_v = d_{model},拼接后形状恢复为 (n,dmodel)(n, d_{model})

  • 最后经过一个线性投影矩阵 WOW^O(形状 (dmodel,dmodel)(d_{model}, d_{model})):

    MultiHead(Q,K,V)=Concat(head1,,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \dots, \text{head}_h) W^O

    输出形状仍为 (n,dmodel)(n, d_{model})

这保证了多头注意力在变换维度的同时,能与后续的残差连接和层归一化无缝衔接。


4. 弥补位置信息的缺失:位置编码

自注意力本身是排列等变的——打乱输入顺序,输出只是同等打乱。 为了注入序列顺序,Transformer 在输入词向量上叠加位置编码 PPPP 的形状也是 (n,dmodel)(n, d_{model}),通过正弦/余弦函数或可学习的嵌入得到。

叠加后输入变为 X+PX + P,使模型能够区分"A 在 B 前面"这种位置关系。


二、为什么自注意力比 RNN 更适合长序列?

对比维度RNNTransformer 自注意力
信息流动路径长度O(n),长程依赖衰减严重O(1),任意两个词直接连接
并行能力必须按时间步顺序计算矩阵乘法,整个序列一次性并行
梯度稳定性BPTT 连乘,易消失/爆炸梯度只穿过 Softmax 和线性层,路径极短
记忆瓶颈压缩在固定大小的隐状态中,信息被稀释每个输出可直接访问完整 Value 矩阵
可解释性较难注意力权重矩阵 n×nn \times n 可直接可视化
复杂度O(n·d²) 但顺序依赖标准 O(n²·d),但高度并行,实际快于 RNN

详细解释

  1. 信息流动路径长度是 O(1) RNN 从第一个词传信息到第 nn 个词需 nn 步递归,长程依赖衰减严重。自注意力通过一次矩阵乘法建立任意两位置的直接连接,路径恒为 1。

  2. 完全并行化,训练效率飞跃 RNN 必须按时间步顺序计算,无法在序列维度上并行。自注意力本质是矩阵乘法,整个序列可一次性并行处理,GPU 利用率极高,训练速度快几十倍。

  3. 梯度传播更稳定 RNN 的 BPTT 涉及连乘,易梯度消失/爆炸。自注意力的梯度仅穿过 Softmax 和线性映射,路径极短,梯度稳定,远距离依赖信号更易学习。

  4. 无固定大小的记忆瓶颈 RNN 将全部历史压缩在一个固定维度的隐状态中,长序列信息被稀释。自注意力中每个输出可直接访问完整 Value 矩阵,记忆容量随序列长度自然扩展。

  5. 可解释性更强 注意力权重矩阵 AAn×nn \times n)可直接可视化,清晰展示词与词之间的依赖关系,便于调试和分析。

  6. 复杂度对比与前沿方案 标准自注意力时间复杂度 O(n2)O(n^2),但矩阵乘法高度并行,在几千长度内实际快于 RNN 的顺序计算。对极长序列,已有稀疏注意力、线性注意力、状态空间模型等变体降至 O(n)O(n)O(nlogn)O(n\log n),并保留全局感受野,依然优于 RNN。


三、面试回答模板(简洁版)

面试时被问到这个,你可以这样简洁地回答:

自注意力怎么工作?

想象每个词都在开圆桌会议,能直接跟任何词对话,而不是像 RNN 那样只能传话。

具体计算很直接: 输入序列 X,形状 [n, d_model]。 用三个矩阵把 X 分别投影成 Q(查询)、K(键)、V(值),形状分别为 [n, d_k][n, d_k][n, d_v]。 在标准多头注意力里 d_k = d_v = d_model / h

然后:

  1. 算分数S = QKᵀ → 形状 [n, n]
  2. 缩放S / √d_k
  3. Softmax:对每行做,得到权重矩阵 A([n, n],每行和为 1)。
  4. 加权求和A V → 输出 [n, d_v],每个词都融合了全局上下文。

多头就是并行做 h 次上述过程,每个头学不同关系,最后把所有头结果拼成 [n, d_model] 再线性映射。 因为自注意力对顺序无感,我们要给输入加上位置编码,告诉模型词的位置。

为什么比 RNN 更适合长序列?

核心就四点:

  1. 路径极短:任意两个词直接连接(O(1)),长程依赖不会丢失。
  2. 彻底并行:全是矩阵乘法,整个句子一次丢进 GPU,训练快几十倍。
  3. 梯度稳定:只穿过 Softmax 和线性层,没有连乘,优化稳定得多。
  4. 没有记忆瓶颈:能直接取用任意位置的 V,信息无损,无需"遗忘"。

一句话:自注意力用全局直接交互替代了 RNN 的逐步递归压缩,从根本上解决了长序列建模的核心痛点。


四、总结

  • 自注意力:Q、K、V 点积缩放 + Softmax + 加权求和 → 每个词聚合全局信息。
  • 多头注意力:多个子空间并行学习,拼接后线性变换。
  • 相比 RNN:路径 O(1)、完全并行、梯度稳定、无记忆瓶颈、可解释性强。

面试时如果能讲清楚 QKV 的形状变化、为什么除 dk\sqrt{d_k}、多头如何拼接,再对比 RNN 的四点优势,面试官会非常认可。


如果觉得有用,欢迎点赞、在看、转发给正在刷题的朋友~