共计 1987 个字符,预计需要花费 5 分钟才能阅读完成。
原生 BERT 预训练(Pretraining)使用通用语料(如 Wikipedia)学习语言通用特征,而领域继续预训练(Continue Pretraining)则针对特定领域数据(如医疗 / 法律文本)优化模型表征。两者的核心差异在于:1)训练数据分布不同;2)目标任务侧重点不同(通用语义 vs 领域特性);3)模型初始化状态不同(随机初始化 vs 加载预训练权重)。

领域继续预训练的三大痛点
- 领域数据稀缺 :专业领域标注数据获取成本高,且公开语料库规模有限
- 训练不稳定 :小学习率导致收敛慢,大学习率易引发梯度爆炸
- 评估指标选择 :传统 GLUE 基准无法反映领域特性,需设计领域专属评估集
技术实现全流程
数据预处理
import re
from bs4 import BeautifulSoup
def clean_domain_text(raw_text):
# 移除 HTML 标签
clean_text = BeautifulSoup(raw_text, 'html.parser').get_text()
# 保留领域特定符号(如医学文献中的 DOI 编号)doi_pattern = r'\b10\.\d{4,}[^\s]*'
# 标准化连续空格
clean_text = re.sub(r'\s+', ' ',
re.sub(f'({doi_pattern})|[^\w\s.]',
lambda m: m.group(1) if m.group(1) else ' ',
clean_text))
return clean_text.strip()
继续预训练核心代码
import pytorch_lightning as pl
from transformers import BertForMaskedLM, BertTokenizer
class DomainBert(pl.LightningModule):
def __init__(self, model_name='bert-base-uncased'):
super().__init__()
self.model = BertForMaskedLM.from_pretrained(model_name)
self.tokenizer = BertTokenizer.from_pretrained(model_name)
def training_step(self, batch, batch_idx):
inputs = {'input_ids': batch['input_ids'],
'attention_mask': batch['attention_mask'],
'labels': batch['labels']
}
outputs = self.model(**inputs)
loss = outputs.loss
self.log('train_loss', loss, prog_bar=True)
return loss
def configure_optimizers(self):
optimizer = torch.optim.AdamW(self.parameters(),
lr=5e-5, # 比原始预训练小 5 -10 倍
weight_decay=0.01)
return {
'optimizer': optimizer,
'lr_scheduler': {
'scheduler': get_cosine_schedule_with_warmup(
optimizer,
num_warmup_steps=1000, # 关键参数
num_training_steps=self.trainer.estimated_stepping_batches),
'interval': 'step'
}
}
显存优化方案
- 混合精度训练 :启用 PyTorch 自动混合精度(AMP)
trainer = pl.Trainer(accelerator='gpu', precision=16) - 梯度累积 :通过累积多个 batch 的梯度模拟更大 batch size
trainer = pl.Trainer(accumulate_grad_batches=4)
性能对比数据
| 模型类型 | 领域 F1-score | 训练耗时(小时 /epoch) | GPU 显存占用(GB) |
|---|---|---|---|
| BERT-base | 78.2 | – | – |
| + 领域继续预训练 | 85.7 (+7.5) | 2.3 | 11.2 |
关键避坑指南
- 学习率 warmup:建议设置 500-2000 步线性 warmup,避免初期梯度震荡
- 词表扩展 :新增领域 token 数不超过原词表 10%,需重新初始化 embedding 层
- 早停策略 :监控验证集 perplexity(PPL)而非 loss,当连续 3 次不下降时终止
开放性思考题
- 如何区分领域适配(Domain Adaptation)与过拟合(Overfitting)的边界?
- 当领域数据不足 1 万条时,哪些策略能提升继续预训练效果?
(注:所有实验数据基于 NVIDIA V100 32GB 显卡测试,实际表现可能因硬件差异略有不同)
正文完
