共计 2269 个字符,预计需要花费 6 分钟才能阅读完成。
背景痛点
在自然语言处理(NLP)领域,传统的 RNN/LSTM 模型长期占据主导地位,但它们存在一个致命缺陷:梯度消失问题。当处理长序列文本时,RNN 需要将信息一步步传递,而 LSTM 虽然通过门控机制有所缓解,但在超长文本(如超过 100 个词)中仍会丢失早期信息。例如:
- RNN 的梯度计算公式为 $\frac{\partial L}{\partial W} = \sum_{t=1}^T \frac{\partial L}{\partial y_T} \frac{\partial y_T}{\partial h_t} (\prod_{k=t}^{T-1} \frac{\partial h_{k+1}}{\partial h_k}) \frac{\partial h_t}{\partial W}$,当 $T$ 较大时连乘项会指数级缩小
- 传统词向量模型(如 Word2Vec)是静态的,无法解决一词多义问题(例如 ”bank” 在金融和河岸场景中的差异)
Transformer 架构解析
图:Transformer 的 Encoder-Decoder 结构
Transformer 通过完全摒弃循环结构,采用 Self-Attention 机制实现并行计算。其核心是三个矩阵:
- Query(查询向量):当前词需要获取的信息
- Key(键向量):其他词的标识特征
- Value(值向量):实际的特征表示
自注意力计算公式为:
$$\text{Attention}(Q,K,V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V$$
其中 $d_k$ 是向量的维度,缩放因子用于防止点积过大导致 softmax 饱和。
BERT 实战代码示例
import torch
from transformers import BertTokenizer, BertModel
# 初始化 tokenizer(特殊标记处理)tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
text = "[CLS] This is a classification example [SEP]"
tokens = tokenizer.tokenize(text) # 自动添加 [CLS] 和[SEP]
# 加载预训练模型
model = BertModel.from_pretrained('bert-base-uncased')
inputs = tokenizer(text, return_tensors="pt") # 自动转换为 PyTorch 张量
# 微调层实现
class BertClassifier(torch.nn.Module):
def __init__(self, dropout=0.1):
super().__init__()
self.bert = BertModel.from_pretrained('bert-base-uncased')
self.dropout = torch.nn.Dropout(dropout)
self.linear = torch.nn.Linear(768, 2) # 假设二分类
def forward(self, input_ids):
outputs = self.bert(input_ids)
pooled = outputs.last_hidden_state[:, 0] # 取 [CLS] 标记对应的向量
return self.linear(self.dropout(pooled))
优化实践技巧
- 长文本处理:
-
当文本超过 512token 时,可采用:
- 滑动窗口法(stride=128)
- 关键句抽取(如 TF-IDF 权重最高的句子)
-
学习率 warmup:
from transformers import get_linear_schedule_with_warmup scheduler = get_linear_schedule_with_warmup( optimizer, num_warmup_steps=100, # 前 100 步线性增长 num_training_steps=1000 ) -
混合精度训练:
from torch.cuda.amp import GradScaler scaler = GradScaler() with torch.cuda.amp.autocast(): loss = model(inputs).loss scaler.scale(loss).backward() scaler.step(optimizer)
常见问题避坑
- 显存管理:
- batch_size=32 时约需 16GB 显存
-
可通过
gradient_accumulation_steps=4模拟更大 batch -
中文处理:
- 需使用
bert-base-chinese版本 - 注意中文无需空格分词,直接输入连续文本
延伸思考
- 领域适应性评估:
- 使用困惑度 (Perplexity) 衡量语言模型拟合程度
-
检查专业术语的 embedding 相似度(如医学术语对)
-
BERT vs GPT 注意力差异:
- BERT 采用双向注意力(可看到前后文)
- GPT 使用单向掩码(只能看到左侧上下文)
# BERT 的 attention_mask [1, 1, 1, 1, 0, 0] # 0 表示 padding 部分 # GPT 的 attention_mask [1, 0, 0, 0, 0, 0] # 严格单向 [1, 1, 0, 0, 0, 0]
实践心得
通过这次从理论到实践的完整流程,最大的收获是理解了 Transformer 如何通过注意力机制实现全局信息捕捉。在实际微调时,学习率 warmup 和梯度裁剪能显著提升训练稳定性。建议初学者先从小规模数据集(如 IMDB 影评)开始实验,逐步掌握超参数调整的技巧。
正文完
发表至: 自然语言处理
近一天内
