返回博客

Gated DeltaNet:遗忘什么,改写什么?

从残差写入推导门控次序、非正交干扰与因果分块,并用可复现 CPU 对照界定固定状态和混合模型的缓存预算。

把越来越长的上下文装进一个固定大小的矩阵,究竟保留了什么?Gated DeltaNet 给出的答案不是把所有历史 key/value 换一种存法,而是不断衰减旧状态、预测当前关联,再按预测残差改写记忆。固定状态的代价,就落在“遗忘什么、覆盖什么,以及哪些查询会被连带改变”上。

本文解读 Songlin Yang、Jan Kautz 和 Ali Hatamizadeh 的 Gated Delta Networks: Improving Mamba2 with Delta Rule。论文首次上传于 2024 年 12 月 9 日,本文读的是 2025 年 3 月 6 日的 v3,并核对 ICLR 2025 正式出版记录。这是一篇基础报告的深入分析,不是今日新发布。Qwen3-Next 的 2025 年 9 月 11 日公告,以及 Qwen3.5 的 2026 年 2 月 16 日公告,提供了该机制进入混合模型的公开背景;它们不等同于本文独立验证了整模型效果。正式论文;v3 正文;Qwen3-Next 公告;Qwen3.5 公告。

一、从最小关联记忆开始:读出不是 softmax

先只看一个头的数学核心。令 token 位置为 \(t\),query/key 宽度为 \(d_k\),value 宽度为 \(d_v\)。矩阵状态把一个 key 映射为一个 value:

\[\mathbf q_t,\mathbf k_t\in\mathbb R^{d_k},\quad\mathbf v_t\in\mathbb R^{d_v},\quad\mathbf S_t\in\mathbb R^{d_v\times d_k},\qquad\mathbf o_t=\mathbf S_t\mathbf q_t\]

这里采用列向量,状态的 value 维在前。为推导方向替换,后文会明确假设 \(\lVert\mathbf k_t\rVert_2=1\);实际实现的归一化含 epsilon,不能把近似单位长度悄悄当成精确等式。读出缩放可吸收到 \(\mathbf q_t\) 中。短卷积、输出归一化、输出门和前后投影暂时移出核心,并不意味着完整网络没有这些环节。

以零初态 \(\mathbf S_0=\mathbf0\) 为例,最小基线是加法式线性记忆:

\[\mathbf S_t=\mathbf S_{t-1}+\mathbf v_t\mathbf k_t^\top,\qquad\mathbf o_t=\sum_{i\le t}\mathbf v_i(\mathbf k_i^\top\mathbf q_t)\]

每个新关联贡献一个外积。展开后,读出是所有 value 按 key/query 内积的加权和,但这些权重没有 softmax 的指数、正性和归一化保证。重复写入同一 key 会继续叠加;相似 key 也会混在一起。它改变了记忆算子,不能把它解释成对完整 softmax 注意力的无损实现。

二、delta 写入的是误差,遗忘门先作用于旧状态

若把状态看作一个临时线性预测器,当前关联可以用平方误差描述:

\[\ell_t(\mathbf S)=\frac12\lVert\mathbf S\mathbf k_t-\mathbf v_t\rVert_2^2,\qquad\nabla_{\mathbf S}\ell_t=(\mathbf S\mathbf k_t-\mathbf v_t)\mathbf k_t^\top\]

在旧状态上走一步大小为 \(\beta_t\) 的梯度更新,就得到 delta rule:

\[\mathbf S_t=\mathbf S_{t-1}+\beta_t(\mathbf v_t-\mathbf S_{t-1}\mathbf k_t)\mathbf k_t^\top\]

因此,它不是每次再存一份 \(\mathbf v_t\),而是先预测 \(\mathbf S_{t-1}\mathbf k_t\),再修正当前关联的误差。这里更新的是会话中的快权重状态,不是把模型的所有训练参数在推理时做一次优化。

Gated DeltaNet 再加入旧状态衰减。正确次序是:

\[\widetilde{\mathbf S}_t=\alpha_t\mathbf S_{t-1},\quad\mathbf e_t=\beta_t(\mathbf v_t-\widetilde{\mathbf S}_t\mathbf k_t),\quad\mathbf S_t=\widetilde{\mathbf S}_t+\mathbf e_t\mathbf k_t^\top\]

