5615 字
28 分钟

BERT和GPT

今天提到“AI 模型”,许多人首先想到的是 GPT:输入一个问题,模型继续生成文字,可以对话、写作、翻译和编程。BERT 看起来更像藏在搜索、分类和信息抽取系统里的一个组件,远没有 GPT 那么“像 AI”。

但在 2018 至 2019 年,率先成为 NLP 通用基础模型、被大量论文和工程项目采用的却是 BERT。GPT-1 明明更早发表,也天然能够生成文本,为什么没有在当时直接走向 ChatGPT?一种流传很广的说法是:OpenAI 最初并不知道 Decoder-Only 模型的生成能力会这么强,只是后来无意中发现了。

这个说法混合了三个不同问题:

  • 自回归语言模型能不能生成文本;
  • 只训练“下一个 token”会不会顺带学会没有专门训练过的任务;
  • 一个续写模型怎样变成能够理解指令的聊天助手。

生成文本从来不是意外;真正逐步浮现的,是 next-token prediction 随数据和模型规模增长表现出的 zero-shot、in-context learning 和通用任务能力。而“像 AI 助手”的交互体验,还依赖后来出现的指令微调、人类反馈对齐与产品系统。

三篇论文,两条路线#

BERT 与 GPT 不是两套互不相关的发明,它们都从 2017 年的 Transformer 出发:

  • 2017 年,Attention Is All You Need 提出完整的 Transformer Encoder–Decoder,用 Encoder 读取源序列,再由 Decoder 在 Encoder 表示的条件下逐步生成目标序列。
  • 2018 年 6 月,Improving Language Understanding by Generative Pre-Training 提出后来被称为 GPT-1 的模型。它堆叠带 causal mask 的 Decoder 式 block,用自回归语言建模做预训练。
  • 2018 年 10 月,BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding 公开。它堆叠 Encoder block,用 Masked Language Modeling(MLM,掩码语言模型)训练深层双向表示;论文于 2019 年发表于 NAACL。

从原始 Transformer 到 GPT-1 与 BERT 的架构分支

原始 Transformer 是共同源头,GPT 与 BERT 分别选取了两种信息流。BERT 并不是把 GPT 改成双向后得到的模型,GPT 也不是后来才从 BERT 中拆出的生成分支。

“Encoder-Only”和“Decoder-Only”中的 Only 表示模型只堆叠一类 block,不是只有一个 Encoder 或 Decoder 层。GPT-1 与 BERT Base 都有 12 层、768 维 hidden state 和 12 个 attention head;BERT Base 约 1.1 亿参数,GPT-1 约 1.17 亿参数。它们的规模相近,但训练语料、输入设计与目标函数并不相同,不能把论文结果当成只改变 attention mask 的严格对照实验。

GPT 更像今天的 AI,为什么当时先火的是 BERT#

时间顺序上是 GPT-1 先于 BERT。“BERT 先火”指的不是 BERT 出现得更早,而是它更快成为当时 NLP 研究和应用的标准底座。

BERT 的快速普及与 GPT 通用能力逐步显现的时间线

当时的主战场不是聊天#

2018 年主流 NLP 的评价方式是 GLUE、SQuAD、MultiNLI 等 benchmark,任务通常有清楚的输入和固定输出:

  • 句子属于哪个类别;
  • 两句话是否蕴含或矛盾;
  • 每个 token 是不是人名、地点或组织;
  • 答案位于原文的哪一段。

BERT 的信息流恰好适合这类问题。整段输入已经存在,模型可以让每个位置同时利用左右上下文,再接一个很小的 task head 输出标签、token 类别或答案的起止位置。整个过程通常只需要一次前向传播。

BERT 论文在 11 项 NLP 任务上取得当时最好的结果:GLUE 提升 7.7 个百分点,MultiNLI 准确率提升 4.6 个百分点,SQuAD v1.1 Test F1 达到 93.2。SQuAD 的数字甚至超过该 benchmark 当时报告的人类 F1,但这只表示模型在特定数据集和指标上的表现,不能解释成机器的阅读理解全面超过人类。

Google 同步开放了代码、BERT Base / Large checkpoint,以及分类和 SQuAD 等任务的微调脚本。当时的开源说明强调,研究者不必从头承担昂贵的预训练,只需下载 checkpoint,几小时内就能在单个 GPU 上完成许多下游任务的微调。强 benchmark 结果、很少的任务特定改造和完整的可复现工具链结合在一起,使“预训练 + 微调”迅速成为 NLP 的标准工作流。

