Transformer 编码器与解码器
整体结构
输入句子 输出句子
"我爱吃饭" "I love eating"
│ ▲
▼ │
┌─────────────┐ ┌─────────────────┐
│ │ │ │
│ 编码器 │────────────────▶│ 解码器 │
│ Encoder │ 语义向量 │ Decoder │
│ │ │ │
└─────────────┘ └─────────────────┘
负责"理解"输入 负责"生成"输出编码器:理解输入
任务是把输入句子压缩成一个富含语义的向量表示。
输入: 我 爱 吃 饭
│ │ │ │
▼ ▼ ▼ ▼
词嵌入(把词变成向量)
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────┐
│ 自注意力机制 │ ← 每个词都去看其他所有词(双向)
└──────────────────────────┘
│ │ │ │
▼ ▼ ▼ ▼
h我 h爱 h吃 h饭 ← 每个词的向量都包含了整句的上下文编码器输出的不是一个词,是每个位置的上下文向量。
解码器:生成输出
一个词一个词地生成翻译结果。
已生成: <start> I love
│
▼ 预测下一个词
┌─────────────────────┐
│ masked 自注意力 │ ← 只能看已生成的词(单向)
└─────────────────────┘
│
▼
┌─────────────────────┐
│ 交叉注意力 │ ← 去问编码器:"我的意思是啥?"
│ cross-attention │ 读取 h我 h爱 h吃 h饭
└─────────────────────┘
│
▼
"eating"两者核心区别
编码器的自注意力:双向,可以看全句
我 ←──────────▶ 饭
每个词看所有词
解码器的自注意力:单向,只能看左边
I ──▶ love ──▶ eating
不能看未来(防止作弊)交叉注意力:连接两者的桥梁
解码器独有的一层,编码器没有:
解码器生成 "eating" 时:
Query 来自解码器(当前生成状态)
Key/Value 来自编码器输出(h我 h爱 h吃 h饭)
注意力权重:我:0.1 爱:0.1 吃:0.7 饭:0.1
↑
重点关注"吃",所以生成 eating不同任务用不同组合
| 任务 | 用哪部分 | 例子 |
|---|---|---|
| 翻译、摘要 | 编码器 + 解码器 | 原始 Transformer、T5 |
| 文本理解/分类 | 只用编码器 | BERT |
| 文本生成 | 只用解码器 | GPT、Claude |