在前面的文章中,我们已经讲过 Transformer 的整体结构、Self-Attention 的计算过程,以及 GPT 为什么选择 Transformer Decoder。我们知道,原始 Transformer 由 Encoder 和 Decoder 两部分组成:

输入序列
  ↓
Encoder
  ↓
Encoder 输出表示
  ↓
Decoder
  ↓
输出序列

在机器翻译任务中,Encoder 负责理解源语言句子,Decoder 负责根据 Encoder 的输出逐步生成目标语言句子。但是后来,Transformer 被拆分成了不同路线:

Encoder-only
Decoder-only
Encoder-Decoder

其中:

BERT 使用 Encoder-only
GPT 使用 Decoder-only
T5 / BART 使用 Encoder-Decoder

下一篇我们解释 GPT 为什么使用 Decoder。GPT 的目标是生成文本,因此它需要从左到右预测下一个 token,不能提前看到未来 token。

现在我们来看另外一个问题:

BERT 为什么使用 Encoder,而不是 Decoder?

这个问题非常重要。因为 BERT 代表的是另一条非常重要的预训练语言模型路线:理解式预训练路线。如果说 GPT 更关注“如何生成文本”,那么 BERT 更关注:

如何充分理解一段文本,并为每个 token 生成融合上下文的表示?

本文我们重点解释:

1. Transformer Encoder 的结构是什么?
2. Encoder 和 Decoder 的根本区别是什么?
3. 为什么 Encoder 更适合理解任务?
4. BERT 为什么选择 Encoder-only 架构?
5. BERT 如何利用双向上下文?
6. Encoder 输出如何用于分类、问答和序列标注?
7. Encoder 的局限性是什么?

一、先回顾 Transformer 的三种结构

Transformer 原论文提出的是 Encoder-Decoder 架构。这种结构最早主要服务于机器翻译。

例如:

英文句子:I love machine learning.
  ↓
Encoder 编码英文句子
  ↓
Decoder 生成中文句子
  ↓
中文句子:我喜欢机器学习。

在这个过程中:

Encoder 负责理解输入
Decoder 负责生成输出

后来,研究者发现 Transformer 的 Encoder 和 Decoder 可以单独拿出来使用。于是形成了三种常见结构:

架构类型 代表模型 核心特点 典型任务
Encoder-only BERT、RoBERTa、ALBERT 双向理解 分类、匹配、抽取、检索
Decoder-only GPT、LLaMA、Qwen、DeepSeek 自回归生成 对话、写作、代码、推理
Encoder-Decoder T5、BART、原始 Transformer 输入理解 + 输出生成 翻译、摘要、文本改写

这三种结构的根本区别在于:

模型在处理当前位置时,能看到哪些 token,以及训练目标是什么。

Encoder 可以同时看到左右上下文。

Decoder 只能看到当前位置之前的上下文。

Encoder-Decoder 则是 Encoder 先理解输入,Decoder 再根据输入逐步生成输出。


二、Transformer Encoder 的基本结构

一个标准 Transformer Encoder Layer 主要包含两个子层:

1. Multi-Head Self-Attention
2. Position-wise Feed Forward Network

每个子层外面都有:

Residual Connection
LayerNorm
Dropout

整体结构可以写成:

输入 x
  ↓
Multi-Head Self-Attention
  ↓
Add & Norm
  ↓
Feed Forward Network
  ↓
Add & Norm
  ↓
输出 x

如果堆叠多个 Encoder Layer,就得到完整的 Transformer Encoder:

Token Embedding
  ↓
Position Embedding
  ↓
Encoder Layer × N
  ↓
上下文表示

在 BERT 中,模型主体就是多层 Transformer Encoder。BERT-Base 使用 12 层 Encoder,BERT-Large 使用 24 层 Encoder。


三、Encoder 中的 Self-Attention 是双向的

Encoder 的核心特点是:

