适用读者:要判断"MoE 模型到底省了什么"、或要给多模型选型做容量表的人。
前置:S23-J08、J09(矩阵尺寸与上下文状态)。
覆盖旧文:A-4335 §2.4–§2.6(专家权重复用 + 网络形状 + 全模型资源比较,452 点)→ 452 点。
扩展点:E-S23-022(稀疏激活:总参数 ≠ 激活参数)、E-S23-023(路由决定权重读取量:同算力差 32 倍)、E-S23-024(残差连接决定临时存储与额外计算)、E-S23-025(推测解码的收益条件)。
上一篇:S23-J09 · 自回归生成与上下文状态
下一篇:S23-J11 · 请求到达、多轮与多模态负载。
1. 一句话结论
MoE 把"参数总量"和"每个 token 的计算量"拆成两个独立旋钮:可以存 2.78 万亿参数,但每个 token 只算其中一小部分。代价是——路由结果决定这一批要读多少权重:同样算力,读得最散时比读得最集中多 32 倍。
出处:AI Infra 教材 §2.4–§2.6(
id 4335)。
稠密 FFN:每个 token 用全部参数 → 存的 = 算的
MoE:路由器选 top-k 个专家 → 存的 ≠ 算的
2. 稠密 FFN 与专家路由
典型 MoE 分支:
输入 x → 路由器打分 → 选 top-k 专家 → 各专家做 gate/up/down 三个投影
→ 按路由权重加权合并 →(可选)加一条所有 token 都走的共享专家
单专家参数量(gate/up/down 三个矩阵):
N_e = 3 · d · f d = 主干/专家输入宽度,f = 专家中间宽度
2.1 Qwen3.6-35B-A3B 的实数
| 项 | 数值 |
|---|---|
| 主干层数 | 40 |
| 隐藏维度 d | 2048 |
| 每层路由专家数 E | 256 |
| 每 token 选择数 k_top | 8 |
| 专家中间维度 f | 512 |
| 单专家参数 | 3×2048×512 = 3,145,728(BF16 6 MiB) |
| 每层全部路由专家 | 1.5 GiB |
| 一个 token 选中的 8 个专家 | 48 MiB |
| 总参数 | 约 346.6 亿(34.66B) |
| BF16 权重 | 约 69.321 GB |
判据:"A3B"里的 3B 是"激活规模",不是"参数规模"。 模型存 34.66B,每个 token 只激活约 3B。
3. 路由决定读取量(E-S23-023)
F_expert = 2 · N_e · Σ_e t_e = 2 · N_e · B · k_top (按分派行数累计)
R_expert = b_W · N_e · U (按实际读入的不同权重累计)
U = 本批实际访问到的不同专家数
原文例题 2-4:B=64、每 token 选 8 个 → 共 512 次分派,比较两种路由:
| 路由情形 | U(每层访问的不同专家) | 每专家 token 数 | 每层读取 |
|---|---|---|---|
| 均匀分派 | 256 | 2 | 1.5 GiB |
| 集中到同一组 8 个专家 | 8 | 64 | 48 MiB |
F_expert = 2 × 3,145,728 × 64 × 8 = 3.22 GFLOPs (两种情形完全相同)
R 均匀 = 2 B × 3,145,728 × 256 = 1.5 GiB
R 集中 = 2 B × 3,145,728 × 8 = 48 MiB
差 32 倍;40 层合计:60 GiB vs 1.875 GiB
判据:"每个专家收到多少行"决定权重复用率。 均匀分派时每专家只有 2 行(矩阵乘法效率低、权重只复用 2 次);集中分派时每专家 64 行(复用 64 次)。负载均衡是通信/延迟问题,集中路由是读取效率问题——两者方向相反。
4. 三种 MoE 变体:共享专家、潜空间、细粒度
| 模型 | 结构 | 关键数字 |
|---|---|---|
| DeepSeek V4-Flash | 256 路由专家、top-6、+1 共享专家;前 3 层哈希路由,其余评分路由 | 单专家 3×4096×2048 = 25,165,824 参数 |
| Kimi K3 | 896 路由专家、top-16;主干 7168 → 潜空间 3584 → 专家 f=3072 → 投影回主干 | 降维减少专家矩阵尺寸,但多了进出潜空间两次投影 |
| Qwen3-235B-A22B | 128 专家 × 宽度 1536 × top-8 | 可与 64 专家 × 3072 × top-4 对照 |
一层专家运算量(含共享专家 N_s):
F_expert, layer = 2·m·N_s + 2·Σ_e t_e·N_e
判据:共享专家处理全部 m 个 token,路由专家只处理分派给它的 t_e 个。 算成本时两部分必须分开——共享专家不受路由影响,是"恒定开销"。
4.1 专家粒度的"不变量"(§2.5.1)
单层路由专家总参数:3·E·d·f 单 token 专家运算:6·k_top·d·f
把 E 减半、f 加倍、k_top 减半 → 两个量都不变。
| 配置 | 参数量 | 单 token 运算 | 矩阵形状 |
|---|---|---|---|
| 128 专家 × 1536 × top-8 | 相同 | 相同 | 更多小矩阵 |
| 64 专家 × 3072 × top-4 | 相同 | 相同 | 更少大矩阵 |
原文算例:16 个 token 下,基线与 64 专家变体都约 454 GFLOPs——运算量相同,矩阵形状与读取模式不同。
判据:选 MoE 粒度时,"参数量/算力"往往不变,变的是多卡切分的最小单位(128 专家可分 8 组 ×16;4 个 KV 头只能分 4 份 → 8 卡需复制 KV)。
5. 网络形状:深度、宽度、残差(E-S23-024)
5.1 深度 vs 宽度
稠密主干参数量 ≈ L·d²(FFN 宽度与隐藏维度保持固定比例时)
d 减半、L 增到 4 倍 → 参数量相近,但依赖链长度 ×4
| 变化 | 参数 | 依赖链 | 状态 |
|---|---|---|---|
| 层多、层窄 | 相近 | 更长(串行步数多) | 每层状态小 |
| 层少、层宽 | 相近 | 更短 | 每层状态大 |
5.2 残差连接决定"要同时保存什么"
普通残差:x_{ℓ+1} = x_ℓ + f_ℓ(x_ℓ) → 子层计算期间必须保留输入 x_ℓ,等结果出来才能相加。
| 连接方式 | 额外保存 | 额外计算(原文数) |
|---|---|---|
| 普通残差 | 1 路输入 | 无 |
| mHC(4 路,DeepSeek V4-Flash) | 4 路 × 4096 维表示 | 8192 token 输入时混合投影 555 GFLOPs + 非矩阵 149 GFLOPs |
| AttnRes(Kimi K3) | 块式保留供后续块选择的表示 | 按深度加权求和 |
mHC 的约束:残差混合矩阵元素非负、行和列和接近 1,用 Sinkhorn 迭代(交替按行、按列归一)实现——为了多层混合时数值稳定。
判据:残差的保存周期是"一次前向",KV 的保存周期是"整个请求"。 AttnRes 增的是临时存储,KV 增的是跨调用状态,两者不能混算。
5.3 MTP 与推测解码(E-S23-025)
普通 decode 每步产出 1 个 token:单输出时间 = T_d
推测解码:草稿 T_s + 验证 T_v,一轮平均得到 ḡ 个有效输出
每输出分摊 = (T_s + T_v) / ḡ
有收益 ⇔ (T_s + T_v)/ḡ < T_d
原文算例:DeepSeek V4-Flash 的 MTP 辅助块对单 token(B=1,P=1)约 1.80 GFLOPs,其中共享词表头占 1.06 GFLOPs(一半以上)——共享权重不等于零成本,每次调用仍要执行词表投影。
判据:推测解码的收益不看"草稿多快",看接受率 ḡ 与验证成本的乘积。
6. 模型矩阵:同一套规则比较五种结构(§2.6)
| 架构参数 | DeepSeek V4.1 Flash | Qwen3-8B | Qwen3.6-35B-A3B | DeepSeek V4-Flash | Kimi K3 |
|---|---|---|---|---|---|
| 逻辑参数总量 | 551.57B + 196.93B Engram | 8.19B | 34.66B | 284.33B | 2.78T |
| 主干层数 L | 40(20+20) | 36 | 40 | 43 | 93 |
| 隐藏维度 d | 5120 | 4096 | 2048 | 4096 | 7168 |
| 注意力组成 | 2 SWA + 38 CSA2 | 36 GQA | 30 线性 + 10 全注意力 | 2 窗口 + 21 CSA + 20 HCA | 69 KDA + 24 MLA |
| 每 MoE 层专家数 E | 384 | —(稠密) | 256 | 256 | 896 |
| 每 token 选择数 k | 6 | — | 8 | 6 | 16 |
| 跨层连接 | Single-Pass mHC 4 路 | 普通残差 | 普通残差 | mHC 4 路 | AttnRes |
同条件对照(8K 上下文、B=1 的 decode):
Qwen3.6-35B-A3B ≈ 7.33 GFLOPs
Qwen3-8B ≈ 20.0 GFLOPs
为什么小模型反而更贵:Qwen3.6 的 2048 维主干缩小了投影、30 层用线性(递推)注意力、MoE 只执行选中专家与共享分支;而 Qwen3-8B 是稠密模型、4096 维、36 层全注意力。
判据:比较模型成本时不能只看参数量。 要看:主干宽度、注意力类型(全/线性/滑窗)、激活参数、以及上下文相关的 N_pair。
7. 可复算(实测)
$ cd /root/博客运营官/blog-v2 && python3 tools/s23_book_calc.py | tail -8
MoE(Qwen3.6-35B-A3B): N_e = 3*2048*512 = 3,145,728 (6 MiB BF16)
每层全部路由专家 = 1.50 GiB;单 token 8 专家 = 48 MiB
B=64,k=8: F_expert = 3.22 GFLOPs(均匀/集中相同)
R(U=256) = 1.50 GiB;R(U=8) = 48.0 MiB;比值 = 32.0
40 层合计:均匀 60.0 GiB vs 集中 1.88 GiB
8. 前提与边界
| 结论 | 成立条件 | 不成立时 |
|---|---|---|
F=2N_e·B·k_top |
不丢弃分派 token(dropless) | 有容量丢弃 → 按实际 t_e 累计 |
R=b_W·N_e·U |
每专家权重整块读入一次 | 专家分片在卡上 → 通信量另算 |
| 专家粒度可无损互换算力 | 只比专家矩阵 | 路由器参数随 E 变;分组矩阵形状影响效率 |
| 推测解码有收益 | (T_s+T_v)/ḡ < T_d |
接受率低 → 反而更慢 |
9. 常见误区
| 误区 | 纠正 |
|---|---|
| "MoE 参数多所以更慢" | 激活参数才是算力,总参数只是容量 |
| "均匀路由最好" | 均匀读取量最大;集中读取最省但负载不均 |
| 把共享专家算进路由 | 共享专家处理全部 m 行,与路由无关 |
| 用稠密模型经验估 MoE 的显存 | 权重 69 GB 里只有一小部分每步被读 |
| 残差多路只增显存 | 还增混合与归一化计算(555+149 GFLOPs) |
10. 自测
- Qwen3.6-35B-A3B 的 40 层路由专家共占多少 BF16 权重?一个 token 的 8 个专家占多少?
B=32、k=8、U=256 时,每层专家读取量是多少?- 128 专家 × 1536 × top-8 改成 64 × 3072 × top-4,参数与单 token 算力变吗?什么变了?
- 推测解码的草稿耗时 1 ms、验证 3 ms、平均接受 3 个 token,对比单步 2 ms 是否值得?
答案
1.5 GiB × 40 = 60 GiB;单 token48 MiB。2 B × 3,145,728 × 256 = 1.5 GiB(U 决定,与 B 无关;B 变化只改 F)。- 参数与单 token 算力都不变;变的是矩阵形状、路由器规模与多卡切分粒度。
- 每输出
(1+3)/3 ≈ 1.33 ms < 2 ms→ 值得。
11. 下一篇
S23-J11 · 请求到达、多轮与多模态负载 —— 从"一次前向"走向"持续到达的请求":并发、排队、多轮对话的上下文累积、多模态输入的额外开销。