Skip to main content

The Smol Training Playbook 阅读笔记

本文为 HuggingFace 团队发布的 The Smol Training Playbook: The Secrets to Building World-Class LLMs 的阅读笔记。全文 214 页,是 HuggingFace 基于 SmolLM3(3B 多语言推理模型,11T tokens 训练)的完整实践复盘。

链接:https://huggingface.co/spaces/HuggingFaceTB/smol-training-playbook

作者:Loubna Ben Allal, Lewis Tunstall, Nouamane Tazi, Elie Bakouch, Ed Beeching, Carlos Miguel Patiño, Clémentine Fourrier, Thibaud Frere, Anton Lozhkov, Colin Raffel, Leandro von Werra, Thomas Wolf

这篇文章说了什么​

这是 HuggingFace 团队用 214 页篇幅,完整复盘他们从零训练 SmolLM3(3B 多语言推理模型)的全过程。不是那种只讲成功方案的论文,而是把失败、bug、推倒重来、基础设施爆炸的细节全部摊开来写的实战手册。

全书按 LLM 训练的生命周期分为四大部分:

  1. 训练指南针(Why → What → How):开篇先泼冷水——"别轻易训练自己的模型"。然后教你怎么判断要不要训、训练什么、怎么训。
  2. 预训练(Pretraining):从消融实验设计、架构选型(Dense/MoE/Hybrid)、优化器与超参数调优、数据混合策略,到真正的分布式训练实战——包括那个让他们训练了 1T tokens 后推倒重来的 Tensor Parallelism bug。
  3. Post-training:SFT → 偏好优化(APO-zero)→ RL 三阶段,怎么把基座模型变成支持混合推理(/think + /no_think)的实用助手。
  4. 基础设施:GPU 选型、存储方案、监控体系——没有这些,预训练和 post-training 都跑不起来。

核心结论一句话:数据质量 > 架构创新,小尺度消融实验是所有决策的基础,基础设施决定你能跑多快。

观后感​

  • 这本书最宝贵的不是技术方案,而是决策过程和失败经验——他们在训练了 1T tokens 后因为 Tensor Parallelism bug 推倒重来,这种坦诚在 AI 论文里很罕见
  • 如果你不确定要不要预训练,就不要预训练。先用 prompt → fine-tune → continue pretrain 这条链路,只有都失败且有明确理由时才考虑从头训练
  • 小尺度消融实验(small-scale ablation)是一切决策的基础,不要在大规模训练上试错
  • 数据质量 > 架构创新,优秀团队花在数据上的精力远超架构调优
  • SmolLM3 3B 的训练成本约 $250K(纯计算),但加上消融实验、失败重来、基础设施调试,实际成本远高于此

一、训练指南针:Why → What → How​

为什么需要这个"指南针"​

大模型领域有一个很普遍的问题:很多人上来就问"用什么架构好""学习率多少合适",但很少有人先问"我到底要不要训练自己的模型"。HF 团队在这一章里,本质上是在教读者怎么避免用几百万美金学一个别人已经知道答案的问题。

1. 为什么要训练(Why)​

这一节的核心逻辑是先排除无效动机,再判断场景是否匹配。

无效理由(大概率失败):

  • "我们有 GPU 闲着"——GPU 闲着你可能更应该租出去
  • "AI 是未来,我们要跟上"——太模糊,没有可验证的假设
  • "我们要做最好的模型"——什么叫"最好"?跟谁比?

剔除这些之后,真正有必要训练的场景只有三类:

场景说明示例
研究验证特定假设,需明确假设与实验规模"新优化器能否扩展到 10B+" 或 "仅 RL 能否实现推理能力"
生产现有模型无法满足需求,且 fine-tune/continue pretrain 都试过了DNA 模型、法律模型、端侧部署(无人机/FPGA)、合规行业
战略开源填补生态空白,目标需具体"目前没有强的 3B 端侧多语言模型"

HF 自己属于第三类——他们发现开源社区缺少真正强的小模型,于是决定做 SmolLM 系列。

一个很重要的建议:如果 fine-tune 1T tokens 就够用,比从头训练 10T tokens 便宜得多。大部分团队应该停在 fine-tune 这一步。

2. 训练什么(What)​

