章节导航 第 7 章 / 共 16 章
中训练(Mid-training)
预训练之后、后训练之前——中训练如何增强模型的领域能力和长上下文处理
什么是中训练
中训练(Mid-training),也称为 continued pre-training 或 pre-SFT training,是介于预训练(Pre-training)和后训练(Post-training)之间的训练阶段:
预训练 (Pre-training)
↓ 数万亿 tokens,通用能力
↓
中训练 (Mid-training) ← 本章
↓ 数百亿 ~ 数千亿 tokens
↓ 能力增强 & 领域注入
↓
后训练 (Post-training)
↓ SFT + RLHF/DPO
↓
最终模型
中训练不是一个新概念——早期的”领域预训练”(domain-adaptive pretraining)本质上就是中训练。但随着训练流水线的成熟和需求的多样化,中训练已经从”可选”变为”几乎必须”的阶段。
更准确地说,中训练与预训练使用相同的训练目标(next-token prediction),但在以下维度上有本质区别:
| 维度 | 预训练 | 中训练 |
|---|---|---|
| 数据量 | 5T - 20T+ tokens | 50B - 2T tokens |
| 目标 | 广泛的通用能力 | 定向增强特定能力 |
| 学习率 | 从 0 warmup 到 peak | 从预训练末态续接或重新 warmup |
| 数据分布 | 尽量均匀覆盖 | 有意识地偏向目标领域 |
| 核心挑战 | 训练稳定性和规模 | 遗忘控制和能力平衡 |
| 典型时长 | 数周到数月 | 数天到数周 |
为什么需要中训练
预训练阶段的目标是建立广泛的通用能力,数据覆盖面广但某些能力可能不够深入。中训练专门解决以下问题:
- 长上下文能力:从 8K 扩展到 128K 甚至更长
- 代码和数学增强:提升推理相关能力
- 多语言增强:增强目标语言(如中文)的能力
- 领域知识注入:医疗、法律、金融等专业知识
- 数据格式适应:结构化数据(表格、JSON)处理能力
- 知识时效更新:注入最新的知识而不重新预训练
- 预训练→后训练的分布桥接:即使不需要新能力注入,中训练也能通过逐步调整数据分布来平滑从预训练到 SFT 的过渡,减少后训练阶段的不稳定性。实证研究表明,桥接中训练在域内性能和遗忘控制上均优于直接从预训练跳到 SFT
从 Survey(北大+美团,2025.10)的视角,中训练可分为三类子范式:
| 子类 | 目标 | 典型场景 |
|---|---|---|
| 能力增强型 | 深化特定能力 | 长上下文 / 代码 / 数学 / 多语言 |
| 领域适应型 | 注入域专家知识 | 医疗 / 法律 / 金融 |
| 桥接型 | 平滑预训练→后训练的分布过渡 | 退火、数据配比渐变 |
| 对齐注入型 | 将价值观和对齐偏好预植入模型 | 宪法/安全/伦理准则的中训练注入 | | 蒸馏型 | 用教师 logit 替代 one-hot 监督 | 小模型提效;注意阶段非对称性 |
这一分类有助于理解”同样叫中训练,为什么设计空间差异很大”——能力增强型需要大量目标域数据,领域适应型更关注遗忘控制,桥接型的核心则是数据配比的渐变策略。蒸馏型是唯一一个按监督信号来源(而非目标)划分的子类,下面单独说明。
蒸馏型中训练:注意阶段非对称性
用强教师的 logit 监督小模型是提效的常用手段,但同一个蒸馏目标在预训练与中训练两个阶段的行为是相反的(arXiv:2609.01532,Meta AI + UW,2026-09)。控制实验显示:标准 forward KL 蒸馏配后训练教师,在预训练阶段相对 NTP 让推理与事实召回双双提升;但在中训练阶段,推理继续提升,事实记忆的获取却被拖慢。
机制是两重不对称:教师对程序性数据(数学、FLAN)自信(低熵),对知识密集型数据(DCLM、Wikipedia)不自信(高熵);而学生更早习得低熵事实,到中训练开始时,未习得的事实恰好集中在高熵一侧。梯度分析给出定量刻画:在 的设置下,蒸馏给最高熵事实的 gold-answer 梯度被削弱到 NTP 的约 0.5×——这个值正是推导中的 下界,意为当蒸馏梯度贡献趋于零时,监督强度不会低于交叉熵项的一半。
提出的 Switch Distillation 用教师预测熵做轻量路由:只在教师自信的 token 上蒸馏,否则退回交叉熵。相对 NTP 得到推理 1.61–1.71×、知识常识 1.13–1.19×,保留 96.7–96.8% 事实召回,且后训练之后收益仍保持(推理 1.25–1.32×、知识常识 1.13–1.20×)。
⚠️ 这一发现的意义超出了蒸馏本身:它说明中训练不是一个”缩小版预训练”,它有自己独立的动力学——这也是本章把中训练作为独立阶段处理的核心理由。
对齐注入型中训练:Constitutional Midtraining
Constitutional Midtraining(Desiree Cho et al., 2026-07-29)开辟了中训练的新维度——将价值观注入从后训练前移到中训练。核心动机:后训练对齐(RLHF/DPO)是”浅层”的——仅修改约 5% 的参数,容易被后续微调擦除。中训练阶段的对齐注入修改 >90% 参数,可能实现更持久的安全特性。
方法:在 120B 规模中训练中插入基于 Anthropic Constitution 的 394M-token 宪法语料,采用 2×2 因子设计:
- 课程排序:先宪法后通用 vs 交替混合
- 深思推理:是否在宪法响应前插入 CoT 推演
关键发现:
- 勒索场景 -17.5pp:宪法中训练将 blackmail 场景下受诱成功率降低 17.5 个百分点,且效果在良性微调后持续——为该假设提供了支持性证据。但”持续”并非无条件成立,它取决于后续后训练的数据域(见下方”当前局限”)
- 能力零损耗:对 MMLU、ARC-Easy、GSM8K 等能力基准无负面影响
- 内容 > 结构:宪法内容的”存在”比其在训练中的排序结构更重要
- 被动韧性 vs 主动对抗:效果在对抗性压力下衰减——模型”不会主动为恶”但”可以被诱导为恶”
⚠️ 当前局限:Constitutional Midtraining 仅在 120B 参数、单一宪法语料上验证。对抗性衰减是重要限制——不能替代后训练安全措施,但作为”深度防御”的额外一层具有独特价值。
⚠️ 补充局限——后训练数据域是价值保留的第一决定变量。“中训练对齐比后训练更持久”这个结论缺少一个关键条件:后训练数据的”域”。CaML 的对照实验(arXiv:2606.26102,Llama 3.1 8B + 同情导向合成中训练语料,用 ANIMA 2.2 动物同情与 MORU 道德推理双基准测量)显示,helpfulness 域后训练对中训练价值观的破坏显著大于 coding 域:
基准 后训练范式 helpfulness 域 coding 域 ANIMA(动物同情) SFT 35.7% 65.2% ANIMA(动物同情) GRPO 15.4% 30.3% MORU(英文,道德推理) — 46.4% 71.9% 英文 MORU 上通用道德推理被拉低 25.5 个百分点。由于 helpfulness 恰是工业界后训练的默认域,这意味着”把价值观注入中训练”如果没有配套的后训练数据域设计,收益可能被大幅抵消。论文给出的实践建议是:采用价值注入中训练的团队,coding 域后训练比 helpfulness 域更能保留中训练价值观,且未测得通用推理能力的损失。
一个有意思的跨语言证据:该域效应不跨语言迁移(多语言 MORU 上差距消失,52.3% vs 51.2%),而中训练注入的价值效应稳定跨语言迁移(coding 相对 helpfulness 的优势在英文 ANIMA 项上为 32 个百分点、非英文项上为 26 个百分点,尽管后训练数据全为英文)。作者据此推断:中训练注入的价值观,比后训练带来的推理改进编码得更深、更跨语言——这与下文 PRISM 的”中训练修改 >90% 参数 vs RL 仅 ~5%“在机制上互相印证。
⚠️ 注意两篇工作的价值观内容不同(Anthropic Constitution vs 动物同情),数值不可直接相减;可迁移的是”域依赖”这个机制本身。
⚠️ 补充局限(更强)——极小比例的竞争性微调数据即可完全擦除中训练对齐效果。上面两条局限分别讲的是”对抗性压力下衰减”和”后训练数据的域”,而 2026-09 的规模化压力测试(arXiv:2609.20412,最大 1100 亿参数、10 亿中训练 token)给出了更硬的约束:
- 动机引导可被极小比例反向数据完全抹除:在后训练数据对两种动机存在歧义时,中训练确实能把动机导向其中一方;但只要加入极小比例暗示竞争性动机的微调数据,中训练的效果就被完全擦除。这与 CaML 的”域差异”不是同一回事——CaML 说的是”某些域破坏大、某些域破坏小”,这里说的是”极小比例即足够”,与域无关。
- 规则必须被显式展示过:在”希望模型遵守一组规则、只演示其中一部分”的场景中,规则必须在中训练或后训练数据中出现过才能被稳健学会。这直接削弱了”中训练能把对齐泛化到未演示行为”这一前提。
- 作者的最终判断是:公开证据不足以支持”中训练能解决对齐强 AI 系统的核心难题”这一说法。
因此,本节”中训练对齐更持久”的结论应被理解为:在受控的良性后训练下成立,且对后训练数据中的竞争性样本极度敏感。中训练对齐可以作为深度防御的一层,但不能因为它修改了 >90% 参数就假定它比后训练更稳固——参数修改比例与鲁棒性不是同一回事。
⚠️ 该工作的机构归属未核实,此处只引编号与结论。
这是一个活跃的开放问题:对齐方向的非营利机构 CaML(Compassion Aligned Machine Learning)已将”中训练植入的价值观能否存活过 RL 后训练”列为专门研究议程——用合成语料微调 OLMo 3 等开放权重模型后再施加 GRPO,并配套建设评测 harness 与开源 checkpoint(LessWrong,2026-09-01)。⚠️ 该研究议程属机构自述 + 早期结果,尚未经同行评审,请按”线索”而非”结论”对待;跟进可关注其评测 harness 的开源进展。
本质洞察:中训练的核心是一个 “定向增强 vs 全局遗忘”的博弈问题。增加目标领域数据会增强目标能力,但如果处理不当,通用能力会同比例退化。本章的核心就是如何赢得这场博弈。
PRISM 实证验证:中训练为什么不可替代
IBM 的 PRISM(ICML 2026)在 7 个基础模型(Granite/LLaMA/Mistral/Nemotron-H,3B-24B,dense+hybrid 架构)上做了 500+ 对照实验,为首项系统性定量证据回答”中训练到底有多关键”。核心发现:
- 数据组合在中训练阶段最关键,而非 RL 阶段:中训练加科学数据在 RL 时 GPQA-Diamond 解锁 +17~28 分,而调整 RL 数据组合仅 <2 分差异。
- 中训练密集重构权重:中训练修改 >90% 参数,RL 仅修改 ~5% 参数。
- RL 只在有中训练时才有效:RL 保持中训练表征几何(CKA > 0.998),但 RL 的权重变化在有无中训练时完全相同——没有中训练时 RL 几乎无法提升推理能力(AIME 接近零),中训练将模型置于”RL 可生效的配置”。
- 中训练的增益量化:27B 高质量 tokens 中训练提升数学 +15
40 分、代码 +512 分、科学 +6~13 分;中训练 + RL 流水线将 6 个推理基准 macro-average 从 <12 提升到 29-42(3-4x 改善)。
PRISM 的核心结论:中训练不是可选的优化步骤,而是 RL 能否生效的前提条件。数据组合决策应集中在中训练阶段——这是投资回报最高的调参窗口。
长上下文中训练
为什么长上下文需要专门训练
虽然 RoPE 理论上支持任意长度外推,但直接在推理时使用远超训练长度的上下文,效果会严重下降。长上下文中训练是弥合这一差距的关键步骤。
RoPE 扩展策略
从第二章的 RoPE 基础出发,长上下文训练通常涉及调整 RoPE 的基频:
ABF(Adjusted Base Frequency):
将 RoPE 的基频 从 10000 调大到更高的值:
例如 LLaMA 3.1 将基频从 500,000 进一步提升以支持 128K 上下文。
Code LLaMA 率先展示了通过修改 RoPE 基频 + 少量长上下文数据微调,即可将 LLaMA 从 4K 扩展到 100K 上下文长度。
训练策略
渐进式扩展:
- 阶段 1:从 8K → 32K(2B tokens,RoPE 调频)
- 阶段 2:从 32K → 128K(2B tokens,进一步调频)
学习率:通常使用预训练峰值 LR 的 1/10 ~ 1/5
数据构造:
- 长文档:书籍、论文、法律文书、代码仓库
- 合成长依赖数据:“needle in a haystack” 式的训练样本
- 多文档聚合:将相关短文档拼接成长序列
长上下文评估
| 评测方法 | 说明 |
|---|---|
| NIAH(Needle in a Haystack) | 在长文本中检索特定信息 |
| RULER | 多种长上下文能力的综合评测 |
| LongBench | 长文本理解 benchmark |
| 真实任务 | 长文档 QA、代码仓库理解、多轮长对话 |
代码和数学增强
动机
代码和数学能力不仅直接有用,还被认为能间接提升通用推理能力。DeepSeek V3 在中训练阶段大幅增加代码和数学数据的比例。
代码数据
来源:
- The Stack V2:67.5B tokens 的代码数据
- StarCoderData:筛选后的高质量代码
- GitHub 自主爬取 + 过滤
- 代码相关的文档和教程
质量控制:
- 基于 star 数的仓库级过滤
- 去除自动生成的代码(如
package-lock.json) - 去除测试文件的过度重复
- 去除含有个人信息(如 API key)的代码
数学数据
来源:
- OpenWebMath:从 Common Crawl 中提取的数学内容
- Proof-Pile-2:数学证明和教科书
- 合成数学数据(由 LLM 生成的数学推理链)
- LaTeX 论文中的数学部分
合成数据在中训练中的角色
Phi 系列(Microsoft)率先证明了合成数据在预训练阶段的威力。在中训练中,合成数据的典型用法:
- 教科书质量的解释:用 GPT-4/Claude 将维基百科知识改写为教科书风格
- 数学推理链:生成 step-by-step 的数学解题过程
- 代码注释增强:为高质量代码添加详细注释和解释
- 多角度改写:同一知识从不同难度、不同风格的角度阐述
注意:合成数据的质量取决于生成模型的能力。用弱模型生成的合成数据可能反而损害训练效果——这就是所谓的 model collapse 风险。
Function-Aware FIM:利用代码结构改进中训练目标
传统代码中训练使用标准 next-token prediction 目标,忽视了代码的结构化特征。Function-Aware FIM(Yubo Wang et al., 2026-07)利用函数调用与 Agent 行动-观察循环的”结构同构”性改进中训练目标:
- 掩码策略:基于程序依赖图选择掩码函数,用复杂度-可推断性双标准筛选
- FIM 训练:预测被掩码的函数体,使模型学习”从上下文推断函数实现”
在 2.6B-token 去污染语料上中训练 Qwen2.5-Coder-Instruct 7B/14B 和 Qwen3-8B 后:SWE-Bench-Verified +2.83.2,SWE-Bench-Lite +3.75.4。
最值得关注的发现是 “跨任务保护效应”:虽然中训练语料仅含 Python 代码,但函数调用的归纳偏置在 Agent 后训练中保护了非 Agent 编码能力——这与传统认知(“Agent 微调会侵蚀代码能力”)直接矛盾。该发现暗示:中训练目标函数的设计可能与数据本身同等重要。
多语言增强
中文能力的增强
如果基座模型主要在英文数据上预训练(如 LLaMA),中训练是增强中文能力的关键窗口。
典型策略:
- 中训练数据中中文比例提升到 30-50%(预训练可能只有 5-10%)
- 混合中英文数据,避免英文能力退化(catastrophic forgetting)
- 使用高质量中文语料:百科、教科书、新闻、优质博客
词表扩展:
如果原始 tokenizer 对中文不友好(如 LLaMA 的 32K 词表),可以在中训练前扩展词表:
- 在中文语料上训练新的 BPE 子词
- 将新 token 添加到词表
- 初始化新 token 的 embedding(通常用已有 embedding 的平均值)
- 中训练时重点训练新 token 的 embedding
Chinese-LLaMA(Cui et al., 2023)详细展示了这一流程。
Catastrophic Forgetting 的缓解
中训练面临的核心挑战是灾难性遗忘——新数据可能覆盖旧知识。这不是理论问题——实际训练中,如果中训练数据配比不当,模型可能在 1000 步内丢失 10%+ 的英文 MMLU 分数。
遗忘的量化定义:
对于 benchmark ,遗忘率定义为:
一般认为遗忘率 < 3% 是可接受的,3-5% 需要关注,> 5% 必须调整。
Stability Gap 现象
值得注意的是,遗忘并非总是渐进式退化。Guo et al.(ACL 2025)发现域持续预训练存在一个一致的稳定性鸿沟(Stability Gap):模型在中训练初期会经历通用能力的急剧下降,随后在继续训练中部分恢复——遗忘曲线呈非单调的 U 形,而非线性退化。
这一发现对实践有直接影响:
- 评估频率:在中训练前 500 步需要更高的评估频率(每 100 步),因为这是遗忘最剧烈的阶段
- 不要过早干预:初期的急剧下降可能是暂时的——在 LLaMA-3 的医学和法律域实验中,模型在 1000-2000 步后出现了明显的恢复。过早降低学习率可能同时抑制了恢复过程
- 缓解策略:soft replay(通用数据温和注入)和梯度投影约束可以有效减小 Stability Gap 的振幅,同时不影响目标域的学习
这个 U 形是什么?——遗忘其实是两件事叠在一起
上面描述了曲线形状,但没解释那个”部分恢复”到底是什么。2026-10 的一篇工作正好补上这一格。
When Forgetting is not Catastrophic: On the Mechanics of Spurious Forgetting(Palit、Draye、Zucchet、Jin、Schölkopf,2026-10-06)的核心论断是:微调中看起来被遗忘的知识,往往仍然存着、可以恢复——这叫 spurious forgetting(虚假遗忘)。更极端的情况是自我撤销的遗忘:在新事实上微调时,旧事实的召回先崩溃,然后在只继续训练新事实的过程中自行恢复,之后才真正被侵蚀。
机制(作者用一个最小联想记忆模型复现,需要三个成分:带共享结构的 key、集中的新 value、以及网络中的归一化):
微调把所有旧表征沿同一个共同方向平移。这个平移隐藏了旧事实,但保留了它们的相对几何;当新事实学完后,归一化撤回这个平移;而逐事实的改变累积下来才造成真正的侵蚀。
于是本章那条 U 形曲线被拆成了两段,来源各不相同:
| 曲线段 | 对应机制 | 可逆性 |
|---|---|---|
| 初期的急剧下降 | 旧表征被沿共同方向平移,旧事实被隐藏 | 可逆(访问丢失) |
| 随后的部分恢复 | 归一化撤回共同平移 | —— |
| 回不来的那部分 | 逐事实改变累积造成的侵蚀 | 不可逆(真遗忘) |
结论一句话:遗忘 = 共享的、可逆的访问丢失 + 缓慢的逐事实侵蚀,只有后者才是真正的灾难性遗忘。
这让上面第 2 条建议从经验法则升级为有机制的判断。 既然回升段对应的是”归一化撤回共同平移”这个自动发生的过程,那么”初期急剧下降”里有一部分根本不是知识被破坏。本章原有的”不要过早干预”是对的,现在有了理由:过早降低学习率确实可能同时抑制了归一化撤回平移的过程。
也给”遗忘率 <3% 可接受”这类单阈值判断补了一层——先分清它是哪一种:
🔧 诊断性判据(可直接用):当中训练出现”掉下去又涨回来”时,先怀疑是访问丢失(可逆,可以等,别急着调参);只有在掉下去不再回来时,才按真遗忘处理(需要调 replay 比例或降 LR)。
论文给出的两条可操作验证手段也值得记:在合成数据训练的 Transformer 上,减去那个共同平移即可消除遗忘崩溃;在预训练语言模型上,移除每次权重更新中的单个方向即可恢复旧事实。
哪种占主导,取决于一件事:新数据是把旧记忆一起移动还是分开移动。这给本章已有的”域距离”概念(§「中训练 vs 从头训练」用 PPL 比值衡量)补了一个更细的判据——PPL 比值告诉你两个域差多远,这条告诉你差的方式。
缓解策略矩阵:
| 策略 | 原理 | 效果 | 成本 | 适用场景 |
|---|---|---|---|---|
| 数据混合(Replay) | 保留预训练数据采样 | ★★★★★ | 低 | 所有场景,必选 |
| 学习率控制 | 减小参数更新幅度 | ★★★★ | 零 | 所有场景,必选 |
| 渐进式注入 | 逐步增大领域数据比例 | ★★★ | 低 | 领域差异大时 |
| EWC | 约束”重要”参数变化 | ★★★ | 高 | 参数量小时 |
| Replay Buffer | 按重要性加权回放 | ★★★★ | 中 | 有旧 eval 数据时 |
| 局部化更新(LSL) | 把遗忘视为每个权重矩阵输入空间中的几何问题,配一个带门控的权重适配器——只在”自己训练分布内”的输入激活上启用,从而把更新局部化 | ★★★ | 中 | 与 EWC 互补:EWC 约束”重要”参数的变化量,LSL 按输入分布门控更新的作用范围 |
这一行补的是矩阵里此前空缺的一格。 上面五行全是”数据侧”(混合什么、注入多少、回放哪些)或”优化侧”(更新幅度多大、哪些参数不许动)的通用手段,没有一条是在改”参数更新本身的作用范围”。
LSL 的两个细节值得单独记:① 它不需要访问旧数据(“without access to prior data”)——这与 Replay 系策略是正交的,可以同时用;② 门控用的是高斯混合模型(GMM),其似然在远离自身训练数据时迅速衰减,天然倾向于在旧阶段的数据上保持关闭。论文报告可在最大 70 亿参数的 LLM 上跨多个训练阶段解决遗忘,同时保留预训练与微调能力,内存与计算开销可控,且对超参选择鲁棒。
⚠️ 上述效果为论文自报,本轮核对至 abs 页;其逐阶段的具体保留度量未回正文核。
最重要的策略是数据混合。下一节将专门讨论如何设计混合比例。
比例该定多少?——可以不定
上面把”数据混合”列为唯一 ★★★★★ 且所有场景必选,但给出的形态是一个固定比例(下一节会给 20-50% 的区间)。固定比例有个前提问题:它不考虑模型实际的保持需求。而遗忘跨能力、跨数据源是不均匀的,并且随训练推进而演化——一个提前定死的比例,注定在训练的某一段是错的。
Replay on Demand(RoD)(Thede 等 6 人,Tübingen / Helmholtz Munich / Imperial / Thomson Reuters,2026-09-30)给出的替代方案是把分配交给模型自己的学习动态:
| 样本类型 | 打分口径 |
|---|---|
| 适应样本(新域) | 剩余学习潜力——当前模型 loss 与”已在该域收敛的适应专家”loss 之差 |
| replay 样本(旧域) | 已观测到的遗忘——当前模型 loss 与原始预训练基座模型 loss 之差 |
两类样本在共享训练预算下做联合 top-k 竞争,由此形成在线课程。结果:跨模型、跨规模、跨适应域,RoD 达到或优于经调优的固定 replay 基线与 model merging 的”适应-遗忘前沿”,而且不需要预先指定 replay 比例——replay 会自动集中到更易被遗忘的数据源,并随遗忘的出现动态增大并重新分配。
与本章已有的 DoReMi 是什么关系:两者不冲突,是同一思路的两个粒度。
| DoReMi | RoD | |
|---|---|---|
| 调什么 | 域权重 | 每步样本 |
| 粒度 | 粗 | 细 |
| 时机 | 离线(用代理模型先跑一遍) | 在线(随训练推进) |
| 依据 | 域的 minimax 最优权重 | 模型当前的遗忘动态 |
⚠️ 保留 20-50% 这个区间,但要改它的身份。 它是冷启动的合理先验,不是最优解。有预算做在线课程时,把它当作初始值而非固定值——这正是 RoD 论文里”without prescribing a replay allocation in advance”的含义。
遗忘监控系统:
在中训练过程中,你需要一个实时的遗忘监控系统。最小可用版本:
import json
from dataclasses import dataclass, field
from typing import Dict, List
@dataclass
class ForgettingMonitor:
"""中训练遗忘监控器"""
benchmarks: List[str] = field(default_factory=lambda: [
"mmlu", "gsm8k", "humaneval", "c_eval", "hellaswag"
])
baseline_scores: Dict[str, float] = field(default_factory=dict)
history: List[Dict] = field(default_factory=list)
alert_threshold: float = 0.05 # 5% 遗忘率告警
def set_baseline(self, scores: Dict[str, float]):
"""在中训练开始前,记录基座模型的 baseline 分数"""
self.baseline_scores = scores.copy()
print(f"[Monitor] Baseline set: {scores}")
def check(self, step: int, current_scores: Dict[str, float]) -> Dict:
"""检查当前遗忘情况"""
report = {"step": step, "scores": {}, "alerts": []}
for bench in self.benchmarks:
if bench not in self.baseline_scores or bench not in current_scores:
continue
baseline = self.baseline_scores[bench]
current = current_scores[bench]
forgetting = (baseline - current) / baseline if baseline > 0 else 0
improvement = (current - baseline) / baseline if baseline > 0 else 0
report["scores"][bench] = {
"baseline": baseline,
"current": current,
"forgetting": f"{forgetting:.2%}",
}
if forgetting > self.alert_threshold:
report["alerts"].append(
f"⚠️ {bench}: 遗忘率 {forgetting:.1%} 超过阈值 "
f"({baseline:.2f} → {current:.2f})"
)
self.history.append(report)
if report["alerts"]:
print(f"\n{'='*50}")
print(f"[Step {step}] ⚠️ 遗忘告警!")
for alert in report["alerts"]:
print(f" {alert}")
print(f"建议: 增加 replay 数据比例 或 降低学习率")
print(f"{'='*50}\n")
return report
# 使用示例
monitor = ForgettingMonitor()
monitor.set_baseline({
"mmlu": 0.683, "gsm8k": 0.521,
"humaneval": 0.378, "c_eval": 0.542, "hellaswag": 0.789
})
# 中训练过程中每 500 步检查一次
# monitor.check(step=500, current_scores={...})
# monitor.check(step=1000, current_scores={...})
关键监控指标:
除了 benchmark 分数,还应监控以下指标来早期预警遗忘:
| 指标 | 计算方式 | 预警信号 |
|---|---|---|
| 通用语料 Perplexity | 在预训练 eval set 上计算 PPL | PPL 上升 > 2% |
| 参数漂移 (L2 norm) | 超过预设阈值 | |
| Embedding 漂移 | 高频 token embedding 的余弦距离 | 距离增大 |
| 梯度投影 | 中训练梯度在预训练梯度方向的投影 | 负投影占比增大 |
中训练的数据配方
这是中训练中最核心也最难的部分。数据配比直接决定了中训练的成败。
数据配比的方法论
数据配比不是靠直觉拍脑袋的,而是需要系统的实验来确定。以下是工业界验证有效的方法论:
方法 1:小模型搜索 + 大模型验证
这是最常用的方法——利用 Scaling Laws 的可迁移性:
from itertools import product
from dataclasses import dataclass
from typing import Dict, List, Tuple
@dataclass
class MixExperiment:
"""数据配比实验框架"""
domains: List[str] # 数据域列表
proxy_model_size: str # 代理模型大小 (如 "1B")
tokens_per_exp: int # 每个实验的 token 数
def generate_grid(
self,
domain_ranges: Dict[str, List[float]],
step: float = 0.1
) -> List[Dict[str, float]]:
"""生成配比搜索网格
Args:
domain_ranges: 每个域的搜索范围, 如 {"code": [0.1, 0.3], "math": [0.05, 0.15]}
step: 搜索步长
"""
configs = []
# 固定域和浮动域
fixed_domains = {d: r for d, r in domain_ranges.items() if r[0] == r[1]}
search_domains = {d: r for d, r in domain_ranges.items() if r[0] != r[1]}
# 生成搜索空间
search_values = {}
for domain, (lo, hi) in search_domains.items():
values = []
v = lo
while v <= hi + 1e-9:
values.append(round(v, 2))
v += step
search_values[domain] = values
# 枚举组合 (web 域作为补充域,自动计算)
for combo in product(*search_values.values()):
config = dict(zip(search_domains.keys(), combo))
config.update(fixed_domains)
used = sum(config.values())
if used > 1.0:
continue
# 剩余分配给 replay/web 域
config["replay_web"] = round(1.0 - used, 2)
if config["replay_web"] < 0.1: # replay 至少 10%
continue
configs.append(config)
return configs
# 案例:中文增强的配比搜索
exp = MixExperiment(
domains=["chinese", "code", "math", "replay_web"],
proxy_model_size="1B",
tokens_per_exp=10_000_000_000, # 10B tokens per experiment
)
configs = exp.generate_grid({
"chinese": [0.2, 0.5], # 中文: 20%-50%
"code": [0.1, 0.2], # 代码: 10%-20%
"math": [0.05, 0.10], # 数学: 5%-10%
}, step=0.1)
print(f"搜索空间大小: {len(configs)} 个配置")
# 每个配置用 1B 代理模型训练 10B tokens
# 评估 MMLU/C-Eval/GSM8K/HumanEval 四个指标
# 选出 Pareto 最优的 2-3 个配置在 7B 上验证
方法 2:在线配比调整(DoReMi 风格)
DoReMi(Xie et al., 2023)提出了一种数据驱动的配比方法:训练一个小的代理模型来学习最优配比权重,然后将权重转移到大模型训练中。
核心思想:让模型在表现差的域上分配更多数据。
Step 1: 用均匀配比训练一个参考模型 M_ref (小模型)
Step 2: 训练一个代理模型 M_proxy,优化配比权重 w_i
使得 M_proxy 在所有域上的 loss 接近 M_ref
对 loss 高于 M_ref 的域,增大 w_i
Step 3: 用学到的 w_i 训练大模型
方法 3:基于目标的反向配比
先确定目标 benchmark 和权重,反向推导配比:
| 目标 benchmark | 权重 | 主要相关数据域 |
|---|---|---|
| MMLU | 0.25 | 百科、教材、学术论文 |
| C-Eval | 0.25 | 中文百科、中文教材 |
| GSM8K | 0.20 | 数学推理数据 |
| HumanEval | 0.20 | 代码数据 |
| HellaSwag | 0.10 | 通用 Web 数据 |
从这个目标权重出发,结合小模型实验的 (数据配比 → benchmark) 映射,反向求解最优配比。
LLaMA 3.1 的中训练策略
Meta LLaMA 3.1 论文 描述了一个多阶段的中训练过程:
- 长上下文扩展:逐步从 8K → 128K
- 数据配比调整:在最后阶段上采样高质量数据
- 退火(Annealing):学习率最后降到接近 0,数据质量拉到最高
DeepSeek 的中训练策略
DeepSeek V3 在预训练 14.8T tokens 后,进行了两阶段的中训练:
- 阶段 1:增加数学、代码和合成数据的比例
- 阶段 2:长上下文扩展 + 退火
退火(Annealing)的深度解析
退火是中训练最后阶段的关键策略,其本质是 “用最好的数据 + 最低的学习率 = 让模型稳定地记住最重要的知识”。
退火的实施:
# 退火阶段的典型配置
annealing_config = {
# 学习率:从当前 LR 线性衰减到接近 0
"lr_schedule": "linear_decay",
"lr_start": 3e-5, # 当前学习率
"lr_end": 1e-6, # 最终学习率
# 数据质量:大幅上采样高质量数据
"data_mix": {
"high_quality_web": 0.30, # ↑ FineWeb-Edu 等高质量网页
"textbooks": 0.15, # ↑ 教科书质量数据
"curated_code": 0.15, # ↑ 精选高质量代码
"math_reasoning": 0.10, # ↑ 数学推理链
"wikipedia": 0.10, # ↑ 百科全书
"general_web": 0.20, # ↓ 一般 Web 数据比例降低
},
# 数据量:通常占中训练总量的 5-10%
"tokens": "50B",
# 关键:退火阶段不做数据去重
# 允许模型多次看到最高质量的数据
"allow_repeat": True,
}
退火的效果:根据 MiniCPM 论文 的报告,退火阶段通常可以在不增加遗忘的情况下,将 benchmark 分数提升 2-5 个百分点。
通用配方建议
| 参数 | 建议值 | 说明 |
|---|---|---|
| 数据量 | 50B - 1.5T tokens | 取决于领域和任务;前沿模型的中训练数据量已显著增长 |
| 学习率 | 预训练 peak 的 10-20% | 过高容易遗忘 |
| 调度方式 | WSD 或 cosine decay | WSD 更灵活 |
| 原始数据混合 | 20-50% | 保持通用能力 |
| 序列长度 | 渐进增长 | 从短到长,分阶段 |
| Warmup | 500-1000 步 | 从上一阶段平滑过渡 |
| 退火阶段 | 5-10% 的总 tokens | 最后阶段用最好的数据 |
前沿模型的中训练规模案例:
| 模型 | 中训练数据量 | 架构 | 关键特点 | 代表性结果 |
|---|---|---|---|---|
| LLaMA 3.1 | ~500B tokens | 405B dense | 长上下文扩展 8K→128K + 退火 | 通用增强 |
| DeepSeek V3 | ~680B tokens | 671B MoE | 数学/代码增强 + 长上下文 | 推理增强 |
| Qwen3-Coder-Next | 600B tokens | 80B MoE (3B 激活) | 仓库级代码 + agentic 轨迹 + 800K 合成软件工程任务 | SWE-Bench Verified 71.3% |
| GLM-5 | 1.55T tokens | 744B MoE (40B 激活) | 三阶段渐进扩展 32K→128K→200K,代码/推理/长上下文/agentic 数据 | SWE-Bench Verified 77.8% |
趋势观察:前沿模型的中训练数据量已从 50-500B tokens 显著增长至 600B-1.55T tokens。Agentic 数据(工具使用轨迹、软件工程任务)是中训练的新兴数据类型——Qwen3-Coder-Next 和 GLM-5 都在中训练中大量使用 agentic 数据,这是 2025-2026 年的新趋势。
中训练学习率:一个常被忽视的关键
学习率的设置是中训练成败的关键因素之一。过高导致遗忘,过低导致学不到新东西。
续训学习率选择策略:
方案 A:从预训练末态续接 (推荐)
└─ 直接从预训练最后的 LR 开始,平滑过渡
└─ 适用于:预训练和中训练数据分布相近
└─ 典型 LR: 预训练末态 LR (如 3e-5)
方案 B:重新 warmup (更安全)
└─ 短暂 warmup (200-500 步) 到目标 LR
└─ 适用于:中训练数据分布与预训练差异大
└─ 典型 LR: 预训练 peak 的 10-20% (如 3e-5 ~ 6e-5)
方案 C:WSD 续训 (最灵活)
└─ 从预训练末态 warmup 到 stable LR
└─ stable 阶段训练主体内容
└─ 最后 decay + 退火
└─ 适用于:所有场景
实战经验:如果你不确定用什么学习率,一个安全的起点是 预训练 peak LR 的 10%。如果发现 eval loss 几乎不降,可以适当调高到 20%。如果发现遗忘严重,降到 5%。
学习率只是其中之一:阶段切换时,还有五个状态量要各自决策
上面三个方案讨论的都是学习率。但从预训练切到中训练,真正发生的是一次状态迁移——权重跨过去了,可优化器与数据管道的状态各有一套”跨或不跨”的独立选择。这些选择常常是默认发生的,没有人显式决策过,出问题时也就没人往这儿查。
下面每一项都应该像学习率那样被显式写进 runbook:
| 状态量 | 要决策的问题 | 失败的典型症状 |
|---|---|---|
| Adam 一阶动量 | 重置还是携带? | 重置后前若干步更新方向”失忆”,loss 平台期变长 |
| Adam 二阶矩 | 重置还是携带? | 携带了旧域的梯度尺度估计,新域早期步长被错误缩放 |
| LR 调度位置 | 处于哪个阶段?warmup / stable / decay 的进度是否保留 | 直接决定上面三个方案能否成立 |
| 数据加载器游标与 epoch 计数 | 重新播种还是续接? | 续接会跳过一部分新域数据;重新播种会重复或遗漏样本 |
| RNG 套件 | 数据顺序、dropout、初始化各自用哪套种子 | 影响可复现性,也影响 replay 采样是否均匀 |
| 精度机制的累积历史 | loss scaling 历史是否保留 | 混合精度下的 scaling 历史与新的 loss 量级不匹配 |
🔧 一条可以直接解释现象的经验:本章把”降低学习率”当作应对遗忘/不稳定的首选手段,但它动的是调度;而重置二阶矩是另一个独立的旋钮。两者不能互相替代。这解释了那个常见困惑——为什么有时候 LR 已经降到很低,训练仍然不稳定:问题可能不在步长大小,而在步长被一个来自旧域的二阶矩估计错误地缩放了。
⚠️ 引用边界:上表是本书按工程常识整理的检查清单,不是某篇论文给出的结论。它成立不依赖任何外部来源;提案中”某厂商的公开记录未披露是否携带 Adam 动量”这类说法,因本轮无法回到一手 tech report 核实,未写入。读者若要在论文或技术报告中引用”阶段切换应如何交接状态”,请自行核对一手材料。
中训练 vs 从头训练
什么时候应该中训练,什么时候应该从头训练?
| 场景 | 推荐方案 |
|---|---|
| 增强特定能力(代码/数学/多语言) | 中训练 |
| 知识更新(时效性) | 中训练 |
| 长上下文支持 | 中训练 |
| 全面换代(新架构/新 tokenizer) | 从头训练 |
| 数据分布剧烈变化(如从英文为主到中文为主) | 从头训练 |
| 预训练数据质量严重不足 | 从头训练 |
经验法则:如果目标领域数据量 < 原始预训练数据的 10%,通常中训练更高效。如果超过 30%,可以考虑从头训练。
更精确的判断框架:
新增数据量
少 (<5%) 多 (>30%)
┌──────────┬──────────┐
域距离 小 │ 中训练 │ 中训练 │
大 │ 中训练 │ 从头训练 │
└──────────┴──────────┘
“域距离”怎么衡量? 一个简单的代理指标:在预训练模型上计算新数据的 perplexity。如果 PPL > 预训练 eval set PPL 的 3 倍,说明域距离大。
双向训练管线:RL→中训练反馈飞轮
本章前述的训练管线是单向的:预训练 → 中训练 → 后训练(SFT + RL)。但 ReMiT(Reinforcement-Guided Mid-Training)提出了一个概念转变——管线可以成为闭环。
ReMiT 的核心机制:利用 RL 训练后模型的推理先验来动态重加权中训练阶段的 token 权重,优先分配给推理关键 token,实现 RL → 中训练的反馈。10 个预训练基准平均提升 3%,且增益在后续后训练中保持 >2%。
传统管线(单向):
预训练 → 中训练 → SFT → RL
ReMiT 管线(闭环):
预训练 → 中训练 → SFT → RL
↑ |
└── 推理先验反馈 ──────┘
当前定位:ReMiT 是前沿探索方向,仅在 10 个基准上验证,规模尚小。当前推荐仍以单向管线为主,但 ReMiT 的概念值得关注——如果后续在更大规模上验证有效,“训练管线从单向变为闭环”可能成为新的范式。
PUST:探索与对齐的彻底解耦
PUST(Proxy-guided Update Signal Transfer,上海 AI 实验室/复旦/浙大,2026-07)比 ReMiT 走得更远——它完全不需要在同一个模型上做探索和更新:
- 小代理模型探索:用轻量级代理模型(而非主模型)在高奖励空间探索行为,生成”改进信号”(相对性能提升的方向指示)
- 信号提取与缓存:将改进信号从代理模型中提取出来,可异步生成、缓存、跨模型复用
- 迁移到主模型:将缓存的信号应用到目标大模型的中训练
核心创新在于 weak-to-strong improvement——弱代理模型的改进信号可以增强强主模型。这对中训练的意义是实质性的:中训练的探索成本从”在大模型上做配比搜索”降到”在小代理上试探方向”。
⚠️ 当前局限:PUST 目前在 Qwen3 系列(数学和代码域)验证,尚无百 B 级以上验证。该方法挑战了”中训练必须在大模型上做”的前提假设,但工业级可行性待确认。
中训练完整实战 Pipeline
将上述所有内容串联起来,以下是一个完整的中训练 pipeline:
阶段 0: 准备
├─ 选定基座模型 & 收集目标领域数据
├─ 在基座模型上跑 baseline eval (记录所有 benchmark 分数)
├─ 准备 replay 数据 (从预训练数据中采样)
└─ 设计配比搜索空间
阶段 1: 配比搜索 (1B 代理模型, ~1 周)
├─ 用 1B 模型跑 10-20 组配比实验 (每组 10B tokens)
├─ 评估每组的 {目标任务, 通用能力, 遗忘} 三维指标
└─ 选出 Pareto 最优的 2-3 组配比
阶段 2: 验证 (7B 模型, ~3 天)
├─ 用候选配比在 7B 上跑 50B tokens
├─ 确认遗忘在可控范围
└─ 锁定最终配比
阶段 3: 正式中训练 (目标模型, ~1-3 周)
├─ 主体训练: WSD 学习率, 监控遗忘
├─ 长上下文扩展 (如需要): 分阶段 8K→32K→128K
└─ 退火: 最后 5-10% tokens, 最高质量数据, 学习率衰减到 0
阶段 4: 评估 & 交接
├─ 全量 eval: 目标任务 + 通用能力
├─ 对比 baseline, 确认遗忘可控
└─ 交接给后训练团队
常见踩坑与经验
| 踩坑 | 症状 | 解决方案 |
|---|---|---|
| 学习率太高 | 前 1000 步 MMLU 下降 > 5% | 降 LR 到 peak 的 5-10% |
| Replay 数据太少 | 通用能力持续退化 | Replay 比例提到 30-50% |
| 数据质量不均 | 特定域 loss 不降 | 检查该域数据质量,做清洗 |
| 序列长度突变 | Loss spike | 分阶段渐进扩展 |
| 退火缺失 | 最终 eval 不稳定 | 添加退火阶段,用最优数据 |
| 评估频率太低 | 遗忘发现太晚无法补救 | 每 500 步 eval 一次 |
| Tokenizer 不匹配 | 中文/代码 token 效率低 | 扩展词表后再中训练 |
| 价值注入后接默认 helpfulness 后训练 | 注入的价值观在 eval 上大幅回落 | 评估并调整后训练数据域(coding 域保留更好),并把价值 eval 纳入后训练监控 |
最重要的一条建议:中训练是一个需要频繁评估和快速迭代的过程。不要在配比确定之前就启动大规模训练——用 5% 的预算做配比搜索,可以让剩下的 95% 预算效果翻倍。
下一章预告:训练一个大模型不仅需要好的配方,还需要强大的分布式训练系统。第八章我们将深入分布式训练工程——数据并行、模型并行、流水线并行,以及如何在数千张 GPU 上高效训练。