第 7 章 第二部分:预训练

中训练(Mid-training)

预训练之后、后训练之前——中训练如何增强模型的领域能力和长上下文处理

中训练 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+ tokens50B - 2T tokens
目标广泛的通用能力定向增强特定能力
学习率从 0 warmup 到 peak从预训练末态续接或重新 warmup
数据分布尽量均匀覆盖有意识地偏向目标领域
核心挑战训练稳定性和规模遗忘控制和能力平衡
典型时长数周到数月数天到数周

为什么需要中训练

预训练阶段的目标是建立广泛的通用能力,数据覆盖面广但某些能力可能不够深入。中训练专门解决以下问题:

  1. 长上下文能力:从 8K 扩展到 128K 甚至更长
  2. 代码和数学增强:提升推理相关能力
  3. 多语言增强:增强目标语言(如中文)的能力
  4. 领域知识注入:医疗、法律、金融等专业知识
  5. 数据格式适应:结构化数据(表格、JSON)处理能力
  6. 知识时效更新:注入最新的知识而不重新预训练
  7. 预训练→后训练的分布桥接:即使不需要新能力注入,中训练也能通过逐步调整数据分布来平滑从预训练到 SFT 的过渡,减少后训练阶段的不稳定性。实证研究表明,桥接中训练在域内性能和遗忘控制上均优于直接从预训练跳到 SFT

从 Survey(北大+美团,2025.10)的视角,中训练可分为三类子范式:

子类目标典型场景
能力增强型深化特定能力长上下文 / 代码 / 数学 / 多语言
领域适应型注入域专家知识医疗 / 法律 / 金融
桥接型平滑预训练→后训练的分布过渡退火、数据配比渐变

| 对齐注入型 | 将价值观和对齐偏好预植入模型 | 宪法/安全/伦理准则的中训练注入 | | 蒸馏型 | 用教师 logit 替代 one-hot 监督 | 小模型提效;注意阶段非对称性 |

这一分类有助于理解”同样叫中训练,为什么设计空间差异很大”——能力增强型需要大量目标域数据,领域适应型更关注遗忘控制,桥接型的核心则是数据配比的渐变策略。蒸馏型是唯一一个按监督信号来源(而非目标)划分的子类,下面单独说明。

蒸馏型中训练:注意阶段非对称性

用强教师的 logit 监督小模型是提效的常用手段,但同一个蒸馏目标在预训练与中训练两个阶段的行为是相反的(arXiv:2609.01532,Meta AI + UW,2026-09)。控制实验显示:标准 forward KL 蒸馏配后训练教师,在预训练阶段相对 NTP 让推理与事实召回双双提升;但在中训练阶段,推理继续提升,事实记忆的获取却被拖慢。

机制是两重不对称:教师对程序性数据(数学、FLAN)自信(低熵),对知识密集型数据(DCLM、Wikipedia)不自信(高熵);而学生更早习得低熵事实,到中训练开始时,未习得的事实恰好集中在高熵一侧。梯度分析给出定量刻画:在 α=0.5\alpha=0.5 的设置下,蒸馏给最高熵事实的 gold-answer 梯度被削弱到 NTP 的约 0.5×——这个值正是推导中的 1−α1-\alpha 下界,意为当蒸馏梯度贡献趋于零时,监督强度不会低于交叉熵项的一半。

提出的 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 推演

关键发现:

  1. 勒索场景 -17.5pp:宪法中训练将 blackmail 场景下受诱成功率降低 17.5 个百分点,且效果在良性微调后持续——为该假设提供了支持性证据。但”持续”并非无条件成立,它取决于后续后训练的数据域(见下方”当前局限”)
  2. 能力零损耗:对 MMLU、ARC-Easy、GSM8K 等能力基准无负面影响
  3. 内容 > 结构:宪法内容的”存在”比其在训练中的排序结构更重要
  4. 被动韧性 vs 主动对抗:效果在对抗性压力下衰减——模型”不会主动为恶”但”可以被诱导为恶”