确定要训之后,需要把抽象目标翻译成具体的技术决策。HF 的决策维度包括:

  • 架构类型:dense 最普适稳定,MoE 算力效率高但内存需求也高(端侧不友好),hybrid(结合 SSM)适合超长上下文(1M+ tokens)
  • 模型规模:由部署环境决定,SmolLM3 选 3B 是因为端侧设备能装下
  • 数据混合:不同目标需要不同的数据配比——多语言、数学、代码的比例要通过消融确定
  • 助手类型:通用助手 / 代码助手 / 推理助手,决定了 post-training 的方向

决策流程:规划(需求 → 组件映射)→ 验证(消融实验)→ 实施

3. 如何训练(How)​

HF 总结了几个经过验证的核心原则:

  • 迭代速度优先:Qwen/DeepSeek 每个季度训 1 个模型,快速积累经验比一次做对更重要
  • 数据质量至上:看一个团队的水平,看他们花多少时间在数据上比看他们用什么架构更有效
  • 小团队启动:核心预训练团队只要 2-3 人,后期再根据需求扩展

二、模型架构设计​

为什么架构选择要保守​

这一章的核心理念是"不要同时改太多东西"。HF 在架构上的策略是:从成熟的 Llama-style dense 架构出发,每次只做一个变更,通过消融验证后再组合。他们的经验表明,在新手团队或资源有限的情况下,架构创新往往是风险最高、回报最不确定的环节。

2.1 架构类型选择​

架构类型核心特点为什么选/不选代表模型
Dense所有参数对每个 token 激活,训练稳定、生态成熟端侧部署内存可控,适合新团队Llama 3.2, Qwen3, SmolLM3
MoE仅激活部分专家,算力效率高所有专家都要加载进内存,端侧不友好Qwen3 MoE, Kimi K2, DeepSeek V3
HybridTransformer + SSM/线性注意力超长序列(1M+ tokens)场景才需要考虑Zamba2, MiniMax-01

SmolLM3 选择 Dense 的核心原因:部署环境决定架构,而非反过来。3B 的端侧模型,MoE 加载全部专家会占太多内存,Hybrid 的收益只在超长上下文场景显著。

2.2 核心组件与消融结论​

注意力机制​

HF 对几种注意力机制做了系统对比,关注的核心指标是 KV-Cache 的大小(因为端侧推理时 KV-Cache 是内存瓶颈):

机制KV-Cache 参数/token性能选择逻辑
MHA2×dim_head×heads×layers最强KV-Cache 太大,端侧不实用
GQA (g=2-8)2×g×dim_head×layers接近 MHASmolLM3 用 g=4,KV-Cache 减少到 MHA 的 1/4
MQA2×1×dim_head×layers略弱Cache 最小但性能损失明显
MLA4.5×dim_head×layers接近 MHADeepSeek 提出的方案,适合超大规模

结论:GQA(4 组)是端侧模型的最佳平衡点。

嵌入共享(Tied Embeddings)​

这一节的核心洞察是:小模型中嵌入层占参数的比例高得离谱。1B 参数的模型中,嵌入层可以占到 35% 的参数。

做法:让输入嵌入和输出线性层共享权重。数学上就是把 lm_head 和 embed_tokens 绑定。

消融结果:1.2B 绑定嵌入模型的性能 ≈ 1.46B 非绑定模型,直接节省 17% 参数。SmolLM3 全盘采纳。

位置编码​

三种主流方案及其关系:

  • RoPE:通过旋转矩阵编码相对位置,核心参数 theta 控制注意力随距离衰减的速度。扩展上下文时需要调大 theta(如 4k→32k 时 theta 从 50k→2M)
  • NoPE:不显式编码位置,仅靠因果注意力掩码让模型自己学位置关系。意外的是,在短上下文上不影响性能,且天然适应长上下文
  • ABF/YaRN:是对 RoPE 频率的调整方法,防止长序列时注意力过度衰减。Qwen3 用 ABF,SmolLM3 用 YaRN

SmolLM3 的方案:RNoPE(ReLU-NoPE),每 4 层移除一层 RoPE。这样既有 RoPE 的位置信息,又获得了 NoPE 的长上下文适应能力。

稳定性优化​

这三个是 HF 验证过但 SmolLM3 没全用的技巧:

  • Z-loss:在 loss 中加 λ·log²(Z) 惩罚项,防止 logits 过大。消融显示不影响性能但不提升,所以 SmolLM3 没加(省训练开销)
  • 移除嵌入权重衰减:OLMo2 团队发现对嵌入层做 weight decay 会导致梯度异常。SmolLM3 采纳了这个发现,移除后训练更稳定
  • QK-norm:对 Query 和 Key 做 LayerNorm。大模型上能稳定训练,但会损害长上下文性能。SmolLM3 因为目标包含 128k 上下文,所以放弃了

