标准回答
注意力遮蔽的本质是 控制每个位置能「看到」哪些位置,通过干预 softmax 的输入来实现。
1. 基本原理
自注意力先算出分数矩阵 scores = Q·Kᵀ / √d,再对每一行做 softmax 得到权重。遮蔽的做法是:在 softmax 之前,把需要屏蔽的位置对应的分数加上一个非常大的负数(−∞ 或如 −1e9)。这样经过 softmax 后,exp(-∞) ≈ 0,这些位置的注意力权重几乎为 0,相当于被「看不见」。注意一定是在 softmax 之前操作,softmax 之后再置零会破坏概率归一化。
2. 常见类型
- 因果掩码(Causal / Look-ahead Mask):用在 Decoder 的自注意力中。生成第 t 个 token 时只能看到第 1…t 个位置,不能看到未来。实现上是一个 上三角为 −∞ 的掩码矩阵,保证训练时的「teacher forcing」不会泄露未来答案,与推理时逐个生成保持一致。
- Padding 掩码:一个 batch 内句子长度不同,会用 pad token 补齐。这些 pad 没有语义,必须屏蔽,否则会干扰真实 token 的注意力分布。它按 token 是否为 pad 生成掩码,作用于所有需要 attend 到 Key 的地方(包括 Encoder 自注意力、Decoder 的 cross-attention)。
- 特定任务掩码:如某些预训练任务、前缀语言模型(prefix LM)让前缀部分双向可见、后缀部分单向,或结构化输入中限制只能关注特定片段,本质都是定制 mask 模式。
3. 实现方式
实践中把所有掩码统一成一个 加性 mask 矩阵:允许的位置为 0,屏蔽的位置为 −∞(或极小值),直接与 scores 相加:scores + mask,再做 softmax。因果掩码与 padding 掩码可以叠加(取并集)。这种加性写法对反向传播友好,也便于在不同注意力层复用。
常见误区
⚠️ 常见踩坑
误以为遮蔽是在 softmax 之后把权重设为 0。这样做会破坏归一化(剩余权重之和不再为 1),结果不正确。正确做法是在 softmax 之前把分数置为 −∞,让 softmax 自然把这些位置压到接近 0 并重新归一化其余位置。
追问
追问 1:为什么因果掩码用 −∞ 而不是直接乘以 0?
因为遮蔽发生在 softmax 之前。如果直接把分数乘 0,这些位置的分数变成 0,但 0 在指数运算里是 exp(0)=1,softmax 后仍会分到非零权重,没起到屏蔽作用。加 −∞ 才能让 exp(−∞)=0,真正把权重压到 0,并让其余位置重新归一化。
追问 2:因果掩码和 padding 掩码可以同时存在吗?怎么结合?
可以,且在 Decoder 中通常同时需要。做法是把两种掩码取并集:只要某个位置被任一掩码标记为不可见(未来位置 或 pad),就在加性 mask 中置为 −∞。实现上把因果上三角掩码与 padding 掩码逐元素「或」起来,再统一加到注意力分数上。
🔗 相似问题
同一考点的不同问法,面试官可能换着问,一起刷更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习