共计 2859 个字符,预计需要花费 8 分钟才能阅读完成。
从 Transformer 到 BERT 的技术演进
2017 年,Transformer 架构的提出彻底改变了自然语言处理领域的发展轨迹。其核心创新在于完全基于自注意力机制(Self-Attention)构建的 Encoder-Decoder 结构,摆脱了传统 RNN 的序列依赖性限制。这种设计带来了两个革命性优势:

- 并行计算能力大幅提升训练效率
- 长距离依赖捕捉能力显著增强
2018 年诞生的 BERT(Bidirectional Encoder Representations from Transformers)则在 Transformer 的 Encoder 部分进行了三大关键创新:
- 双向上下文建模:通过掩码语言模型(MLM)突破传统语言模型的单向限制
- 句子级关系学习:引入下一句预测(NSP)任务
- 深度预训练 + 微调范式:首次证明大规模预训练模型的迁移学习价值
核心架构对比
1. 结构差异
- Transformer
- 完整 Encoder-Decoder 结构
- Encoder 处理输入序列,Decoder 生成输出序列
-
典型应用:机器翻译、文本摘要等生成任务
-
BERT
- 仅保留 Transformer 的 Encoder 部分
- 通过堆叠多层 Transformer Block 构建深度模型
- 典型应用:文本分类、实体识别等理解任务
2. 训练目标对比
- Transformer 标准训练
- 采用 teacher-forcing 方式训练语言模型
- 损失函数:交叉熵(Cross-Entropy)
-
数学表达:$\mathcal{L}{LM} = -\sum)$}^T \log p(x_t|x_{<t
-
BERT 预训练目标
- 掩码语言模型(MLM):随机掩盖 15% 的 token 进行预测
- 下一句预测(NSP):判断两个句子是否连续
- 联合优化:$\mathcal{L}{BERT} = \mathcal{L}$} + \mathcal{L}_{NSP
3. 注意力机制实现差异
| 特性 | Transformer | BERT |
|---|---|---|
| 注意力头数 | 通常 8 头 | 通常 12/16 头 |
| 注意力范围 | 全局注意力 | 全局注意力 |
| 位置编码 | 正弦函数 | 可学习的位置嵌入 |
| 注意力掩码 | 解码器因果掩码 | 全可见注意力(无因果限制) |
实践代码示例
Transformer 实现 Seq2Seq(PyTorch)
import torch
import torch.nn as nn
from transformers import Transformer
# 定义模型参数
embed_size = 512
nhead = 8
num_layers = 6
model = Transformer(
d_model=embed_size,
nhead=nhead,
num_encoder_layers=num_layers,
num_decoder_layers=num_layers
)
# 模拟输入数据
# src: [batch_size, src_len, embed_size]
# tgt: [batch_size, tgt_len, embed_size]
src = torch.rand(32, 20, embed_size) # 批大小 32,源序列长度 20
tgt = torch.rand(32, 15, embed_size) # 批大小 32,目标序列长度 15
# 前向传播
output = model(src, tgt) # [32, 15, 512]
BERT 文本分类(HuggingFace)
from transformers import BertTokenizer, BertForSequenceClassification
import torch
# 加载预训练模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 文本预处理
text = "This is a positive sentence."
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
# inputs: {'input_ids': tensor(...), 'attention_mask': tensor(...)}
# 模型预测
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits # [1, 2]
性能分析与优化
计算复杂度对比
- Transformer 复杂度:$O(L^2 \cdot d)$
- L: 序列长度, d: 嵌入维度
- BERT 复杂度:$O(N \cdot L^2 \cdot d)$
- N: Transformer 层数(通常 12/24 层)
显存优化技巧
- 梯度检查点(Gradient Checkpointing)
model.gradient_checkpointing_enable() - 混合精度训练
scaler = torch.cuda.amp.GradScaler() with torch.cuda.amp.autocast(): outputs = model(**inputs) - 动态 padding 与批处理
from transformers import DataCollatorWithPadding collator = DataCollatorWithPadding(tokenizer, padding='longest')
常见问题与解决方案
预训练模型选择误区
- 误区 1:盲目选择最大模型
-
解决方案:根据任务复杂度选择模型尺寸
- Base 版(110M 参数)适合大多数分类任务
- Large 版(340M 参数)适合复杂理解任务
-
误区 2:忽略领域适配
- 医疗 / 法律等专业领域应使用领域预训练模型
- 如 BioBERT、LegalBERT 等
长文本处理技巧
- 位置编码扩展
- 原生 BERT 最大支持 512token
-
解决方案:
- 使用 Longformer 等改进架构
- 采用段落分割 + 聚合策略
-
注意力优化
from transformers import BertConfig config = BertConfig.from_pretrained("bert-base-uncased", attention_window=128) model = BertModel(config)
小样本过拟合应对
- 分层学习率
optimizer = AdamW([{'params': model.bert.parameters(), 'lr': 2e-5}, {'params': model.classifier.parameters(), 'lr': 1e-4} ]) - 数据增强
- 同义词替换
- 回译增强
- EDA(Easy Data Augmentation)
延伸思考问题
-
为什么 BERT 的 MLM 训练目标使其不适合直接用于文本生成任务?能否通过调整注意力机制实现生成功能?
-
如果要将 Transformer 改造为双向编码结构,需要修改哪些关键组件?这种改造会带来哪些计算代价?
-
在计算资源受限的场景下,如何设计实验流程来快速验证 BERT 与 Transformer 哪个更适合当前任务?
正文完
发表至: 人工智能
近一天内