GPT-1 也是这场预训练迁移浪潮的重要起点,并在 12 个评测数据集中的 9 个上改进了当时结果。不过它的主线同样是先做生成式预训练,再针对每个任务监督微调;当时的 1.17 亿参数模型还没有表现出足以统一各种任务的开放生成和 zero-shot 能力。以今天的聊天产品作为标准回看 2018 年,很容易高估当时一个原始语言模型作为交互界面的可用性。

“OpenAI 无意中发现 GPT 会生成文本”属实吗#

强版本的说法不属实。自回归语言模型学习的就是:

P(x1,,xn)=t=1nP(xtx<t)P(x_1,\ldots,x_n)=\prod_{t=1}^{n}P(x_t\mid x_{<t})

从这个分布中选择或采样下一个 token,再把它接回输入,原本就是生成文本的方式。GPT 的论文标题中也直接写着 Generative Pre-Training,因此没有证据支持“OpenAI 当时不知道它能续写”这种说法。

弱化后的说法有一部分事实依据。OpenAI 在 GPT-1 的发布说明中提到,他们还注意到,底层语言模型开始能在没有针对任务训练的情况下完成一些工作。例如,在影评后补上 “very”,比较模型认为 positive 和 negative 哪个更可能出现,可以勉强做情感判断;选择题也可以比较不同答案对应文本的语言模型概率。说明同时强调,这些 zero-shot 方法的绝对表现仍然很低。

所以当时令人意外的不是“模型竟然能生成”,而是:

只训练语言模型,它似乎会顺带学到一些没有显式标注过的任务。

到 2019 年的 GPT-2,这已经不是一次偶然观察。Language Models are Unsupervised Multitask Learners 主动提出假设:如果模型容量足够大、语料足够丰富,语言模型为了更好地预测自然文本,可能会学习其中自然出现的翻译、问答和摘要示范。论文专门以 zero-shot 方式检验这个假设,并观察到模型规模增大时,任务表现与长段落连贯性一起改善。

GPT-3 随后把这种路线推进到 in-context learning:任务说明和少量示例都放进上下文,不更新参数,模型直接续写答案。再往后,指令微调和 RLHF 让模型学会把用户输入解释为要执行的请求,而不只是模仿它后面最可能出现的文字。更准确的历史关系是:

GPT-1 注意到 zero-shot 苗头,GPT-2 主动验证规模化的无监督多任务假设,GPT-3 系统展示上下文学习,指令微调与 RLHF 再把 completion model 塑造成 assistant。

原始 Transformer 中的 Encoder 与 Decoder#

两条路线共享 Transformer 的大部分部件:

  • token embedding 与位置信息;
  • Multi-Head Self-Attention;
  • 逐位置前馈网络(FFN);
  • 残差连接与 LayerNorm;
  • 多层相同 block 的堆叠。

差异首先来自注意力子层之间的连接方式。

原始 Encoder block 包含双向 self-attention 和 FFN。这里的“双向”不是先从左向右跑一遍,再从右向左跑一遍,而是同一层中每个位置都可以直接读取整个源序列。

原始 Decoder block 包含三个子层:

  1. 对已经出现的目标 token 做 causal self-attention;
  2. 以 Decoder hidden state 为 query,对 Encoder 输出做 cross-attention;
  3. FFN。

GPT 没有独立 Encoder,因此也没有需要读取的 Encoder 输出。所谓 Decoder-Only,更准确地说是:它保留原始 Decoder 中带因果约束的 self-attention 与 FFN,却去掉了 cross-attention。这是一种“Decoder 式”的单栈结构,并不是把原始 Transformer Decoder 原封不动地单独拿出来。

结构Self-attention 范围Cross-attention典型输出
BERT / Encoder-Only整个输入序列每个位置的上下文表示
GPT / Decoder-Only当前及左侧 token通常无下一个 token 的概率
原始 Transformer / Encoder–DecoderEncoder 双向、Decoder 因果Decoder 读取 Encoder以输入为条件生成目标序列

真正的分界线:每个 token 能看见谁#

两边都使用缩放点积注意力。加入 mask 后,可以写成:

Attention(Q,K,V)=softmax(QKdk+M)V\operatorname{Attention}(Q,K,V) =\operatorname{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}+M\right)V

