Midtraining 与 CPT:训练领域专用 LLM 实战指南 · 干货攻略

  • 链接: https://x.com/cwolferesearch/status/2086849991721546189
  • 分类: x-tips
  • 来源: X @cwolferesearch
  • 作者: Jay
  • 更新: 2026-08-25

这是什么

大语言模型的训练管线近代已从「预训练 + 后训练」两阶段演变为更复杂的多阶段流程。MidtrainingContinued Pretraining(CPT) 是夹在通用预训练与后训练(SFT / RL)之间的两个中间训练阶段,都是在已有一个预训练好的基座模型基础上,继续用 next-token prediction 目标在大规模文本数据上进行训练——但二者在实践中的定位有细微区别:

CPT(继续预训练) Midtraining(中期训练)
典型场景 拿别人的预训练模型(如 Llama)继续在特定领域数据上训练 在自己的训练管线里,设计好的课程学习(curriculum learning)阶段
数据策略 往往完全切换到目标领域数据,或大幅提高领域数据比例 渐进式 anneal 数据配比,保留一部分通用预训练数据
目标 深度领域适配,通常接受一定的通用能力损失 在领域适配与通用能力保持之间找平衡

两者的核心共同点:都用 next-token prediction 目标在大规模文本上继续训练,都面临 catastrophic forgetting(灾难性遗忘)问题,都要处理 data mixture、learning rate schedule、训练时长等超参数调优问题。


为什么值得关注

谁在用?为什么?

CPT 和 Midtraining 已经成为训练专用 LLM 的标准手段,适用于:

  • 代码领域:Cursor Composer 2、Kimi-K2.5 衍生模型、DeepSeek 系列
  • 数学领域:OpenWebMath、CPT 后数学推理提升显著
  • 金融/医疗/法律领域:需要领域术语和知识体系的专用模型
  • 中文/多语言能力:Llama-3-SynE 等在 Llama-3-8B 基础上补充中文和科学推理能力

解决了什么问题

不做 Midtraining/CPT,直接在通用基座上做 SFT 或 RL 的问题在于:模型在预训练阶段没见过足够多的领域数据,SFT 只能做表层能力激活,无法真正建立领域知识深度。 CPT/Midtraining 通过在 next-token 层面注入领域数据,可以:

  1. 扩展模型的可解问题边界(expand the solvability frontier)
  2. 让后训练(SFT/RL)更有效,因为基座已有领域知识
  3. 降低从头训练专用模型的算力成本

核验过程

官方来源(Primary Sources)

  1. Cameron R. Wolfe Ph.D. Substackhttps://cameronrwolfe.substack.com/p/midtraining-notes - 本攻略干货的核心来源,Wollfe 是 Ph.D.,有 20+ 年 ML 训练经验 - 定义了 CPT 与 Midtraining 的区别与联系 - 提供了多篇论文的详细解读:proxy experiment 方法论、Composer 2 三阶段训练、domain upsampling 策略

  2. arXiv:2510.14865Midtraining Bridges Pretraining and Posttraining Distributions - 来自 CMU 等机构(2025),系统性对比了 Midtraining 与 CPT - 核心结论经独立研究验证:midtraining 在 in-domain 性能与通用知识保持上均优于纯 CPT - 提出「bridge」概念:midtraining 数据充当预训练与后训练分布之间的过渡层

  3. arXiv:2505.07796Learning Dynamics in Continual Pre-Training for Large Language Models - 研究了 CPT 过程中的学习动态,发现「stability gap」现象 - 提出三种缓解方法:multi-epoch 子集训练、高质量子集选择、data mixture 更接近原始预训练分布

  4. FutureAGI 博客(2026)— https://futureagi.com/blog/continued-llm-pretraining - 提供 2026 年实操层面的 LR 和 replay 经验值(见下)

交叉验证结论(Cross-Validation)

说法 核验来源 结论
CPT 与 Midtraining 术语边界模糊,实操高度相似 arXiv:2510.14865 + Medium/DSC 博客 ✅ 多源确认,定义一致
短 proxy run(~1B tokens)可预测长 CPT 效果 Wolfe Substack 引用的 [1] ✅ Substack 详细描述了该实验设计
Midtraining 在领域性能与通用能力保持上均优于纯 CPT arXiv:2510.14865 ✅ 独立研究验证,表格数据支撑
最优 learning rate:CPT 用 5e-6 ~ 5e-5,比原始预训练低 5-10x FutureAGI 博客 2026 ✅ 经验值,多处引述一致
Replay buffer:5-20% 通用数据混入防止遗忘 FutureAGI 博客 2026 ✅ 经验值,与 arXiv:2505.07796 的发现吻合
Midtraining 数据配比典型值:70-85% 通用 + 15-30% 领域数据 Medium/DSC 博客 ✅ 独立来源估算
FLAN 在短训练后性能见顶,OpenWebMath 持续提升 Wolfe Substack [1] 图 ⚠️ 来自 Substack 单来源,实验图表;arxiv 无直接引用同一数据集
Composer 2 三阶段:主 CPT → 长上下文扩展 → 短 SFT Wolfe Substack [3] Cursor 技术报告 ⚠️ 来自 Cursor 技术报告, Wolfe Substack 二手引用

上手步骤

1. 判断你的场景:选 CPT 还是 Midtraining?

需求是「深度领域专家」→ CPT(接受通用能力损失)
需求是「领域专家 + 保持通用推理」→ Midtraining(推荐)
需求是「在自己的训练管线里做 curriculum」→ Midtraining
需求是「拿开源基座改」→ 两者皆可,CPT 更常见

2. Proxy Experiment 方法论:低成本找出有效数据集

核心思想:先做小规模实验(~1B tokens),验证哪些数据集有效,再投正式算力。

