T5 与 BART:编码器-解码器模型 本节摘要:编码器懂理解,解码器会生成。把它们拼回一起,你就得到一个专为「输入→输出」任务设计的模型:翻译、摘要、改写、转录。decoder-only 的 GPT 和 encoder-only 的 BERT 各为不同目标精简了 2017 架构,但许多任务天然是输入-输出的——翻译(英→法)、摘要(5000 token 文章→200 token 摘要)、语音识别(音频 token→文本 token)、结构化抽取(散文→JSON)。对它们,编码器-解码器最契合:编码器产出源的稠密表示,解码器在每一步交叉关注这个表示来生成输出,训练是输出侧的 shift-by-one——与 GPT 同一个损失,只是以编码器输出为条件。
本节摘要:编码器懂理解,解码器会生成。把它们拼回一起,你就得到一个专为「输入→输出」任务设计的模型:翻译、摘要、改写、转录。decoder-only 的 GPT 和 encoder-only 的 BERT 各为不同目标精简了 2017 架构,但许多任务天然是输入-输出的——翻译(英→法)、摘要(5000 token 文章→200 token 摘要)、语音识别(音频 token→文本 token)、结构化抽取(散文→JSON)。对它们,编码器-解码器最契合:编码器产出源的稠密表示,解码器在每一步交叉关注这个表示来生成输出,训练是输出侧的 shift-by-one——与 GPT 同一个损失,只是以编码器输出为条件。本节聚焦两篇定义现代 playbook 的论文:T5(「文本到文本迁移 Transformer」,把所有 NLP 任务重写成 text-in/text-out,用 span corruption 预训练)和 BART(双向自回归 Transformer,多噪声去噪自编码器)。到 2026 年,encoder-decoder 在「输入结构重要」的地方仍活跃——Whisper(语音→文本)、谷歌翻译、Flan-T5。decoder-only 赢了聚光灯,但 encoder-decoder 从未退场。
阅读完本节,你应当能够:
<extra_id_N> 替换,解码器只输出被腐蚀的 span。许多任务天然是输入-输出的:翻译、摘要、语音识别、结构化抽取。对它们,编码器-解码器最干净:编码器产出源的稠密表示,解码器生成输出并在每步交叉关注那个表示。训练是输出侧的 shift-by-one,损失与 GPT 相同,只是以编码器输出为条件。
两篇论文定义了现代 playbook:T5(Raffel 2019,把每个 NLP 任务重写成 text-in/text-out,单一架构、单一词表、单一损失,用掩码 span 预测预训练)和 BART(Lewis 2019,去噪自编码器,用多种方式腐蚀输入,让解码器重建原序)。
关键:编码器对每个输入只跑一次,解码器自回归生成,但每步交叉关注同一个编码器输出。缓存编码器输出对长输入是免费加速。
随机选输入里的若干 span(平均长 3 token,共 15%),每个 span 替换成一个唯一哨兵:<extra_id_0>、<extra_id_1>……解码器只输出被腐蚀的 span,带哨兵前缀:
源: The quick <extra_id_0> fox jumps <extra_id_1> dog 目标: <extra_id_0> brown <extra_id_1> over the lazy
这比预测整条序列的信号便宜,在 T5 论文的消融里与 MLM(BERT)和 prefix-LM(UniLM)竞争力相当。
BART 试了五种噪声函数:① token 掩码、② token 删除、③ 文本填充(掩一个 span,解码器推断正确长度)、④ 句子置换、⑤ 文档旋转。文本填充 + 句子置换组合下游最好。解码器总是重建原序——输出是完整序列而非仅腐蚀 span,所以 BART 预训练算力比 T5 高。
与 GPT 同样的自回归生成,greedy/beam/top-p 采样都适用。**beam search(width 4~5)**是翻译和摘要的标准,因为这些任务的输出分布比聊天窄。
| 任务 | 编码器-解码器? | 为什么 |
|---|---|---|
| 翻译 | 通常选 | 源序列清晰;输出分布固定;beam search 有效 |
| 语音转文本 | 选(Whisper) | 输入模态与输出不同;编码器塑造音频特征 |
| 聊天 / 推理 | 不选,decoder-only | 没有持久的「输入」——对话本身就是序列 |
| 代码补全 | 通常不选 | 长上下文 decoder-only 赢;Qwen 2.5 Coder 是 decoder-only |
| 摘要 | 两者皆可 | BART、PEGASUS 早期胜 decoder-only 基线;现代 decoder-only LLM 已追平 |
| 结构化抽取 | 两者皆可 | T5 干净,因为「text→text」吸收任何输出格式 |
2022 年后的趋势:decoder-only 接管 encoder-decoder 原来的地盘,因为① instruction-tuned 的 decoder-only LLM 靠 prompting 泛化到任何任务,② 一种架构比两种好 scale,③ RLHF 假设有个 decoder。encoder-decoder 在输入模态不同(语音、图像)或 beam search 质量重要的地方守住阵地。
完整代码见原课程 phases/07-transformers-deep-dive/08-t5-bart-encoder-decoder/code/main.py。我们实现 T5 式的 span corruption——本节最实用的单件,因为此后每个 encoder-decoder 预训练配方都用到它。
def corrupt_spans(tokens, mask_rate=0.15, mean_span=3.0, rng=None): """选总和约占 mask_rate 的若干 span,返回 (腐蚀输入, 目标)。""" n = len(tokens) n_mask = max(1, int(n * mask_rate)) # 共要掩 ~15% token n_spans = max(1, int(round(n_mask / mean_span)))# 平均每 span 3 token # ... 随机放 span 边界,把每个 span 换成 <extra_id_k>,目标侧拼哨兵+原 span
目标格式遵循 T5 约定:<sent0> span0 <sent1> span1 ...。腐蚀输入把未改动的 token 与 span 位置的哨兵 token 交错。
给定腐蚀输入和目标,重建原句。腐蚀可逆则前向良定义。这是 sanity check——真实训练从不这么做,但测试很便宜,能抓出 span 记账里的 off-by-one bug。
五个函数:token_mask、token_delete、text_infill、sentence_permute、document_rotate。组合其中两个,展示结果。
设计要点:span corruption 的妙处是目标变短——解码器只输出少量 span,而非整条序列,训练信号密度更高、更便宜。这是 T5 在等算力下能与 BERT 竞争的关键。
from transformers import T5ForConditionalGeneration, T5Tokenizer tok = T5Tokenizer.from_pretrained("google/flan-t5-base") model = T5ForConditionalGeneration.from_pretrained("google/flan-t5-base") inputs = tok("translate English to French: Attention is all you need.", return_tensors="pt") out = model.generate(**inputs, max_new_tokens=32) print(tok.decode(out[0], skip_special_tokens=True))
T5 的技巧:任务名写进输入文本。同一个模型处理几十种任务,因为每个任务都是 text-in/text-out。2026 年这个模式已被 instruction-tuned 的 decoder-only 模型泛化,但 T5 是头一个把它形式化的。
原课程产出 outputs/skill-seq2seq-picker.md:一个选择器 Skill,给定输入-输出结构、延迟、质量目标,在新任务上选 encoder-decoder 还是 decoder-only。
code/main.py,对一句 30 token 的句子应用 span corruption,验证把源里非哨兵 token 与解码出的目标 span 拼起来能还原原句。text_infill 噪声:把随机 span 换成单个 <mask> token,解码器要推断正确长度加内容。给一个例子。flan-t5-small,在留出的 50 对上测 BLEU,与同等算力微调 Llama-3.2-1B 对比。<extra_id_N>,解码器只输出 span——目标变短,信号更便宜。下一节,我们把 Transformer 从文本扩展到视觉——ViT 如何把一张图切成 patch、当 token 喂进同一个 Transformer 块,让「一个块统治所有模态」在视觉上落地。