DeepSeek-V4知识点讲解记录
本文介绍了Hyper-Connections(HC)在Transformer架构中的创新应用。HC将传统的单条残差连接扩展为多条并行残差通道,每层操作包含三个关键步骤:通过输入映射A_l混合多条通道作为层输入,经过Transformer子层F_l计算后,使用输出映射C_l将结果分配回各通道,同时残差变换B_l实现通道间的信息交互。与普通残差连接相比,HC通过矩阵X_l∈ℝ^(n_hc×d)维护多通
你可以把这里的 Hyper-Connections 理解成:把原来“单条残差通道”扩展成“多条并行残差通道”,然后每一层都先从这些通道里混出一个输入,经过 Transformer 子层,再把输出分配回这些通道。论文说它把 residual stream 从 (\mathbb{R}^d) 扩展到 (\mathbb{R}^{n_{\mathrm{hc}}\times d}),并引入输入映射 (A_l)、残差变换 (B_l)、输出映射 (C_l) 三个线性映射。
先看普通残差连接。
在最常见的 Transformer 层里,残差大概是:
[
x_{l+1}=x_l+F_l(x_l)
]
这里:
[
x_l \in \mathbb{R}^d
]
表示第 (l) 层输入的隐藏向量,维度是 (d)。比如 (d=4096),那它就是一个长度 4096 的向量。
[
F_l(\cdot)
]
表示第 (l) 层的主体计算,比如 Attention 层或者 MoE/FFN 层。它吃进去一个 (d) 维向量,也输出一个 (d) 维向量。
所以普通残差就是:
[
\text{新状态}=\text{旧状态}+\text{本层加工后的结果}
]
也就是:
[
x_{l+1}=x_l+F_l(x_l)
]
它只有一条残差流。可以想象成一根管道:
x_l ────────────────┐
+ ──> x_{l+1}
x_l -> F_l(x_l) ────┘
而 标准 Hyper-Connections 不再只有一条残差流。它把残差状态扩展成 (n_{\mathrm{hc}}) 条残差流:
[
X_l =
[x_{l,1};\ldots;x_{l,n_{\mathrm{hc}}}]^T
\in \mathbb{R}^{n_{\mathrm{hc}}\times d}
]
这句话的意思是:
[
X_l
\begin{bmatrix}
x_{l,1}
x_{l,2}
\vdots
x_{l,n_{\mathrm{hc}}}
\end{bmatrix}
]
其中每一个 (x_{l,i}) 都是一个 (d) 维向量:
[
x_{l,i}\in\mathbb{R}^d
]
所以如果 (n_{\mathrm{hc}}=4),那 (X_l) 就是:
[
X_l
\begin{bmatrix}
\text{第 1 条残差通道,长度 }d
\text{第 2 条残差通道,长度 }d
\text{第 3 条残差通道,长度 }d
\text{第 4 条残差通道,长度 }d
\end{bmatrix}
]
也就是说,普通残差是一个向量:
[
x_l\in\mathbb{R}^d
]
而 HC 的残差状态是一个矩阵:
[
X_l\in\mathbb{R}^{n_{\mathrm{hc}}\times d}
]
现在看公式:
[
X_{l+1}=B_lX_l+C_lF_l(A_lX_l)
\tag{1}
]
这个公式可以拆成三步看。
第一步:(A_lX_l)
[
A_l \in \mathbb{R}^{1\times n_{\mathrm{hc}}}
]
它是一个行向量,比如 (n_{\mathrm{hc}}=3) 时:
[
A_l=
\begin{bmatrix}
a_1 & a_2 & a_3
\end{bmatrix}
]
而:
[
X_l=
\begin{bmatrix}
x_{l,1}
x_{l,2}
x_{l,3}
\end{bmatrix}
\in \mathbb{R}^{3\times d}
]
所以:
[
A_lX_l
\begin{bmatrix}
a_1 & a_2 & a_3
\end{bmatrix}
\begin{bmatrix}
x_{l,1}
x_{l,2}
x_{l,3}
\end{bmatrix}
]
结果是:
[
A_lX_l=a_1x_{l,1}+a_2x_{l,2}+a_3x_{l,3}
]
它的形状是:
[
A_lX_l\in\mathbb{R}^d
]
也就是说,(A_l) 的作用是:从多条残差通道里混合出一个真正送进第 (l) 层的输入。
可以理解成:
x_{l,1} ──┐
x_{l,2} ──┼── 加权混合 A_l ──> A_l X_l ──> F_l
x_{l,3} ──┘
第二步:(F_l(A_lX_l))
这一步就是正常 Transformer 子层计算。
[
F_l(A_lX_l)\in\mathbb{R}^d
]
因为论文里说 (F_l) 的输入和输出形状都是 (\mathbb{R}^d)。
也就是说:
[
A_lX_l
]
是送进 Attention 或 MoE 层的输入;
[
F_l(A_lX_l)
]
是这一层加工后的输出。
这一步和普通残差里的 (F_l(x_l)) 很像,只不过普通残差直接把 (x_l) 送进去,而 HC 是先从多条残差通道里混出一个输入再送进去。
第三步:(C_lF_l(A_lX_l))
[
C_l\in\mathbb{R}^{n_{\mathrm{hc}}\times 1}
]
比如 (n_{\mathrm{hc}}=3) 时:
[
C_l=
\begin{bmatrix}
c_1
c_2
c_3
\end{bmatrix}
]
而:
[
F_l(A_lX_l)\in\mathbb{R}^d
]
所以:
[
C_lF_l(A_lX_l)
\begin{bmatrix}
c_1
c_2
c_3
\end{bmatrix}
F_l(A_lX_l)
]
结果是:
[
\begin{bmatrix}
c_1F_l(A_lX_l)
c_2F_l(A_lX_l)
c_3F_l(A_lX_l)
\end{bmatrix}
\in\mathbb{R}^{3\times d}
]
也就是说,(C_l) 的作用是:把这一层的输出重新分配到多条残差通道里。
如果 (c_1) 大,说明第 1 条残差通道更多接收当前层输出;如果 (c_2) 小,说明第 2 条通道少接收一些。
第四步:(B_lX_l)
[
B_l\in\mathbb{R}^{n_{\mathrm{hc}}\times n_{\mathrm{hc}}}
]
比如 (n_{\mathrm{hc}}=3) 时:
[
B_l=
\begin{bmatrix}
b_{11} & b_{12} & b_{13}
b_{21} & b_{22} & b_{23}
b_{31} & b_{32} & b_{33}
\end{bmatrix}
]
它乘上:
[
X_l=
\begin{bmatrix}
x_{l,1}
x_{l,2}
x_{l,3}
\end{bmatrix}
]
得到:
[
B_lX_l
\begin{bmatrix}
b_{11}x_{l,1}+b_{12}x_{l,2}+b_{13}x_{l,3}
b_{21}x_{l,1}+b_{22}x_{l,2}+b_{23}x_{l,3}
b_{31}x_{l,1}+b_{32}x_{l,2}+b_{33}x_{l,3}
\end{bmatrix}
]
也就是说,(B_l) 的作用是:让旧的多条残差通道之间互相混合,形成下一层的旧状态部分。
普通残差里的旧状态部分是:
[
x_l
]
HC 里的旧状态部分变成了:
[
B_lX_l
]
所以 (B_l) 可以理解成“残差通道之间的混合矩阵”。
把三步合起来:
[
X_{l+1}=B_lX_l+C_lF_l(A_lX_l)
]
含义就是:
[
\text{下一层多通道残差状态}
\text{旧多通道残差状态的混合}
+
\text{当前层输出分配到多通道后的结果}
]
更直观地写:
多条旧残差通道 X_l
│
├── B_l 混合旧通道 ───────────────┐
│ │
└── A_l 混出一个输入 -> F_l -> C_l 分配回多通道
│
相加得到 X_{l+1}
所以,普通残差和 HC 的对比是:
| 类型 | 公式 | 含义 |
|---|---|---|
| 普通残差 | (\displaystyle x_{l+1}=x_l+F_l(x_l)) | 一条残差流,旧状态直接加当前层输出 |
| HC | (\displaystyle X_{l+1}=B_lX_l+C_lF_l(A_lX_l)) | 多条残差流,先混合输入,经过层,再分配输出,同时旧残差流之间也可混合 |
最关键的区别是:普通残差只有一个 (x_l),而 HC 有一个矩阵 (X_l),里面装着 (n_{\mathrm{hc}}) 条残差通道。论文强调,实际送进层里的 (A_lX_l) 仍然是 (d) 维,所以内部层 (F_l) 不需要改结构;只是外面的残差连接变丰富了。
一个很简单的类比:
普通残差像是:
主干道上的车流继续往前走,同时旁边工厂加工一批货,再并回主干道。
HC 像是:
有多条平行主干道。
每一层先从多条路上抽取一部分车流,混成一股,送进工厂加工。
加工完之后,再按比例分配回多条路。
同时,多条旧路本身也可以互相分流、换道。
其中:
[
A_l
]
负责“从多条路抽取、混成一股”;
[
F_l
]
负责“工厂加工”;
[
C_l
]
负责“加工结果分配回多条路”;
[
B_l
]
负责“旧车流在多条路之间换道”。
一句话总结:
普通残差是 (x_l) 这一个状态往前传;标准 HC 是 (X_l) 这一组状态往前传。(A_l) 把多条状态混成层输入,(F_l) 做层计算,(C_l) 把层输出分配回多条状态,(B_l) 则控制旧状态之间如何继续传播和混合。
是的,你抓到了关键:Muon 和普通 SGD/AdamW 的最大不同,主要就在它会对“更新矩阵”做 Newton-Schulz 近似正交化。其他部分,比如算梯度、动量、权重衰减、学习率缩放,确实和常见优化器的框架很像。
DeepSeek-V4 论文里也说,他们用 Muon 是因为它带来更快收敛和更好的训练稳定性;大多数模块用 Muon,但 embedding、prediction head、mHC 的静态偏置/门控因子、RMSNorm 权重仍保留 AdamW。
1. 先用最朴素的优化器理解
训练模型时,参数是一个矩阵:
[
W \in \mathbb{R}^{n\times m}
]
比如某个线性层的权重矩阵。
普通梯度下降大概是:
[
W_t = W_{t-1} - \eta G_t
]
其中:
[
G_t = \nabla_W L_t(W_{t-1})
]
就是当前 loss 对 (W) 的梯度。
直觉是:
梯度 (G_t) 告诉我们:往哪个方向改 (W),loss 会下降。
但是问题是,原始梯度矩阵可能很“不均衡”:有些方向特别大,有些方向特别小,有些行/列之间高度相关。直接拿它更新,可能导致训练抖动、某些方向更新过猛、某些方向学得很慢。
2. AdamW 好在哪里?
AdamW 可以先粗略理解为:它给每个参数元素单独调学习率。
普通 SGD 是:
[
W_t = W_{t-1} - \eta G_t
]
所有参数都用同一个全局学习率 (\eta)。
AdamW 会维护两个东西:
[
m_t
]
梯度的一阶动量,也就是“最近梯度方向的平均”。
[
v_t
]
梯度平方的平均,也就是“这个参数过去梯度有多大”。
然后大概更新为:
[
W_t = W_{t-1} - \eta \frac{m_t}{\sqrt{v_t}+\epsilon}
]
不用纠结细节,重点是:
如果某个参数历史梯度经常很大,AdamW 会自动把它的步子缩小;如果某个参数历史梯度比较小,它相对会走大一点。
所以 AdamW 的优势是 逐元素自适应缩放。
但它也有一个局限:它主要是按元素处理,比较像“每个格子单独调节”。对于矩阵参数来说,它不太直接考虑“这个矩阵作为整体的几何结构”。
3. Muon 好在哪里?
Muon 的核心想法是:对于矩阵参数 (W),不要只把梯度当成一堆独立数字,而要把它当成一个矩阵整体处理。
论文算法里关键步骤是:
[
O’_t = \mathrm{HybridNewtonSchulz}(\mu M_t + G_t)
]
然后:
[
O_t = O’_t \cdot \sqrt{\max(n,m)} \cdot \gamma
]
最后:
[
W_t = W_{t-1}\cdot(1-\eta\lambda)-\eta O_t
]
这里 (O_t) 才是真正拿去更新参数的方向。
也就是说,Muon 不是直接用:
[
G_t
]
或者动量后的:
[
M_t
]
去更新,而是先把更新方向送进:
[
\mathrm{HybridNewtonSchulz}(\cdot)
]
做一次“矩阵正交化/白化式处理”。
4. 什么叫把更新矩阵“正交化”?
论文后面说,对于一个矩阵 (M),假设它的 SVD 是:
[
M = U\Sigma V^T
]
Newton-Schulz 迭代的目标是把 (M) 近似正交化为:
[
UV^T
]
也就是把中间的奇异值矩阵:
[
\Sigma
]
基本去掉,只保留方向结构:
[
U V^T
]
直观理解:
[
M = U\Sigma V^T
]
里面:
- (U,V):表示方向;
- (\Sigma):表示每个方向上的强度大小。
如果某些奇异值特别大,说明某些方向更新特别猛;如果某些奇异值特别小,说明某些方向几乎不动。
Muon 的正交化大概是在说:
我相信这个矩阵更新的“方向”有用,但不希望它在某些方向上过度放大、在某些方向上过度缩小。
所以我把它处理成一个更均衡的矩阵更新方向。
5. 为什么这会更稳定、更快?
你可以把普通梯度矩阵想成一个“变形很严重的推力”。
比如某次更新里,梯度矩阵在某个方向上强度是 100,在另一个方向上强度是 0.01。直接更新会导致:
强方向:一步迈太猛,容易震荡
弱方向:几乎不动,学得很慢
AdamW 会做逐元素缩放,但它不一定能很好处理矩阵整体的方向相关性。
Muon 通过近似正交化,让更新矩阵的不同方向更均衡。直觉效果是:
不要让一个方向主导整个矩阵更新;
让矩阵参数在多个方向上更均匀、更稳定地前进。
所以它可能带来:
- 更快收敛:有效方向不被病态尺度拖慢;
- 更稳定训练:避免某些矩阵方向更新过大;
- 更适合大矩阵权重:比如 Attention、MLP、MoE 里的线性权重矩阵。
这也是为什么 DeepSeek-V4 不是所有参数都用 Muon,而是“多数模块”用 Muon,一些非矩阵型或特殊参数继续用 AdamW。
6. 和 AdamW 的差异可以这么看
| 优化器 | 核心处理对象 | 主要想解决什么 |
|---|---|---|
| SGD | 整个梯度直接走 | 简单,但容易受梯度尺度影响 |
| Momentum SGD | 梯度方向做滑动平均 | 减少抖动,利用历史方向 |
| AdamW | 每个参数元素自适应缩放 | 不同参数梯度尺度不同的问题 |
| Muon | 对矩阵更新方向做近似正交化 | 矩阵整体方向不均衡、病态尺度问题 |
AdamW 像是:
每个参数格子自己调步长。
Muon 像是:
先看整个权重矩阵的更新方向,把这个矩阵更新方向整理得更“端正”、更均衡,再更新。
7. Hybrid Newton-Schulz 是不是唯一重点?
可以说它是 Muon 在这篇论文里最关键、最不普通的部分。
不过完整 Muon 还有几个配套点:
第一,动量
[
M_t=\mu M_{t-1}+G_t
]
这个和普通 momentum 类似,用来平滑梯度方向。
第二,Nesterov trick
算法里是:
[
\mathrm{HybridNewtonSchulz}(\mu M_t+G_t)
]
它不是只用当前动量 (M_t),而是用一个类似 Nesterov 的 lookahead 方向,让更新更有前瞻性。
第三,Newton-Schulz 正交化
这是最核心差异。
第四,RMS 重缩放
[
O_t = O’_t\cdot \sqrt{\max(n,m)}\cdot\gamma
]
正交化之后,更新矩阵的尺度会变,所以要重新缩放到合适大小。论文说这样可以复用 AdamW 的超参数。
第五,权重衰减
[
W_t = W_{t-1}\cdot(1-\eta\lambda)-\eta O_t
]
这和 AdamW 的 decoupled weight decay 类似,防止权重无限变大。
所以你可以这么记:
Muon = Momentum/Nesterov + 矩阵更新正交化 + 重缩放 + AdamW 式权重衰减。
真正让它区别于你朴素理解的优化器的,是“矩阵更新正交化”。
8. 为什么不用精确 SVD,而用 Newton-Schulz?
如果目标是:
[
M=U\Sigma V^T
]
然后取:
[
UV^T
]
最直接的方法是做 SVD。
但 SVD 对大模型训练来说太贵了。每个 step、每个大矩阵都做 SVD,基本不可接受。
Newton-Schulz 的好处是:它用矩阵乘法迭代来近似这个正交化过程。
论文里的迭代是:
[
M_k
aM_{k-1}
+
b(M_{k-1}M_{k-1}^T)M_{k-1}
+
c(M_{k-1}M_{k-1}T)2M_{k-1}
]
它本质上是在用多项式迭代把奇异值推向 1。DeepSeek-V4 用 10 步 hybrid Newton-Schulz:前 8 步用一组系数快速靠近,后 2 步用另一组系数稳定到 1 附近。
所以它是:
想要 SVD 正交化的效果,
但不用真的做昂贵 SVD,
而是用几次矩阵乘法近似实现。
9. 一句话回答“好在哪里”
Muon 好在:它把大模型里的矩阵参数更新方向做了近似正交化,让不同矩阵方向的更新更均衡,从而可能更快收敛、更稳定训练。
你现在的理解可以改成:
普通优化器主要处理“梯度往哪里走”和“步长多大”;AdamW 进一步给每个参数元素自适应步长;Muon 则把权重矩阵作为整体,在更新前把矩阵方向整理成更接近正交、尺度更均衡的更新方向。它真正特殊的地方就是 Hybrid Newton-Schulz 近似正交化,其他步骤是为了让这个更新方向更平滑、更可控、更适配大模型训练。
更多推荐



所有评论(0)