Skip to content

Encoder与Decoder

完整的 Transformer 由两个可独立使用的部件组成:编码器(Encoder)负责「理解输入」,解码器(Decoder)负责「生成输出」。理解它们的差异,是理解 BERT / GPT 为什么各自「只用一半」的基础。

1. 各自的结构

        Encoder 层                     Decoder 层
   ┌──────────────────┐           ┌──────────────────────┐
   │ 多头自注意力(无掩码)│           │ 多头自注意力(因果掩码)  │ ← 只看已生成部分
   │   Add & Norm      │           │   Add & Norm          │
   │                   │           │ 交叉注意力(Q=解码,V/K=编)│ ← 回看源句
   │   FFN             │           │   Add & Norm          │
   │   Add & Norm      │           │   FFN                 │
   └──────────────────┘           │   Add & Norm          │
    2 个子层                        └──────────────────────┘
                                    3 个子层(多一个 Cross-Attn)

2. 核心差异对照

维度EncoderDecoder
自注意力可见范围双向(能看全句)单向(因果掩码,只看过去)
是否有交叉注意力有(看编码器输出)
角色理解 / 表示输入条件生成输出
能否并行训练训练能、生成不能
典型代表BERTGPT

3. 编码器:为什么能「双向看」

编码器处理的是已经完整给定的输入(源句、待分类的句子),没有「未来泄露」问题,所以每个词都能大方地看左右两边:

输入:  我  喜欢  你
"喜欢" 同时看 ← 我   和   你 →   得到最丰富的上下文表示

这让编码器产出高质量的双向理解表示,非常适合「读懂任务」。

4. 解码器:为什么要「因果掩码」

解码器的任务是逐词生成。生成第 t 个词时,未来的词还不存在;若训练时能偷看未来,就和真实生成场景不一致(训练作弊)。于是用因果掩码把未来遮住:

生成 "我爱你" 时,位置"爱"的可见范围:
   <bos> 我  [爱]  你?
    ✓    ✓   ✓    ✗  ← "你"还没生成,必须遮住

5. 交叉注意力:连接两座岛的桥

这是 Decoder 独有、也最容易被忽视的一层:

   自注意力:  Q,K,V 都来自解码器   → "我生成的部分,自己理一理"
   交叉注意力: Q 来自解码器, K/V 来自编码器 → "带着当前生成状态,去源句里找该翻的词"
     编码器最终输出 (memory)
            │  作为 K, V

   Q(解码器) ──►[ Cross-Attention ]──► 融合源句信息

翻译「I love you → 我爱你」时,生成「爱」这一刻,交叉注意力会让解码器把目光聚焦到源句的 "love" 上——这正是对齐(alignment) 的来源。

6. 只用一半会怎样?

前人在此基础上做了两个方向的「减法」,开创了两大家族:

   完整 Transformer
      ├── 只保留 Encoder  ──► BERT 家族(双向理解)
      ├── 只保留 Decoder  ──► GPT 家族(单向生成)
      └── 两者都保留       ──► T5 / 原始Transformer(序列到序列)
  • 想要「把一句话读透、抽特征」→ 用 Encoder。
  • 想要「给个开头、续写下去」→ 用 Decoder。

小结

  • Encoder:双向自注意力,无交叉注意力,擅长理解。
  • Decoder:因果自注意力 + 交叉注意力,擅长条件生成。
  • 交叉注意力是「解码器回看源句」的桥梁,也是翻译对齐的来源。
  • 各取一半 → 得到 BERT(Encoder-only)与 GPT(Decoder-only)。

下一步

先看 Encoder 这一半被发挥到什么极致 → BERT架构