状态:草稿(2026-10-31),实测。 所有训练均由笔者在单张 8GB 笔记本 GPU 上亲自运行。条件、学习率候选及判定标准在首次运行前均已记录(预注册),运行则严格按照该规则自动进行。论文数据为与 第 1 篇相同的原文核对版。 编写规则:以实测数据为基础,未能测得的标记为「未实测」,未确认的标记为「未确认」。
目录
- 1. 验证目标
- 2. 实验设计
- 3. 学习率搜索:不同优化器的「理想区间」各不相同
- 4. 正式运行:1 亿 Token,3 个随机种子
- 5. 大批大小:差距拉大
- 6. 事后检查:查看结果后产生的三个疑问
- 7. 解读
- 8. 局限性
- 原始数据
1. 验证目标
第 1 篇中看到的论文观点归纳为三个问题。
- 在相同的模型、数据和 Token 下仅更换优化器, 即使为各个优化器分别调整了学习率, Muon 是否仍能达到比 AdamW 更低的损失?
- MUON+ 的「正交化后归一化的一步」在这种规模下是否也能拉开差距?
- 增大批大小是否会拉大 AdamW 与 Muon 之间的差距(2505.02222、2608.25990 的观点)?
规模比论文中要小得多,是一个 3400 万参数的模型和 1 亿个 Token。因此本文的结论是「在此规模下表现如此」,而非用于验证或反驳论文。
2. 实验设计
模型与数据
- 模型:自研的 decoder-only Transformer(nanoGPT 系列)。维度 512,8 层,8 个注意力头,上下文长度 512,RMSNorm(前置归一化),RoPE,GELU MLP(4倍),无偏置,嵌入层与输出层分离。总参数量 3356 万,其中隐藏层二维矩阵占 2517 万。
- 数据:FineWeb-Edu(ODC-By 1.0)公开样本第一片段的前约 10 亿个字符。在此基础上直接训练了 8,192 词汇量的 Byte BPE。训练使用 2.60 亿 Token(1 Token ≈ 3.9 个字符),验证使用与训练不重叠的 4000 篇文档中的 52 万个 Token。
- 将词汇量缩减至 8k 的原因:如果使用 GPT-2 词汇量(5 万),在这个规模的模型中,嵌入层(2570 万)将大于隐藏层矩阵。而我们要比较的是隐藏层矩阵的优化器。
- 未混入韩语。因为在由英文文本生成的 8k 词汇表中,韩语会被拆分为字节单位,且混合比例会成为另一个变量。
控制变量
数据顺序(固定排列,所有运行以相同顺序处理相同的序列)、Token 预算、批大小、bf16 自动混合精度、torch.compile、梯度范数裁剪 1.0、学习率调度(WSD:前 2% 线性预热,中间保持不变,最后 20% 线性衰减至 0)、评估集。随机种子仅改变初始化。
三种优化器
| 隐藏层矩阵(q·k·v·o,两个 MLP) | 嵌入层·输出层·归一化层 | |
|---|---|---|
| AdamW | AdamW β=(0.9, 0.95),weight decay 0.1 | 同 AdamW(归一化层衰减为 0) |
| Muon | 涅斯捷罗夫动量 0.95 → Newton–Schulz 5次迭代(bf16) → sqrt(max(1, 行/列)) 校正 | 辅助 AdamW,学习率 = AdamW 搜索的最优值 |
| MUON+ | 与 Muon 相同,正交化结果再按列范数 → 行范数额外除以一次 | 同上 |
刻意匹配了两个方面。首先,将 Muon 运行中辅助 AdamW 的学习率固定为 AdamW 运行的最优值,从而确保两次运行的差异仅在于「隐藏层矩阵的优化器」这一个变量。其次,使 weight decay 在单步中权重缩减的比率(学习率 × λ)与 AdamW 保持一致。Muon 的学习率规范(大约 0.02)与 AdamW(大约 1e-3)相差约 20 倍,因此如果将 λ 同样设为 0.1,实际衰减幅度将相差 20 倍(第 1 篇第 4 节)。
MUON+ 与论文中的伪代码有两处不同。论文中没有使用涅斯捷罗夫动量,且大小校正为 sqrt(行/列),而此处保持与 Muon 完全相同,仅增加了一步归一化。由于论文提到「改变的只有这一步」,此选择旨在将差异缩小到该步骤,而大小差异则由学习率搜索来吸收。
学习率搜索与正式运行(预定规则)
- 搜索:5000 万 Token,批大小 64 个序列(32,768 个 Token,1525 步),随机种子 0。候选学习率:AdamW {1e-3, 2e-3, 4e-3, 8e-3},Muon {0.01, 0.02, 0.04, 0.08},MUON+ {0.02, 0.04, 0.08, 0.16}。挑选出产生最低最终验证损失的值,如果该值位于网格边界,则在该方向上再多跑一个点(仅限一次)。
- 正式运行:1 亿 Token(3051 步),批大小 64 个序列,采用各自的最优学习率,随机种子 0、1、2。
- 大批大小:1 亿 Token,批大小 256 个序列(131,072 个 Token,762 步),仅测 AdamW 与 Muon,学习率为批大小 64 最优值的 1 倍和 2 倍。表现较好的一方多测一个随机种子。
- 判定:如果最终损失差大于两个优化器种子标准差之和,则判定为「更优」,若小于则判定为「无显著差异」。
该顺序由执行脚本按规则自动串联,旨在杜绝查看结果后再进行人工干预的空间。
环境
单张 8GB 笔记本 GPU,PyTorch 2.9(CUDA 12.8),在 Kubernetes 上运行训练任务(Kubeflow Trainer)。每次运行结束时会保存验证损失曲线(约 40 个点)、吞吐量(排除前 11 步)以及 GPU 最大显存。
3. 学习率搜索:不同优化器的「理想区间」各不相同
| 优化器 | 学习率 → 最终验证损失(50M Token) | 选取的值 |
|---|---|---|
| AdamW | 5e-4: 3.863 · 1e-3: 3.727 · 2e-3: 3.829 · 4e-3: 4.315 · 8e-3: 6.351 | 1e-3 |
| Muon | 0.005: 3.611 · 0.01: 3.602 · 0.02: 3.633 · 0.04: 3.973 · 0.08: 5.195 | 0.01 |
| MUON+ | 0.01: 3.612 · 0.02: 3.643 · 0.04: 4.105 · 0.08: 5.186 · 0.16: 6.463 | 0.01 |
可以看出三个特点。
- 最优值本身相差约十倍。 AdamW 为 1e-3,Muon 为 0.01。这是由于第 1 篇中提到的「尺度校正规范」导致的。如果用相同的学习率数值进行比较,必然有一方会吃亏。
- AdamW 只要偏离最优值两倍,损失就会变差 0.10,偏离四倍则变差 0.59。而 Muon 在偏离最优值一半(0.005)和两倍(0.02)时,差距分别为 0.009 和 0.032。在此规模下,Muon 对学习率的敏感度较低。观察 AdamW 的曲线可以发现,它从一开始就稳定且缓慢,没有出现尖峰(Spike)。这可能是因为预热时间较短,因此在第 6 节中进行了单独验证。
- MUON+ 的曲线与 Muon 几乎完全相同。不过,MUON+ 的最优值(0.01)恰好是扩展后网格的边缘,因此 0.005 一侧表现更好的可能性依然存在(第 6 节)。
4. 正式运行:1 亿 Token,3 个随机种子
| 优化器 | 学习率 | 最终验证损失(平均值 ± 标准差) | 各种子表现 | 吞吐量(Token/秒) | GPU 最大显存 |
|---|---|---|---|---|---|
| AdamW | 1e-3 | 3.4896 ± 0.0026 | 3.4902, 3.4867, 3.4918 | 99,583 | 3.24GB |
| Muon | 0.01 | 3.4085 ± 0.0033 | 3.4087, 3.4117, 3.4052 | 94,170 | 3.15GB |
| MUON+ | 0.01 | 3.4214 ± 0.0029 | 3.4181, 3.4227, 3.4236 | 93,610 | 3.15GB |
判定(预定标准:差值 > 两个标准差之和)
- AdamW − Muon = 0.081,标准差之和 0.006 → Muon 更优。 在所有三个随机种子中,Muon 都比 AdamW 低 0.07 以上。
- AdamW − MUON+ = 0.068 → MUON+ 也优于 AdamW。
- Muon − MUON+ = −0.013,标准差之和 0.006 → 在此规模和学习率下, Muon 略优于 MUON+。 这与论文中 LLaMA-60M 的结果(MUON+ 略优,PPL 从 25.75 降至 25.25)方向相反。我们在第 6 节中重新审视了学习率位于网格边缘这一点。
达到相同损失所需 Token 数量
在曲线的中段固定学习率区间(2M–80M Token),两个优化器采用相同的调度策略,因此可以比较首次达到相同损失所需的 Token 数量。这与 2505.02222 中的 Token 比率 R = T(AdamW) / T(Muon) 定义相同。
| 目标损失 | AdamW 使用的 Token | Muon 使用的 Token | 比率 |
|---|---|---|---|
| 4.2 | 27.4M | 16.8M | 1.63 |
| 4.0 | 37.4M | 23.6M | 1.59 |
| 3.8 | 58.9M | 39.4M | 1.50 |
| 3.7 | 78.1M | 54.2M | 1.44 |
在达到相同损失时,AdamW 比 Muon 多消耗了 1.4–1.6 倍的 Token,且随着训练的进行,该比例逐渐减小。如果将最后的衰减阶段也计算在内,Muon 在 9020 万 Token 处就达到了 AdamW 的最终损失(3.490)(所有随机种子均如此)。不过,由于在衰减阶段损失会沿着调度曲线急剧下降,这种「约 10% 的节省」只能作为下限来看待。因为如果以 9000 万 Token 的预算从头开始运行 Muon,由于此时已经结束了衰减,损失可能会更低(该运行未实测)。
这比论文中提到的「达到相同损失可少用 10–15% 的 Token」(2505.02222,数亿至数十亿参数,达到 Chinchilla 规定倍数的 Token)的优势要大得多。这可能是因为模型较小(3400 万),且 Token 数量仅为参数量的约 3 倍,属于非常短的训练。从上表也可以看出,随着训练时间的延长,该比例确实在不断下降。
时间和内存
- Muon 的吞吐量比 AdamW 低 5.4%(94,170 对比 99,583 Token/秒)。这是因为每一步都需要进行 Newton–Schulz 矩阵乘法。而 MUON+ 的归一化步骤额外增加了 0.6% 的开销。
- 即便如此,从绝对时间来看 Muon 仍然领先。达到 AdamW 最终损失所需的训练时间,Muon 为 15.9 分钟,AdamW 为 16.5 分钟(必须运行到最后才能达到)。
- 在 GPU 内存方面,Muon 少用了 0.09GB。对于每个隐藏层矩阵,AdamW 需要维护两个状态(一阶和二阶矩),而 Muon 只维护一个(动量)。这与 2517 万参数 × 4 字节 ≈ 0.1GB 的计算结果相符。
5. 大批大小:差距拉大
我们将批大小扩大了4倍(131,072个token),并在762步中训练了相同的1亿个token。学习率在批大小为64的最佳值的1倍和2倍之间进行测试,并选择了较好的一方(两者都是1倍较好),然后用该值多跑了一个随机种子。
| 批大小 | AdamW | Muon | AdamW − Muon |
|---|---|---|---|
| 32,768个token(3,051步) | 3.490(种子3) | 3.409(种子3) | 0.081 |
| 131,072个token(762步) | 3.727(1e-3,种子2:3.726·3.729) | 3.508(0.01,种子2:3.507·3.509) | 0.219 |
| 大批大小的2倍学习率 | 3.936(2e-3) | 3.515(0.02) |
如果将相同的token以四分之一的步数使用,两者都会受损,但受损的幅度不同。AdamW恶化了0.24,Muon恶化了0.10。差距从0.081扩大到0.219,变成了2.7倍。固定学习率阶段的token比例也呈现相同的方向。在达到4.2损失时,token比在批大小64时为1.63,在批大小256时为1.78(在4.0时为1.59对1.76)。这与“在大批大小下,Muon的数据效率得以保持或增加”(2505.02222)以及“批大小越大,AdamW与Muon的差距越大”(2608.25990 表5:0.048 → 0.110)方向一致。
顺便一提,在大批大小下,Muon的吞吐量负担降到了1.5%(99,604对101,120 token/秒)。由于Newton–Schulz每步只运行一次,步数减少时其开销份额也会减少。
6. 事后检查:看到结果后产生的三个疑问
以下五个运行是在看到上述结果后决定的。因此,它们不用于改变上述判断,仅用于观察“该判断有多大可信度”。它们都只有一个随机种子。
| 疑问 | 运行 | 结果 | 对比对象 |
|---|---|---|---|
| MUON+的学习率达到了网格的边缘 | MUON+ 0.005,50M token | 3.5953 | MUON+ 0.01:3.6120,Muon最优 0.01:3.6018 |
| AdamW是否因2%的预热(30步)而受损 | AdamW 1e-3,预热10% | 3.7723 | 预热2%:3.7270 |
| 〃 | AdamW 2e-3,预热10% | 3.7235 | 预热2%:3.8286 |
| 大批大小的差距是否是因为预热时间短(15步)造成的 | AdamW 1e-3,批大小256,预热10% | 3.7082 | 预热2%:3.7271 |
| 〃 | Muon 0.01,批大小256,预热10% | 3.5192 | 预热2%:3.5082 |
- 当进一步降低学习率时,MUON+略微领先于Muon(在50M token时为0.006)。第4节中的“Muon优于MUON+”很可能是因为MUON+的学习率没有完全调好。不过,由于差值大约是种子波动(标准差约0.003)的两倍,在这个体量下,“两者几乎相同”才是诚实的结论。
- 当增加预热时,AdamW的最优学习率转移到了2e-3,但达到的损失几乎相同(3.7235对3.7270)。短预热并没有削弱AdamW的最佳表现。
- 在大批大小下,如果增加预热,差距从0.219缩小到0.189。 短预热使AdamW处于约0.02的不利地位,但“差距超过批大小64差距(0.081)两倍”这一结论依然成立。
7. 解读
- 在此体量下,Muon明显获胜。 在分别调整学习率、调整weight decay的实际强度并保持辅助AdamW相同时,差距仍然超过了种子波动的十倍。
- 这种优势在“短且大的批大小”情况下最为显著。 训练越处于初期,批大小越大,差距就越大。这与第1篇博客的图表一致,即当步数较少时,将每一步均匀分配到所有方向上更有价值。反过来说,在长训练中差距预计会缩小,论文中10–15%的数据也印证了这一点。
- MUON+带来的收益在此体量下与噪声无法区分。 在通过预定搜索选出的学习率下,它反而差了0.013;而在事后检查中降低学习率后,它领先了0.006。论文中60M模型的收益也很小(0.5 PPL)。“正则化的一步”是一个需要重新调整学习率才能见效的改动,而这种效果在小模型中很小。为了将差距缩小到正则化的一步而将Nesterov和大小校正设置得与Muon相同,这是与论文设置不同的地方。
8. 局限性
- 仅使用了一个模型(3,400万)、一份数据(FineWeb-Edu英语),以及1亿个token(约为参数量的3倍)。这不是一项用于确认或反驳论文结论(数亿至数千亿参数、长训练)的实验。
- 学习率是在50M token时选定的,并用在了100M token上。大批大小仅测试了两个学习率点。
- 预热(2%)、调度、β和weight decay并没有针对每个优化器单独调整。只调整了学习率这一个参数。
- 大批大小和MUON+测试了两到三个种子,而搜索只使用了一个种子。
- “达到相同损失所需的token数”仅在固定学习率阶段进行了测量。包含衰减阶段在内的准确节省比例需要通过改变预算的运行来进一步测算(未实测)。
原始数据
- 代码:
train_gpt.py(模型·优化器·训练循环),driver.py(预定搜索·正式运行·大批大小顺序),prep_data.py(数据·分词器),analyze_a.py·token_ratio.py(表格)。 - 原始数据:每次运行的
log.csv(各评估点的token数·验证损失·时间)和done.json(最终损失·吞吐量·内存),预注册文档PLAN.md. - 数据:FineWeb-Edu sample-10BT第一片段的行块0–213(ODC-By 1.0)。模型和优化器代码均为自行编写。