超连接与 Sinkhorn:残差流为什么要开四条副本
残差连接从"系数恒为 1 的一条线"变成"4 份并行副本 + 每层自算 pre/post/combine 系数",再用 20 次 Sinkhorn 迭代把混合矩阵压成双随机矩阵。顺带解释官方 Prerequisites 里那句看起来毫不相干的 mHC + AITER 说明,以及为什么 AMD 镜像必须够新。
本篇属于系列 关于deepseek部署你要知道的一切 · 第 7 篇
来源:vLLM Recipes · deepseek-ai/DeepSeek-V4.1-Flash(页面标注 Updated 2026-09-20)
说明 本文是系列《关于deepseek部署你要知道的一切》的第 7 篇,面向只熟悉 vanilla transformer 的读者,把官方页面里的术语逐个拆开解释。文中所有数字、参数与命令均来自上述页面,未作独立核实。
一句话结论
残差连接是 transformer 里最不起眼、也最不能动的一根线:x → x + f(x),系数永远是 1。
超连接(Hyper-Connections)把它改成了四条并行的副本,并且让每个子层自己算出“怎么读、怎么写、怎么混合”这三组系数;
为了不让 40 层叠下来把信号放大到爆炸或衰减到消失,混合矩阵被 20 次 Sinkhorn 迭代压成双随机矩阵。
这是全系列里官方描述最短、也最“反直觉”的一个改动——但它的部署含义很实际:它多出了一些小算子,而这些算子在不同 GPU 上走的内核不一样。
先复习:残差连接为什么重要
一个 transformer block 的骨架其实就一句话:
x = x + 子层(x) # x 是残差流,子层是注意力或 FFN
- **残差流(residual stream)**是模型的“主干道”:每一层都往上面加一点东西,然后交给下一层。
- 如果没有这个
+x,40 层叠起来的梯度会消失或爆炸,深层网络根本训不动。 - 主干道的宽度(hidden size)是固定的:这台模型是 5120。
超连接的做法是:把这条主干道从 1 条变成 4 条并行副本。 对应到工程上,就是“残差流的有效宽度变成了 4 × hidden”——信息可以在四条线上分头流动、互相交换。
官方那段话的逐句拆解
残差流以 4 份并行的副本承载;每个子层从流中推导出自己的 pre / post / combine 系数, 其中 combine 矩阵通过 20 次 Sinkhorn 迭代被做成双随机矩阵。
① “每个子层推导自己的系数”——把固定值 1 变成可学习的函数。
原来的 x + f(x),系数是写死的(1 和 1)。现在每个子层都要先看一眼当前的残差流,
算出三组数:pre(进入子层前怎么读)、post(子层的输出怎么加权写回)、combine(四条副本之间怎么混合)。
直观理解:网络自己决定“这一层该多大程度上改动主干”,而不是所有层一视同仁。
② “combine 矩阵做成双随机矩阵”——这是一句安全保证。 双随机矩阵(doubly stochastic matrix)的定义很朴素:每个元素非负、每行之和为 1、每列之和为 1。 它的直觉意义是”软置换“——只是在四条副本之间重新分配信息总量,既不凭空放大,也不凭空抹掉。 (对比一下:如果只是个普通矩阵,40 层连乘下来,数值可能指数级漂移。)
③ “20 次 Sinkhorn 迭代”——怎么把一个矩阵变成双随机。 Sinkhorn–Knopp 是一个经典算法:交替把每一行的和归一化成 1,再把每一列的和归一化成 1,重复若干次, 它会收敛到双随机矩阵。这里的“20 次”就是这个重复次数。 (提醒:双随机的定义和 Sinkhorn 迭代属于通用数学背景,页面只写了结论,没有展开推导。)
为什么这件事值得单独写一篇
因为它示范了 2026 年前后模型架构改动的一个典型套路:主干结构不动,动的是“主干怎么被读写”。 注意力、FFN、MoE 这些大件大家都熟;超连接改的是“连接本身”——改动小、收益可能不小, 但代价是多出来一批形状奇怪的小算子(pre/post/combine 的逐元素运算和 4×4 的混合), 它们既不像矩阵乘法那样能吃满张量核心,也不像 elementwise 那样可以随便融合。
这正好解释了官方页面在 Prerequisites 里那句看起来毫不相关的话:
vllm-project/vllm#56503——那项改动把 mHC 的 delayed pre block 从 eager Torch 参考实现移到 AITER 上,时间上晚于 0909 标签。
翻译一下:超连接里那个“pre 计算”的算子,最初是用 PyTorch 的 eager 模式(一行行老老实实算,慢)跑的,
后来才被搬到了 AMD 的 AITER 内核库里。所以你要用 AMD 跑这台模型,镜像必须足够新——
这也就是为什么官方说“不能用发布当天的 deepseekv41-chat-0909 标签”。
一个细节:图像 embedding 是“展开之前”进来的
官方在 Images 一节里有一句话值得和本篇对照着看:
合并后的 embedding 以
inputs_embeds进入文本模型,位置在超连接流展开之前。
说明超连接是在文本模型的入口处就展开了:图像向量和文本向量一起,作为同一条主干道的起点, 而不是在四条副本铺开之后再插进来。这对多模态场景很重要——图和文从第一层起就在同一条路上。
三个常见误解
你以为:四条副本 = 四倍计算量。 实际上:副本的宽度是分摊的(总宽度量级不变),多出来的主要是那些系数计算和混合运算的开销, 不是“跑四遍模型”。
你以为:Sinkhorn 是一种训练方法或优化器。 实际上:它只是一个数值归一化算法(交替行/列归一化),在这里用来保证混合矩阵的数值性质。 它出现在训练好的模型里做前向计算,不涉及梯度。
你以为:这是 V4.1 独有的新发明。 实际上:超连接是一条独立的研究线(把残差连接“加宽 + 可学习化”);V4.1 把它和稀疏注意力、Engram 一起装进了同一个模型。 理解它的意义在于:当一个模型的参数账、内核选择出现奇怪的小项时,往往就是这类小机制在收钱。
术语卡片
| 术语 | 中文 | 一句话定义 |
|---|---|---|
| Hyper-Connections | 超连接 | 把残差流拆成 4 份并行副本、并让每个子层自算读写系数的残差改造 |
| residual stream | 残差流 | transformer 的主干道,每层往上累加输出 |
| pre / post / combine | 读 / 写 / 混合系数 | 子层自己推导的三组系数,决定怎么读主干、怎么写回、副本之间怎么混合 |
| doubly stochastic matrix | 双随机矩阵 | 元素非负、行和列和都为 1 的矩阵,语义上是“软置换” |
| Sinkhorn iterations | Sinkhorn 迭代 | 交替行/列归一化,把矩阵逼成双随机的算法,这里迭代 20 次 |
| mHC delayed pre block | mHC 延迟 pre 块 | 超连接里的 pre 计算块;AMD 上需 PR #56503 才走 AITER 内核 |
小结
- 残差连接从“固定系数 1”变成“4 副本 + 可学习系数”,主干道的读写方式由每一层自己决定。
- 20 次 Sinkhorn 迭代把它约束成双随机矩阵——保证是“信息的重新分配”,不是放大或衰减。
- 部署含义是内核层面的:这些额外算子在不同 GPU 上走不同实现(AMD 上需要较新的镜像才走 AITER), 所以镜像版本不是“越旧越稳”,而是必须够新。
下一篇:《1M 上下文怎么来的:RoPE、YaRN 与 theta》——回到长上下文,看看 65,536 的训练窗口是怎么被撑到 1,048,576 的。
讨论
这里是静态站点,没有内嵌评论区。如果这篇文章对你有用,欢迎通过 RSS 订阅后续更新。