
🧠 记忆锚点:遗忘是数据分布与更新过强共同造成;领域指标和通用回归必须一起看。
💡 答案要点
灾难性遗忘 = 微调后模型忘记了预训练时学到的通用知识
示例:
微调前:
Q: 首都北京在哪个国家?
A: 中国
微调后(用客服数据):
Q: 首都北京在哪个国家?
A: 抱歉,我只能回答产品相关问题
(忘记了通用知识)原因:
- 微调数据分布与预训练数据差异大
- 训练时间过长,学习率过高
- 数据量太小,过拟合
解决方案:
| 方法 | 说明 | 效果 |
|---|---|---|
| 混合通用数据 | 微调时混入预训练数据 | ⭐⭐⭐⭐⭐ |
| 降低学习率 | 使用更小的学习率 | ⭐⭐⭐⭐ |
| Early Stopping | 不要训练太久 | ⭐⭐⭐ |
| LoRA | 只更新部分参数 | ⭐⭐⭐⭐⭐ |
| 正则化 | L2/Dropout | ⭐⭐⭐ |
最佳实践:
1. 混合通用数据(推荐):
python
# 微调数据:领域数据 + 通用数据
dataset = {
"domain_data": 8000, # 80% 领域数据
"general_data": 2000, # 20% 通用数据
}
# 通用数据来源
- Wikipedia 摘要
- 常识问答
- 代码片段
- 数学题2. 学习率策略:
python
# 全量微调
learning_rate = 1e-5 # 比预训练小 10-100 倍
# LoRA 微调
learning_rate = 3e-4 # 可以稍大,因为只更新少量参数3. 使用 LoRA:
python
# LoRA 天然防止灾难性遗忘
# 原因:原始参数冻结,只训练小矩阵
# 即使 LoRA 过拟合,移除后模型恢复原状评估遗忘程度:
python
# 微调前后对比
tasks = [
"常识问答", # MMLU
"数学推理", # GSM8K
"代码生成", # HumanEval
]
for task in tasks:
score_before = evaluate(base_model, task)
score_after = evaluate(finetuned_model, task)
retention = score_after / score_before
print(f"{task} 保留率: {retention:.1%}")
# 合格线:保留率 > 95%面试话术:
"我在微调时混入 20% 的通用数据,学习率设为 1e-5,用 LoRA 代替全量微调。微调后在 MMLU 上的表现只下降了 2%,成功避免了灾难性遗忘。"