Transformer 解剖:从 Attention 到推理系统

第 6 章 Encoder / Decoder / Decoder-only:三种架构的取舍

作者 杨艺韬 · 5,162 字

第 6 章 Encoder / Decoder / Decoder-only:三种架构的取舍

第二部分我们把 Transformer Block 拆得很透了。但同样的 Block——Self-Attention + FFN + RMSNorm + Residual——可以搭出三种完全不同的整体架构:

这三种架构的差别不是表面上的「一个用 Encoder、一个用 Decoder」,而是三套不同的 attention 模式 + 三种不同的训练目标 + 三种不同的推理形态。它们各自适合什么任务、为什么 2020 年之后 Decoder-only 几乎清场了所有大模型——这是这一章要回答的问题。

读完这一章你能:

6.1 原始 Transformer 是 Encoder-Decoder

时间回到 2017。Vaswani 论文的标题叫 Attention Is All You Need,副标题不那么显眼地写着「for machine translation」——这篇论文从一开始就是为机器翻译设计的。

机器翻译的形态是「输入一段源语言,输出一段目标语言」(seq2seq):

"我爱北京天安门" → "I love Tiananmen Square in Beijing"

这种「序列到序列转换」的任务最自然的架构是 Encoder-Decoder

flowchart LR
  SRC["源序列<br/>'我爱北京天安门'"] --> ENC[Encoder<br/>双向 Self-Attention]
  ENC --> CTX[上下文向量<br/>每个源 token 一个]
  CTX --> CROSS[Cross-Attention]
  PREV["已生成的目标 token<br/>(I love Tiananmen)"] --> DEC[Decoder<br/>因果 Self-Attention]
  DEC --> CROSS
  CROSS --> OUT["下一 token: Square"]

注意三种 attention 同时存在:

  1. Encoder Self-Attention(双向,无因果掩码):每个源 token 看全部源 token
  2. Decoder Self-Attention(因果掩码):目标位置 ii 只能看 i\le i 的目标 token
  3. Cross-Attention:Decoder 的每个位置作为 query,去 Encoder 的输出做注意力

第三种 attention 是机器翻译特有的——它让 Decoder「回头看」源序列,相当于第 1 章 Bahdanau Attention 的彻底数学化。

原始 Transformer 论文里,Encoder 和 Decoder 各 6 层。Encoder 不带因果掩码、Decoder 带因果掩码外加 Cross-Attention。这个架构在 WMT 2014 EN-DE 翻译任务上把 BLEU 推到了当时的 SOTA。

6.2 三种架构的 attention mask

把三种架构的 attention 模式抽象出来,可以画成下面这张图(mask 矩阵中 ✓ 表示「可以看」,空白表示「不能看」):

Encoder-only(BERT) —— 完全双向:

          k_1  k_2  k_3  k_4
q_1        ✓    ✓    ✓    ✓
q_2        ✓    ✓    ✓    ✓
q_3        ✓    ✓    ✓    ✓
q_4        ✓    ✓    ✓    ✓

每个 query 都能看到所有 key。这是 Self-Attention 不加掩码的「裸」形式。

Decoder-only(GPT) —— 严格因果:

          k_1  k_2  k_3  k_4
q_1        ✓
q_2        ✓    ✓
q_3        ✓    ✓    ✓
q_4        ✓    ✓    ✓    ✓

只能看自己和左边——上三角全是 -\infty(参考第 2.10 节)。

Encoder-Decoder(T5) —— 三种 attention 共存。Encoder 部分用双向掩码,Decoder Self-Attention 用因果掩码,Cross-Attention 让 Decoder 看完整 Encoder 输出。

flowchart TB
  subgraph "Encoder Self-Attention<br/>双向"
    E1[q_src 看 k_src<br/>所有都可见]
  end
  subgraph "Decoder Self-Attention<br/>因果"
    D1[q_tgt 看 k_tgt<br/>只看左边]
  end
  subgraph "Cross-Attention<br/>跨序列"
    X1[q_tgt 看 k_src<br/>所有都可见]
  end

这三种 mask 决定了三种架构的本质能力差异。Encoder-only 看得最全(每个位置看其他全部位置);Decoder-only 看得最严(每个位置只看左侧);Encoder-Decoder 是两种合体——Encoder 双向,Decoder 因果加跨视图。

6.3 Encoder-only:BERT 的世界