# Step 1: 在 1B tokens 规模测试每个候选数据集
datasets = ["openwebmath", "flan", "code_search", "medical_text"]
for ds_name in datasets:
    run_cpt(tokens=1_000_000_000, dataset=ds_name, lr=2e-5, steps=1000)
    eval_score = run_downstream_evals()
    print(f"{ds_name}: {eval_score}")

# Step 2: 筛选有效数据集(只看提升显著且非负面的)
# Step 3: 用有效数据集做混合,配比按「最佳训练时长」加权
# Step 4: 正式 CPT run(50B+ tokens)

为什么有效:不同数据集有不同的学习动态——FLAN 快速见顶,OpenWebMath 持续提升。短 run 可以发现这个差异。

3. 学习率与训练时长调优

# 推荐 CPT 学习率范围(已验证)
CPT_PEAK_LR = 5e-6  # ~1e-5 是常见起始值,比原始预训练低 5-10x
WARMUP_RATIO = 0.01  # 总步数的 1-5%
DECAY_TYPE = "cosine"
MIN_LR = CPT_PEAK_LR * 0.1

# 调优顺序:
# 1. 固定训练时长(比如 10B tokens),搜索最优 learning rate
# 2. 用最优 LR,搜索训练时长(不同数据集动态不同)
# 3. 最终混合后重复 1 和 2

4. 数据混合与 Replay Buffer

# 防止 catastrophic forgetting 的标准配方
GENERAL_DATA_RATIO = 0.10  # 10-20% 的通用预训练数据
DOMAIN_DATA_RATIO = 0.90

# 典型 Midtraining 混合(更保守):
# 70-85% 通用 + 15-30% 领域数据

# 如果遇到 stability gap(领域性能先降后升):
# → 用更高质量的领域数据子集
# → 降低领域数据比例
# → 混合更多通用数据

Checkpoint 合并技巧:训练后期merge早、晚两个 checkpoint,可兼顾领域性能与通用能力:

# 比如 merge 10B token checkpoint 和 50B token checkpoint
merged = 0.3 * checkpoint_10b + 0.7 * checkpoint_50b

5. Cursor Composer 2 三阶段训练参考

如果你的场景是代码领域专用 LLM,Composer 2 提供了可借鉴的管线设计:

阶段 1: 主 CPT(消耗主要算力)
        - 序列长度:32K tokens
        - 数据配比:code-dominated(代码数据为主)

阶段 2: 长上下文扩展
        - 序列长度:256K tokens
        - 训练步数:相对较短

阶段 3: 短 SFT
        - 针对具体 coding tasks
        - 为 RL 做准备

然后进入 RL 阶段:用与部署环境相同的 harness 做 end-to-end 任务训练

6. Midtraining vs CPT 的实验判断

如果你不确定用哪个,arXiv:2510.14865 建议做 A/B 对比:

# CPT 方案:100% 领域数据(或极低通用比例)
cpt_result = run_cpt(通用比例=0.05, domain_ratio=0.95, tokens=50B)

# Midtraining 方案:渐进式 anneal 到 30% 领域
midtrain_result = run_midtraining(起点通用=0.95, 终点通用=0.70, tokens=50B)

# 对比两个方向:
# - in-domain benchmark 得分
# - C4 等通用 benchmark 保留(衡量遗忘程度)
# - 下游 SFT/RL 的最终性能

坑与适用边界

⚠️ Catastrophic Forgetting

这是 CPT/Midtraining 最核心的风险。表现: - 领域性能提升了,但通用 benchmark 掉分严重 - 模型在训练数据分布上表现好,但 out-of-distribution 数据上退步

缓解手段(优先级排序):

  1. Replay buffer:混入 10-20% 通用预训练数据(最有效)
  2. Lower learning rate:CPT 用 5e-6 ~ 5e-5,比原始预训练低 5-10x
  3. 参数高效方法:LoRA / DoRA 冻结基座权重,只训练适配器
  4. Checkpoint merge:早、晚 checkpoint 线性插值
  5. 数据质量:领域数据质量越高,需要的量越少,遗忘风险越低

⚠️ Stability Gap

arXiv:2505.07796 发现:某些场景下,领域性能在 CPT 初期会先下降再上升,形成不稳定期。

  • 表现:前 5-10% 的训练 steps,领域性能反而比基座差
  • 原因:领域数据分布与通用数据差异大,模型在「unlearning 旧知识」阶段性能会抖动
  • 解法:用高质量子集、更多 replay、或从更接近目标分布的数据开始

⚠️ 不是每个数据集都有正效果

Wolfe Substack [1] 的 proxy experiment 发现:不是所有候选数据集都对 CPT 有正向贡献。FLAN 和 OpenWebMath 在他们的实验中一致提升性能,但很多数据集要么无效,要么有负面影响。不做 proxy screening 直接全量上会浪费算力甚至损伤模型。

适用边界

  • 适合:有明确领域目标、有足够领域数据(至少数十亿 tokens)、需要深度领域知识的场景
  • 不适合:数据量太少(few-shot 级别直接用 SFT)、领域边界模糊或交叉场景、只需要表层能力激活
  • ROI 注意点:CPT/Midtraining 的算力投入很大,先用 proxy experiment 验证有效性再投正式算力

一句话结论

Midtraining 和 CPT 是预训练与后训练之间的关键「深领域适配」阶段,核心配方是:小规模 proxy experiment 筛选有效数据集、用比原始预训练低 5-10x 的 learning rate、混入 10-20% 通用数据做 replay、动态 anneal 数据配比——不做这些系统性调优直接上会浪费算力甚至让模型灾难性遗忘,而做好了可以让下游 RL/SFT 的效果大幅提升。