2.3 SmolLM3 最终架构​

总结一下所有决策的叠加结果:

  • 基础架构:Dense Llama-style,3B 参数
  • 注意力:GQA(32 query heads, 8 KV heads = 4 groups)
  • 嵌入共享:节省 17% 参数
  • 位置编码:RNoPE(每 4 层移除 RoPE)+ 文档掩码
  • 稳定性:移除嵌入权重衰减,不用 Z-loss,不用 QK-norm

三、优化器与训练超参数​

为什么这一节这么重要​

优化器和超参数是所有消融实验的底座。如果底座不稳,架构消融的结论就不可靠。HF 强调消融的顺序:先调学习率 → warmup → batch size → 优化器,架构决策放在最后。

3.1 优化器选择​

优化器特点为什么选/不选
AdamW一阶自适应优化器,生态最成熟、文献最丰富SmolLM3 采用:β₁=0.9, β₂=0.95, weight decay=0.1, grad clip=1.0
Muon二阶矩阵级优化,用 Newton-Schulz 迭代近似梯度矩阵的 signKimi K2、GLM 4.5 采用,但对学习率高度敏感,调参成本高

HF 的立场:新手直接 AdamW,不要折腾。Muon 在大 batch 场景下确有优势,但调参门槛高,失败成本大。

3.2 学习率调度​

三种调度策略的核心区别在于"你对训练步数的确定性":

策略形状优点缺点适用场景
WSD预热→平稳→衰减不确定总步数也能训,中途可扩展需确定衰减阶段的 token 比例SmolLM3 采用,因为不知道要训多少步
Cosine平滑余弦下降收敛稳定,数学优雅必须先确定总步数固定时长的训练
Multi-Step阶梯式下降可在指定步数做针对性下降步数和幅度都要手动调DeepSeek LLM (80-90-100% 步数)

几个关键的数值规律:

  • 预热步数:2000 步几乎适用于所有模型,不需要改
  • WSD 衰减比例:用 10-20% 的 tokens 做衰减就够了。SmolLM3 用 10%(约 1.1T tokens)
  • 预训练学习率约为 SFT 的 10 倍:SmolLM3 预训练 lr=2e-4,SFT lr=2e-5

3.3 批大小与学习率的耦合​

一个很多人不知道但很有用的规则——平方根缩放定律:批大小增大 k 倍,学习率按 √k 调整。

例如:批大小从 2M→4M tokens,学习率从 2e-4→2.8e-4(乘以 √2 ≈ 1.4)。

SmolLM3 的做法:测试 2M-4M 之间的几个批大小,发现性能无显著差异,直接选吞吐量最优的 2.36M。


四、数据筛选与混合​

为什么数据是最重要的杠杆​

HF 反复强调的一个观点:优秀团队花在数据上的精力远超架构调优。架构改动的影响往往是边际的(几个百分点),数据质量和混合比例的影响可能是决定性的(模型能不能学会某个能力)。

4.1 数据类型与来源​

数据类型来源SmolLM3 用量作用
英文网页FineWeb-Edu + DCLM (50:50)5.1T tokens构建语言基础能力和世界知识
多语言 (15种)FineWeb2-HQ628B tokens (12%)多语言生成能力
代码The Stack v2, StarCoder2Stack-Edu 后期注入 (10%)代码生成和逻辑推理
数学FineMath3+/4+, MegaMath54B + 后期注入 (3%)数学推理能力

4.2 为什么要分阶段训练​

HF 采用了三阶段数据策略,核心思想是:不同阶段注入不同类型的数据,效果完全不同。

阶段tokens 量数据为什么这样安排
Stage 18TFineWeb-Edu + DCLM + 12% 多语言 + 10% 代码 + 3% 数学用大量通用+领域数据打基础
Stage 22T注入 FineMath4+, Stack-Edu, MegaMath在基础稳定后,用高质量领域数据"拔高"专项能力
Stage 31.1T (LR 衰减期)加入 OpenMathReasoning, OpenCodeReasoning衰减阶段注入推理数据,让模型在 lr 下降时精细学习

这个策略的关键洞察:后期注入高质量数据比一开始就混入效果好。因为早期高 lr 阶段模型在学语言基础,精细的推理数据容易被"洗掉";后期 lr 小时,高质量数据的信号更清晰。

4.3 数据混合的关键边界​

