无权重,但有跨层信息通道
x + f(x) 里没有额外的 d×d 矩阵;残差让深层 block 学习增量,并提供梯度短路径。
ARCHITECTURE / WEIGHTS
一个 decoder block 包含 Q/K/V/O 投影、SwiGLU 的 gate/up/down、两层归一化与残差; 堆叠 L 次后再加 embedding、final norm 与 LM head。MoE 则把 MLP 扩成 router 与多个专家。
x 始终沿 residual stream 前进;Attention 与 MLP 每次都在往这条主干里加一个学习到的增量。
x [B,T,d]
Attention 和 MLP 的输出作为增量加到 residual stream 上。深层网络因此有可传播的梯度短路径,也让每层可以局部改写信息。RMSNorm 的缩放参数也属于权重;残差加法本身没有可训练矩阵。
下面按行向量表示 token,省略 batch 和多头拼接,先看一个 head。Q/K 的宽度为 dₖ;M 是加性注意力 mask,允许位置为 0,禁止位置在理想公式中为 −∞。
普通 softmax attention 先在可见位置上分配权重,再汇总 value。Gated Attention 可以在这份汇总上乘一个由当前 token 计算的门,再送进输出投影。本节看 Qwen 论文的 G1:SDPA 之后、W_O 之前,先理解计算路径,再看它怎样学习。
版本依据:Gated Attention v1(2025-05-10)§2.2、式 5 与 Table 1;Qwen3-Next 官方说明(2025-09-10)明确采用这项输出门技术。它与相邻 Gated DeltaNet 层是不同机制;不据此推断每个 Qwen3.5 版本的门形状或训练配方。
沿用本页的行向量约定。单个 query 的预归一化后输入 x∈ℝᵈ;a 是 T 个允许位置上的 softmax 权重,V∈ℝᵀˣᵈʰ。一个 head 的 h=aV,门 g 与 h 同宽;Wg∈ℝᵈˣᵈʰ,Wo 将 head 输出投回残差宽度。多头时先分别门控再拼接。
| 选择 | 含义与参数账本 |
|---|---|
| Head-specific | 各 head 有独立门控分数;既可以每头一个标量,也可以每头逐通道。 |
| Headwise / elementwise | 前者每头一个标量,后者每个 head 通道一个数。各头独立时,设 H 个 query heads、宽度 dₕ,无偏置投影分别新增 dH 与 dHdₕ 个权重。 |
| G1 / 其他位置 | 论文还比较 Q/K/V 投影后的门与 W_O 后的 G5。门的位置改变计算图,不能仅凭名称替换。 |
本地教具只取一头、三个允许位置、二维输入与输出。x=[1.2,−0.7],ℓ=[1.1,−0.4,0.2],目标 y*=[0.15,−0.2];下列矩阵都按行列显示:
得到 z=[0.81,−0.52],g≈[0.692110,0.372852]。整头标量对照用 σ(0.4);“移到 W_O 后”只是把这两个门值挪到投影之后,不是重训论文的 G5 模型。各输出按六位小数展示:
| 路径 | y[0] | y[1] |
|---|---|---|
| 无输出门 | 0.674285 | 0.357607 |
| G1:逐通道门 | 0.477612 | 0.223816 |
| G1:整头标量门 | 0.403686 | 0.214095 |
| 移到 W_O 后(不同机制) | 0.466679 | 0.133334 |
逐通道门对应对角矩阵 Dg,一般 DgWo≠WoDg;本例同为二维,仍不能交换。若所有 head 通道共用同一标量 c,且投影无 bias,则 (ch)Wo=c(hWo)。固定不变的 Dg 可以折叠为 DgWo;输入变化会改变 g,本例另一个 x 的结果已不符合这一份固定折叠。
局部目标 L=½‖y−y*‖²,把 x、ℓ 和 V 视作给定输入。设 e=y−y*、t=eWoᵀ,则:
| 局部坐标 | 解析导数 | 中心有限差分 |
|---|---|---|
| logit₀ | 0.016369877 | 0.016369877 |
| V₀[0] | 0.211127222 | 0.211127222 |
| Wg[0,0] | 0.090071432 | 0.090071432 |
| Wo[1,0] | 0.006971517 | 0.006971517 |
只更新 Wg、η=0.1,一次 SGD 后本地 loss 从 0.143475 变为 0.142383。这次给定目标下降不说明语言模型更好。保存文件含全部 17 项导数与更新前后张量;只更新门时,固定的 attention 权重 a 保持不变。
sigmoid 的局部斜率是 g(1−g)。数学上有限 z 得到 0<g<1;大幅饱和时斜率很小。下面按九位有效数字展示,避免把接近零误读为精确的零:
| z | σ(z) | g(1−g) |
|---|---|---|
| -20 | 2.06115362e-09 | 2.06115361e-09 |
| -2 | 0.119202922 | 0.104993585 |
| 0 | 0.5 | 0.25 |
| 2 | 0.880797078 | 0.104993585 |
| 20 | 0.999999998 | 2.06115369e-09 |
实际有限精度可能舍入到端点;不能把实数性质直接当作任意精度实现的保证。小门会压低该 h 路径的梯度,门参数路径还乘 g(1−g);但完整网络仍有其他路径,不能由此断言总梯度消失。
固定 logits 与 V 时,输出门不会重分配 softmax 权重。论文 §4.3 的 attention-sink 减少来自训练后模型的实测,不能从一次乘法推出注意力图已变化。门值接近零也不是显式 top-k、结构化稀疏或自动跳过 SDPA 的执行指令。
再取两次 query 的反例:前一次整头门 σ(−20)≈2.06×10⁻⁹;后一次打开为 σ(4)。对后一次的同三个允许位置,固定 logits=[2.4,−0.3,0.1],V 与 Wo 沿用上例。若因前一次门小而误删第 0 项,后一次输出就不同:
| 后一次 query 的缓存 | y[0] | y[1] |
|---|---|---|
| 完整保留 K/V | 1.040303 | -0.023200 |
| 因前一小门值误删第 0 项 | -0.370835 | 1.304269 |
这个有限反例已足够否定“当前门小,所以未来都不需要旧 K/V”。它不模拟某个引擎的 cache 剪枝,也不估计模型的 KV 节省、吞吐或长上下文成绩。
读到 gate,先问作用于什么:本节门控 head 输出;GDN/KDA 的遗忘与写门更新循环状态;SwiGLU 门控 FFN 分支;MoE router 选择专家;AttnRes在深度来源上做 softmax。循环层也可能另有输出门,不能把所有门都归为状态遗忘。
固定输入与检查代码随结果保存。仓库根目录执行,只需 Python 3.10+ 标准库:
python3 artifacts/gated-attention-20261030T125431Z/check-mechanisms.py默认重算并核对正文和 results.json;--write 仅首次创建,不能覆盖。代数采用 1e−12 尺度容差,有限差分步长 1e−6、导数及其缓存误差容差 1e−8。没有下载模型、复现作者训练或测量硬件速度。
先选预设,再改维度。此处激活参数按被选专家加共享部分计数,包含 router 参数;按常见规模口径,embedding 表整体计入;单 token 的查表访问量另行计算。
PRESET
本页要求 Hq 可被 Hkv 整除;KV heads 超过 query heads 时会同步调低。Hkv=Hq 才是 MHA。q_width=Hq×headDim 可以不同于残差宽度 d,只需 Q/O 投影形状配套。
Vd + L[Q+K+V+O + 3d·d_ff + 2d] + d_final + head
当前是 untied dense:embedding 与输出头各占一份矩阵。若 tied,输出头复用 E,不再增加 Vd。每个 token 都经过全部 MLP 参数。
下表按照当前配置动态更新。真实框架常把 Q、K、V 合成一个 fused QKV 矩阵,数学上仍是三组投影。
| 模块 | 典型权重形状 | 当前参数量 | 作用 |
|---|
PUBLIC STRUCTURE SNAPSHOTS
这些是常见公开模型卡/配置里的代表性结构。不同 revision 可能额外包含 bias、GQA、滑动窗口、多模态塔或其他组件。
| 模型 | d / L | Q heads / KV heads | FFN width | experts / top-k | 总参数 / 激活 |
|---|---|---|---|---|---|
| LLaMA 2 7B | 4096 / 32 | 32 / 32 · MHA | 11008 | 1 / 1 | 约 6.7B / 6.7B |
| Mistral 7B | 4096 / 32 | 32 / 8 · GQA | 14336 | 1 / 1 | 约 7.2B / 7.2B |
| Llama 3 8B | 4096 / 32 | 32 / 8 · GQA | 14336 | 1 / 1 | 约 8.0B / 8.0B |
| Mixtral 8×7B | 4096 / 32 | 32 / 8 · GQA | 14336 / expert | 8 / 2 | 约 46.7B / 12.9B |
这些公开配置用于对照结构量级;词表、embedding、bias、视觉编码器与版本差异都会改变最终参数。
比较模型规模时:同样是 32 层,MoE 的总参数可能远大于 dense,但每个 token 只走 top-k 专家;同样参数量,GQA 的 8 个 KV heads 会比 32 heads MHA 的 KV Cache 小很多。比较模型时必须同时看 L、d、FFN、head 结构、embedding 大小和是否 tied。
点击“重新路由”,看不同 token 被分给哪些 experts。这里只展示机制,不模拟真实训练后 router 的负载。
ROUTING VIEW
每个 token 先得到 E 个 gate 分数,只把 top-k 的专家结果加权相加。router 本身很小,专家的权重却都要驻留内存。
每 token 只走 k 个 experts,适合提高“总参数 / 激活参数”比。
所有 experts 都要可加载或可调用,内存不会只按激活参数计算。
跨设备路由需要 all-to-all;token 分配不均会造成热点、丢弃或等待。
需要负载均衡目标、router 稳定性与容量处理;专家是否真的专业化要评估。
Top-k 在排名切换处会产生离散变化。常规反传固定本次选中的集合,沿集合内的连续计算求导。已选专家的输出影响 loss,其参数和输入可收到梯度;router 则可能通过门控权重及辅助目标得到梯度。未选专家在当前 token 上没有任务分支梯度,但可能被 batch 中其他 token 选中。
门控权重如何归一化很关键。若使用完整 softmax 的 pₑ,选中权重仍受全部 logits 的分母影响;若只对选中的 logits 重新归一化,未选 logits 通常不从这个门控分支获梯度。特别是 top-1 后再归一成常数 1,任务 loss 不会经该常数给 router 学习信号,需其他设计。Switch 的门控保留选中概率,其他 MoE 实现需按各自的门控定义分析梯度路径。
| 问题 | 机制/处理 | 应查看的证据 |
|---|---|---|
| 少数专家垄断 | 辅助均衡 loss、路由 bias 或其他负载控制;用于稳定专家容量和调度,均衡程度由具体目标与系数控制。 | 逐层/逐专家 token 占比、router 概率、训练阶段和最忙 rank。 |
| 专家容量溢出 | 常见估算 capacity≈ceil(capacity_factor·tokens·k/experts)。实现可丢弃该专家分支、重路由、padding 或使用 dropless 调度。 | 实际接收/丢弃数量、残差绕行语义、峰值和各 expert 的 GEMM 形状。 |
| 数值不稳定 | router logits 的精度、初始化、logit 正则和梯度处理按配方决定。 | logit/entropy 分布、非有限值、路由变化、aux/task loss 比例。 |
| “专家”是否专业化 | 路由按语言/领域聚集可能只是相关性;专家序号不天然对应人类定义的技能。 | 受控路由/消融后的性能、跨数据的行为和实际任务贡献,用这些结果判断专家的实际贡献。 |
总 loss 中的任务项与均衡项可能竞争:过强的均衡压力影响任务学习,过弱可能造成专家饥饿和容量溢出。DeepSeek-V3 等具体配方还采用不同的负载控制组合,需读相应报告。即使 load 很均匀,通信、专家小矩阵与数据布局也可能成为瓶颈。
辅助 loss 通过反传改变 router;另一条路线是在选专家时加入动态 bias。DeepSeek 的 Loss-Free Balancing 用历史负载调整它,避免直接叠加一项均衡目标的梯度。bias 仍会改变选中的专家与后续训练路径,不能理解成“模型学习完全不受影响”。
三个专家、四个 token、每 token 选两个专家;四行 affinity 为 [0.9,0.8,0.1]、[0.7,0.9,0.2]、[0.8,0.65,0.3]、[0.65,0.8,0.3]。从零 bias 开始,γ=0.2,重复回放同一批分数三次;不更新模型参数。分数相同按较小专家序号优先。
| 回放 | 本次使用的 bias | E0 / E1 / E2 分派数 | 最忙负载 / 均值 − 1 |
|---|---|---|---|
| 0 | 0.0 / 0.0 / 0.0 | 4 / 4 / 0 | 0.500000 |
| 1 | −0.2 / −0.2 / 0.2 | 3 / 3 / 2 | 0.125000 |
| 2 | −0.4 / −0.4 / 0.4 | 2 / 2 / 4 | 0.500000 |
均衡先改善又反弹,说明这组步长与固定回放不构成单调收敛保证。8 次分派不是 8 个不同 token;这里也没有容量丢弃、节点约束、通信或语言模型质量测量。
固定专家输出 v=[1,−1,2]。回放 1 的实际选择和输出如下,权重依旧由原始 s 归一化;表内专家按序号排列。
| Token | 选中专家 | 对应门控权重 | 合并输出 |
|---|---|---|---|
| T0 | E0 / E1 | 0.529412 / 0.470588 | 0.058824 |
| T1 | E0 / E1 | 0.437500 / 0.562500 | −0.125000 |
| T2 | E0 / E2 | 0.727273 / 0.272727 | 1.272727 |
| T3 | E1 / E2 | 0.727273 / 0.272727 | −0.181818 |
若错误地把 T2 的偏置后分数 [0.6,0.5] 也拿来归一化,输出会变为 1.454545。脚本核对这一差异,并在 Top-k 集合不变的邻域对 12 个直接输入 affinity 做有限差分;不把它称为 sigmoid、router 权重或离散排序的完整反传。
另取两个专家、Top-1:四个文本 token 的分数均为 [0.6,0.5],四个图像 token 均为 [0.5,0.6]。零 bias 时,合计分派完全均衡,每种模态却各自集中到一个专家。
| 统计范围 | Token 数 | E0 / E1 分派数 | 最忙负载 / 均值 − 1 |
|---|---|---|---|
| 总体 | 8 | 4 / 4 | 0.000000 |
| 文本 | 4 | 4 / 0 | 1.000000 |
| 图像 | 4 | 0 / 4 | 1.000000 |
DeepSeek-V4.1-Flash 报告为文本和图像分别维护 correction bias,并在训练步结束后按各自负载更新。本例只演示统计范围的区别;按模态分组本身不保证一步更新后就均衡,也不能凭路由比例认定专家具有人类定义的技能。
保持前缀分数 [0.6,0.5] 不变。若后面三个 token 都偏向 E0,先统计整条序列再给前缀重路由,γ=0.2 会把前缀改选为 E1;把后面三个 token 改为偏向 E1,前缀又会选 E0。这是明确构造的错误两遍协议:同一前缀读到了未来负载。正确回放先使用已确定的历史 bias,当前计数只影响下一次;脚本同时核对这两种路径。
| 固定来源 | 本节采用的事实 | 需要单独保留 |
|---|---|---|
| Loss-Free Balancing · v1 · 2024-08-28 | 第 3 节、算法 1:历史负载控制选路 bias。 | 原论文式 3 的门控保留原分数;不能直接替换成本例的选中后归一化。 |
| DeepSeek-V3 · v1 · 2024-12-27 | 第 2.1.2 节:bias 选路,原始 affinity 归一化后加权。 | 仍有很小的序列级辅助均衡项;本例不实现它,也不实现节点限制。 |
| DeepSeek-V4.1-Flash · v1 · 2026-09-17 | 第 2.1.1 节:文本、图像分别维护 correction bias。 | 不据此推定其他模型或后续版本的模态划分、系数和统计窗口。 |
实际训练应声明计数跨哪些 rank、microbatch 和模态,何时同步与更新,以及 checkpoint 是否保存 bias 等控制状态。分派数、容量丢弃、每卡耗时与独立质量分别记录。
在仓库根目录执行;固定输入、完整输出、梯度和边界反例均随代码保存。
node artifacts/moe-mhc-20261030T065726Z/check-mechanisms.mjsTop-2 会让一个 token 产生两条专家分支。执行器按目标设备和专家排列这些分支,计算后根据原 token ID 汇合,再乘门控权重求和。排列索引必须在发送与返回两侧保持一致。
四个输入 token 分属两张逻辑卡:R0 持有 T0/T1 与 E0/E1,R1 持有 T2/T3 与 E2/E3。专家均为 2×2 线性层,路由 logits 固定;Top-2 中的两项单独 softmax,得到门控权重。该实验追踪专家输出、参数梯度与输入梯度,不对固定 router 求导。
| Token | 输入 | E0 / E1 / E2 / E3 的路由 logits |
|---|
| 专家 | 2×2 权重(按行排列) |
|---|
容量按原 token 顺序先到先留,丢弃后不重归一化权重。对照参考采用同样的门控和丢弃规则。表中的发送数量包含本地交付;跨 rank 的格子才需要远端交换。
| 来源 | 发 R0 | 发 R1 |
|---|
| 原 token | 源 → 目标 | 专家 | 门控权重 | 容量决定 |
|---|
| 排列后索引 | 原 token / 专家 | 输入副本 | 专家输出 | 乘门控后 |
|---|
| Token | 分派后合并 | 直接参考 | 各分支输入梯度之和 |
|---|
| 专家 | 2×2 参数梯度(按行排列) |
|---|
上游梯度固定为 [[0.2,−0.3],[0.1,0.4],[−0.2,0.5],[0.3,0.1]],对应目标 L=ΣY⊙G。空专家的输出分支和参数梯度均为空/零。测试用有限差分核验专家参数与输入梯度;不模拟 AllToAll 延迟。
按专家聚集后,条目顺序与输入顺序不同。同一个 token 还有多条分支;只把输出数组按当前位置写回,会把结果分给错误 token 或覆盖另一分支。
切换集中路由后,部分专家没有 token,热门专家可能超过容量。丢弃改变参与求和的分支,正确性参考也应使用同样的丢弃和权重规则。
这些最容易在“层数”和“参数数”里被忽略。
x + f(x) 里没有额外的 d×d 矩阵;残差让深层 block 学习增量,并提供梯度短路径。
相对 LayerNorm 少了去均值;权重通常是 d 个数。QK-Norm 还会在 head 维度增加小向量。
gate、up、down 三矩阵。即使 FFN width 降低,参数也可能高于传统 2d·4d 两层 MLP。
输入表 V×d 与 LM head d×V 可能共享;tied 省参数但让输入/输出统计耦合。
参数估算与分派实验保留原假设:四线性专家、固定门控、容量丢弃不重归一化;三专家 bias 与模态回放不训练 router。输出门另用一头二维教具核对 G1、17 局部导数及 KV 反例;新增投影不计入原计算器,不复现完整模型、厂商效果或速度。