前置知识: 深度学习

混合专家模型

00:00
12 min Advanced

稠密70B transformer每个token激活所有参数,671B MoE每个token只激活37B并在每个基准上击败它,稀疏是十年来最重要的扩展思想

混合专家模型 (MoE)

稠密70B transformer每个token激活所有参数。671B MoE每个token只激活37B并在每个基准上击败它。稀疏是十年来最重要的扩展思想。

类型: 构建 语言: Python 前置知识: 阶段7 · 05(完整Transformer), 阶段7 · 07(GPT) 预计时间: ~45分钟

问题所在

稠密transformer推理时的FLOPs等于其参数量(前向传播乘2)。扩展稠密模型,每个token支付全部账单。到2024年,前沿正撞上计算墙:要明显更智能,你需要指数级更多的每token FLOPs。

混合专家打破了这个联系。用 E 个独立专家 + 每个token选择 k 个专家的路由器替换每个FFN。总参数 = E × FFN_size。每token活跃参数 = k × FFN_size。典型2026配置: E=256, k=8。存储随 E 扩展,计算随 k 扩展。

2026年前沿几乎全是MoE: DeepSeek-V3(671B总/37B活跃), Mixtral 8x22B, Qwen2.5-MoE, Llama 4, Kimi K2, gpt-oss。在Artificial Analysis的独立排行榜上,前10名开源模型全是MoE。

核心概念

FFN替换

稠密transformer块:

h = x + attn(norm(x))
h = h + FFN(norm(h))

MoE块:

h = x + attn(norm(x))
scores = router(norm(h))              # (N_tokens, E)
top_k = argmax_k(scores)              # 每token选k of E
h = h + sum_{e in top_k}(
        gate(scores[e]) * Expert_e(norm(h))
    )

每个专家是独立的FFN(通常是SwiGLU)。路由器是单个线性层。每个token选择自己的 k 个专家,获得其输出的门控混合。

负载均衡问题

如果路由器将90%的token通过专家3,其他专家挨饿。尝试了三种修复:

  1. 辅助负载均衡损失 (Switch Transformer, Mixtral)。添加与专家使用方差成正比的惩罚。有效,但增加了超参数和第二梯度信号。
  2. 专家容量 + token丢弃 (早期Switch)。每个专家最多处理 C × N/E 个token;溢出token跳过该层。损害质量。
  3. 无辅助损失均衡 (DeepSeek-V3)。添加学习的每专家偏置,移动路由器的top-k选择。偏置在训练损失之外更新。不对主目标加惩罚。2024年的大解锁。

DeepSeek-V3的方法:每个训练步骤后,对每个专家,检查其使用是否高于或低于目标。按 +/-γ 微调偏置。选择使用 scores + bias。用于门控的专家概率是未改变的原始 scores。将路由与表达解耦。

共享专家

DeepSeek-V2/V3还将专家分为共享路由。每个token通过所有共享专家。路由专家通过top-k选择。共享专家捕获通用知识;路由专家专业化。V3运行1个共享专家加256个路由专家中的top-8。

细粒度专家

经典MoE(GShard, Switch): 每个专家与完整FFN一样宽。E 很小(8-64), k 很小(1-2)。

现代细粒度MoE(DeepSeek-V3, Qwen-MoE): 每个专家更窄(1/8 FFN大小)。E 很大(256+), k 更大(8+)。相同总参数,但组合扩展快得多。C(256, 8) = 400万亿 种可能的每token”专家”。质量上升,延迟不变。

成本概况

每token,每层:

配置每token活跃参数总参数
Mixtral 8x22B~39B141B
Llama 3 70B (稠密)70B70B
DeepSeek-V337B671B
Kimi K2 (MoE)~32B1T

DeepSeek-V3在几乎每个基准上击败Llama 3 70B(稠密),同时每token的活跃FLOPs更少。更多参数 = 更多知识。更多活跃FLOPs = 每token更多计算。MoE将它们解耦。

代价: 内存

