跳转至

Dense 模型预训练完整 Recipe

更新日期:2026-04-15


一、完整训练 Recipe 概览

flowchart LR
    data["数据准备<br/>清洗 / 去重 / 配比"]
    arch["架构选型<br/>层数 / 宽度 / GQA / RoPE"]
    init["初始化<br/>μP / 标准"]
    warmup["Warmup<br/>(0-2k step)"]
    main["主训练<br/>cosine / WSD lr"]
    cooldown["Cooldown<br/>(最后 10-20%)"]
    eval["评测<br/>loss + downstream"]

    data --> arch --> init --> warmup --> main --> cooldown --> eval

    classDef stage fill:#fff,stroke:#cc785c,color:#1a1a1a;
    class data,arch,init,warmup,main,cooldown,eval stage
阶段 占比 关键决策 失败信号
数据 训练前 配比 / 课程学习 loss 早期不降 / 后期 spike
架构 训练前 RMSNorm + RoPE + GQA + SwiGLU OOM / 显存效率低
Warmup ~0.5% step linear 0 → peak lr 早期 NaN / 梯度爆炸
主训练 ~80-90% step cosine 或 WSD loss spike / NaN
Cooldown 10-20% step lr → 0 + 高质量数据 评测下降

二、参考 Recipe: LLaMA-3 8B 规模

2.1 模型配置

2.2 训练超参

2.3 数据配比 (估计)

2.4 训练硬件与时间


三、关键训练阶段

3.1 Warmup 阶段 (step 0-2000)

# Warmup 的作用:
# 1. 让 Adam 的二阶动量 v 累积足够统计量
# 2. 防止早期大梯度导致发散

for step in range(warmup_steps):
    lr = peak_lr * step / warmup_steps
    # 从 0 线性增加到 peak_lr

不要跳过 warmup!即使模型已经训练稳定,突然的 lr 变化仍可能导致 loss spike。

3.2 主训练阶段 (step 2000-N)

# Cosine decay
for step in range(warmup_steps, total_steps):
    progress = (step - warmup_steps) / (total_steps - warmup_steps)
    lr = min_lr + 0.5  (peak_lr - min_lr)  (1 + cos(pi * progress))

3.3 Annealing 阶段 (最后 10-15% steps)

Annealing 阶段是 LLaMA-3 和 DeepSeek 共同采用的关键技巧:训练后期大幅提高高质量数据(数学、代码、教科书)的比例。

# 在 total_steps * 0.85 时切换数据配比
if step > total_steps * 0.85:
    data_mix = ANNEALING_MIX  # 高质量数据为主
else:
    data_mix = MAIN_MIX

# 效果: 
# - 下游 benchmark 分数显著提升 (尤其 MATH, GSM8K, HumanEval)
# - Loss 本身变化不大, 但 downstream 能力明显增强

3.4 长上下文扩展阶段 (可选)

# 大部分训练在 8K 上下文
# 最后一段切换到 128K 上下文训练
# 配合 RoPE base 从 10000 → 500000 (或 1M)

if step > total_steps * 0.95:
    seq_len = 128000
    rope_base = 500000
    data_sources = ['long_docs', 'books', 'arxiv_papers']

四、并行策略

参考 C1-C3 的并行设计原则。


五、监控与调优

5.1 核心监控指标

metrics_to_log = {
    # 每步
    'loss': tensorboard,
    'grad_norm': tensorboard,
    'lr': tensorboard,
    'tokens_per_sec': tensorboard,

    # 每 N 步
    'mfu': N=100,
    'memory_usage': N=100,

    # 每 1000 步
    'eval_hellaswag': 1000,
    'eval_mmlu': 1000,
    'eval_gsm8k': 1000,
    'eval_humaneval': 1000,
}

5.2 Loss 曲线的典型形态

正常的 loss 曲线: Step 0-100: 从 10 快速降到 4 (初始化噪声) Step 100-2K: 从 4 降到 3 (warmup 阶段, 学基础) Step 2K-10K: 从 3 降到 2.5 (快速学习) Step 10K-100K: 从 2.5 降到 2.0 (幂律下降) Step 100K-1M: 从 2.0 降到 1.8 (边际收益递减) Annealing: 额外下降 0.05 (高质量数据的效果)

5.3 异常情况


六、评估

6.1 训练中的轻量评估

# 每 1000 步运行一次, 轻量 benchmark
light_evals = [
    'hellaswag',    # 常识推理, ~1K 样本
    'arc_challenge', # 科学推理
    'piqa',          # 物理常识
    'winogrande',    # 指代消歧
]

# 这些 benchmark 的收敛行为和最终能力强相关
# 可以用来快速判断训练是否正常

6.2 最终评估

参考 I1 评测体系文档。训练结束后,用完整基准做对标。


七、训练失败复盘案例

7.1 案例:Loss 在 50K 步后开始上升

症状: - Step 0-50K: loss 正常下降 - Step 50K-60K: loss 缓慢上升 (从 2.3 到 2.5) - 其他指标 (grad_norm, lr) 正常

调查: 1. 检查数据 → 发现第 50K 步附近切换了数据源,新数据有质量问题 2. 检查数据 pipeline → 去重有 bug,导致高重复数据

修复: 1. 修复去重 bug 2. Rollback 到 step 45K 的 checkpoint 3. 继续训练,loss 恢复下降

7.2 案例:MFU 从 50% 掉到 35%

症状: 训练 30 天后 MFU 突然下降

调查: 1. 检查所有 GPU → 2 个 GPU 的内存带宽降低 2. HBM 有 bit flip, 需要降频运行

修复: 替换故障 GPU,MFU 恢复


八、最小可行 Recipe (玩具规模)

想自己动手训一个模型?这是可行的最小配置:

# Toy Recipe: 训 130M 参数模型 (类 GPT-2 small)
toy_config = {
    'n_layers': 12,
    'd_model': 768,
    'n_heads': 12,
    'd_ff': 3072,
    'vocab_size': 50257,  # GPT-2 tokenizer
    'seq_len': 1024,

    # Training
    'batch_size': 64,
    'peak_lr': 6e-4,
    'min_lr': 6e-5,
    'warmup_steps': 100,
    'total_tokens': 10B,  # 接近 Chinchilla 最优

    # Data: FineWeb (开源数据)
    'data': 'fineweb-10B',

    # Hardware
    'gpus': '4× A100/H100',
    'time': '~3-5 天',
    'cost': '~$500',
}


参考文献


上级 · D. 预训练 Recipe