2018 年 10 月,Google 发布 BERT。它做了一件事:把原始 Transformer 的 Encoder 单独拿出来训练,扔掉 Decoder。架构上它就是 12 层(base)或 24 层(large)双向 Self-Attention 堆叠。

为什么扔掉 Decoder 也能用?关键在 BERT 改变了训练目标。原始 Transformer 的目标是「翻译」(seq2seq),需要 Decoder 自回归生成。BERT 提出两个新目标:

1. Masked Language Modeling (MLM):随机把输入序列里 15% 的 token 替换成 [MASK],让模型预测这些位置的原始 token。

原句:  "the cat sat on the mat"
mask:  "the cat [MASK] on the [MASK]"
目标:  预测 [MASK] 位置应该是 "sat" 和 "mat"

2. Next Sentence Prediction (NSP):给两个句子,判断 B 是不是 A 的下一句。

后者(NSP)后来被 RoBERTa 证明几乎无用、被丢掉。但 MLM 留下来了——它的关键价值是:MLM 需要双向上下文——预测 [MASK] 时,模型必须同时看左边和右边的内容。这正好对应 Encoder 不带因果掩码的双向 Self-Attention。

flowchart LR
  S["the cat [MASK] on the mat"] --> EMB[Embedding + 位置]
  EMB --> ENC[12 层双向 Encoder]
  ENC --> H[每个位置的<br/>上下文向量]
  H --> P["[MASK] 位置的向量<br/>过 LM head"]
  P --> PRED["预测: sat (高概率)<br/>jumped, slept, ..."]

Encoder-only 的下游用法

BERT 训练完之后,怎么用?答案是fine-tune——拿预训练好的 Encoder 接一个小的下游头,在具体任务的标注数据上微调:

注意一个根本性质:BERT 不能做生成。它的训练目标是「填空」(双向上下文 → 单点预测),而不是「续写」。直接用 BERT 做生成(比如让它预测下一个 token)也能训出来,但效果不如 Decoder-only——因为它的 attention mask 不带因果性,模型在训练时见到了「未来」,生成时反而不擅长「只用过去」。

Encoder-only 的现代命运

2018-2020 年是 BERT 的全盛期——它在 GLUE、SuperGLUE 等理解类基准上把 SOTA 推得很高。

但到了 2020 年之后,BERT 系的优势逐渐被压缩:

但有一个领域 Encoder-only 仍是王者:嵌入与检索

句子嵌入(sentence embedding)需要一个把句子映射成定长向量、且语义相似句子的向量也接近的模型。这件事 Decoder-only 模型做得不好——它们的输出是逐 token 的概率分布,没有天然的「整句嵌入」概念。Encoder-only 模型的 [CLS] 或 mean-pooled 输出本来就是整句的上下文向量,套一个 contrastive learning 训练框架(如 SimCSE、E5)就成了优秀的嵌入模型。

今天 RAG 系统里负责「把文档和 query 编码成向量做检索」的几乎全是 Encoder-only 模型:BGE、E5、Cohere Embed、OpenAI text-embedding-3。它们都是 BERT-style 的双向 Encoder,用对比学习训练。Decoder-only 大模型负责生成;Encoder-only 模型负责检索——这是今天工业里非常清晰的分工。

6.4 Encoder-Decoder:T5 的世界

T5(Text-to-Text Transfer Transformer,Raffel et al., 2020)把 Encoder-Decoder 推到了一个极致:所有 NLP 任务都被重新定义为「输入文本 → 输出文本」的转换

分类:
  输入: "sst2 sentence: this movie is great"
  输出: "positive"

翻译:
  输入: "translate English to German: Hello"
  输出: "Hallo"

摘要:
  输入: "summarize: <一长段文章>"
  输出: "<摘要>"

填空:
  输入: "fill in the blank: I _ to school today."
  输出: "went"

T5 的所有任务都用同一个 Encoder-Decoder 架构 + 同一组权重处理,用前缀(prefix)告诉模型要做什么。这是「统一接口」的早期尝试——把 NLP 不同任务的接口都抹平成 text-to-text。

T5 的训练目标:Span Corruption

T5 的预训练目标比 BERT 的 MLM 复杂一些:span corruption(片段破坏)。

原句:  "Thank you for inviting me to your party last week."

输入:  "Thank you <X> me to your party <Y> week."
        ↑                ↑
        sentinel X        sentinel Y