每个 token 可以同时关注自己、左边 token 和右边 token。

例如句子:

我 今天 去 学校 上课

在 Encoder 中,当模型更新“学校”这个 token 的表示时,它可以关注:

左边:我、今天、去
自己:学校
右边:上课

 

对于 Encoder 来说,只要不是 padding token,当前位置通常可以关注整个句子中的所有 token。这和 GPT 的 Decoder 不同。

GPT 的 Decoder 使用 Causal Mask:

第 1 个 token 只能看第 1 个 token
第 2 个 token 只能看第 1、2 个 token
第 3 个 token 只能看第 1、2、3 个 token

而 Encoder 不需要 Causal Mask。Encoder 的可见关系更像这样:

第 1 个 token 可以看所有 token
第 2 个 token 可以看所有 token
第 3 个 token 可以看所有 token
...

这就是 Encoder 的双向上下文建模能力。


四、为什么双向上下文适合理解任务?

很多自然语言理解任务并不是从左到右生成文本,而是要求模型理解整句话或整段文本。

例如:

情感分类
自然语言推理
语义匹配
命名实体识别
阅读理解
文本检索

这些任务通常需要同时利用左右上下文。举个例子:

这个苹果很好吃。

这里的“苹果”表示水果。再看另一个句子:

这个苹果手机很好用。

这里的“苹果”表示 Apple 公司。如果模型只看左边:

这个苹果

它很难判断“苹果”到底是水果还是手机品牌。但如果模型可以同时看到右边:

很好吃
手机很好用

就更容易判断词义。再比如句子:

我今天去 [MASK] 上课。

如果只看左边:

我今天去

可能的答案很多:

学校
公司
图书馆
操场

但如果同时看到右边:

上课

模型就更容易预测:

学校
教室
培训班

这就是双向上下文的优势。所以,Encoder 更适合理解任务,因为理解任务通常要求模型综合利用完整输入,而不是只根据左侧上下文生成下一个 token。


五、BERT 为什么使用 Encoder-only?

BERT 的全称是:

Bidirectional Encoder Representations from Transformers

也就是:

来自 Transformer 的双向编码器表示

从名字就能看出来,BERT 的核心是:

Bidirectional
Encoder
Representations

BERT 使用 Encoder-only 架构,主要是因为它的目标不是生成文本,而是学习深层双向语言表示。

GPT 的目标是:

给定前文,预测下一个 token

所以 GPT 使用 Decoder。BERT 的目标是:

给定完整上下文,理解每个 token 的语义

所以 BERT 使用 Encoder。

对比一下:

模型 架构 可见上下文 训练目标 更适合
GPT Decoder-only 只能看左边 Next Token Prediction 生成任务
BERT Encoder-only 左右都能看 Masked Language Modeling 理解任务

BERT 不需要生成长文本,所以它不需要 Causal Mask。BERT 更需要充分理解输入,所以它使用可以双向建模的 Transformer Encoder。


六、Encoder 和 Decoder 的关键区别

Encoder 和 Decoder 都使用 Self-Attention,但它们的 Attention 约束不同。

1. Encoder Self-Attention

Encoder 中的 Self-Attention 是双向的。

例如输入:

x1 x2 x3 x4

每个 token 都可以看到所有 token:

x1 可以看 x1 x2 x3 x4
x2 可以看 x1 x2 x3 x4
x3 可以看 x1 x2 x3 x4
x4 可以看 x1 x2 x3 x4

注意力矩阵没有因果遮挡。

只需要屏蔽 padding 位置。

2. Decoder Self-Attention

Decoder 中的 Self-Attention 是单向的。

例如:

x1 x2 x3 x4

可见关系是:

x1 可以看 x1
x2 可以看 x1 x2
x3 可以看 x1 x2 x3
x4 可以看 x1 x2 x3 x4

右上角的未来 token 会被 Causal Mask 屏蔽。

3. Cross-Attention

