Decoder阶段的多头自注意力和encoder的多头自注意力有什么区别?**(为什么需要decoder自注意力需要进行 sequence mask)
1️⃣ 考察意图
面试官想考察你对 Transformer 核心机制的理解深度,尤其是自回归生成与双向编码的设计动机差异。这题表面是背概念,实际是工程取舍题:为什么 Decoder 必须用因果掩码(causal mask)?答好了能展示你对序列建模中信息流控制、训练-推理一致性、以及并行化训练技巧的硬实力。刁钻点在于:很多人只背了“防止看到未来”,但说不出如果不掩码会导致什么具体问题(如训练时用未来 token 预测当前 token,推理时做不到,导致分布偏移),以及如何用 mask 矩阵高效实现。
2️⃣ 标准答
核心区别:双向 vs 单向注意力
- Encoder 自注意力:每个 token 可以 attend 到序列中所有 token(包括前后)。这是双向的,因为 Encoder 的任务是理解整个输入序列的上下文(如 BERT 的 MLM 任务),不需要因果约束。
- Decoder 自注意力:每个 token 只能 attend 到自身及之前的位置。这是单向的,因为 Decoder 是自回归生成模型(如 GPT 系列),在推理时只能基于已生成的 token 预测下一个。
为什么需要 Sequence Mask?
- 防止信息泄露:训练时,如果不加 mask,Decoder 在预测第 t 个 token 时,可以直接“看到”第 t+1 个 token 的 ground truth,导致模型学到“作弊”模式——用未来信息预测当前,推理时无法复制。
- 训练-推理一致性:推理时 Decoder 只能看到已生成的 token,训练时必须模拟同样的条件。否则训练和推理的分布会 mismatch,导致生成质量下降(如 perplexity 虚低但实际生成差)。
- 并行化训练:虽然推理是串行的,但训练时我们可以一次性输入整个目标序列(teacher forcing),通过 mask 矩阵让每个位置只 attend 到合法位置,从而实现并行计算。
Sequence Mask 的具体实现
- 在 softmax 之前,将未来位置的 attention score 设为
-inf(或一个极大负数),这样 softmax 后这些位置的权重为 0。 - 常见实现:生成一个上三角矩阵(对角线为 0,右上角为
-inf),加到 attention score 上。 - 工程细节:在 PyTorch 中,
nn.TransformerDecoderLayer的self_attn会自动处理 mask,但自定义实现时需注意attn_mask的 shape 是(tgt_len, tgt_len),且 dtype 为bool或float。用torch.triu(torch.ones(L, L) * float('-inf'), diagonal=1)生成。
实际落地的坑 + 解法
- 坑 1:mask 与 padding mask 的叠加:Decoder 输入序列通常有 padding,需要同时应用 causal mask 和 padding mask。正确做法:先计算 attention score,然后
score = score + causal_mask + padding_mask(padding_mask 中 padding 位置设为-inf)。顺序不能错,否则 padding 位置可能泄露信息。 - 坑 2:FlashAttention 中的 mask 处理:使用 FlashAttention 时,mask 是隐式处理的(通过 block-wise 计算),但如果你自定义 mask 矩阵,需确保与 FlashAttention 的 causal 参数不冲突。例如
flash_attn_func(q, k, v, causal=True)会自动应用 causal mask,无需额外传入。 - 坑 3:推理时的 mask:推理时 Decoder 输入是逐步增长的,每次只需计算新 token 与之前所有 token 的 attention,不需要重新计算整个 mask 矩阵。可以用 KV cache 优化,只计算当前 step 的 query 与 cached key/value 的 attention。
扩展对比:Cross-Attention 不需要 mask
- Decoder 中的 cross-attention:query 来自 Decoder,key/value 来自 Encoder。此时不需要 causal mask,因为 Encoder 输出是完整的上下文,Decoder 的每个 token 都可以 attend 到 Encoder 的所有位置。但需要注意 padding mask 仍然需要,以屏蔽 Encoder 的 padding 位置。
总结:Encoder 的双向注意力用于理解,Decoder 的单向注意力用于生成。Sequence mask 是保证自回归生成训练-推理一致性的关键工程手段。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,设计动机——Encoder 需要双向上下文理解,Decoder 需要单向自回归生成;第二,实现细节——通过上三角 mask 矩阵将未来位置 score 设为 -inf,确保训练时每个 token 只能 attend 到自身及之前;第三,工程坑——mask 与 padding mask 叠加顺序、FlashAttention 的隐式 mask、推理时 KV cache 优化。总结一句:Sequence mask 是保证 Decoder 训练-推理一致性的核心机制,防止信息泄露和分布偏移。”
4️⃣ 高频追问 & 应对
追问 1:如果 Decoder 训练时不加 mask,但推理时加,会怎样?
训练时模型会学到“作弊”模式:预测第 t 个 token 时直接复制第 t+1 个 token 的 embedding(因为 attention 权重会集中在未来位置)。这会导致训练 loss 极低(perplexity 接近 1),但推理时无法复制未来信息,生成质量极差(如重复、语法错误)。实际上,这就是 teacher forcing 中信息泄露的典型问题,必须用 mask 阻断。
追问 2:为什么 Decoder 的 self-attention 用 causal mask,而 cross-attention 不用?
因为 cross-attention 的 key/value 来自 Encoder,Encoder 已经编码了整个输入序列的上下文,没有“未来”概念。Decoder 的每个 token 都可以访问 Encoder 的所有位置,用于提取与当前生成相关的信息。如果给 cross-attention 加 causal mask,会限制 Decoder 只能看到 Encoder 的前半部分,导致生成时无法利用完整上下文,影响质量(如翻译时漏掉句子后半部分)。
追问 3:在 GPT 系列中,Decoder 的 mask 是如何实现的?和原始 Transformer 有区别吗?
GPT 系列(如 GPT-2、GPT-3)使用 Decoder-only 架构,没有 Encoder。其 self-attention 同样使用 causal mask,但实现上更高效:通常用
torch.triu生成 mask 矩阵,并利用 FlashAttention 的causal=True参数隐式处理。区别在于 GPT 的 mask 是固定的(上三角),而原始 Transformer 的 Decoder 还需要处理 cross-attention 的 mask。另外,GPT 在训练时使用 causal mask + padding mask 的组合,但 padding mask 通常通过attention_mask参数传入。
5️⃣ 避坑 · 常见错误答法
- ❌ 说“Decoder 的 mask 是为了防止过拟合” → ✅ 正确说法:mask 是为了防止信息泄露,保证训练-推理一致性,与过拟合无关。过拟合是模型在训练数据上表现好但泛化差,mask 是控制信息流。
- ❌ 说“Encoder 和 Decoder 的 mask 是一样的,只是方向不同” → ✅ 正确说法:Encoder 不需要 mask(除非是 padding mask),Decoder 需要 causal mask。方向不同是结果,不是原因,根本原因是任务目标不同(理解 vs 生成)。
- ❌ 说“推理时也需要完整的 mask 矩阵” → ✅ 正确说法:推理时 Decoder 输入逐步增长,可以用 KV cache 只计算当前 step 的 attention,不需要重新生成整个 mask 矩阵。mask 只在训练时以矩阵形式存在,推理时通过逐步生成隐式实现因果约束。
6️⃣ 简历呼应
- 如果你有 LLM 训练项目:从训练-推理一致性角度切入,强调你在项目中如何用 causal mask 实现 teacher forcing,并对比有无 mask 的 perplexity 差异(如从 1.2 升到 4.5)。可以提你如何用 FlashAttention 优化 mask 计算。
- 如果你只做过传统 NLP:用 RNN 的因果约束类比——RNN 天然是单向的(只能看到过去),Transformer Decoder 通过 mask 模拟这种单向性。强调你理解序列建模中信息流控制的重要性。
- 如果你是校招无项目:聚焦论文复现——你复现了 GPT-2 的 Decoder 模块,用
torch.triu实现 causal mask,并在 WikiText-2 上验证了 mask 对 perplexity 的影响。可以提你对比了nn.TransformerDecoder和自定义实现的差异。 - 《Attention Is All You Need》(原始 Transformer 论文,Section 3.2 和 3.3)
- 《Language Models are Unsupervised Multitask Learners》(GPT-2 论文,讨论 Decoder-only 架构的 mask 设计)
- PyTorch 官方文档:
nn.TransformerDecoderLayer的self_attn参数说明 - FlashAttention 论文(Section 2.3 讨论 causal mask 的隐式实现)
- 《The Annotated Transformer》(Harvard NLP 博客,有 mask 矩阵的代码实现)