通过消融实验确定的几个比例限制:

  • 多语言 > 12% 会侵蚀英文性能:加太多非英文数据,英文能力下降
  • 代码 > 25% 会损害通用能力:代码数据过多,模型变得过于"结构化",日常对话能力变差
  • 低质数据重复训练有害:同样的低质网页重复训练多次,模型会学到噪音规律
  • 消融实验是确定比例的唯一方法:HF 用 100B tokens 小尺度消融来验证每种混合比例

五、训练实战:故障与排查​

为什么这一章最有价值​

论文只会告诉你"我们用了什么方案成功了",但这一章告诉你什么会失败、怎么发现、怎么修。对真正要训练模型的人来说,这部分可能比架构设计更有用。

5.1 三种典型故障​

故障现象根因诊断方法修法
吞吐量从 14k→5k tokens/secFSx 存储悄悄驱逐了数据,dataloader 在重新拉取监控吞吐曲线,发现周期性骤降数据迁移到本地 NVMe,再加 1 个备用节点(预加载数据,故障时秒级替换)
loss 曲线异常噪声数据加载器 nanosets 没有打乱序列,造成 batch 内样本同质化loss 波动幅度异常大替换为 TokenizedBytes,离线预打乱(每 epoch 用不同 seed)
3B 模型性能 < 1.7B SmolLM2Tensor Parallelism bug:所有 TP rank 用了相同的随机种子,权重初始化高度相关loss 看着正常,但评估 benchmark 全面低于预期seed + tp_rank,让每个 rank 独立初始化

5.2 TP Bug 的深层教训​

这是全书最有价值的一个案例。详细展开:

发生了什么:SmolLM3 训练了 1T tokens 后,发现评估结果比 SmolLM2(1.7B)还差。一个更大的新模型,理应更强,结果却更弱。

为什么难以发现:loss 曲线看起来完全正常,没有发散、没有 spike。因为所有 TP rank 用同样的种子只是让初始化失去了多样性,不是让模型完全失效。模型还是会学,只是学得很慢、很不好。

怎么定位的:因为 HF 团队已经通过消融实验把架构、优化器、数据、超参数这些变量全部验证过了。当性能出问题时,他们知道唯一的未验证变量是分布式初始化的代码路径。于是直接查 TP 的 seed 逻辑,发现是同一个 seed 在不同 rank 上重复用了。

核心教训:系统性地通过消融排除变量,是高效 debug 的前提。如果架构和超参数都没验证过,你根本不知道问题是出在算法还是工程。

5.3 长上下文扩展​

SmolLM3 从 4k 扩展到 128k 的路径:

  • 4k → 32k:训练,RoPE theta 从 50k 调到 2M
  • 32k → 64k:继续训练,theta 调到 5M
  • 64k → 128k:不再训练,用 YaRN 做 extrapolation

数据策略:没有额外 upsample 长文档。因为 FineWeb-Edu 中已经有约 10% 的文档超过 2k tokens,天然提供了长上下文数据。强拉长文档比例反而可能损害短上下文性能。


六、Post-training:从基座到混合推理助手​

为什么 Post-training 是"炼金术"​

HF 把这部分称为 dark arts 不是开玩笑的。预训练有明确的目标函数(next token prediction),Post-training 没有——你需要让模型"有用"、"无害"、"遵循指令",这些都是模糊的目标。这部分的经验大多是靠踩坑踩出来的。

6.1 产品目标决定训练方案​

SmolLM3 的 post-training 目标很具体:混合推理助手。用户用 /think 触发深度推理,用 /no_think 要简洁回答。所有 SFT 数据和偏好数据的设计都围绕这个目标展开。

评估体系也是为了验证这个目标:

评估类型Benchmark在测什么
能力评估GPQA Diamond, AIME25, LiveCodeBench知识/数学/代码能不能做对
集成任务RULER, IFEval, TAUBench长上下文能不能用、指令能不能跟、工具会不会调
抗过拟合GSMPlus数学是不是真的学会了,还是背了答案

6.2 SFT:怎么把推理能力"写"进模型​

SFT 阶段的核心是数据设计。HF 做了几个关键决策:

数据配比按 token 数而非样本数:这是一个常见的坑。如果按样本数 50:50 配比 /think 和 /no_think,/think 样本通常更长,会导致推理数据占训练 token 的大头(可能 80%+)。所以应该按 token 数配比,SmolLM3 约 60% /no_think + 40% /think。