⚠️ 当前局限:Constitutional Midtraining 仅在 120B 参数、单一宪法语料上验证。对抗性衰减是重要限制——不能替代后训练安全措施,但作为”深度防御”的额外一层具有独特价值。

⚠️ 补充局限——后训练数据域是价值保留的第一决定变量。“中训练对齐比后训练更持久”这个结论缺少一个关键条件:后训练数据的”域”。CaML 的对照实验(arXiv:2606.26102,Llama 3.1 8B + 同情导向合成中训练语料,用 ANIMA 2.2 动物同情与 MORU 道德推理双基准测量)显示,helpfulness 域后训练对中训练价值观的破坏显著大于 coding 域:

基准后训练范式helpfulness 域coding 域
ANIMA(动物同情)SFT35.7%65.2%
ANIMA(动物同情)GRPO15.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+ 对照实验,为首项系统性定量证据回答”中训练到底有多关键”。核心发现:

  1. 数据组合在中训练阶段最关键,而非 RL 阶段:中训练加科学数据在 RL 时 GPQA-Diamond 解锁 +17~28 分,而调整 RL 数据组合仅 <2 分差异。
  2. 中训练密集重构权重:中训练修改 >90% 参数,RL 仅修改 ~5% 参数。
  3. RL 只在有中训练时才有效:RL 保持中训练表征几何(CKA > 0.998),但 RL 的权重变化在有无中训练时完全相同——没有中训练时 RL 几乎无法提升推理能力(AIME 接近零),中训练将模型置于”RL 可生效的配置”。
  4. 中训练的增益量化:27B 高质量 tokens 中训练提升数学 +1540 分、代码 +512 分、科学 +6~13 分;中训练 + RL 流水线将 6 个推理基准 macro-average 从 <12 提升到 29-42(3-4x 改善)。

PRISM 的核心结论:中训练不是可选的优化步骤,而是 RL 能否生效的前提条件。数据组合决策应集中在中训练阶段——这是投资回报最高的调参窗口。

长上下文中训练

为什么长上下文需要专门训练

虽然 RoPE 理论上支持任意长度外推,但直接在推理时使用远超训练长度的上下文,效果会严重下降。长上下文中训练是弥合这一差距的关键步骤。

RoPE 扩展策略

从第二章的 RoPE 基础出发,长上下文训练通常涉及调整 RoPE 的基频:

ABF(Adjusted Base Frequency):

将 RoPE 的基频 θ\theta 从 10000 调大到更高的值:

θi=b−2i/d\theta_i = b^{-2i/d}

例如 LLaMA 3.1 将基频从 500,000 进一步提升以支持 128K 上下文。

Code LLaMA 率先展示了通过修改 RoPE 基频 + 少量长上下文数据微调,即可将 LLaMA 从 4K 扩展到 100K 上下文长度。

训练策略

渐进式扩展:

  1. 阶段 1:从 8K → 32K(2B tokens,RoPE 调频)
  2. 阶段 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)率先证明了合成数据在预训练阶段的威力。在中训练中,合成数据的典型用法:

  1. 教科书质量的解释:用 GPT-4/Claude 将维基百科知识改写为教科书风格
  2. 数学推理链:生成 step-by-step 的数学解题过程
  3. 代码注释增强:为高质量代码添加详细注释和解释
  4. 多角度改写:同一知识从不同难度、不同风格的角度阐述

注意:合成数据的质量取决于生成模型的能力。用弱模型生成的合成数据可能反而损害训练效果——这就是所谓的 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 词表),可以在中训练前扩展词表:

  1. 在中文语料上训练新的 BPE 子词
  2. 将新 token 添加到词表
  3. 初始化新 token 的 embedding(通常用已有 embedding 的平均值)
  4. 中训练时重点训练新 token 的 embedding

Chinese-LLaMA(Cui et al., 2023)详细展示了这一流程。

Catastrophic Forgetting 的缓解

中训练面临的核心挑战是灾难性遗忘——新数据可能覆盖旧知识。这不是理论问题——实际训练中,如果中训练数据配比不当,模型可能在 1000 步内丢失 10%+ 的英文 MMLU 分数。

