What is the purpose of the decoder in a transformer model
1️⃣ 考察意图
面试官想考察你对 Transformer 解码器结构与生成机制的底层理解,而非简单背诵。这是典型的“背概念+工程取舍”混合题。刁钻点在于:解码器中的掩码自注意力和交叉注意力如何协同实现自回归生成?你能否区分 GPT(仅解码器)与 T5(编码器-解码器)中解码器的差异?答好了能展示你对 LLM 生成原理的硬核掌握,包括因果掩码、KV Cache 优化、以及训练-推理不一致的工程坑。
2️⃣ 标准答
解码器在 Transformer 中的核心目的是自回归生成:基于已生成的 token 序列和编码器输出,逐步预测下一个 token。它通过三层结构实现这一目标:掩码自注意力、交叉注意力、前馈网络(FFN),每层后接残差连接和层归一化。
- 掩码自注意力(Masked Self-Attention)
- 作用:确保每个位置只能关注到它之前(包括自身)的 token,防止“看到未来”。
- 实现:在 softmax 前对注意力分数矩阵的上三角部分填充
-inf(或使用torch.triu掩码)。 - 工程取舍:训练时用并行计算(一次性输入整个序列),推理时用自回归(逐 token 生成),导致训练-推理不一致。实际落地中,推理时需用 KV Cache 缓存历史 key/value,避免重复计算,但会引入显存开销(例如 7B 模型,序列长度 2048 时 KV Cache 约 1.5GB)。
- 坑:训练时掩码矩阵是固定的,但推理时若使用 beam search,需注意掩码维度与 batch size 的匹配,否则会因广播错误导致注意力泄漏。
- 交叉注意力(Cross-Attention)
- 作用:从编码器输出中提取相关信息,实现序列到序列的映射(如机器翻译中源语言到目标语言)。
- 结构:Query 来自解码器上一层的输出,Key 和 Value 来自编码器输出。
- 工程取舍:交叉注意力是计算瓶颈,因为编码器输出长度通常远大于解码器当前步数。实际中可对编码器输出做池化或压缩(如使用 Perceiver 架构),但会损失细粒度信息。
- 坑:在长文本生成(如摘要)中,交叉注意力可能过度关注局部,导致重复生成。解法是引入重复惩罚(repetition penalty)或对比搜索(contrastive search)。
- 前馈网络(FFN)
- 作用:对每个位置的表示做非线性变换,通常包含两层线性层和 ReLU/GELU 激活。
- 工程取舍:FFN 参数量占模型总参数的 2/3(如 GPT-3 175B 中 FFN 约 116B),是计算和存储的主要开销。实际中可用 MoE(Mixture of Experts) 稀疏化,但需解决负载均衡问题。
- 典型应用差异
- GPT 系列(仅解码器):没有交叉注意力,只有掩码自注意力 + FFN。生成时完全依赖自回归,适合语言建模和文本生成。
- T5(编码器-解码器):解码器包含交叉注意力,适合序列到序列任务(翻译、摘要)。
- LLaMA:使用 RoPE(旋转位置编码) 替代绝对位置编码,提升外推能力;采用 SwiGLU 激活函数替代 ReLU,提升训练稳定性。
- 实际落地的坑 + 解法
- 训练-推理不一致:训练时用 teacher forcing(并行),推理时自回归(串行)。解法:在训练中引入计划采样(Scheduled Sampling),以一定概率用模型自己的预测替换真实 token,但会引入偏差。
- 显存爆炸:长序列生成时,KV Cache 随序列长度线性增长。解法:使用 FlashAttention 减少显存占用(O(n) 而非 O(n²)),或对历史 KV 做滑动窗口(如 Mistral 的 4K 窗口)。
- 生成质量:解码器可能陷入重复或低概率 token。解法:使用 top-k(k=40-100)或 top-p(p=0.9-0.95)采样,配合温度参数(temperature=0.7-1.0)控制随机性。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:结构、生成机制、工程取舍。结构上,解码器包含掩码自注意力、交叉注意力和 FFN,掩码保证自回归性质,交叉注意力连接编码器。生成机制上,它逐步预测下一个 token,训练时并行,推理时串行。工程取舍上,KV Cache 是推理优化的关键,但会带来显存开销;训练-推理不一致需要通过计划采样或 FlashAttention 缓解。总结一句:解码器的核心是在因果约束下高效生成序列。”
4️⃣ 高频追问 & 应对
追问 1:为什么 GPT 只用解码器,而 T5 用编码器-解码器?什么时候该选哪种?
核心区别在于任务是否需要双向上下文。GPT 适合无条件生成(如对话、故事续写),因为只需单向因果依赖;T5 适合条件生成(如翻译、摘要),因为需要编码器提供源序列的完整双向表示。工程取舍:编码器-解码器架构参数量翻倍(T5 3B 约 6B 参数),但生成质量更高;仅解码器架构更高效(GPT-3 175B 单模型),但无法直接处理序列到序列任务。实际中,LLaMA 等仅解码器模型通过前缀掩码(prefix masking)也能模拟编码器-解码器效果,但需调整训练数据。
追问 2:解码器中的掩码自注意力在推理时如何优化?为什么不用完整矩阵?
推理时使用 KV Cache:每生成一个 token,只计算当前 Query 与所有历史 Key/Value 的注意力,而非重新计算整个序列。这使时间复杂度从 O(n²) 降到 O(n),显存占用从 O(n²) 降到 O(n)。但 KV Cache 会随序列长度线性增长(如 2048 序列约 1.5GB 显存),因此需要 PagedAttention(vLLM 使用)或 Multi-Query Attention(MQA)来共享 Key/Value,减少显存。注意:KV Cache 的掩码是因果掩码,只需确保当前 token 不看到未来,历史 token 的掩码已固化。
追问 3:解码器的交叉注意力在长文本生成中有什么问题?如何解决?
主要问题是注意力分散:当编码器输出序列很长(如 10K tokens),解码器每个位置的 Query 需要与所有 Key 计算注意力,导致 softmax 后概率分布过于平滑,模型无法聚焦关键信息。解法:1)局部注意力:只关注编码器输出的局部窗口(如 512 tokens),但会丢失长距离依赖;2)稀疏注意力:使用 BigBird 或 Longformer 的稀疏模式,但实现复杂;3)压缩记忆:用 Perceiver 将编码器输出压缩为固定长度(如 256 tokens),但会损失细粒度信息。实际落地中,推荐先用滑动窗口(窗口大小 1024)做快速实验,再根据任务调整。
5️⃣ 避坑 · 常见错误答法
- ❌ “解码器就是做生成,和编码器差不多,只是多了一个掩码。”→ ✅ 解码器与编码器结构不同:编码器用双向自注意力(无掩码),解码器用因果掩码自注意力 + 交叉注意力。交叉注意力是序列到序列任务的关键,仅解码器模型(如 GPT)没有这一层。
- ❌ “掩码自注意力就是不让模型看到未来,训练和推理都一样。”→ ✅ 训练时掩码是固定的(并行计算),推理时掩码是动态的(自回归)。训练-推理不一致是工程核心难点,需要 KV Cache 和计划采样来缓解。
- ❌ “解码器生成时用贪心解码就行,beam search 太慢。”→ ✅ 贪心解码容易陷入局部最优(如重复生成),beam search 虽然慢但能提升 BLEU 分数(如机器翻译中 beam=4 比贪心高 2-3 个点)。实际中需权衡:实时场景用贪心+温度采样,离线场景用 beam search+长度惩罚。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从解码器生成与检索结果融合的角度切入,强调交叉注意力如何从检索到的文档中提取信息,以及如何用 KV Cache 优化长文档生成(如 10K tokens 的摘要任务)。
- 如果你只做过传统 NLP:用序列到序列任务(如机器翻译)类比,解释解码器如何从编码器输出中“翻译”信息,并对比 LSTM 解码器(串行、梯度消失)与 Transformer 解码器(并行、残差连接)的差异。
- 如果你是校招无项目:聚焦论文复现,如实现一个简易解码器(基于 PyTorch),在 IWSLT 数据集上训练,比较 beam search 与贪心解码的 BLEU 差异,并分析 KV Cache 的显存优化效果。
- 《Attention Is All You Need》—— Transformer 原始论文,解码器结构详解
- 《The Annotated Transformer》—— Harvard NLP 的 PyTorch 实现教程
- 《LLaMA: Open and Efficient Foundation Language Models》—— 仅解码器架构的工程优化(RoPE、SwiGLU)
- 《FlashAttention: Fast and Memory-Efficient Exact Attention》—— 解码器推理加速的关键技术
- 《PagedAttention: Efficient Memory Management for LLM Serving》—— vLLM 中 KV Cache 的显存优化方案