0. 为什么单聊这一层
fa1–fa4 讲的是怎么把注意力改轻(稀疏 / 压缩 / 混合 SSM)。但这一篇要聊的 Gated DeltaNet(GDN)走得更远——它不是注意力,而是一类线性注意力 / 递归状态空间层,核心靠一个固定大小的「状态矩阵」在每次 token 上做增量更新,把全局历史压进 O(d²) 的定长张量里。
它的层结构非常干净,只有两个算子:
- 算子 1 · Causal Conv1D:在 Q/K/V 投影之后,对三个分支各做一层深度可分离因果卷积 + SiLU,提供局部上下文与位置感知。
- 算子 2 · Recurrent State Update:接收卷积后的 Q′/K′/V′ 与数据依赖的衰减 / 写入门控 αₜ、βₜ,执行 Gated Delta Rule,更新固定大小的
ssm_state矩阵并输出。
两者形成「先局部卷积、后全局线性注意力」的层级:Conv1D 解决短程依赖和位置,Recurrent State 以 O(n·d²) 把长历史压缩成定长状态。下面这张图就是它的完整链路。
1. 算子 1:Causal Conv1D(局部 + 位置)
位于 Q/K/V 投影之后,对 Q、K、V 三个分支分别做:
- 深度可分离因果卷积(Depthwise Causal Conv1D):在每个通道上独立做一维因果卷积,卷积核只在当前及之前的位置滑动,保证因果性(看不到未来)。
- SiLU 激活:卷积后接 SiLU。
- conv_state 滑动窗口:训练 / 推理时维护一个定长滑动窗口状态,使得递归步进只需缓存最近
kernel_size个位置,不随序列增长。
它的作用有两层:
- 短程依赖建模:卷积天然聚合邻近 token,弥补线性注意力「只看全局状态、对局部不敏感」的短板。
- 位置感知(替代 RoPE):GDN 层完全不使用 RoPE,位置信息就靠这层因果卷积的局部感受野来提供——所以文档里「Causal Conv1D 类似位置编码或短程依赖建模」的判断是准确的。
2. 算子 2:Recurrent State Update(Gated Delta Rule)
这是 GDN 的核心。它接收卷积后的 Q′/K′/V′,以及两个数据依赖的门控信号:
- αₜ(衰减门控,∈ (0,1)):控制对历史状态的指数遗忘强度。
- βₜ(写入门控):控制当前 token 写入状态的强度。
完整公式(含衰减门控 αₜ):
Sₜ = Sₜ₋₁ · αₜ ( I − βₜ kₜ kₜᵀ ) + βₜ vₜ kₜᵀ
逐项读:
Sₜ₋₁ · αₜ:先把上一时刻状态整体乘衰减门控,历史被按 αₜ 比例遗忘(这是朴素 Delta Rule 缺的那一项)。αₜ ( I − βₜ kₜ kₜᵀ ):在遗忘后的状态上,再做一次「沿当前 key 方向的 Delta 校正」——βₜ kₜ kₜᵀ是从旧状态里减去「与当前 key 相关的旧预测」的投影,腾出空间。+ βₜ vₜ kₜᵀ:把当前 value 按写入门控 βₜ 写进状态,作为「key → value」的外积。
注意:文档里写的
Sₜ = Sₜ₋₁ − βₜ(Sₜ₋₁φ(kₜ))φ(kₜ)ᵀ + βₜ vₜ φ(kₜ)ᵀ是不包含 αₜ 衰减门控的朴素 Delta Rule 形式,与原始论文一致;但 GDN 的完整公式必须包含 αₜ 衰减项,否则就退化成了没有遗忘机制的线性注意力。
3. 位置编码:无 RoPE
GDN 层不使用旋转位置编码(RoPE)。整层的绝对 / 相对位置线索都来自:
- 算子 1 的因果卷积感受野(局部顺序);
- 递归状态
Sₜ本身按时间顺序滚动(隐式时序)。
这正是 GDN 能保持线性复杂度、又不过度依赖位置编码注入的原因。
4. 状态维度:是矩阵,不是向量
ssm_state 的形状是每个注意力头一个 d_v × d_k 矩阵(而非单向量):
d_k:key 维度(外积kₜ kₜᵀ的一边);d_v:value 维度(外积vₜ kₜᵀ的另一边);- 矩阵规模与序列长度无关,因此状态大小恒定——这是 O(n·d²) 线性复杂度的根基。
文档里「状态矩阵(或向量)」的表述略模糊,应明确为矩阵:每个头持有一张 d_v × d_k 的定长表,递归地在上面做「遗忘 + 校正 + 写入」。
5. 复杂度:为什么是线性
- 朴素注意力:每 token 要与全部历史做点积,复杂度 O(n²·d)。
- GDN 递归状态:每个 token 只做「读状态 + 更新定长矩阵 + 写状态」,状态大小恒为
d_v·d_k,复杂度 O(n·d²)。
当序列很长(n ≫ d)时,O(n·d²) 显著低于 O(n²·d),这正是 GDN 能撑长上下文、且 KV Cache 不随序列爆炸的根本原因——它的「记忆」是一张定长矩阵,而不是逐 token 的 KV 列表。
6. 与 Qwen3.5 / 3.6 / 3.8 的关系(型号勘误)
文档里出现的 qwen3.8-27B 这一确切型号如今确认真实存在——早期本文判断其「不存在」有误,已据 2026-08-28 仓库快照扫描更正(交叉验证见(七)Qwen3.8 双 checkpoint 对比)。Qwen3.8 系列主档是 2.4T-A95B 这类 MoE 模型,同时也存在 27B 稠密 这一档 checkpoint。
但有一点是确凿的:Gated DeltaNet 架构(GDN 层)确实是 Qwen3.5 / 3.6 / 3.8 系列的核心组件,是这一系列能在长上下文下保持线性推理成本的关键模块之一。所以——
- ⚠️ 更正:「Qwen3.8-27B 确实存在」(27B 稠密 checkpoint,2026-08-28 仓库扫描确认;此前「不存在」判断已撤销)
- ✅ 正确:「GDN 是 Qwen3.5/3.6/3.8 系列(含 2.4T-A95B MoE 与 27B 稠密)的核心架构组件」
7. 文档交叉验证后的四处修正小结
结合原始论文(Yang et al., Gated DeltaNet, ICLR 2025)与 Qwen3.5/3.6/3.8 系列实现代码交叉验证,整体描述基本正确,四处需修正:
| # | 修正点 | 文档原表述 | 正确表述 |
|---|---|---|---|
| 1 | 型号名称 | qwen3.8-27B | 27B 稠密 checkpoint 真实存在(2026-08-28 仓库扫描确认,此前「不存在」判断已撤销);GDN 是 Qwen3.5/3.6/3.8 核心组件 ✅ |
| 2 | 完整公式 | 仅含 β 的 Delta Rule | 须加衰减门控 α:Sₜ = Sₜ₋₁·αₜ(I − βₜ kₜkₜᵀ) + βₜ vₜkₜᵀ |
| 3 | 位置编码 | 提了一句 Conv1D「类似位置编码」 | 准确——GDN 完全无 RoPE,位置靠因果卷积 + 状态滚动 |
| 4 | 状态维度 | 「状态矩阵(或向量)」略模糊 | 明确为每 head 一个 d_v × d_k 矩阵(定长,与序列长无关) |
下一篇预告:GDN 与 Mamba / 线性注意力家族(GLA、RWKV、RetNet)的横向对比——它们都在「用定长状态替代 KV 列表」,但状态更新规则完全不同。
💬 留言
NaphJohn/LLM-blog尚未启用 Discussions:请在 GitHub 仓库 Settings → General → Features 勾选 Discussions 后刷新本页,评论区即自动显示。