QKV 的计算形式没有因为 BERT 或 GPT 而改变。矩阵 M 决定哪些 query–key 组合可见:合法位置加 0,被屏蔽的位置加 -\infty;softmax 后,后者的注意力权重变成 0。

以“他去银行取钱”为例,计算“银行”这个位置的表示时:

  • BERT 可以同时读取“他、去、银行、取、钱”,因此右侧的“取钱”能立即帮助确定这里的“银行”是金融机构;
  • GPT 在“银行”位置只能读取“他、去、银行”,不能提前读取还没有出现的“取、钱”。

BERT 双向注意力与 GPT 因果注意力的可见性矩阵

这不表示 GPT 永远得不到右侧信息。模型计算到“钱”时,该位置的 hidden state 已经能汇集此前的“他去银行取钱”。区别在于:BERT 的每个位置都拥有整段输入的双向表示;GPT 的第 ii 个位置只拥有长度为 ii 的前缀表示。

causal attention 也不表示 GPT 训练时必须真的一个 token 一个 token 地运行网络。训练语料的整段文本已经存在,所有位置可以组成一个下三角 attention 矩阵,一次并行计算,再分别与右移后的真实 token 计算 loss。只有推理时未来 token 尚不存在,生成才产生严格的时间依赖。

Padding mask 是另一件事。它用于阻止模型读取为了凑 batch 长度而填入的 padding;BERT 会使用它,GPT 在使用 padding 组成 batch 时也会同时使用 padding mask 和 causal mask。

两种 attention 为什么配上两种训练目标#

attention mask 是模型允许怎样传递信息,预训练目标是模型要利用这些信息预测什么。它们是两个设计维度,不是同一个概念,但 BERT 与 GPT 分别选择了非常自然的搭配。

BERT 的 MLM 与 GPT 的 next-token prediction

BERT:破坏一部分输入,再把它恢复出来#

如果双向模型直接用完整句子预测每个原 token,目标 token 本身已经在输入里,网络复制答案即可。BERT 因此随机选取 15% 的 WordPiece token 作为预测位置,并做如下处理:

  • 80% 替换为 [MASK]
  • 10% 替换为随机 token;
  • 10% 保持原 token 不变。

模型只在这 15% 的选中位置计算 MLM loss。后两种处理用于减轻预训练与微调的不一致,因为 [MASK] 在正常下游输入里不会出现。

原始 BERT 还训练 Next Sentence Prediction(NSP):给定两个文本片段,判断第二段是否真的是第一段的后继。NSP 是原始 BERT 的具体选择,不是 Encoder-Only 的定义。RoBERTa 后来移除了 NSP,仍然属于双向 Encoder 预训练路线。

GPT:真实文本整体右移一位#

GPT 在每个位置根据真实前缀预测后继 token。对“我喜欢自然语言处理”,训练对可以理解为:

输入:我 喜欢 自然 语言
目标:喜欢 自然 语言 处理

训练时每个位置都使用语料中的真实前缀,即 teacher forcing。四个预测位置仍然可以并行计算;生成时则没有真实的“处理”可供使用,必须先生成它,再继续预测下一个 token。

两种目标得到的监督密度也不同。GPT 几乎在序列每个位置计算 next-token loss;原始 BERT 只在选中的 15% 位置计算 MLM loss,但每次预测可以利用目标两侧的上下文。不能只凭这一点断言谁更高效,因为模型会受到训练 token 数、mask 策略、batch、优化方法和下游评测的共同影响。

模型输出究竟是什么#

BERT 的输入表示由三部分相加:

input embedding=token embedding+position embedding+segment embedding\text{input embedding} =\text{token embedding} +\text{position embedding} +\text{segment embedding}

序列开头放置 [CLS],句子或片段之间用 [SEP] 分隔,segment embedding 标识 token 属于片段 A 还是 B。最后一层会为每个输入位置产生一个双向 hidden state:

  • [CLS] 的表示常接分类 head,完成情感分类、自然语言推断等序列级任务;
  • 每个 token 的表示可接 token classification head,完成命名实体识别;
  • 两个 head 可以分别预测答案起点和终点,完成抽取式问答。

这些 special token 和 segment embedding 是原始 BERT 的输入设计,不是所有 Encoder-Only 模型必须具有的结构。

GPT 同样为每个位置产生 hidden state,只是其中只包含前缀信息。Language-model head 将 hidden state 投影到词表 logits,softmax 后得到下一个 token 的分布。选择一个 token、追加到序列、再次预测,就构成自回归生成。