合并可得论文式 (10) 对应的递推:

\[\mathbf S_t=\alpha_t\mathbf S_{t-1}(\mathbf I-\beta_t\mathbf k_t\mathbf k_t^\top)+\beta_t\mathbf v_t\mathbf k_t^\top\]

原始常规设定中 \(0<\alpha_t<1\)、\(0<\beta_t<1\)。本文使用 0、1 端点来说明极限行为或检查实现,会明确标注;有限 sigmoid 等参数化不保证精确达到端点。关键接口是残差读取已衰减的状态。先用旧状态做 delta 再整体乘 \(\alpha_t\),会额外缩小新写入的 value,变成另一个算子。

合成例取 \(d_v=1,d_k=2\),旧状态为 \([1,2]\),\(\alpha=1/2,\beta=1\),key 为 \([1,0]^\top\),新 value 为 3。正确过程先得 \([1/2,1]\),残差为 \(5/2\),最终状态为 \([3,1]\)。若先按未衰减状态做 delta,再整体衰减,结果却为 \([3/2,1]\)。这只是矩阵演算,不能当作模型准确率。

原创矩阵演算与机制示意,非训练效果或 GPU 性能数据。矩阵状态 S 的形状为值维度乘键维度;固定大小不代表无损保存任意历史。加法写入、定向 delta 纠正、全局遗忘后 delta 纠正是三种替代机制,不是串行操作。正确门控顺序是先把旧状态乘 α,再以衰减状态对单位 L2 键的读数计算 β 倍残差,最后沿该键写入;用更新后的状态读取查询,查询缩放已吸收。教学算例的状态为一乘二矩阵,旧状态 [1,2],α=0.5、β=1、键 [1,0]、目标值 3:衰减状态 [0.5,1],写入残差 2.5,新状态 [3,1]。若先按未衰减状态做 delta 更新得到 [3,2],再整体衰减,则错误地得到 [1.5,1]。另一个教学端点算例使用 α=β=1、单位键 [1,1] 除以根号二、目标值 0,旧状态 [1,2] 变为 [−0.5,0.5];对查询 [1,0] 的读数从 1 变为 −0.5,表明非正交地址可受写入干扰,并非语义检索证据。按用途分支:递归解码每步更新固定矩阵并读出;分块预填充求解严格下三角的残差依赖,然后进行带衰减且包含对角项的因果读出。混合架构的全注意力层仍保留随上下文增长的 KV。
原创机制图与合成矩阵演算。正确顺序是整体衰减、按衰减状态计算残差、再沿单位键写入;[1,2] 在 α=0.5、β=1、键 [1,0]、目标值 3 下变为 [3,1]。对照错误是先 delta 更新、再整体衰减,会得到 [1.5,1]。第二个端点算例展示非正交键可改变另一查询的读数,不能解释为模型语义检索效果。递归解码与分块预填充是用途不同的执行路径,后者有严格下三角的残差依赖和包含对角项的衰减读出。固定矩阵不是无损历史;混合全注意力层的 KV 仍随上下文增长。数字不是训练实验或 GPU 测量,完整递推与假设见正文。

三、“定向改写”不等于其他记忆完全不动

对单位 key,右乘当前 key 可得:

\[\mathbf S_t\mathbf k_t=\alpha_t(1-\beta_t)\mathbf S_{t-1}\mathbf k_t+\beta_t\mathbf v_t\qquad(\lVert\mathbf k_t\rVert_2=1)\]

若 \(\beta_t=1\),当前 key 的读出精确变为目标 value;若 \(\alpha_t=1\),则是旧预测与目标之间的插值。但对一个与当前 key 正交的查询,仅有:

\[\mathbf S_t\mathbf q=\alpha_t\mathbf S_{t-1}\mathbf q\qquad(\mathbf k_t^\top\mathbf q=0)\]

正交方向没有受到额外 delta 修正,却仍被 \(\alpha_t\) 衰减。对一般查询,连带改变量为:

\[\mathbf S_t\mathbf q-\alpha_t\mathbf S_{t-1}\mathbf q=\beta_t(\mathbf v_t-\alpha_t\mathbf S_{t-1}\mathbf k_t)(\mathbf k_t^\top\mathbf q)\]

只要 \(\mathbf k_t^\top\mathbf q\ne0\),该查询便可能受影响。用一个极限算例看得更清楚:

\[\mathbf S_{\mathrm{old}}=[1,2],\quad\mathbf k=\frac1{\sqrt2}[1,1]^\top,\quad v=0,\quad\alpha=\beta=1\quad\Longrightarrow\quad\mathbf S_{\mathrm{new}}=[-1/2,1/2]\]

此时查询 \([1,0]^\top\) 的读数从 1 变为 \(-1/2\),另一个坐标也变化。所谓定向,是沿 key 的线性方向更新,不是已经找到一个独立语义槽位。学到的 key 是否可分、哪些关联需要同时保留,决定了这种更新的实际效果。

归一化还关系到旧状态的传播。转移矩阵 \(\alpha_t(\mathbf I-\beta_t\mathbf k_t\mathbf k_t^\top)\) 在 key 方向和正交方向的特征值分别为:

\[\lambda_{\parallel}=\alpha_t(1-\beta_t\lVert\mathbf k_t\rVert_2^2),\qquad\lambda_{\perp}=\alpha_t\]

单位 key 与常规门范围可保证这一步对旧状态扰动不放大;它不保证整个受输入驱动的网络或梯度稳定。去掉 key 归一化时,即使 \(\beta=1/2\),一维 \(k=3,\alpha=1,v=0\) 也把旧状态 1 变为 \(-7/2\)。所以“beta 来自 sigmoid”本身并不是收缩证明。

四、固定终态不能承诺还原所有历史

不必诉诸“实数矩阵最多存多少比特”这样的过强说法。一个带正常内部门值的反例已足够。令一维 key 恒为 1,\(\alpha=\beta=1/2\),则:

\[s_t=\frac14s_{t-1}+\frac12v_t,\quad s_0=0,\qquad(v_1,v_2)=(4,0)\ \text{or}\ (0,1)\quad\Longrightarrow\quad s_2=\frac12\]

两段不同 value 历史得到相同的核心终态。仅给最终 \(s_2\) 和相同查询,无法知道第一段历史的首个值是 4 还是 0。这个反例固定了 gates 与 keys,只讨论单层关联状态;它不证明整个网络连同卷积缓存、其他层和混合注意力也产生相同输出。它说明我们必须按任务检验需要保留的信息,而不能由状态大小直接宣称完整历史被无损保存。

门 \(\beta=0\) 只是不写入,若 \(\alpha<1\) 旧状态仍会变化。核心真正保持不变需要 \(\alpha=1,\beta=0\);清空旧状态则对应 \(\alpha=0\) 的极限,但当前 token 仍可写入。这三种操作不能混作“忽略一个 token”。

五、把公式接到实现:三种门和两种状态方向

本文固定读取 Transformers 提交 4cc2aa84301c9aa210b5513dab9fefae03981f6e 中的 Qwen3-Next 核心,以及 Qwen3.5 MoE 的调用路径;这是来源代码审阅,不是运行官方模型。代码把状态存成 \([B,H_v,d_k,d_v]\),即本文单头状态的转置方向。key/query 头重复到 value 头后,每个 value 头有自己的状态;不能把共享 key 头数直接当作状态头数。固定版本核心;Qwen3.5 调用路径。

在该版本中,写入门与衰减门采用:

\[\beta_t=\sigma(b_t),\qquad\log\alpha_t=-\exp(A_{\log})\operatorname{softplus}(a_t+\delta)\]

其中 \(a_t,b_t\) 是输入投影得到的门信号,\(A_{\log}\) 与 \(\delta\) 是相应头的学习参数。\(\log\alpha_t\) 作为 log-decay 传给核心,而不是把 log 值直接当乘法门。query/key 的 L2 处理带 epsilon,query 另除以 \(\sqrt{d_k}\)。value 不按同一方式归一化。

