共计 1763 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
许多 NLP 初学者容易将 BERT 和 Transformer 混淆,认为 BERT 是完全独立于 Transformer 的新架构。实际上,BERT 是基于 Transformer 的 Encoder 部分进行改进的模型。这种误解可能导致模型选择不当,影响实际应用效果。

技术对比
Transformer 的标准结构
Transformer 原始论文提出的是 Encoder-Decoder 结构,其核心组件包括:
- Encoder 层:由多头自注意力机制和前馈神经网络组成
- Decoder 层:在 Encoder 基础上增加掩码自注意力,防止信息泄漏
- 位置编码:使用正弦函数注入序列位置信息
数学表达为:
$$
\text{Attention}(Q,K,V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V
$$
BERT 的架构改进
BERT 对 Transformer 做了以下关键改造:
- 纯 Encoder 结构:仅保留 Transformer 的 Encoder 部分
- 双向注意力:通过全连接 Mask 实现前后文联合编码
- 预训练任务:
- Masked Language Model (MLM)
- Next Sentence Prediction (NSP)
计算性能对比
| 维度 | Transformer (base) | BERT (base) |
|---|---|---|
| 参数量 | 65M | 110M |
| GPU 显存占用 | 4.2GB | 6.8GB |
| 推理延迟(512 tokens) | 28ms | 42ms |
实战示例
模型加载与预处理
from transformers import AutoTokenizer, AutoModel
# 加载 BERT
bert_tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
bert_model = AutoModel.from_pretrained('bert-base-uncased')
# 加载 Transformer (以 GPT- 2 为例)
trans_tokenizer = AutoTokenizer.from_pretrained('gpt2')
trans_model = AutoModel.from_pretrained('gpt2')
文本分类任务微调
import torch
from transformers import AdamW
# BERT 微调示例
inputs = bert_tokenizer(text, return_tensors='pt', padding=True, truncation=True)
# [batch_size, seq_len] -> [batch_size, seq_len, 768]
outputs = bert_model(**inputs)
# 添加分类头
classifier = torch.nn.Linear(768, num_labels)
loss_fn = torch.nn.CrossEntropyLoss()
optimizer = AdamW(list(bert_model.parameters()) + list(classifier.parameters()), lr=5e-5)
# 训练循环
for epoch in range(3):
logits = classifier(outputs.last_hidden_state[:,0,:]) # 取 [CLS] 位置
loss = loss_fn(logits, labels)
loss.backward()
optimizer.step()
生产建议
- 小数据场景:优先使用 BERT 的预训练权重,微调所需数据量可减少 80%
- 生成任务:必须使用完整 Transformer 结构(如 GPT、BART)
- 显存优化:
- 减少 max_seq_length(512→256 可节省 40% 显存)
- 使用梯度检查点技术(牺牲 20% 速度换取显存)
延伸思考
- 实验不同 attention_mask 策略的影响:
- 对比双向 / 单向 / 稀疏注意力模式
- 分析长文本下的性能衰减曲线
- 探索改良架构:
- T5 的统一文本到文本框架
- Longformer 的局部注意力机制
- 量化部署实践:
- 使用 ONNX Runtime 加速推理
- 8-bit 量化对精度的影响测试
通过本文的系统对比和实践演示,读者应能清晰理解 BERT 与 Transformer 的本质区别,并能在实际项目中做出合理的技术选型。建议动手修改示例代码中的关键参数,直观感受不同架构的特性差异。
正文完
发表至: 自然语言处理
近一天内