所以“GPT 没有 Encoder”不等于“GPT 不编码输入”。它当然会把 prompt 变成逐层更新的 contextual hidden states;它缺少的是一个独立、双向、先完成整段输入编码的 Encoder 模块。

两种结构分别适合哪些任务#

“BERT 负责理解,GPT 负责生成”适合作为第一层直觉,却不能当作能力边界。固定标签也能写成文本让 GPT 生成,Encoder 也能通过反复 masking 或增加特殊解码结构生成内容。更稳定的判断标准是:任务需要什么形态的输出,以及这种输出能否直接匹配模型的训练接口。

同一个情感分类任务在 BERT 与 GPT 中的不同接口

任务输出形态更自然的结构原因
情感、主题、意图分类固定标签Encoder-Only整段输入一次编码,直接计算标签 logits
自然语言推断、句对匹配固定标签或分数Encoder-Only两段输入可双向交互后统一打分
命名实体、词性标注每个 token 一个标签Encoder-Only每个位置都需要左右上下文
抽取式问答原文中的起止位置Encoder-Only一次为所有候选位置打分
Rerankingquery–document 分数Encoder-Only完整句对交互后直接输出相关性
Embedding、语义检索定长向量专门训练的 Encoder一次前向得到向量,便于离线建库
续写、长答案、对话可变长度文本Decoder-Onlynext-token 接口直接对应开放输出
代码生成、结构化输出可变长度 token 序列Decoder-Only语法与上下文可统一为序列建模
Zero/Few-shot 跨任务prompt 后的文本Decoder-Only说明、示例与答案都能放进同一序列
翻译、摘要、改写以输入为条件的新序列Encoder–Decoder 或 Decoder-Only需要读取输入并生成不同长度的输出

表中的“更自然”不是“只有它能做”。

Decoder-Only 可以生成“正面”来完成情感分类,但它需要至少一次解码,可能输出额外解释、拼写变体或不合格式的内容。在大量固定标签请求中,一个较小的专用 Encoder 往往更快、更稳定,也更容易校准。

Encoder-Only 可以通过迭代填 mask 生成句子,但它没有天然的可变长、从左向右输出接口。每次该填哪些位置、何时停止,都需要额外机制。

Embedding 也需要一个限定:原始 BERT 的 [CLS] 并不是无需训练就能用于所有语义检索任务的理想向量。实际系统通常使用对比学习、蒸馏或检索目标训练过的 Encoder。

模型规模同样会改变结论。一个经过大规模预训练和指令微调的 Decoder-Only 模型可能在分类上胜过很小的 BERT;这不能说明生成标签的接口在计算上更合适,只说明架构之外的数据、规模与后训练也很重要。

训练并行,生成串行#

BERT 面对已经给定的输入,通常一次前向传播就能得到全部位置的表示及最终预测。

GPT 推理分成两个计算形态:

  1. Prefill:prompt 已经全部给定,可以并行计算各位置,并产生每层的 key/value;
  2. Decode:第 t+1t+1 个 token 必须等待第 tt 个 token 被选定,只能逐步生成。

Decode 阶段通常使用 KV cache 保存历史 key/value,避免每生成一个 token 就重新计算整个前缀。它减少了重复计算,却没有消除 token 之间的时间依赖。

因此,准确说法是“因果模型训练可并行、prompt prefill 可并行、生成必须串行”,而不是“GPT 所有时候都一次只算一个 token”。

也不能据此直接断言 BERT 一定更快。BERT 与 GPT 是架构类别,不代表固定参数量;一个 3 亿参数 Encoder 与一个数百亿参数 Decoder 没有直接比较延迟的意义。只有在模型规模、硬件、序列长度和任务相近时,输出接口带来的差异才适合单独分析。

为什么通用大模型更多选择 Decoder-Only#

BERT 迅速占领了固定下游任务,Decoder-Only 最终却成为通用生成模型的主流路线,原因并不是 causal attention 天生“更智能”,而是它提供了一个极其统一、易于扩展的接口。

训练目标简单而普遍#

next-token prediction 可以直接使用连续文本,不需要人工标注,也不需要预先决定未来模型会被用来做分类、翻译还是编程。网页中自然存在的问题与答案、代码与注释、概念与解释、不同语言之间的对应关系,都可能成为模型为了预测后文而学习的模式。

所有任务都可以序列化#

指令、示例、输入、推理过程、答案和工具调用记录都可以表示成 token。只要任务能写成:

上下文 + 任务说明 + 若干示例 + 当前输入 → 后续文本

同一个 language-model head 就能尝试处理它,不需要为每种任务替换输出层。这个特点自然支持 prompting 与 in-context learning。

开放输出覆盖面更广#

分类只是生成一个 token 或几个 token 的特殊情形,而对话、代码和文章无法轻易压缩成固定标签。以生成作为统一接口,覆盖的输出空间更大,适合构建面向未知任务的通用系统。

不过,基础语言模型只学习“什么文字最可能接在后面”,不等于理解用户希望它做什么。网页中可能有回答问题,也可能有反问、跑题和有害内容。监督式指令微调让模型学习“指令—理想回答”的形式,RLHF 等方法再根据人类偏好调整行为。Decoder-Only 提供了生成底座,后训练才把它变成更可靠的助手。

双向 Encoder 并没有因此失去价值。分类、检索、reranking、embedding、内容审核和 token 标注仍然大量存在;当任务明确、吞吐重要、输出空间固定时,专用 Encoder 经常比通用生成模型更合适。

不只有二选一:Encoder–Decoder#

BERT 与 GPT 的对比容易造成一种错觉:Transformer 只能在 Encoder-Only 与 Decoder-Only 之间二选一。原始 Transformer 本身就是第三种路线。

Encoder–Decoder 模型先让 Encoder 双向读取输入,再让 Decoder 通过 cross-attention 读取 Encoder 表示并因果生成输出。T5、BART 等模型延续了这种结构,尤其适合“给定一段输入,生成另一段输出”的 seq2seq 任务:

  • 翻译:源语言与目标语言是两条不同序列;
  • 摘要:完整读取长文后生成更短的新文本;
  • 改写与纠错:保留输入语义,但生成不同的表面形式。

它不是 BERT 和 GPT 的简单折中。Encoder 与 Decoder 分工明确:输入侧可以充分使用双向上下文,输出侧保留自回归生成,cross-attention 则把二者连接起来。Decoder-Only 也能把输入和输出拼接成一条序列完成这些任务,工程上该选哪种结构还取决于 checkpoint、规模、推理框架与部署成本。

应该记住的三件事#

第一,BERT 与 GPT 的结构分界线是信息可见范围。BERT 的每个位置读取完整输入,GPT 的每个位置只能读取当前及左侧前缀。

第二,架构与预训练目标相关但不等价。BERT 用双向 attention 配合 MLM,GPT 用 causal attention 配合 next-token prediction;mask 决定能看什么,loss 决定要学会预测什么。

第三,架构塑造的是任务偏好与推理接口,不是智能的硬边界。BERT 更自然地输出标签、位置和向量;GPT 更自然地输出可变长度文本。现代助手的能力还来自训练数据、模型规模、in-context learning、指令微调与对齐。

判断一个模型为什么适合某项任务,可以依次问三个问题:

  1. 目标位置能够看到哪些 token?
  2. 预训练 loss 让模型预测什么?
  3. 推理时需要一次得到固定结果,还是逐步生成未知长度的序列?

“BERT 理解、GPT 生成”只是这三个问题压缩后的入门结论。

参考#

  • Vaswani et al. Attention Is All You Need. NeurIPS 2017. arXiv:1706.03762
  • Radford et al. Improving Language Understanding by Generative Pre-Training. 2018. 论文 PDF
  • Devlin et al. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL 2019. ACL Anthology
  • Liu et al. RoBERTa: A Robustly Optimized BERT Pretraining Approach. 2019. arXiv:1907.11692
  • Radford et al. Language Models are Unsupervised Multitask Learners. 2019. 论文 PDF
  • Brown et al. Language Models are Few-Shot Learners. NeurIPS 2020. arXiv:2005.14165
  • Ouyang et al. Training Language Models to Follow Instructions with Human Feedback. NeurIPS 2022. arXiv:2203.02155
  • Artetxe et al. On the Role of Bidirectionality in Language Model Pre-Training. EMNLP 2022. arXiv:2205.11726
  • Raffel et al. Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer. JMLR 2020. 论文页面
  • Lewis et al. BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension. ACL 2020. ACL Anthology
BERT和GPT
https://blog.gzher.com/posts/paper-bert-vs-gpt/
作者
中会 / ChatGPT 5.6 Sol
发布于
2026-07-19
许可协议
CC BY-NC-SA 4.0