此外,Q/K/V 路径有短因果卷积与 SiLU;核心读出还经 RMS 归一化和独立的 SiLU 输出门,再投影回模型宽度。状态衰减门、残差写入门与输出门,各自控制不同接口。把它们都称为“attention gate”,会掩盖实际操作。

下面四行仅实现本文单头、列向量约定下的原始核心;q/k 的准备和缩放应在外部明确完成:

S = alpha[t] * S
r = beta[t] * (v[t] - S @ k[t])
S = S + np.outer(r, k[t])
out[t] = S @ q[t]

序列边界也属于实现的一部分。输入乘 padding mask,不必然等价于核心的 \(\alpha=1,\beta=0\) 空操作;投影偏置、门和卷积历史仍须核对。打包两个独立样本时,必须让关联状态和卷积状态在边界隔离;不能仅凭函数接受 \(\texttt{cu\_seqlens}\) 参数,就认定实际后端使用了它。该固定版纯 Torch fallback 接收额外参数,却没有读取打包边界,专用后端需要单独验证。

缓存 reset 会同时清零卷积与递推状态。最终矩阵也没有可直接裁掉尾部的 token 轴;对应缓存在递推状态初始化后标记不可 crop。需要回滚时,应检查快照、重放或其他记录机制及其开销;直接丢弃几个末尾 token,不能自动还原此前的状态。来源:固定版本缓存接口。

六、prefill 怎么并行?先解有因果依赖的残差

逐 token 递推适合解释 decode,但训练或 prefill 不能只指望大量小矩阵运算变快。下面从核心递推重新推导一个便于核验的分块表达,不把它声称为官方 GPU 内核的逐行实现。块长为 \(C\),输入状态为 \(\mathbf S_{\mathrm{in}}\);块内 \(i,j\) 从 1 开始。定义:

\[\gamma_i=\prod_{r=1}^i\alpha_r,\qquad\rho_{ij}=\begin{cases}\prod_{r=j+1}^{i}\alpha_r,&j\le i,\\0,&j>i,\end{cases}\qquad\rho_{ii}=1\]

空乘积为 1。用乘积写法可以处理教学端点 \(\alpha=0\),无需计算可能出现 \(0/0\) 的累计积之比。展开状态,再代回残差:

\[\mathbf S_i=\gamma_i\mathbf S_{\mathrm{in}}+\sum_{j\le i}\rho_{ij}\mathbf e_j\mathbf k_j^\top,\qquad\mathbf e_i=\beta_i\left(\mathbf v_i-\gamma_i\mathbf S_{\mathrm{in}}\mathbf k_i-\sum_{j<i}\rho_{ij}\mathbf e_j(\mathbf k_j^\top\mathbf k_i)\right)\]

残差 \(\mathbf e_i\) 依赖此前残差,但不依赖未来。把 Q/K/V 和 E 按 token 排成行,维度分别为 \(C\times d_k\)、\(C\times d_k\)、\(C\times d_v\) 与 \(C\times d_v\);定义 strictly-lower 部分后有:

\[\mathbf D=\operatorname{diag}(\beta_1,\ldots,\beta_C),\quad\mathbf G=\operatorname{diag}(\gamma_1,\ldots,\gamma_C),\quad\mathbf L=\operatorname{strictLower}(\boldsymbol\rho\odot\mathbf K\mathbf K^\top),\qquad(\mathbf I+\mathbf D\mathbf L)\mathbf E=\mathbf D(\mathbf V-\mathbf G\mathbf K\mathbf S_{\mathrm{in}}^\top)\]

这是对角全为 1 的下三角系统。应解线性系统或使用等价三角变换,而不是显式计算矩阵逆。求得所有残差,再读出各位置并传递块终态:

\[\mathbf O=\mathbf G\mathbf Q\mathbf S_{\mathrm{in}}^\top+(\boldsymbol\rho\odot\mathbf Q\mathbf K^\top)\mathbf E,\qquad\mathbf S_{\mathrm{out}}=\gamma_C\mathbf S_{\mathrm{in}}+\mathbf E^\top\operatorname{diag}(\rho_{C1},\ldots,\rho_{CC})\mathbf K\]

