灾难性遗忘与数据混合(Catastrophic Forgetting & Data Mixing)
所属:01-fundamentals / 02-post-training
面试权重:★★★
来源:通用领域知识;未做一手考证
相关项目:Own — HKGAI LLM(训练语料中策略性混入约 10% 通用数据以锚住通用能力)、QueWI(Qwen2.5-4B SFT 做意图识别,典型的小数据窄任务场景)→ 见02-interview/projects/hkgai-llm.md
一句话#
灾难性遗忘是用窄分布数据继续训练时,新任务的梯度更新覆盖了基座原有的表征,导致通用能力退化;标准缓解手段是 replay / 数据混合(在微调语料里掺入通用数据),而工程上真正的难点不是「怎么缓解」,而是**「怎么知道它发生了」—— 必须同时盯住目标能力和通用能力两条曲线**。
为什么重要(面试角度)#
这是 SFT 一节的直接延伸,而且极其容易答得含糊。面试官想区分的是:
- 你会不会把「遗忘」与「过拟合」「chat template 不一致」混为一谈(这三者的症状相似、根因完全不同)。
- 你说的「加通用数据」是多少、为什么是这个数、加多了会怎样。
- 最关键:你怎么量化它。只会说「我们感觉模型变笨了」的候选人,和能说出「我们在 every-N-step 跑一套冻结的通用能力回归集,看两条曲线的发散点」的候选人,是两个层级。
你有 HKGAI 的实际数据配比经验,这个题必须能给出可执行的度量方案。
核心内容#
机制#
神经网络的微调是全局的权重更新:反向传播不会区分「哪些权重属于新任务、哪些属于旧能力」,它在所有被更新的参数上按梯度走。当新任务的数据分布很窄(少量、单领域、单格式)而步长(学习率 × 步数)足够大时,权重就会从预训练解移向一个只对窄任务有利的区域,原有的表征被覆盖。
几个理解的抓手:
- 稳定性—可塑性困境(stability–plasticity dilemma):模型既要在新任务上可塑,又要对旧能力稳定,这对目标是内在冲突的。微调本质是在这个谱上取点。
- 它是程度问题,不是二值事件。很少是「通用能力全崩」,更常见的是细粒度退化:多语言能力变弱、长文推理变差、拒绝回答的风格改变、少见领域的知识记错 —— 这些症状在粗粒度指标上看不出来。
- 触发条件:数据量小 + 分布窄 + epoch 多 + 学习率大 + 全参数微调。这五个因素中任意一个放大都会加重遗忘;这就是为什么「小数据集上的 SFT」最容易出事。
- 同一机制的其他名字:在偏好对齐阶段它表现为 alignment tax(对齐税);在推理模型上表现为主模型在其他 benchmark 上的回退。不要把它们当成不同的问题 —— 面试时点出这一层会显得理解更深。
「SFT 数据应拟合预训练分布」这条原则#
一个值得单独讲的工程原则:SFT 数据的分布应当尽量贴近预训练分布,而不是偏离它。
理由链条:
- 微调数据量相对预训练语料是极小的(可能差 4–6 个数量级)。数据越少,同样的分布偏移意味着越大的梯度步长、越少的约束。
- 如果微调数据的语言、领域、长度、文体都与预训练分布差异巨大,模型必须改写已有的知识表示去适配新格式 —— 这就是覆盖发生的路径。
- 分布贴近则相反:模型只需在既有表征上做小幅调整,「学会新格式」和「保住旧能力」之间的冲突变小。
实践中这条原则的落地形式:
- 保持与预训练接近的数据格式与文体(不要造出与预训练语料风格完全割裂的样本)。
- 保持长度分布合理(全体样本都是几千 token 的长回答,会扭曲模型的输出长度先验)。
- 保留通用数据作为分布锚点 —— 也就是下面的 replay。
- 不要为了格式统一而把所有样本都套上同一种模板 —— 模板一致性(训练与推理要对齐)和分布单一化(要避免)是两件事,容易混淆。
⚠️ 准确性的边界:这是一条经验性原则,不是定理。它的证伪点在于:有些能力(例如全新的输出格式、工具调用的特殊 token 结构)本来就不在预训练分布里,必须偏离才能学到。所以正确的说法是「在能达成目标的前提下尽量贴近」,而不是「必须贴合」。
Replay / 数据混合(Data Mixing)#
最有效、最常用的缓解手段:在微调语料里按比例掺入通用数据(general data),让梯度同时接受来自旧分布的约束。
- HKJC/HKGAI 的做法是混入约 10% 通用数据 —— 这是一个常见量级的经验值,不是普适常数。合适的比例取决于微调数据的规模、任务偏移程度和评测目标,只能在实测中定。
- 这是一个权衡,不是免费的:
- 通用数据会占用容量:目标任务的收敛会变慢,甚至目标指标略有下降。
- 掺得太多 → 目标能力学不扎实(相当于把微调稀释成了轻量的继续预训练)。
- 掺得太少 → 通用能力守不住。
- 所以它是在「目标能力」和「通用能力」之间的一条权衡曲线,选点是业务决策(公共服务场景通常更看重通用能力不退化)。
- 更细的做法:不是笼统地掺「通用数据」,而是按缺失的能力面定向掺(多语言、长上下文、特定领域 QA 各掺什么),并用评测的切片来验证每一项是否被守住。这比调一个总数更有效。
如何度量(本节是重点)#
结论先行:你需要一把「双尺」—— 目标能力评测和通用能力评测,跑在同一批 checkpoint 上,画在同一条横轴上。
1. 先有基线(baseline),再有结论。 在微调开始前的 checkpoint(即 SFT 的起点 / 基座)上跑同一套评测,得到参照线。没有这条线,孤立的一个分数什么也证明不了 —— 因为你不知道它「原来是」多少。这一步最常被跳过,也是判断力最容易失分的地方。
2. 通用能力评测集的六条设计准则。
| 准则 | 为什么 |
|---|---|
| 不在微调分布内 | 用微调数据的同分布测试集去测「有没有遗忘通用能力」是逻辑错误 |
| 冻结、永不出现在训练里 | 一旦被喂进训练(尤其是合成数据流水线生成的样本刚好撞上)就完全失效 |
| 覆盖多个能力切面 | 知识、推理、指令遵循、多语言、长上下文、代码 —— 单一大指标会掩盖退化 |
| 切片报告,不报聚合 | 聚合分数不变,可能意味着「外语崩了、数学涨了」互相抵消 |
| 够小够快、可重复 | 必须能在 every-N-step 上跑,否则你只在训练结束后才知道出事 |
| 格式与推理时的 chat template 一致 | 否则分数变化可能只是模板导致的,与遗忘无关(这是最常见的误诊) |
3. 画轨迹,不看点。
把「目标能力指标」和「通用能力指标」画在同一张图的同一横轴上(step 或 epoch):
↑ 指标
│ 目标能力 ────────────╱────
│ ╱
│ 通用能力 ────────╲
│ ╲
│ ╲________ ← 发散点:该在这里停 / 调配比
└──────────────────────────────────→ step- 两条曲线的发散点就是决策点:在那里提前停止、或提高通用数据比例、或降低学习率。
- 单点指标会骗你:训练 loss 一路下降、目标指标一路上升,通用能力在底下悄悄滑坡 —— 而你只看目标指标,是发现不了的。
- 护栏:给通用能力设一条「不得低于基线 X%」的硬阈值,触发即回滚。这比事后分析有用得多。
4. 用分布漂移作为代理指标(更早的预警)。 能力指标是滞后的(要在评测集上跑出结果才知道)。更灵敏的信号是输出分布本身的漂移:
- 在通用 prompt 集上,计算微调后模型与基座模型输出分布的 KL 散度(这是 RLHF 里 KL 惩罚监控的同一思路 —— 在 RL 里它是显式项,在 SFT 里没有人替你算,得自己加)。
- 观察输出侧的行为学症状:输出长度分布是否整体偏移、是否变模板化(开头句式高度重复)、是否出现语言混杂(中英夹杂比例异常)、是否对原本能答的问题开始拒答或答非所问、采样多样性(相同 prompt 多次采样的差异度)是否下降。
- 这些信号先于能力指标恶化出现,是最好用的早期报警器。
5. 必须排除的三个「假遗忘」。 症状相似、根因完全不同,如果误诊,你的缓解动作会全部打偏:
| 假象 | 特征 | 真正的根因 |
|---|---|---|
| Chat template 不一致 | 微调后全面变差,包括目标任务 | 训练与推理的特殊 token / role 标记 / 空格不一致 |
| 过拟合 | 训练集上极好、测试集全崩(包括目标任务的测试集) | 数据量小 + epoch 太多 |
| 评测方式变化 | 只有换了评测脚本/提示词之后才"变差" | 评测管线本身变了,模型没变 |
判据速记:遗忘是「目标能力升、通用能力降」;过拟合是「目标任务自己的测试集也降」;template 问题是「全部一起降」。三者的处置动作完全不同。
6. 污染校验(否则你什么也没测到)。
通用能力评测集如果被合成数据流水线污染(同一模板生成的变体切进了评测集),你会测出一个虚高的通用能力,进而误判「没有遗忘」。所以第 2 条里「冻结 + 不在分布内」不是形式要求,它决定了整套度量有没有意义(详见 data-engineering.md 的污染一节)。
7. 决策规则(把度量接进行动)。
| 观测 | 动作 |
|---|---|
| 目标能力升、通用能力稳 | 保持,继续跑 |
| 目标能力升、通用能力降 | 提高通用数据比例 / 降低 lr / 减少 epoch / 改 LoRA / 在发散点提前停止 |
| 目标能力不升、通用能力降 | 立即停:说明当前配比与步长都不对,先修数据再谈训练 |
| 全部指标都降 | 先查 chat template 与评测管线,不要先归因于遗忘 |
缓解手段清单(按代价从低到高)#
- 数据混合 / replay(最有效,代价是与目标能力的权衡)
- 降低学习率、减少 epoch、加早停(SFT 通常 2–3 epoch 以内,见
sft.md) - LoRA / PEFT:把更新限制在低秩子空间,天然限制了对原有权重的破坏 —— 但这是降低风险而不是消除风险,见
lora-peft.md - 对基座权重的显式正则:L2-SP 类方法、或对 reference 的 KL 约束(RLHF/DPO 里 KL 就是干这个的)
- 分层冻结:冻结底层/embedding,只训高层
- 事后模型合并(model merging):把微调模型与基座做权重插值/任务向量合并,用权重空间的平均挽回一部分通用能力。代价是需要额外的评测来选合并系数,且效果不稳定
- 只训真正需要变的部分:如果只是格式/风格问题,优先用 prompt 或 RAG 解决,不微调 —— 这是最被低估的一条
常见面试问法#
Q:SFT 之后模型变笨了,为什么? A:先别急着下结论,按顺序排除三个假象:chat template 是否与推理一致(症状是全面变差)、是否过拟合(症状是目标任务的测试集也降)、评测管线是否变了。如果排除后确实是「目标升、通用降」,那就是灾难性遗忘:窄分布数据 + 小数据 + 多 epoch + 大 lr 让梯度覆盖了基座表征。缓解见上(混通用数据、降 lr/epoch、LoRA、权重正则)。
Q:你怎么知道模型发生了灾难性遗忘? A:这是一个度量题,不是概念题。 关键是要有一把双尺:
① 在微调前的 checkpoint 上跑同一套评测建立基线;② 通用能力评测集必须冻结、不在训练分布内、覆盖多个能力切面、切片报告、格式与推理时一致;③ 把目标能力和通用能力画在同一横轴上,看轨迹不看单点,两条曲线的发散点就是决策点;④ 用输出分布漂移(相对基座的 KL、输出长度/风格/多样性变化)作更早的预警;⑤ 校验评测集没有被合成数据污染,否则测出来的是假的。同时给通用能力设「不得低于基线 X%」的硬阈值触发回滚。
Q:为什么要在训练数据里混通用数据?加多少? A:因为梯度不区分新旧任务,掺入通用数据让优化目标同时受旧分布约束,是最有效的 replay 手段。至于加多少 —— 没有普适常数,必须实测。它是一个权衡:加多了目标能力学不扎实,加少了通用能力守不住。工程上更有效的做法不是调一个总数,而是按缺失的能力面定向掺(多语言、长上下文、领域知识各补什么),并用评测切片验证。
Q:SFT 数据为什么要拟合预训练分布? A:因为微调数据量远小于预训练语料,分布偏移越大,模型越需要改写已有表征去适配,覆盖旧能力的风险越高。分布贴近时只需小幅调整,学新格式与保旧能力之间的冲突最小。但这是经验原则不是定理 —— 有些能力(全新的输出格式、特殊 token 结构)本来就在预训练分布之外,必须偏离才能学到,所以是「在能达成目标的前提下尽量贴近」。
Q:LoRA 能不能完全避免灾难性遗忘? A:不能。它通过把更新限制在低秩子空间降低了破坏原有权重的风险,通常比全参微调更保通用能力。但适配器仍然作用在主干的前向路径上,任务偏移大时低秩瓶颈之外的影响依旧存在,而且「低秩 → 不会遗忘」是一个未经验证的推断。所以无论用不用 LoRA,都要跑那套双尺评测。
易错点#
- ❌ 只会背「加通用数据」,说不出比例依据,也不知道加多了会付出什么代价。
- ❌ 只用目标能力指标评估微调 —— 这是最常见、最致命的错误。
- ❌ 没有在微调前的 checkpoint 上跑基线,于是「退化」无从判断。
- ❌ 通用能力评测集与训练数据同分布 / 被合成数据污染,测了个寂寞。
- ❌ 用训练 loss 判断有没有遗忘 —— 训练 loss 下降恰恰是遗忘的伴随现象。
- ❌ 把 chat template 不一致、过拟合、评测管线变化统统归因于遗忘,导致缓解动作全部打偏。
- ❌ 只看单个聚合分,不看能力切片 —— 能力之间此消彼长会互相抵消。
- ❌ 认为 LoRA 用了就不会遗忘。
- ❌ 认为「遗忘」是二值事件,只在「模型彻底崩了」时才承认。
自测#
1. 设计一套能真正测出灾难性遗忘的实验。请列出评测集的设计准则、需要测量的量,以及你的判读规则。
答案
评测集设计:通用能力评测集必须满足 —— ① 不在微调数据分布内;② 冻结、永不出现在训练中(并做污染校验:n-gram 重叠 / embedding 检索);③ 覆盖多个能力切面(知识、推理、指令遵循、多语言、长上下文等);④ 足够小、足够快,能每 N 步跑一次;⑤ prompt 格式与训练时 chat template 一致,否则测的是模板不是能力;⑥ 报告切片而非单一聚合分。
需要测量:① 目标能力指标;② 通用能力各切片的指标;③ 两者的轨迹(按 step/epoch 画在同一横轴上),而不只是最后一点;④ 分布漂移代理量 —— 在通用 prompt 集上相对基座模型的输出 KL、输出长度分布、模板化程度、采样多样性;⑤ 每组的零梯度/有效样本情况(如果是 RL,辅助判断)。
判读规则:先在微调前的 checkpoint 上跑同一套评测建立基线,然后 —— 目标升 / 通用稳 = 保持;目标升 / 通用降 = 进入发散点,提高通用数据比例或降 lr、减 epoch、在发散点提前停止;目标不升 / 通用降 = 立即停止,先修数据;全部指标一起降 = 先查 chat template 与评测管线,不要归因于遗忘。
2. 为什么说「用训练 loss 判断有没有遗忘」是错的?
答案
训练 loss 衡量的是模型在微调数据分布上的拟合程度,它下降是优化的正常结果,与模型在其他分布上的能力无关 —— 甚至在遗忘发生时,训练 loss 往往降得更快更漂亮(模型正在把容量集中到窄任务上)。
遗忘的定义是「在微调分布之外的能力变差」,它只能由分布外的评测观测到。这就是必须准备独立的、冻结的通用能力评测集,并在微调前的 checkpoint 上建立基线的根本原因。在 RL 场景下同理:reward 上升也不能作为通用能力未退化的证据。
3. 一段 SFT 之后,团队发现模型在目标任务的测试集上从 78% 掉到 71%,同时在通用 benchmark 上从 65% 掉到 60%。你会先做什么?
答案
先不要把结论定成「灾难性遗忘」。按判据表,目标能力与通用能力同时下降并不符合遗忘的典型签名(遗忘是目标升、通用降),更像「训练本身出了问题」。
排查顺序:① chat template 是否与推理/评测时逐字符一致(症状正是全面变差,这是最高频的根因);② 过拟合或训练未收敛 —— 看训练 loss 曲线、epoch 数、以及是全体退化还是只在某类样本上退化;③ 评测管线是否被改动(换了 prompt、换了后处理、换了 ground truth);④ 学习率是否过大导致训练不稳(loss 是否震荡);⑤ 数据是否有系统性错误(错误的示范被学走 —— 这在模仿学习里会同时伤害目标任务和其他任务)。
只有在排除以上之后,才考虑按遗忘来处理(混通用数据、降 lr/epoch、LoRA、权重正则),并且此时确实需要补一套双尺评测来量化。
4. 你在微调语料里混了 30% 通用数据,通用能力守住了,但目标任务的指标明显不如纯微调版本。你怎么决策?
答案
这是一个显式的权衡选择,不是一个纯技术问题,要按业务优先级决策:
① 先量化权衡曲线:用同一套双尺评测跑多个配比(例如若干个点),画出「目标能力 vs 通用能力」的权衡曲线,找到拐点 —— 而不是拍一个数。② 判断目标能力差在哪个切片:如果差在特定类型上,可能不是通用数据「稀释」造成的,而是数据覆盖问题,那应该定向补数据而不是减少通用数据。③ 看是否能从别处拿回目标能力:更长的训练步数、更有针对性的困难样本、或后续用偏好对齐(DPO/GRPO)补 —— 通用数据在 SFT 阶段守住的能力,后面通常更难补回来,而目标能力往往还能通过其他手段提升。④ 业务口径决定选点:面向公众/政企的场景通常更看重通用能力不退化(一旦出现明显的通用能力回退,用户信任损失难以挽回),所以倾向保守;纯垂域内部工具则可以更激进。
一句话:把权衡显式化,用数据和业务优先级选点,而不是靠感觉。
5. 除了混通用数据,还有哪些缓解灾难性遗忘的手段?请按代价从低到高排序,并说明各自的局限。
答案
从低到高:① 不微调 —— 用 prompt / RAG 解决格式与知识注入问题(最低代价,最常被忽略);② 降低学习率、减少 epoch、加早停(几乎无额外代价,但治标不治本);③ LoRA / PEFT —— 把更新限制在低秩子空间降低破坏原有权重的风险,但「低秩就不会遗忘」是未经验证的推断,仍需评测;④ 对基座权重的显式正则 / KL 约束(如 L2-SP、RLHF 里的 KL 项),需要调系数,过强会学不动;⑤ 分层冻结(冻结底层与 embedding,只训高层),会限制需要底层表征改变的任务;⑥ 事后模型合并(权重插值 / 任务向量),代价低但效果不稳定,需额外评测选系数;⑦ 数据混合(最有效,但与目标能力存在直接权衡)。
所有手段的共同局限:它们都不能保证不遗忘,只能降低概率与幅度。所以真正的保障不是某一个技巧,而是那套「双尺 + 轨迹 + 硬阈值回滚」的度量机制 —— 没有度量,所有缓解手段都是盲调。