原始 Transformer Decoder 还有一层 Encoder-Decoder Attention,也叫 Cross-Attention。

它的作用是:

Decoder 生成目标语言时,去关注 Encoder 对源语言的编码结果。

但 BERT 没有 Decoder,所以也没有 Cross-Attention。BERT 只保留 Encoder 部分:

Embedding
  ↓
Encoder Layer × N
  ↓
上下文表示

 


七、BERT 如何利用 Encoder 做预训练?

如果 Encoder 可以看到完整句子,那么有一个问题:

训练时如果让模型直接预测当前 token,它会不会直接看到答案?

例如输入:

我 今天 去 学校 上课

如果让模型预测“学校”,但“学校”本身就在输入中,那任务就没有意义了。所以 BERT 设计了 Masked Language Modeling,也就是 MLM。

MLM 的做法是:

随机遮住一部分 token
让模型根据左右上下文预测被遮住的 token

例如:

我 今天 去 [MASK] 上课

模型需要预测:

学校

 


八、BERT 为什么不使用 Decoder?

BERT 不使用 Decoder,主要有三个原因。

1. BERT 的目标不是生成文本

Decoder 更适合生成任务。例如:

写文章
写代码
对话
翻译生成
续写故事

这类任务需要模型从左到右逐步生成 token。但 BERT 的主要目标是理解输入文本。例如:

这句话表达什么情感?
两个句子是否语义相似?
文章中哪个片段能回答问题?
每个 token 是否是实体?

这些任务不需要模型逐 token 生成长文本,而是需要模型理解完整输入。所以 BERT 不需要 Decoder 的自回归生成能力。

2. Decoder 不能天然利用右侧上下文

Decoder 使用 Causal Mask,当前位置不能看到未来 token。这对生成任务是必要的。但对理解任务来说,右侧上下文非常重要。例如:

这个苹果手机很好用。

如果模型处理“苹果”时不能看右边的“手机”,理解就会受限。BERT 要学习双向表示,所以不适合使用带 causal mask 的 Decoder。

3. Encoder 输出更适合做表示学习

BERT 希望为输入文本生成上下文表示。这些表示可以用于各种下游任务:

句子级分类
句子对匹配
token 级标注
span 抽取
向量检索

Encoder 的输出天然适合做这些任务。所以 BERT 选择 Encoder-only,是由它的任务目标决定的。


九、Encoder 输出如何用于下游任务?

BERT 经过多层 Encoder 后,会输出每个 token 的上下文表示。不同任务会使用不同位置的输出。

1. 文本分类:使用 [CLS]

对于文本分类任务,通常使用 [CLS] 位置的输出表示。

输入:

[CLS] 这部电影非常精彩 [SEP]

经过 BERT 后得到:

h_CLS

然后接一个线性分类层。

例如情感分类:

positive
negative

2. 句子对任务:仍然使用 [CLS]

对于自然语言推理、语义相似度等任务,输入是两个句子:

[CLS] 句子 A [SEP] 句子 B [SEP]

BERT 会通过 Self-Attention 建模两个句子之间的关系。

最后仍然使用 [CLS] 表示进行分类。

例如自然语言推理任务要判断:

entailment
neutral
contradiction

3. 命名实体识别:使用每个 token 的输出

命名实体识别是 token-level 任务。

例如:

小明 在 北京 上学

模型需要给每个 token 预测标签:

小明:PERSON
北京:LOCATION

这时不能只用 [CLS],而是要使用每个 token 对应的隐藏状态:

[
h_1, h_2, \ldots, h_n
]

每个位置接一个分类层,预测该 token 的标签。

4. 阅读理解:预测答案起点和终点

在抽取式阅读理解中,输入通常是:

[CLS] 问题 [SEP] 文章 [SEP]

BERT 需要从文章中抽取一个答案片段。

它会为每个 token 预测两个概率:

作为答案起点的概率
作为答案终点的概率
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