Gram Newton–Schulz#
本页内容6 个部分
查看概览图
把五轮大矩形迭代
折叠进 Gram 空间
算法重排减少长方形 GEMM;restart 控制半精度漂移;symmetric kernel 再砍掉约一半方阵 MMA。
每一轮都碰大矩形 X
Xt · n × m
-
对称
A = X · Xᵀ -
对称
B = bA + cA² -
一般 GEMM
X ← aX + BX
循环主体只保留 n × n 方阵
-
INIT
建立 Gram 状态
R₀ = XXᵀ · Q₀ = I -
1—2
方阵内迭代
Z = aI + bR + cR²Q ← QZ · R ← ZRZ -
↻
Restart
X ← QX · R ← XXᵀ · Q ← I截断伪负特征值与 eigenvector drift -
3—5
继续方阵迭代
最后一次 QX 得到输出
下三角
对称结果只做约一半 MMA,再镜像写回上三角
适用:XXᵀ、R²、ZRZ 不适用:BX 一般 GEMM
主来源:Dao AI Lab, Gram Newton-Schulz: A Fast, Hardware-Aware Newton-Schulz Algorithm for Muon(Jack Zhang, Noah Amsel, Berlin Chen, Tri Dao, 2026)。开源实现:Dao-AILab/gram-newton-schulz。
Muon 用 Newton–Schulz(NS)近似动量矩阵的 polar factor。标准 NS 每一轮都要对大矩形矩阵做乘法;Gram Newton–Schulz(Gram NS)通过代数重排,把大部分迭代搬到更小的方形 Gram 矩阵上,再配合对称 GEMM kernel 降低计算量。
一句话版本:
Gram NS = 只在开始、restart 和结束时碰大矩形矩阵 ,其余时间在小方阵 上累计逆平方根多项式;再用 symmetric GEMM 只算半个输出。 它对长方形权重最有利,但必须用 restart、FP16 和安全缩放控制半精度误差。
1. 计算问题与 Gram 改写#
1.1 Muon 为什么要做 polar decomposition#
设某层权重为 ,梯度为 。Muon 先积累矩阵动量:
然后用动量矩阵的 polar factor 作为更新方向:
如果
那么
这里取只包含非零奇异值的紧 SVD;秩亏时得到 canonical partial isometry,零奇异值不会被奇多项式变成 1。直觉上,这一步保留 的左右奇异向量,但把奇异值大致压到 。精确 SVD 太贵,Muon 因此用若干轮五次多项式 Newton–Schulz 近似它:
由于
时有
所以 NS 不改变奇异向量,只对每个奇异值应用标量多项式:
只要多轮复合后的 把相关区间内的奇异值送到 附近,就得到 的近似。
1.2 标准 Newton–Schulz 慢在哪里#
实践中通常把 转置到短边在前。设
一轮标准 NS 可以写成:
A = X @ X.mT
B = b * A + c * (A @ A)
X = a * X + B @ X
对应的主计算量为:
| 乘法 | 输出形状 | FLOP |
|---|---|---|
轮共需要:
Muon 常用 ,也就是:
真正的问题不是方阵 ,而是每一轮都有两次涉及 的大矩形乘法:
X @ Xᵀ # 构造 Gram
B @ X # 把多项式作用回 X
MLP、GQA/MLA 投影和细粒度 MoE expert 的权重往往很长方, 越大,这两项越占主导。
1.3 核心改写:直接在 Gram 空间里迭代#
当 满行秩时,polar factor 还有一个等价表达(秩亏时须在非零谱上取逆平方根,即用伪逆):
这意味着不必每轮都显式构造新的长方形 。可以改成:
1. R₀ = XXᵀ # 一次大矩形乘法
2. 在 n×n 的 R₀ 上近似 Q ≈ R₀⁻¹ᐟ² # 主要迭代
3. X_out = QX # 一次大矩形乘法
如果 ,那么 都只是 ;相较于每轮都操作 的 ,计算量显著下降。
这也是 “Gram Newton–Schulz” 名字的来源:主要状态从长方形 变成了 Gram 矩阵 。
2. 等价性与计算成本#
2.1 为什么这种改写与标准 NS 数学等价#
五次奇多项式可以分解为:
对一个标量奇异值 ,定义:
并迭代:
那么有:
其中:
- ,跟踪当前奇异值的平方;
- (),累计从输入到当前输出的缩放;
- 当 时,。
把它提升到矩阵,就是 Naive Gram NS:
最后返回:
在精确算术中,它与逐轮生成 的标准 NS 等价;差别只是计算顺序。
2.2 标准 NS 与 Gram NS 的执行路径#
标准 NS#
X = normalize(X)
for a, b, c in coefficients:
A = X @ X.mT
B = b * A + c * (A @ A)
X = a * X + B @ X
return X
特点:
- 每轮都更新 的 ;
- 每轮两次乘法涉及长方形 ;
- 中间误差不会在一个单独的逆平方根状态中长期积累,因此相对稳健。
Naive Gram NS#
X = normalize(X)
R = X @ X.mT
Q = I
for a, b, c in coefficients:
Z = a * I + b * R + c * (R @ R)
Q = Q @ Z
R = Z @ R @ Z
return Q @ X
特点:
- 循环主体只操作 方阵;
- 开始和结束各有一次长方形乘法;
- 精确算术等价,但半精度下可能不稳定。
2.3 FLOP 节省来自哪里#
如果使用 symmetric GEMM,Naive Gram NS 在 时的成本是:
实际的稳定版本需要一次 restart,成本变成:
取一个常见例子:。
| 实现 | FLOP(省略公因子 ) | 相对普通实现 |
|---|---|---|
| 普通 NS,无 symmetric kernel | baseline | |
| 标准 NS + symmetric kernel | 少约 28% | |
| Stabilized Gram NS | 少约 58% |
所以稳定 Gram NS 相比已经使用 symmetric GEMM 的标准 NS 仍少约 42% FLOP。
如果 ,Gram NS 在 FLOP 上没有优势,而且会启动更多 GEMM;文章的实现对方阵回退到标准 NS。收益主要来自长方形权重,而不是所有形状。
3. 有限精度稳定性#
3.1 最大难点:精确等价不等于半精度稳定#
理论上:
所以 的特征值都应非负。但在 FP16/BF16 中,构造 Gram 矩阵会引入很小的伪负特征值,例如 。
Gram NS 本质上在近似:
对负特征值做实数逆平方根迭代没有意义。虽然这些负值最初只是舍入噪声,迭代映射却会不断放大其绝对值:
伪负特征值出现
↓
R_t 的负方向指数放大
↓
Z_t 变大
↓
Q_t 和最终 X_t 爆炸
↓
Inf / loss spike
文章还观察到第二种误差:eigenvector drift。精确算术中 都是同一个 Gram 矩阵的多项式,应该共享特征向量;半精度乘法会逐渐破坏这种关系,使不同谱方向互相污染。
因此,Naive Gram NS 虽然代数上正确,却不能直接用于半精度训练。
3.2 Restart:用少量大矩形乘法换稳定性#
解决办法是在连续运行几轮 Gram 迭代后,把累计变换真正作用回 ,再从新的 重建 Gram 状态:
# 先在 Gram 空间运行两轮
...
# restart
X = Q @ X
R = X @ X.mT
Q = I
# 再运行剩余轮次
...
对五轮 Polar Express 类系数,文章推荐在前两轮后 restart。它有三个作用:
- 截断伪负特征值的连续放大;
- 清除 之间累计的 eigenvector drift;
- 重新建立与当前 一致的 。
restart 越多越稳定,但每次都会新增:
也就是两次涉及大矩形 的乘法。极端情况下每轮都 restart,就退化成标准 NS。因此 restart 是速度与稳定性的调节旋钮。
3.3 其他稳定性措施#
FP16 优先于 BF16#
Gram NS 已把数值尺度控制在 附近,不太需要 BF16 的大动态范围。FP16 尾数精度更高,文章因此默认使用 FP16;他们报告两者的训练 loss 没有明显差异,但 FP16 在部分测试矩阵上更准确。
更保守的 safety factor#
理论多项式通常只保证在 时稳定。舍入误差可能让奇异值略大于 ,因此 Polar Express 会做安全缩放。文章建议 Gram NS 使用更保守的值,例如从 1.02 调到 1.05。
不显式构造 #
朴素写法:
会先把整个 舍入回 FP16,然后再参与后续 GEMM,损失 的精度。文章改成:
这样 、 可以在 GEMM epilogue 的 FP32 accumulation 中处理。
高精度数值计算要谨慎#
对满行秩矩阵、使用谱条件数时,显式形成 会平方条件数:
Muon 只需要近似正交化,通常可以接受;如果目标是高精度 polar decomposition,Gram NS 未必合适。
4. Kernel 实现与证据#
4.1 Symmetric GEMM kernel:只做下三角 MMA#
文章的第二层贡献是 Hopper/Blackwell 上的 CuTeDSL symmetric GEMM。它不局限于经典 SYRK,还支持在已知结果对称时计算:
或融合形式:
执行方式:
普通 GEMM tile grid symmetric GEMM tile grid
■ ■ ■ ■ · · · ·
■ ■ ■ ■ ■ · · ·
■ ■ ■ ■ ■ ■ · ·
■ ■ ■ ■ ■ ■ ■ ■
全矩阵执行 MMA 只给下三角分配工作
epilogue 同时写 (i,j) 和 (j,i)
工程要点:
- triangular scheduler 只调度下三角 tile,并均匀分配给 CTA cluster;
- 非对角 tile 算完后,同时转置写入上三角;
- 对角 tile 只写一次;
- 对称信息省掉约一半 MMA,但不会省掉最终完整矩阵的存储;
- 对标准 NS, 和 走 symmetric GEMM, 仍是一般 GEMM+Add。
只换 kernel、不改算法时,文章报告标准 NS 在 Hopper 上已经能快约 26–29%。
4.2 实验结果应该怎样解读#
作者在 Llama-430M、Qwen-600M、Gemma-1B 和自定义 MoE-1B 上测试,并报告:
- 验证集 perplexity 与标准 Muon 的差异保持在
0.01内; - orthogonalization / Newton–Schulz 子步骤减少约 40–50% 时间;
- 长方形权重的 NS 最高约
2×; - 对模拟 Kimi K2 的细粒度 MoE 权重配置,Hopper 和 Blackwell 上均报告约
2×NS speedup。
必须区分:“NS 子步骤快 2×”不等于“整个训练快 2×”。
如果 NS 原来只占训练 step 的比例 ,把它加速 倍,Amdahl 定律给出的整体 speedup 是:
例如 时,整体只快约 1%; 时,整体约快 9%。这项优化在以下场景更重要:
- 前后向已使用 FP8/更低精度,而 NS 仍需 16-bit;
- SFT/RL 的全局 batch 较小,前后向工作较少;
- 大规模 pipeline 中 optimizer step 难以被 backward 完全隐藏;
- 权重高度长方形,尤其是细粒度 MoE expert。
4.3 它和 batched SYRK PR 不是同一个改动#
NVIDIA Emerging-Optimizers 的 batched SYRK PR #276 做的是:
A = batched_syrk(X) # X @ Xᵀ,只算下三角并镜像
B = batched_syrk(A, A) # bA + cA²
X = torch.baddbmm(X, B, X, beta=a)
它仍然是标准 NS:每轮都更新长方形 ,只是前两个对称乘法换成 batched SYRK。
Dao Lab 的 Gram NS 则是:
算法重排:不再每轮更新长方形 X
+
restart:控制 Gram 空间的半精度误差
+
symmetric GEMM:加速方形对称乘法
+
fused GEMM epilogue:减少中间 I/O 和舍入
因此两者的包含关系更接近:
| 方案 | 算法路径 | 利用对称性 | 是否减少每轮长方形 GEMM |
|---|---|---|---|
PyTorch baddbmm NS |
标准 NS | 否 | 否 |
| Batched SYRK NS | 标准 NS | 是 | 否 |
| Gram NS | Gram 空间重排 | 是 | 是 |
4.4 阅读时应保留的边界条件#
- 等价只在精确算术中成立。 半精度下,计算顺序改变会产生不同结果。
- 形状决定收益。 方阵应回退到标准 NS;长方形矩阵才有明显算法收益。
- 性能数字依赖硬件和 batch。 文中的 kernel 主要针对 Hopper/Blackwell,不能直接外推到任意 GPU。
- restart 位置不是普适常数。 换多项式系数或迭代次数后,应重新调 restart。
- Gram 会平方条件数。 它适合 Muon 的近似正交化,不自动等价于通用高精度 polar solver。
- 2× 是局部 speedup。 是否改善 end-to-end 训练,要看 NS 在总 step 中的占比与并行隐藏情况。
参考链接#
- Dao AI Lab:Gram Newton-Schulz
- 开源实现:Dao-AILab/gram-newton-schulz
- 对称 GEMM:Dao-AILab/quack
- NVIDIA batched SYRK PR #276
- NVIDIA 原始 Triton SYRK PR #47
4.1 要点回顾#
Gram Newton–Schulz 的核心不是“发现 对称”,而是把 NS 的累计多项式从长方形 搬到小方形 Gram 空间,再用 restart 修复这种重排在半精度下产生的谱误差。 Symmetric GEMM 是第二层加速;长方形越强、NS 越难被隐藏,收益越大。
延伸阅读#
- Triton Kernel 实现练习:怎样从逐元素计算走到归约、矩阵乘法和 Attention?