目标:  "<X> for inviting <Y> last </s>"

把若干连续 token 打包成「span」,整段 mask 掉,让模型从 sentinel token 开始 generate 出原始内容。这件事要求 Decoder 有跨视图能力(从被破坏的输入恢复完整内容)+ 生成能力(自回归输出)——所以 Encoder-Decoder 是天然合适的架构。

Encoder-Decoder 的关键优势

为什么有人坚持 Encoder-Decoder?两个理由:

第一,Encoder 的双向性强于 Decoder-only。同样的 token,Encoder 看左右上下文,Decoder-only 只看左侧——直觉上 Encoder 对输入的理解更精确。在某些「输入复杂、输出简短」的任务(如机器翻译、摘要),Encoder 的双向理解能省下不少 attention 步骤。

第二,Cross-Attention 是天然的输入-输出对齐机制。机器翻译里 source 和 target 之间的对应关系(哪个英文词对应哪个中文词)通过 Cross-Attention 直接学习——比 Decoder-only 用 prompt 拼接的方式更结构化。

T5、BART、mT5、Flan-T5、UL2 这条路线在 2020 年前后非常活跃,至今在某些任务(特别是机器翻译、文档摘要)仍然是 SOTA。Google 的 Gemini 早期内部架构也是 Encoder-Decoder。

但代价也明显

Encoder-Decoder 的代价集中在工程复杂度上:

这些代价在「单一任务」场景下还能接受,但当大模型时代来临、需要一个模型解决无数任务时,简单胜过复杂——下一节 Decoder-only 的胜利就建立在这条原则上。

6.5 Decoder-only:从 GPT-1 到清场

2018 年 6 月,OpenAI 发布 GPT-1。论文标题:Improving Language Understanding by Generative Pre-Training

它做了和 BERT 相反的事:只保留 Decoder,扔掉 Encoder。架构上是 12 层带因果掩码的 Self-Attention。训练目标更简单——纯粹的语言建模:

L=i=1TlogP(xix<i)\mathcal{L} = -\sum_{i=1}^{T} \log P(x_i | x_{<i})

给定前 i1i-1 个 token,预测第 ii 个 token 的概率。这就是高中生都能理解的「预测下一个词」。

GPT-1 出来时,BERT 的双向 MLM 在判别任务上更强,所以 GPT-1 没有引起特别大轰动。GPT-2(2019, 1.5B 参数)开始展示「无监督多任务学习」——纯粹的语言建模训出的模型已经能做问答、翻译、摘要等任务,只要把它们用恰当的 prompt 表达出来。

真正的转折是 GPT-3(2020, 175B 参数)。它的论文标题:Language Models are Few-Shot Learners。GPT-3 证明了:当 Decoder-only 模型足够大时,它能通过「上下文学习」(in-context learning, ICL)解决新任务,不需要任何任务特定的微调

prompt:
"Translate English to French:
sea otter => loutre de mer
plush giraffe => girafe en peluche
cheese => fromage
peppermint => "

GPT-3 output:
"menthe poivrée"

仅仅给出几个例子(few-shot),模型就能在 prompt 中「理解」任务并执行。这件事 BERT 做不到(它没有自然的生成能力);T5 也做不到(它的训练目标里没有「上下文中的几个示范」这种范式)。

Decoder-only 在 GPT-3 之后开始清场

flowchart TB
  G1[GPT-1<br/>2018] --> G2[GPT-2<br/>2019]
  G2 --> G3[GPT-3<br/>2020]
  G3 --> CHAT[ChatGPT<br/>2022]
  CHAT --> EXP[爆发<br/>所有大模型转向 Decoder-only]
  EXP --> LM1[Llama]
  EXP --> CL[Claude]
  EXP --> DS[DeepSeek]
  EXP --> MS[Mistral]
  EXP --> QW[Qwen]
  EXP --> GE[Gemini]

到 2023 年,开源大模型生态几乎一边倒地选了 Decoder-only。BERT 被局限在嵌入领域,T5 系列变成小众。

6.6 Decoder-only 为什么赢

这是一个值得展开讲的问题。Decoder-only 在很多任务上性能不一定更好——T5 在翻译上就常优于同尺寸的 GPT。但它最终统治了大模型市场,原因不是性能,是统一性

理由一:训练目标统一

