共计 2165 个字符,预计需要花费 6 分钟才能阅读完成。
1. BERT 模型概述与 NLP 重要性
BERT(Bidirectional Encoder Representations from Transformers)是 2018 年由 Google 提出的预训练语言模型,彻底改变了 NLP 任务的解决范式。其核心突破在于:

- 双向上下文建模:通过 Transformer 架构同时捕获左右两侧的上下文信息
- 预训练 + 微调范式:先在大规模语料上预训练通用语言表示,再针对下游任务微调
- 统一框架:在 11 项 NLP 任务上刷新 SOTA,包括文本分类、问答、NER 等
2. Transformer 架构与自注意力机制
BERT 的基础是 Transformer 的 Encoder 堆叠,其核心是自注意力机制(Self-Attention):
[\text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V ]
- 多头注意力实现:
- 将 Q /K/ V 拆分为 $h$ 个头并行计算
- 每个头的维度为 $d_{model}/h$
-
最终拼接所有头的结果
-
位置编码公式:
[PE_{(pos,2i)} = \sin(pos/10000^{2i/d_{model}}}) ]
[PE_{(pos,2i+1)} = \cos(pos/10000^{2i/d_{model}}}) ]
3. BERT 预训练任务公式解析
3.1 掩码语言模型(MLM)
随机掩盖 15% 的 token,预测被掩盖的词:
[P(w_i|w_{1..i-1},w_{i+1..n}) = \text{softmax}(W_oh_i + b_o) ]
- 80% 替换为[MASK]
- 10% 随机替换
- 10% 保持不变
3.2 下一句预测(NSP)
判断句子 B 是否是 A 的下一句:
[P(is_next|A,B) = \sigma(w^T[CLS] + b) ]
[CLS]位置输出用于二分类
4. PyTorch 实现关键组件
import torch
import torch.nn as nn
class BertSelfAttention(nn.Module):
def __init__(self, config):
super().__init__()
self.num_heads = config.num_attention_heads
self.head_dim = config.hidden_size // config.num_attention_heads
self.query = nn.Linear(config.hidden_size, config.hidden_size)
self.key = nn.Linear(config.hidden_size, config.hidden_size)
self.value = nn.Linear(config.hidden_size, config.hidden_size)
def forward(self, hidden_states):
batch_size = hidden_states.size(0)
# 线性投影
q = self.query(hidden_states)
k = self.key(hidden_states)
v = self.value(hidden_states)
# 多头拆分
q = q.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2)
k = k.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2)
v = v.view(batch_size, -1, self.num_heads, self.head_dim).transpose(1,2)
# 注意力得分
scores = torch.matmul(q, k.transpose(-1,-2)) / math.sqrt(self.head_dim)
attn_weights = nn.functional.softmax(scores, dim=-1)
# 上下文向量
context = torch.matmul(attn_weights, v)
context = context.transpose(1,2).contiguous()
return context.view(batch_size, -1, self.num_heads * self.head_dim)
5. 性能优化技巧
5.1 预训练阶段
- 梯度累积:解决显存不足问题
- 混合精度训练:FP16 节省显存
- 动态掩码:每次 epoch 重新生成掩码
5.2 微调阶段
- 分层学习率:底层参数使用较小 lr
- 早停机制:监控验证集性能
- 知识蒸馏:用大模型指导小模型
6. 常见问题与解决方案
- OOM 错误
- 减小 batch_size
- 使用梯度检查点
-
尝试模型并行
-
训练不稳定
- 适当增大 warmup 步数
- 添加梯度裁剪
-
检查数据清洗
-
下游任务效果差
- 调整学习率调度
- 尝试不同的 [CLS] 池化方式
- 增加领域适应预训练
延伸学习建议
- 精读原始论文《BERT: Pre-training of Deep Bidirectional Transformers》
- 研究 HuggingFace Transformers 库实现
- 尝试在 Colab 上复现预训练流程
- 参与 GLUE 基准测试实践
通过深入理解 BERT 的数学原理和实现细节,开发者可以更高效地将其应用于实际业务场景,并根据需求进行定制化改进。
正文完
发表至: 人工智能
近一天内
