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',
}
参考文献¶
-
[1] LLaMA-3 Technical Report. 2024. 论文
-
[2] Hoffmann et al. Chinchilla. 2022. 论文
-
[3] Kaplan et al. Scaling Laws. 2020. 论文
-
[4] Touvron et al. LLaMA. 2023. 论文
-
[6] FineWeb Dataset
-
[7] NanoGPT (Karpathy) — 最简训练参考
-
[8] llm.c (Karpathy) — 纯 C 训练参考
↑ 上级 · D. 预训练 Recipe