遗忘的量化定义:

对于 benchmark BB,遗忘率定义为:

Forgetting(B)=Scorebefore−ScoreafterScorebefore×100%\text{Forgetting}(B) = \frac{\text{Score}_\text{before} - \text{Score}_\text{after}}{\text{Score}_\text{before}} \times 100\%

一般认为遗忘率 < 3% 是可接受的,3-5% 需要关注,> 5% 必须调整。

Stability Gap 现象

值得注意的是,遗忘并非总是渐进式退化。Guo et al.(ACL 2025)发现域持续预训练存在一个一致的稳定性鸿沟(Stability Gap):模型在中训练初期会经历通用能力的急剧下降,随后在继续训练中部分恢复——遗忘曲线呈非单调的 U 形,而非线性退化。

这一发现对实践有直接影响:

  1. 评估频率:在中训练前 500 步需要更高的评估频率(每 100 步),因为这是遗忘最剧烈的阶段
  2. 不要过早干预:初期的急剧下降可能是暂时的——在 LLaMA-3 的医学和法律域实验中,模型在 1000-2000 步后出现了明显的恢复。过早降低学习率可能同时抑制了恢复过程
  3. 缓解策略: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 是什么关系:两者不冲突,是同一思路的两个粒度。

DoReMiRoD
调什么域权重每步样本
粒度粗细
时机离线(用代理模型先跑一遍)在线(随训练推进)
依据域的 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 上计算 PPLPPL 上升 > 2%
参数漂移 (L2 norm)∥θt−θ0∥2/∥θ0∥2\|\theta_t - \theta_0\|_2 / \|\theta_0\|_2超过预设阈值
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权重主要相关数据域
MMLU0.25百科、教材、学术论文
C-Eval0.25中文百科、中文教材
GSM8K0.20数学推理数据
HumanEval0.20代码数据
HellaSwag0.10通用 Web 数据

从这个目标权重出发,结合小模型实验的 (数据配比 → benchmark) 映射,反向求解最优配比。

LLaMA 3.1 的中训练策略

Meta LLaMA 3.1 论文 描述了一个多阶段的中训练过程:

  1. 长上下文扩展:逐步从 8K → 128K
  2. 数据配比调整:在最后阶段上采样高质量数据
  3. 退火(Annealing):学习率最后降到接近 0,数据质量拉到最高

DeepSeek 的中训练策略

DeepSeek V3 在预训练 14.8T tokens 后,进行了两阶段的中训练:

  1. 阶段 1:增加数学、代码和合成数据的比例
  2. 阶段 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 decayWSD 更灵活
原始数据混合20-50%保持通用能力
序列长度渐进增长从短到长,分阶段
Warmup500-1000 步从上一阶段平滑过渡
退火阶段5-10% 的总 tokens最后阶段用最好的数据

前沿模型的中训练规模案例:

模型中训练数据量架构关键特点代表性结果
LLaMA 3.1~500B tokens405B dense长上下文扩展 8K→128K + 退火通用增强
DeepSeek V3~680B tokens671B MoE数学/代码增强 + 长上下文推理增强
Qwen3-Coder-Next600B tokens80B MoE (3B 激活)仓库级代码 + agentic 轨迹 + 800K 合成软件工程任务SWE-Bench Verified 71.3%
GLM-51.55T tokens744B 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 一阶动量 mm重置还是携带?重置后前若干步更新方向”失忆”,loss 平台期变长
Adam 二阶矩 vv重置还是携带?携带了旧域的梯度尺度估计,新域早期步长被错误缩放
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 走得更远——它完全不需要在同一个模型上做探索和更新:

  1. 小代理模型探索:用轻量级代理模型(而非主模型)在高奖励空间探索行为,生成”改进信号”(相对性能提升的方向指示)
  2. 信号提取与缓存:将改进信号从代理模型中提取出来,可异步生成、缓存、跨模型复用
  3. 迁移到主模型:将缓存的信号应用到目标大模型的中训练

核心创新在于 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 上高效训练。