Decoder-only 只有一个目标——预测下一 token。所有任务、所有数据形态都被压成同一个 loss:

分类  → 把 label 当作下一个要生成的 token
翻译  → 把目标语言当作要生成的延续
QA   → 把 answer 当作要生成的延续
摘要  → 把摘要文本当作要生成的延续
代码  → 把代码当作要生成的延续
对话  → 把回复当作要生成的延续

一个目标,一个损失函数,一组权重——这意味着所有任务的数据都可以混在同一批次里训练。GPT-3 训练时混合了网页、书籍、代码、Wikipedia,而不是给每种数据搭一个特殊架构。这种「数据形态无差别」性质使得 Scaling 异常顺滑——你想让模型更强,就喂更多数据;模型自动学会哪些 pattern 适用于哪些场景。

理由二:In-Context Learning 天然涌现

Decoder-only 的因果建模有一个微妙性质:当上下文中包含「示例」时,模型在预测下一 token 时会自然地参考这些示例。这就是 ICL。

数学上 ICL 是 Decoder-only 的 attention 在 context 中找到了「示例 - 模式」结构、把这个结构用到当前 query 上。这件事在 Encoder-Decoder 里也能做,但需要额外的 prompt 设计;在 Encoder-only 里几乎做不到(它没有自回归生成这一步)。

ICL 让大模型用法发生了根本变化——不需要为每个新任务收集几千条标注数据微调,只需要在 prompt 里给几个例子就行。这对工业落地的成本影响是数量级的。

理由三:推理形态简单

Decoder-only 的推理是单一循环:「读 prompt → 一个一个生成 token,每次都把新生成的接到 context 末尾」。

Encoder-Decoder 的推理需要两阶段:先 encoding 整个输入,再 decoding 自回归生成。两阶段在工程上意味着:

vLLM、SGLang、TensorRT-LLM 这些主流推理引擎首选支持的都是 Decoder-only 架构——一个原因就是它的推理流程更直接。

理由四:长上下文的延续性

Decoder-only 的「上下文」就是「左侧的 token」——上下文长度可以无限延伸。读 1K 还是读 1M,架构本身不变,只需要位置编码能外推(第 4 章 RoPE / YaRN)。

Encoder-Decoder 的输入长度受 Encoder 限制(Encoder 一次性吃完,KV Cache 大小固定)。理论上也能扩展,但工程上要为 Encoder 单独做一遍长上下文优化——又是 1.5 倍的工作量。

理由五:Decoder-only 不弱于 Encoder-Decoder

最后,给定相同参数量和数据量,Decoder-only 在大多数任务上性能与 Encoder-Decoder 相当——少数任务(翻译、摘要)Encoder-Decoder 略胜,但差距没有统一性带来的好处大。

Wang et al.(2022)在 What Language Model Architecture and Pretraining Objective Work Best for Zero-Shot Generalization? 里做了系统的对比:在相同算力预算下,Decoder-only + 因果语言建模在多任务零样本性能上略胜 Encoder-Decoder + Span Corruption。

综合:简单胜复杂

Decoder-only 不是「性能最优」,是「统一性最强、工程最简、扩展最自然」。在大模型时代,这三个性质合起来比性能本身更重要——你可以用 10 倍数据弥补 5% 的任务性能差距,但你不可能让一个复杂架构的 Encoder-Decoder 模型扩展到 1T 参数还保持工程稳定。

6.7 一个特殊变体:Prefix-LM

不能不提 Prefix-LM——它是 Decoder-only 和 Encoder-Decoder 的中间形态。

Prefix-LM 的设计:前 k 个 token 用双向 attention(充当 encoder),后面的 token 用因果 attention(充当 decoder)。也就是说,attention mask 是这样的:

对于前 k 个 token (prefix):
   双向: 互相都能看
对于后 T-k 个 token (response):
   因果: 只能看自己和左边的所有 token

mask 矩阵示意:

        prefix→     ←causal→
        k_1 k_2 k_3 k_4 k_5 k_6
q_1 (p)  ✓   ✓   ✓                  ← prefix 能看所有 prefix
q_2 (p)  ✓   ✓   ✓                  ← prefix 能看所有 prefix
q_3 (p)  ✓   ✓   ✓                  ← prefix 能看所有 prefix
q_4 (c)  ✓   ✓   ✓   ✓              ← response 能看 prefix 和左侧 response
q_5 (c)  ✓   ✓   ✓   ✓   ✓
q_6 (c)  ✓   ✓   ✓   ✓   ✓   ✓

