预训练三剑客:BERT、GPT 与 T5 架构对比与实战【NLP系列第五篇】 预训练三剑客BERT、GPT 与 T5 架构对比与实战【NLP系列第五篇】1. 同一个 Transformer三种用法上一篇我们拆完了 Transformer 的每个零件自注意力、多头、位置编码、残差连接、LayerNorm、FFN……但你可能注意到一个问题——市面上主流的大模型用的并不是同一个 Transformer。BERT只拿 EncoderGPT只拿 DecoderT5才拿完整的 Encoder Decoder同一个架构为什么有三种用法它们各自擅长什么怎么选这篇博客就来回答这些问题。我们沿着预训练 微调这条主线把 BERT、GPT、T5 的结构、预训练目标、微调方式逐一对比最后落到实战什么场景选什么模型、怎么写代码。2. 核心概念预训练 微调范式在讲具体模型之前先理解一下预训练 微调这个范式。它改变了 NLP 的游戏规则。2.1 预训练在大规模无标注文本上训练模型让它学会通用的语言能力——语法、语义、常识等。这个过程是self-supervised的不需要人工标注数据直接从原始文本中自动构造训练样本。比如 GPT 的预训练任务就是根据前面的词预测下一个词——每一段文本天然就是训练数据。2.2 微调预训练完后模型已经会说人话了但要它做具体任务情感分类、问答、翻译还需要用少量标注数据做二次训练。微调时模型主体不变只在顶部加一个简单的输出层用小学习率2e-5 ~ 5e-5更新全部参数。为什么有效因为预训练让模型学到了通用的语言知识微调只是把这些知识引导到具体任务上——比从头训练快得多、效果好得多。3. 三大模型架构对比3.1 GPTDecoder-onlyGPT 系列由 OpenAI 提出核心思路很直接用 Transformer 的 Decoder 做语言模型根据左侧上下文预测下一个 token。模型结构GPT 使用的是Transformer Decoder 的一部分——只保留了Masked Self-AttentionFFN的结构去掉了交叉注意力因为没有 Encoder。解码器层堆叠 12 层GPT-1。GPT 的位置编码和原始 Transformer 不同不再是固定的正弦余弦编码而是改用可学习的位置嵌入——每个位置对应一个可学习的向量训练过程中自动优化。最终每个 token 的表示是词嵌入 位置嵌入的向量和维度 768。预训练自回归语言建模训练目标就是标准的自回归语言模型Autoregressive LM根据已看到的前文预测下一个位置的 token。训练数据直接从原始文本中自动构建——拿一段文本把它切成前文→下一个词的样本对即可。这种方式的优点是数据获取成本为零缺点是只能看到左侧上下文无法利用右侧信息。微调GPT 微调时在模型顶部加一个线性分类头Linear Head将最后一个位置的隐状态映射到任务标签上。每个任务在输入前加上特殊标记Start和Extract模型只取Extract位置的输出做分类。2018 年 GPT-1 发布时微调是通过 Task Classifier 做的。后来 GPT-3 发现直接写 Prompt 让模型生成也能做分类——这就是 In-Context Learning。两种方式都能用微调效果更稳定Prompt 更灵活。3.2 BERTEncoder-onlyBERT 由 Google 于 2018 年提出和 GPT 走了完全相反的路——它用 Transformer 的Encoder核心思想是双向自注意力。模型结构BERT 直接使用Transformer Encoder每个 token 的自注意力可以看到序列中的所有位置包括左右两侧。两个版本模型版本层数模型维度注意力头数参数量BERT-base12768121.1 亿BERT-large241024163.4 亿BERT 的输入由三部分嵌入相加组成Token Embedding词本身的语义表示Position Embedding可学习的位置向量Segment Embedding区分句子对中的两个句子此外输入中通常包含两个特殊符号[CLS]句首标记其输出向量常用于下游分类任务[SEP]句间分隔符出现在每个句子末尾预训练MLM NSPBERT 的预训练包含两个任务掩码语言模型MLM随机遮盖输入中 15% 的 token让模型根据双向上下文预测被遮的词。遮盖策略80% 替换为[MASK]10% 替换为随机词10% 保持不变这样模型既能看到左侧也能看到右侧实现了真正的双向建模——这是 BERT 相比 GPT 最大的优势。下一句预测NSP训练模型判断两个句子是否是连续的。这个任务提升了 BERT 在问答、推理等需要理解句子关系的任务上的表现。微调BERT 微调非常灵活文本分类取[CLS]位置的输出过一个线性层序列标注取每个 token 位置的输出逐 tokek 分类问答预测答案的起始位置和结束位置微调时模型主体不变只加一个简单的输出层用下游数据对整个模型做端到端训练。3.3 T5Encoder-DecoderT5 由 Google 在 2020 年提出它走了第三条路——完整的 Encoder Decoder。核心思想T5 的想法很纯粹所有 NLP 任务本质上都是文本到文本的转换。分类也好、翻译也好、摘要也好——输入是文本输出也是文本。#### 模型结构T5 大体遵循原始 Transformer 架构Encoder 做双向理解Decoder 做自回归生成。此处不再展开上一篇讲得够多了。预训练Corrupted Span PredictionT5 的预训练目标结合了 BERT 和 GPT 的思路随机遮盖在输入文本中随机遮盖若干连续片段span平均长度约 3 个 token替换标记每个被遮盖的 span 替换为一个特殊标记X生成目标Encoder 读被破坏的文本Decoder 生成被遮盖的 span 内容举个例子原始文本为 “Thank you for inviting me to your party”Encoder 输入Thank you X me to Y party. Decoder 输出X for inviting Y your这样既保留了 Encoder 的双向建模能力理解完整上下文又为训练提供了生成式学习信号Decoder 输出遮盖内容。微调Text-to-Text FormatT5 微调时不需要加任何分类头——只需要在输入前加一个任务前缀task prefix任务类型输入形式目标输出翻译translate English to German: That is good.Das ist gut.情感分类sentiment: This movie was great.positive问答question: What is the capital of France? ...Paris摘要summarize: The study found that...生成的摘要好处是一个模型、一套架构做所有任务不需要为分类、翻译、摘要分别设计不同的输出头。4. 代码实战用 HuggingFace Transformers 跑三大模型下面演示如何用transformers库加载三种预训练模型做推理。所有代码都标注了输入输出的 shape。4.1 GPT-2 文本生成fromtransformersimportAutoTokenizer,AutoModelForCausalLM# 加载 GPT-2 模型和分词器tokenizerAutoTokenizer.from_pretrained(gpt2)modelAutoModelForCausalLM.from_pretrained(gpt2)# 输入文本promptThe future of AI isinputstokenizer(prompt,return_tensorspt)# inputs.input_ids shape: (1, seq_len) — batch1print(f输入 shape:{inputs.input_ids.shape})# torch.Size([1, 5])# ⭐ 自回归生成逐个 token 预测output_idsmodel.generate(inputs.input_ids,max_new_tokens20,# 最多生成 20 个新 tokendo_sampleTrue,# 采样而不是 greedytemperature0.7,# 控制随机性越低越确定pad_token_idtokenizer.eos_token_id,)print(f输出 shape:{output_ids.shape})# torch.Size([1, 5 20])# 解码输出generatedtokenizer.decode(output_ids[0],skip_special_tokensTrue)print(f生成结果:\n{generated})# 输出示例: The future of AI is bright, but its also a future that we need to be careful about...4.2 BERT 情感分类fromtransformersimportAutoTokenizer,AutoModelForSequenceClassificationimporttorch.nn.functionalasF# 加载 BERT 分类模型预训练在 IMDB 上tokenizerAutoTokenizer.from_pretrained(nlptown/bert-base-multilingual-uncased-sentiment)modelAutoModelForSequenceClassification.from_pretrained(nlptown/bert-base-multilingual-uncased-sentiment)# 输入文本textThis movie was absolutely fantastic!inputstokenizer(text,return_tensorspt,paddingTrue,truncationTrue)# inputs.input_ids: (1, seq_len)# inputs.attention_mask: (1, seq_len) — 区分 padding 和真实 tokenprint(finput_ids shape:{inputs.input_ids.shape})# torch.Size([1, 8])print(fattention_mask shape:{inputs.attention_mask.shape})# torch.Size([1, 8])# BERT 前向传播outputsmodel(**inputs)# outputs.logits: (1, num_labels) — [CLS] 经过分类头的输出print(flogits shape:{outputs.logits.shape})# torch.Size([1, 5])# softmax 得到概率分布probsF.softmax(outputs.logits,dim-1)predprobs.argmax(dim-1).item()print(f情感得分 (1-5):{pred1})# 1最差, 5最好print(f各星级概率:{probs[0].tolist()})4.3 T5 翻译fromtransformersimportAutoTokenizer,AutoModelForSeq2SeqLM# 加载 T5-smalltokenizerAutoTokenizer.from_pretrained(t5-small)modelAutoModelForSeq2SeqLM.from_pretrained(t5-small)# T5 微调时只需加 task prefixinput_texttranslate English to German: That is good.inputstokenizer(input_text,return_tensorspt)# inputs.input_ids shape: (1, seq_len)print(f输入 shape:{inputs.input_ids.shape})# torch.Size([1, 9])# T5 用 Encoder-Decoder 生成output_idsmodel.generate(inputs.input_ids,max_new_tokens20,)print(f输出 shape:{output_ids.shape})# torch.Size([1, ~5])translationtokenizer.decode(output_ids[0],skip_special_tokensTrue)print(f翻译结果:{translation})# Das ist gut.三个模型的输入输出对比模型输入格式输出是什么输出维度GPT文本续写开头自回归生成的 token 序列(1, input_len gen_len)BERT文本 注意力掩码每个 token 的隐状态 /[CLS]分类(1, seq_len, 768)/(1, num_labels)T5文本 task prefixEncoder-Decoder 生成的 token 序列(1, gen_len)5. 避坑指南5.1 预训练不要自己练GPT-3 一次训练成本约 1200 万美元。哪怕 BERT-base 也要 16 块 TPU 跑 4 天。绝大多数场景直接使用 HuggingFace 上开源的预训练权重微调就够了。5.2 模型选择看任务分类 / 匹配 / NER选 BERTEncoder-only双向上下文理解最强文本生成 / 对话 / 续写选 GPTDecoder-only自回归天生适合生成翻译 / 摘要 / 多任务统一选 T5Encoder-Decodertext-to-text 框架最灵活如果拿不准T5 是最稳妥的选择——Encoder-Decoder 既能理解又能生成5.3 微调 learning rate 要小预训练模型的权重已经收敛到一个很好的局部最优了微调只是为了适配下游任务。学习率设太大1e-4会破坏预训练学到的语言知识。建议范围2e-5 ~ 5e-5AdamW 优化器 linear warmup。5.4 输入长度限制模型最大输入长度BERT512 tokenGPT-21024 tokenT5512 token超长文本需要切片处理。BERT 的 512 限制是 Transformer 的 self-attention 复杂度O ( n 2 ) O(n^2)O(n2)决定的。5.5 GPU OOM从 batch size 8 或 16 开始试OOM 了就减半。也可以用gradient_accumulation_steps等效增大 batch size。# 显存不够时batch_size8梯度累积 4 步 ≈ batch_size32training_argsTrainingArguments(per_device_train_batch_size8,gradient_accumulation_steps4,)6. 总结三大模型对比维度BERT (Encoder)GPT (Decoder)T5 (Enc-Dec)注意力双向全可见单向因果掩码双向 单向预训练目标MLM NSP预测下一个 tokenSpan Corruption是否能生成否是是是否能理解是是是擅长的任务分类、NER、QA对话、续写、代码生成翻译、摘要、统一框架代表模型BERT、RoBERTaGPT、LLaMA、QwenT5、Flan-T5输入长度限制5121024~8192512一句话总结BERT 最懂你GPT 最能写T5 最全能。选模型先看任务理解用 BERT生成用 GPT想做所有事用 T5。参考链接BERT 论文GPT-1 论文T5 论文HuggingFace Transformers 官方文档