Encoder-Only 推理流程
Encoder-only(如 BERT、RoBERTa、ELECTRA)与 Decoder-only 最大不同是:
- 没有自回归 Decode 阶段
- 整个输入序列一次并行计算
- 双向注意力(全局可见)
- CLS 位置经过训练自然演化成句子级别向量
- 普通 Token 位置经过训练自然演化成上下文词义向量
本文将从真实 Transformer 内部机制出发,完整拆解 Encoder-only 的推理全过程。
1. 输入与基础表示
1.1 输入序列设定
示例输入 token 序列:
[CLS], T1, T2, T3, T4
目标任务可能包括:
- 分类任务(使用 CLS)
- Masked LM 填空任务(预测被 [MASK] 的 token)
- 句子对任务(使用 segment embedding)
1.2 Embedding 组成
每个 token 都会先映射为:
h_i_pre = TokenEmb(i) + PosEmb(i) + SegmentEmb(i)
例如:
h_cls_pre = Emb(CLS) + Pos1
h1_pre = Emb(T1) + Pos2
h2_pre = Emb(T2) + Pos3
...
此时每个 token 之间没有“信息交流”,只是位置 + 词义的静态叠加。
2. 编码器总体架构说明
2.1 完全并行,无 Decode
所有 token 在 每一层同时 进行 Transformer 处理:
Layer1: 并行处理 [CLS, T1, T2, T3, T4]
Layer2: 并行处理 [CLS, T1, T2, T3, T4]
...
没有类似 GPT 的“逐 token”增长过程。
2.2 双向注意力 Mask
注意力 Mask 是全开放的:
CLS T1 T2 T3 T4
CLS ✔ ✔ ✔ ✔ ✔
T1 ✔ ✔ ✔ ✔ ✔
T2 ✔ ✔ ✔ ✔ ✔
T3 ✔ ✔ ✔ ✔ ✔
T4 ✔ ✔ ✔ ✔ ✔
每个 token 都能看见全序列。
CLS 也能看到所有 token。
2.3 多层堆叠的整体计算公式
对每一层:
h_i^{l+1} = LayerNorm( h_i^l + MHA(h_i^l) + FFN(h_i^l) )
多个相同结构重复堆叠形成深度编码器。
3. 单层 Transformer 的内部计算(完全具象)
以 第 1 层 的 CLS 与 T1 为例说明。
3.1 Step 1:线性投影生成 Q/K/V
Q_cls = h_cls_pre × W_Q
K_cls = h_cls_pre × W_K
V_cls = h_cls_pre × W_V
Q1 = h1_pre × W_Q
K1 = h1_pre × W_K
V1 = h1_pre × W_V
所有 token 都会生成自己的 Q/K/V。
3.2 Step 2:注意力得分计算(以 CLS 为例)
CLS 查询全体 token:
score(CLS→i) = Q_cls · K_i
得到:
αcls = softmax([Q_cls·K_cls, Q_cls·K1, Q_cls·K2, Q_cls·K3, Q_cls·K4])
3.3 Step 3:加权求和得到上下文融合向量
context_cls = Σ αcls_i * V_i
这就是第一层的“全局信息初步聚合”。
3.4 Step 4:FFN 非线性变换
ffn_cls = FFN(context_cls)
结构通常是:
Linear → GELU → Linear
3.5 Step 5:残差连接 + LayerNorm
完整更新:
h_cls_1 = LayerNorm(h_cls_pre + context_cls + ffn_cls)
同理:
h1_1 = LayerNorm(h1_pre + context_1 + ffn_1)
所有 token 都被更新为新的隐藏状态,为下一层输入。
4. 逐 Token 逐层的信息流
4.1 CLS 的注意力路径(为何成为“句子向量”)
每一层 CLS 都会:
访问所有 token → 聚合 → 再访问所有 token → 再聚合 → ...
经过 N 层后:
CLS_final = 全序列语义的深度压缩向量
关键不是结构特殊,而是:
分类任务通过反向传播要求 CLS 输出最能表示句子整体语义,
所以模型内部会“自发”让 CLS 学会汇聚全局信息。
4.2 普通 Token 的路径(为何代表该词的上下文含义)
Ti 的注意力是:
Ti → attend to all token → 得到属于自己的上下文语义向量
多层后:
Ti_final = 该词在上下文下的语义表示(masked LM 使用)
4.3 为什么二者自然分化为不同语义?
因为训练目标不同:
- 分类任务损失来自 CLS
- MLM 损失来自被 MASK 的位置
模型会自动学习:
- CLS 负责整个句子的含义
- 被 MASK 的位置负责还原词义
- 其它 token 保持上下文语义稳定
5. 多层堆叠后的语义形成机制(极其关键)
每一层的功能不是固定编码,而是训练后自然演化出来的角色。
5.1 第 1 层:局部词面语义
类似词袋 + 局部融合:
- CLS 初步聚合浅层词义
- 每个 Ti 捕捉临近词的关系
5.2 第 2 层:句法结构提炼
模型开始学习:
- 主谓宾关系
- 修饰结构
- 依存关系
5.3 第 3 层:长距离依存建模
注意力开始跨越句子:
- 主语与远处谓词
- 所有代词的指代关系
5.4 第 4~N 层:深层语义抽象
最终形成:
CLS_final = 整句语义
Ti_final = 每个词的上下文语义
6. 不同任务的推理路径(非常重要)
6.1 Masked LM(位置级任务)
6.1.1 获得 MASK 位置向量
假设 T3 被 MASK:
h3_final = Transformer_Layers([CLS,T1,T2,MASK,T4])
6.1.2 使用 LM Head 预测词表概率
logits = h3_final × W_vocab^T
P(token) = softmax(logits)
得出最可能的词。
6.2 文本分类(句子级任务)
6.2.1 获得 CLS_final
CLS_final = h_cls_N # N层后的CLS
6.2.2 分类头
logits = CLS_final × W_cls + b
P(label) = softmax(logits)
分类完全依赖 CLS_final 的全局语义。
7. Encoder-Only 信息流全景图(总览图)
Input → Embedding → Layer1 → Layer2 → ... → LayerN
↓
CLS_final ------------------→ Classification Head
↓
Ti_final --------------------→ MLM Head
注意:
- 没有 Decoder、没有 KV Cache、没有自回归过程
- 所有 token 并行更新,直到达到深层抽象
8. 最终总结(核心要点)
- Encoder-only 是纯并行计算,没有 decode 过程。
- 注意力是全局双向的,每个 token 看见整句。
- CLS 通过训练自动演化为“句子语义压缩向量”。
- 普通 token 通过训练演化为“上下文词义向量”。
- Masked LM 使用被 MASK 的位置向量进行词预测。
- 分类任务使用 CLS_final 经过分类头输出结果。
- 多层堆叠从浅层词义 → 句法结构 → 长依存 → 深语义。