GLM(清华,2021)和 UL2(Google,2022)用的就是 Prefix-LM。直觉是:输入 prompt 用双向理解(充分挖掘信息),生成回复用因果(保持自回归)——既享受 Encoder 的双向理解优势,又保持 Decoder-only 的统一性。

但 Prefix-LM 终究没成主流——主要原因还是工程上的复杂度(mask 是「半双向半因果」的特殊形状),以及它的优势在 Decoder-only 大模型规模上后逐渐被「scale 把所有问题压平」抵消。

6.8 一张总对照表

把前面讨论的内容浓缩成一张表:

维度 Encoder-only (BERT) Encoder-Decoder (T5) Decoder-only (GPT) Prefix-LM (GLM)
Attention mask 全双向 Encoder 双向 + Decoder 因果 + Cross-Attention 严格因果 前缀双向 + 后缀因果
训练目标 MLM / RTD(双向填空) Span Corruption(破坏-恢复) 因果语言建模(next-token) Span/Causal 混合
能否生成 不天然 可以 可以 可以
是否擅长嵌入 一般 不天然 一般
In-Context Learning
推理形态 单次 forward 两阶段(encode + decode) 自回归循环 自回归循环(前缀只 forward 一次)
工程复杂度
主要用例 嵌入、分类、检索 翻译、摘要 生成、对话、所有大模型 探索性变体
代表模型 BERT、RoBERTa、E5、BGE 原始 Transformer、T5、BART、Flan-T5 GPT-3/4、Llama、Claude、DeepSeek、Mistral GLM、UL2

这张表是这一章的浓缩——每一行都是一种工程决定。理解了这张表,你看任何一篇大模型论文都能立刻判断它属于哪一支血脉、为什么这么设计。

6.9 选架构的工程经验

如果你今天要为一个新任务选架构,下面是经验法则:

  1. 要训通用大模型 → Decoder-only。这是工业界 2023 之后的事实标准,所有工具链(vLLM、TensorRT-LLM、Hugging Face、PEFT)都围绕它优化。
  2. 要做嵌入 / 检索 / 分类 → Encoder-only。BGE、E5、SimCSE 等都是 Encoder-only 路线。
  3. 要做翻译 / 摘要等专门 seq2seq → Encoder-Decoder 仍是合理选项。如果数据量不大、希望模型小而专精,T5/BART 路线开发成本更低。
  4. 要混合长输入 + 短输出(如阅读理解)→ Decoder-only + 长上下文。今天的大模型已经能在 1M context 下工作,传统 Encoder-Decoder 的优势被抹平。
  5. 不要用 Prefix-LM。除非你有非常具体的研究目的——它的工程支持远不如 Decoder-only。

本章小结

  1. 同一个 Transformer Block,三种架构:Encoder-only(双向 Self-Attention)、Encoder-Decoder(双向 + 因果 + Cross-Attention)、Decoder-only(因果 Self-Attention)。
  2. 三种 attention mask 决定了三种能力:Encoder-only 看得最全(适合理解)、Decoder-only 看得最严(适合生成)、Encoder-Decoder 是合体(适合 seq2seq)。
  3. BERT 路线擅长理解和嵌入——双向 MLM 训练,下游任务接小头。今天主要活在嵌入和检索领域。
  4. T5 路线擅长 seq2seq——所有任务都用 text-to-text 表达。在翻译、摘要上仍然优秀,但工程复杂度限制了它在大模型时代的地位。
  5. Decoder-only 在大模型时代清场——胜在统一性(一个目标处理所有任务)、In-Context Learning 自然涌现、推理流程简单、长上下文延续性好。
  6. Prefix-LM 是中间变体——理论上漂亮,工程上未成主流。
  7. 2023 之后开源大模型几乎全部 Decoder-only——Llama、Mistral、DeepSeek、Qwen、Yi 全是这条路线。

下一章我们沿着 6.5 节挖下的伏笔继续——为什么 BERT 输给了 GPT?这不只是架构差异,更是「预训练范式」的差异。BERT 的「填空」和 GPT 的「续写」是两种世界观,第 7 章会讲清楚这场 2018-2023 年间的范式之战。

延伸阅读