所有专家都驻留在GPU上,无论哪些被激活。671B模型需要约1.3 TB VRAM用于fp16权重。前沿MoE部署需要专家并行——跨GPU分片专家,跨网络路由token。延迟由全对全通信主导,而非矩阵乘法。

动手构建

参见 code/main.py。纯标准库的紧凑MoE层:

  • n_experts=8 个SwiGLU式专家(各一个线性层,用于说明)
  • top-k=2 路由
  • softmax归一化门控权重
  • 通过每专家偏置实现无辅助损失均衡

步骤1:路由器

def route(hidden, W_router, top_k, bias):
    scores = [sum(h * w for h, w in zip(hidden, W_router[e])) for e in range(len(W_router))]
    biased = [s + b for s, b in zip(scores, bias)]
    top_idx = sorted(range(len(biased)), key=lambda i: -biased[i])[:top_k]
    # 对选中专家的原始分数做softmax
    chosen = [scores[i] for i in top_idx]
    m = max(chosen)
    exps = [math.exp(c - m) for c in chosen]
    s = sum(exps)
    gates = [e / s for e in exps]
    return top_idx, gates

偏置影响选择,不影响门控权重。这就是DeepSeek-V3的技巧——偏置纠正负载不平衡,不引导模型的预测。

步骤2:运行100个token通过路由器

跟踪哪些专家触发多少次。没有偏置时,使用是偏斜的。通过偏置更新循环(过度使用的专家 ,使用不足的 ),使用在几次迭代后收敛到均匀分布。

步骤3:参数量比较

打印MoE配置的”稠密等价”。DeepSeek-V3形状: 256路由 + 1共享, 8活跃, d_model=7168。总参数量令人瞠目。活跃量是稠密Llama 3 70B的七分之一。

实际应用

HuggingFace加载:

from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("mistralai/Mixtral-8x22B-v0.1")

2026年生产推理: vLLM原生支持MoE路由。SGLang有最快的专家并行路径。两者都自动处理top-k选择和专家并行。

何时选择MoE:

  • 你想要更低推理成本下每token的前沿质量。
  • 你有VRAM / 专家并行基础设施。
  • 你的工作负载是token密集型(聊天, 代码)而非上下文密集型(长文档)。

何时不选MoE:

  • 边缘部署——你为任何活跃FLOP支付全部存储。
  • 延迟关键的单用户服务——专家路由增加开销。
  • 小模型(<7B)——MoE的质量优势只在计算阈值(~6B活跃参数)以上出现。

交付成果

参见 outputs/skill-moe-configurator.md。该技能根据参数预算、训练token和部署目标为新MoE选择E, k和共享专家布局。

练习

  1. 简单。 运行 code/main.py。观察无辅助损失偏置更新如何在50次迭代中均衡专家使用。
  2. 中等。 用基于哈希的路由器替换学习路由器(确定性,无学习)。比较质量和均衡。为什么学习路由器更好?
  3. 困难。 实现GRPO风的”推出匹配路由”(DeepSeek-V3.2技巧):记录推理时哪些专家触发,在梯度计算时强制相同路由。在玩具策略梯度设置上测量效果。

关键术语

术语们怎么说实际含义
专家个FFN中的一个”独立的前馈网络;专用于FFN计算稀疏切片的参数
路由器为每个token对每个专家评分的微型线性层;top-k选择。
Top-k路由”每token k个活跃专家每个token的FFN计算恰好通过k个专家,按加权
辅助损失负载均衡惩罚”惩罚偏斜专家使用的额外损失项。
无辅助损失”DeepSeek-V3的技巧”通过路由器选择上的每专家偏置均衡;无额外梯度
共享专家”始终开启”每个token通过的额外专家;捕获通用知识
专家”按专家分片”将不同专家分布到不同GPU;跨网络路由token
稀疏”活跃参数 < 总参数比率 k × expert_size / (E × expert_size);DeepSeek-V3为37/671 ≈ 5.5%。

延伸阅读

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式