掩码用户输入:SFT 时只计算助手回复部分的 loss,不计算用户输入的 loss。这看似常识,但很多人会漏掉。

序列打包:把多个短对话拼成一个序列训练,吞吐量提升 3-5 倍。SmolLM3 采用,效果无差异。

超参数:lr 2e-5(预训练的 1/10),batch 128,训练 1-2 epoch。SFT 很容易过拟合,所以要控制 epoch 数。

6.3 偏好优化:为什么要用 APO-zero​

偏好优化的目标是让模型学会"什么回答是好的",而不仅是"学着做"。HF 对比了三种方案:

算法原理效果为什么选/不选
DPO直接用偏好对微调,概率上拉高 chosen、压 rejectedIFEval 提升 10%最稳定但提升有限
APO-zero在 DPO 基础上显式控制偏好强度,有专门的 margin 参数IFEval 提升 15-20%SmolLM3 采用,控制精度更高
ORPO把偏好信号集成进 SFT loss,无需参考模型接近 APO-zero需要更多偏好数据,HF 数据不够

关键超参数的经验值:

  • 学习率 = SFT 的 1/20(1e-6),偏好优化需要非常低的学习率
  • β=0.1:平衡"靠近偏好"和"不偏离 SFT 基础能力"
  • 169k 偏好对就够用:不需要海量数据,HF 用 Qwen3-32B vs Qwen3-0.6B 的对比生成偏好对

6.4 RL 的真实收益和风险​

HF 对 RL 的态度很务实:有明确验证性奖励的场景用 RL(代码能否执行、数学答案对不对),用 RLVR(基于验证奖励的 RL)。

SmolLM3 因为时间限制没做 RL,但他们做了实验验证:RLVR 能把 AIME25 从 10% 提到 20%。但同时也警告了 reward hacking——如果不控制输出长度,模型会生成超长回答来"碰运气"答对,实际上没有学会推理。


七、基础设施​

为什么没有基础设施一切归零​

HF 说得好:预训练是蛋糕,post-training 是糖霜,基础设施是烤箱。烤箱坏了,前面全白做。

7.1 GPU 选型与利用率​

GPUBF16 TFLOPs (理论)SmolLM3 实际利用率说明
H10099072-77% (714-758 TFLOPs)HF 主力,利用率已经不错但还有 20%+ 优化空间
A10031270-80%性价比选择
H20099075-79%H100 的大显存版

HF 的 GPU 验证流程:训练前用 GPU Fryer/DCGM 做诊断,SmolLM3 训练前发现了 2 块节流 GPU 并替换。

7.2 存储方案决定吞吐量上限​

这是 HF 在 SmolLM3 训练中踩过的大坑:

存储类型吞吐量延迟发生了什么
本地 NVMe RAID26.59 GiB/s190μs最终方案,从 FSx 迁移过来
FSx (Weka)4.21 GiB/s500μs最初采用,但数据被悄悄驱逐导致吞吐骤降
EBS1.1 GiB/s1ms+太慢,只适合小规模

教训:FSx 听起来是"管理服务很省心",但数据驱逐问题在生产环境是致命的。最终 HF 放弃 FSx,把数据全迁到本地 NVMe RAID,加一个备用节点来保证可靠性。

7.3 监控指标​

HF 对"健康训练"的定义:

  • GPU 温度 < 85℃
  • GPU 利用率 > 90%
  • 吞吐量:13.5-14k tokens/sec/GPU(H100)
  • 工具链:Prometheus + Grafana 实时监控 + Slack 告警

八、核心经验总结​

  1. 消融实验的顺序很重要:先调学习率 → warmup → batch size → 优化器,架构决策放在训练 recipe 稳定之后。在非稳定基线上做架构消融,结论不可复现
  2. 每次只改一个变量:组合修改 = 组合无知(compound ignorance),你不知道哪个变更起了作用
  3. 小尺度结论不一定在大尺度成立:SmolLM3 在 1T tokens 后发现小尺度消融的结果跟大尺度不完全一致,最终推倒重来。小尺度验证的是方向,不是最终结论
  4. 数据是关键杠杆:高质量的后期数据注入(如 MegaMath, Stack-Edu)比微调架构更有效
  5. 基础设施是默默决定成败的因素:存储慢了 → 吞吐量下降 → GPU 空转 → 钱和时间都在燃烧
  6. Post-training 的 SFT 数据配比很关键:按 token 数而非样本数配比 /think vs /no_think 数据;偏好优化数据量不需要很大(SmolLM3 只用 169k 偏好对)