这里 \(\boldsymbol\rho\) 已含因果上三角零掩码,输出包含对角,因为当前 token 先写入再读出;残差依赖矩阵 \(\mathbf L\) 则必须严格下三角。两种掩码不同。局部读出也必须有衰减乘积:一维 \(k_i=q_i=1\)、\(\alpha_i=\beta_i=1/2\)、value 为 \((4,0)\) 时,正确读出为 \((2,1/2)\);省掉局部衰减,第二项会错误变成 \(3/2\)。

原论文通过扩展 WY/UT 表达把块内关系组织为硬件友好的计算。上面的残差系统是直接从式 (10) 重推的验收表达;读取论文块输出式时,应同时核对因果对角与衰减,而不是仅凭符号外形照搬。实际内核会在 log 域等形式中处理衰减并安排矩阵运算。本参考前向替换保留块内循环,只用于可读验证。计算分块也不能被误当成样本分界:下一个计算块应接 \(\mathbf S_{\mathrm{out}}\),不是重新清零。来源:官方实现仓库固定版本。

七、常量状态的预算,只属于被明确圈出的核心

单序列、单头的 decode 核心每 token 更新和读出约为 \(O(d_kd_v)\),状态有 \(d_kd_v\) 个元素,均不随历史长度 \(T\) 增长。但宽度、value 头数、批量与精度会改变实际成本。对上面的教学分块,固定 \(C\) 时总工作量可写为 \(O(Td_kd_v+TC(d_k+d_v))\):外积/输入状态读出及 K/Q 的块内配对都不能漏算。显式形成局部矩阵还需要 \(O(C^2)\) 临时元素;这不是完整训练激活显存预算。

混合模型的缓存更接近下面的分项核算:

\[M_{\mathrm{cache}}=B\sum_{\ell\in\mathcal R}H_{v,\ell}d_{k,\ell}d_{v,\ell}b_{\mathrm{state},\ell}+2BT\sum_{\ell\in\mathcal A}H_{\mathrm{KV},\ell}d_{h,\ell}b_{\mathrm{KV},\ell}+M_{\mathrm{conv}}+M_{\mathrm{other}}\]

其中 \(\mathcal R\) 为循环层,\(\mathcal A\) 为完整注意力层,\(B\) 为批量,\(H_v\) 为循环状态头数,\(H_{\mathrm{KV}}\) 为完整层 KV 头数,\(d_h\) 为其头宽;\(b_{\mathrm{state}},b_{\mathrm{KV}}\) 分别为每元素字节数,不能默认相同。卷积缓存及额外服务缓存另列。权重、临时缓冲和训练反向激活都不在这个缓存式中。

固定 Qwen3.5-397B-A17B 配置的文本解码器有 45 个循环层、15 个完整注意力层。每个循环层、每序列的状态有 \(64\times128\times128=1{,}048{,}576\) 个元素;若按 FP32 存,就是 4 MiB 的矩阵算术预算。每个完整层、每个历史 token 的 key/value 合计 \(2\times2\times256=1{,}024\) 个元素。后者仍随 \(T\) 增长;数字是配置推算,不是实测显存。来源:固定模型配置。

因此,循环核心的固定状态不等于整模型常量内存,更不等于任何长度下都更快。prefill 与 decode 应分别测量,记录 batch、上下文、生成长度、精度、后端和实际缓存;比较完整模型时还要控制参数、训练数据及任务质量。论文的主对照采用 1.3B 参数、100B FineWeb-Edu tokens、4K 训练长度,混合滑窗为 2K;它提供特定设置的报告证据,不能直接推广成 Qwen 模型的性能保证。

八、一个可复现的数学检查,和仍需验证的边界

我实际运行了原创 NumPy 2.3.5 / CPU float64 检查:随机种子 20261009,序列长 \(\{1,2,5,17,33\}\),宽度对 \(\{(1,1),(2,3),(7,4)\}\),三类门设定包括区间内部、教学端点与强衰减,块长 \(\{1,2,4,8,64\}\),并传入非零初态。共 225 项递推/分块前向对照,最大输出绝对差 \(4.44\times10^{-16}\),最大终态差 \(2.22\times10^{-16}\),验收阈值 \(10^{-11}\)。数字显示的是本检查下的浮点一致性,不是模型效果。

另检查了图中两种更新顺序、非正交干扰、两段历史同终态、未归一化扩张、包含对角的读出、核心空操作和显式独立样本重置;故意漏掉衰减的读出会失败。独立审阅者又用标量展开实现和不规则分块复核,得到相同结果。完整原创脚本可下载并复现;它只需要 NumPy,运行后在脚本旁写出结果 JSON:

python3 gated-delta-memory-update.py

我没有运行神经网络权重、官方 CUDA/FLA 内核、反向传播或 GPU 性能实验。若将推导接到生产实现,建议继续以下验收;这些是建议对照,不是本文已获得的结果。

问题对照与记录通过标准的含义
核心及分块一致性相同 Q/K/V 与 gates;非零初态、块尾、极小 decay、不同块长;同时比较输出和终态确认实现的是同一递推,而非仅最后输出偶然接近
精度与训练实际 dtype、内核和 backward;梯度对照、高精度参考、长序列与大幅 value前向 float64 通过不能替代低精度和梯度验收
padding、打包与回滚独立样本与拼接样本、不同 padding 位置、卷积边界、快照恢复和重放确认样本隔离及缓存生命周期,未把掩码当 reset
真实检索与成本重复/相似 key、应保留信息的距离、上下文切换;训练与任务预算对齐后分别测 prefill/decode判断哪些信息被有益遗忘,哪些被错误覆盖,并核算整模型成本

理解 Gated DeltaNet,关键是把遗忘、误差写入、读出和缓存边界分别说清楚。它可以用固定大小的关联状态承担一部分序列建模,但保留哪些信息需要学习与验证;加入完整注意力的混合设计,也必须把仍随长度增长的部分重新计入预算。

文献元数据由 citation-management 技能辅助核验。Kassis、Agarwal、He、Patel 与 Brueckner 的 Scientific Agent Skills(2026) 用于工具署名,不作为记忆机制或性能结论的证据。

参考资料

  1. Gated Delta Networks: Improving Mamba2 with Delta Rule — Yang, Kautz and Hatamizadeh, ICLR 2025, pp. 29687–29707 · 查阅 2026-10-09
  2. Gated Delta Networks — arXiv v3, revised 2025-03-06; first posted 2024-12-09 · 2024-12-09 · 查阅 2026-10-09
  3. Qwen3-Next: Towards Ultimate Training & Inference Efficiency — Qwen Team · 2025-09-11 · 查阅 2026-10-09
  4. Qwen3.5: Towards Native Multimodal Agents — Qwen Team · 2026-02-16 · 查阅 2026-10-09
  5. Qwen3.5-397B-A17B config.json — fixed revision 8472618112abcbd45acbcdc58436aff4233c23f7 · 查阅 2026-10-09
  6. Qwen3-Next core — Transformers fixed commit 4cc2aa84301c9aa210b5513dab9fefae03981f6e · 查阅 2026-10-09
  7. Qwen3.5 MoE block — Transformers fixed commit 4cc2aa84301c9aa210b5513dab9fefae03981f6e · 查阅 2026-10-09
  8. Cache interfaces — Transformers fixed commit 4cc2aa84301c9aa210b5513dab9fefae03981f6e · 查阅 2026-10-09
  9. Official GatedDeltaNet implementation — NVlabs fixed commit b53d6d3a161267432a79c1c04af69fa52bddc921 · 查阅 2026-10-09
  10. Scientific Agent Skills: A Library of Procedural Knowledge for Research Agents — Kassis et al. (2026), tools acknowledgment · 2026-08-30 · 查阅 2026-10-09
利友诚

关于作者

利友诚 · Youcheng Li

北京大学智能学院人工智能专业博士研究生,导师为王立威教授;Isoplex Intelligence(壹索智能)联合创始人兼 CTO。

研究关注医疗人工智能、生成式基础模型、诊断推理与科学智能体。以第一作者或共同第一作者身份在 Nature Biomedical Engineering、Scientific Data、KDD 和 PLOS Computational Biology 发表研究。