Transformer 解剖:从 Attention 到推理系统
第 12 章 Mixture of Experts:稀疏激活的工程账
第 11 章我们看到密集模型在 Scaling 上撞到的几堵墙——数据耗尽、算力上限、边际递减。MoE(Mixture of Experts,专家混合)是工业界绕开其中一堵墙的关键技术:总参数量放大数倍乃至一个数量级,每个 token 的推理算力却增加有限。
DeepSeek-V3 就是个标志性的例子:总参数 671B(比 Llama-3 70B 大近 10 倍),但每个 token 推理时只激活 37B(比 Llama-3 70B 还小一半)。同样的算力跑出大得多的模型容量——这就是 MoE 卖的核心账。
读完这章你能:
- 解释 MoE 的核心想法:「条件计算」(conditional computation);
- 写出路由器(router)和 Top-K 门控的数学;
- 理解 MoE 训练里最头疼的问题——负载均衡——以及主流的解决方案;
- 对比 Mixtral 8x7B、DeepSeek-V2/V3、Qwen MoE、GShard / Switch Transformer 等不同 MoE 设计;
- 估算一个 MoE 模型的「总参数」「激活参数」「推理 FLOPs」三个不同量。
12.1 一个直觉:稀疏神经网络
先讲一个直觉的故事。
人脑大约有 860 亿神经元。但任何时刻活跃的神经元只占很小一部分。当你在读这段文字时,大量负责「运动」「视觉空间」「记忆其他场景」的神经元都在休眠。大脑用稀疏激活节省能量——这是进化给生物计算找到的一种节能策略。
稠密的 Transformer 不是这样工作的。每个 token 流过 FFN 时,所有的 个隐层神经元都被激活、都参与计算——无论这个 token 是英文「the」还是中文「的」、是代码 function 还是数学符号 ∑。这意味着大量计算花在了「与当前 token 无关」的神经元上。
MoE 的核心想法:给 FFN 增加结构,让每个 token 只激活其中一部分。
具体地:把一个大的 FFN 拆成 N 个小的「专家」(experts),每个专家是一个独立的 FFN(同样是两层 MLP)。再加一个路由器(router)——它接收输入 token,决定「这个 token 应该交给哪几个专家处理」。每个 token 只激活 N 个专家中的 K 个(典型 K=2 或 K=8),其他的根本不参与计算。
flowchart LR X["输入 token x"] --> R[Router] R -->|gate score| E1[Expert 1] R -->|gate score| E2[Expert 2] R -->|gate score| E3[Expert 3] R -->|...| EN[Expert N] R --> TOPK[选 Top-K=2 个分数最高的] TOPK --> ACTIVE["激活: E2, E3"] ACTIVE --> SUM[加权求和] SUM --> OUT[输出] E1 -.未激活.-> OFF[不计算] EN -.未激活.-> OFF
这件事叫条件计算(conditional computation):根据输入条件动态决定哪些参数要被计算。它把「模型容量」和「单次推理算力」解耦——你可以有 100 个专家(容量大),但每次只算 2 个(算力小)。
12.2 数学:MoE Layer 的形式
把一个稠密 FFN 替换成 MoE 时,公式是这样:
1. Router 计算每个专家的 gate score:
是路由器的权重矩阵。 是专家 被「选中」的分数。
2. 选 Top-K 专家:
是分数最高的 K 个专家的索引集合。
3. 重新归一化 Top-K 分数:
让 K 个被选中专家的权重和为 1。HuggingFace 的 Mixtral 实现就是这三步的逐行对应:transformers-4815a0a/src/transformers/models/mixtral/modeling_mixtral.py:107 先对全部 N 个专家做 softmax,:108 取 Top-K,:109 再把这 K 个除以它们的和。
4. 加权求和被选中专家的输出:
其中 是专家 的 FFN(结构和稠密 FFN 一样,只是单独参数)。
形状记号:
| 张量 | 形状 |
|---|---|
| Top-K 索引 | |
| 每个专家的输出 | |
| MoE 输出 |
整个 MoE Layer 的输入输出形状和稠密 FFN 一致—— 进, 出。这意味着可以直接替换 Transformer Block 里的 FFN,其余部分(attention、norm、residual)一字不变。
12.3 一个最小代码实现
import torch
import torch.nn as nn
import torch.nn.functional as F
# SwiGLU 沿用第 9 章 9.3 节的定义
class MoELayer(nn.Module):
def __init__(self, d_model, d_ffn, n_experts, top_k):
super().__init__()
self.n_experts = n_experts
self.top_k = top_k
# N 个独立专家
self.experts = nn.ModuleList([
SwiGLU(d_model, d_ffn) for _ in range(n_experts)
])
# Router
self.router = nn.Linear(d_model, n_experts, bias=False)
def forward(self, x):
# x: (B, T, D)
B, T, D = x.shape
x_flat = x.view(-1, D) # (B*T, D)
n_tokens = x_flat.size(0)
# 1. Gate scores
logits = self.router(x_flat) # (B*T, N)
# 2. Top-K 选择
topk_vals, topk_idx = logits.topk(self.top_k, dim=-1) # (B*T, K)
topk_weights = F.softmax(topk_vals, dim=-1) # 归一化
# 3. 把 token 按选中的专家分组并送过去
out = torch.zeros_like(x_flat)
for i in range(self.n_experts):
# 找到所有选中专家 i 的 (token, slot) 对
mask = (topk_idx == i) # (B*T, K)
if mask.any():
token_idx, k_slot = mask.nonzero(as_tuple=True)
# 这些 token 的输入
tokens_for_i = x_flat[token_idx] # (n_i, D)
# 经过专家 i
expert_out = self.experts[i](tokens_for_i) # (n_i, D)
# 加权累加到输出
weights = topk_weights[token_idx, k_slot].unsqueeze(-1)
out[token_idx] += weights * expert_out
return out.view(B, T, D)
这是一个最小可读版本,没有做负载均衡损失、没有做 All-to-All 通信优化——但展示了 MoE 的核心数据流。
(这里的 F.softmax(topk_vals) 和 12.2 节写的「先对 N 个做 softmax、再对 Top-K 归一化」是同一个结果:两者的分子都是 、分母都是 ,全局那个归一化常数被约掉了。)
for i in range(self.n_experts) 这个循环在小规模上能跑,但 N 大时(比如 256)开销大。生产实现用 torch.scatter + torch.gather + grouped GEMM 的组合,把这个循环并行化。
12.4 关键挑战:负载均衡
MoE 训练里最大的工程问题是负载均衡。
设想:你有 8 个专家,每次每个 token 选 Top-2。理想情况下每个专家应该平均分到 1/4 的 token。但实际训练中,模型常常退化到「只用少数几个专家」的模式——比如 8 个专家里 2 个被选 80%,剩下 6 个几乎没机会工作。
为什么?因为路由器是个软目标,模型在训练初期可能因为随机初始化让几个专家「先发优势」——这几个专家被路由更多 token,得到更多梯度,能力增长更快,又被更多选——形成正反馈。最终少数专家承担大部分工作,剩下的「死掉」(dead experts)。
负载不均衡有两个严重后果:
- 模型容量利用率低:6 个 dead experts 的参数白白浪费,相当于把 N=8 退化成 N=2。
- 硬件利用率低:训练时专家分布在不同 GPU 上,一个 GPU 跑爆了、其他 GPU 空闲——bottleneck 拖慢整体速度。
flowchart TB
subgraph ideal ["理想(均匀)"]
EA["Expert 1: 12.5%"]
EB["Expert 2: 12.5%"]
EC["Expert 3: 12.5%"]
ED["..."]
EE["Expert 8: 12.5%"]
end
subgraph collapse ["崩塌(头部聚集,数字为示意)"]
BA["Expert 1: 45%"]
BB["Expert 2: 35%"]
BC["Expert 3: 12%"]
BD["Expert 4-7: 各 2%"]
BE["Expert 8: 0% (dead)"]
end
Auxiliary Loss:硬性负载均衡
经典解决方案是给训练 loss 加一项辅助损失(auxiliary loss),鼓励均匀使用:
其中:
- :专家 被选中的比例(actual usage frequency)
- :专家 的平均 gate 概率
- :辅助损失权重(Switch Transformer 取 0.01)
直觉:当某个专家既「被频繁选中( 大)」又「平均分数高( 大)」时,这一项变大——模型被惩罚,下次会让其他专家分担。这一项让所有专家被均匀使用。
上式是 Switch Transformer(arXiv:2101.03961)的写法;GShard 用的是同一思路、系数略不同的版本()。Mixtral 论文没有交代训练时的均衡损失,但 HF 的 Mixtral 实现内置了它:transformers-4815a0a/src/transformers/models/mixtral/modeling_mixtral.py:485 的 load_balancing_loss_func(docstring 注明实现的是 Switch Transformer 的式 (4)–(6)),末尾 :550 的 torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(0)) 再在 :551 乘以 num_experts,就是 。
Auxiliary-Free Load Balancing
DeepSeek-V3(arXiv:2412.19437)采用了一种无辅助损失的负载均衡(方法出自同团队 Wang et al. 2024,arXiv:2408.15664)——给每个专家 的原始亲和度分数 (对应 12.2 节的 ,不过 V3 用 sigmoid 而非 softmax 计算它)加一个动态 bias :
两个关键细节容易被讲错:
- bias 只参与「选谁」,不参与「加权」。加了 bias 的分数 只用来挑 Top-K;被选中的专家在加权求和时用的仍然是原始分数 。这样路由权重反映的还是模型真实学到的相关性。
- bias 不是梯度学出来的。它在反向传播之外、以
no_grad的方式按负载统计手动增减:每个训练步结束时,某个专家这一步收到的 token 超过目标就把 减去一个固定步长 ,不足就加上 。
这种方案的好处:bias 这条均衡通路完全不进入主 loss 的梯度,不和主任务抢梯度。V3 并没有彻底去掉辅助损失——它另加了一项权重极小()的序列级均衡损失,只为防止单条序列内的极端失衡。这套 bias 机制在 DeepSeek V4 里被沿用(见《DeepSeek V4 源码剖析》专栏第 7 章)。
Token Dropping vs Expert Capacity
另一个工程细节:每个 GPU 上的某个专家能处理多少 token 是有上限的(叫 expert capacity)——它的硬件资源固定。如果某个专家被分配的 token 超出 capacity,就要 drop 多余的(直接跳过它的 FFN,残差走过去)或者 overflow(流到其他专家)。
设 capacity factor (典型值),则每个专家最多接受 个 token。超出的 drop。这给了 buffer 容忍轻度负载不均衡,但极端不均衡仍然会大量 drop。
12.5 主流 MoE 设计对比
把工业界主流 MoE 模型的关键参数放一起:
| 模型 | 总参数 | 激活参数 | 专家数 | Top-K | 共享专家 | 注意 |
|---|---|---|---|---|---|---|
| GShard (Google) | 600B | — | 2048 | 2 | 否 | 早期奠基(2020),激活参数论文未单列 |
| Switch Transformer (Switch-C) | 1571B | — | 2048 | 1 | 否 | Top-1;论文只给每序列 FLOPs(890B),未单列激活参数 |
| GLaM (Google) | 1200B | 97B | 64 | 2 | 否 | 激活约占总参数 8% |
| Mixtral 8x7B | 47B | 13B | 8 | 2 | 否 | 开源 MoE 起点 |
| Mixtral 8x22B | 141B | 39B | 8 | 2 | 否 | |
| DeepSeek-MoE 16B | 16.4B | 2.8B | 64 (fine-grained) | 6 | 2 | 细粒度专家(arXiv:2401.06066) |
| DeepSeek-V2 | 236B | 21B | 160 | 6 | 2 | MLA + DeepSeek MoE |
| DeepSeek-V3 | 671B | 37B | 256 | 8 | 1 | MLA + 无辅助损失均衡 |
| Qwen1.5-MoE-A2.7B | 14.3B | 2.7B | 60 | 4 | 4 | 共享专家在 HF 实现里被合并成一个大块 |
几个观察:
1. 专家数从 8 涨到 256+。早期 Mixtral 用 8 个大专家(把 32 层的同号专家加起来,每个约 5.6B 参数——注意 8×7B 并不等于 56B,因为 attention 和 embedding 是共享的),新一代 DeepSeek 用 256 个小专家(同样口径下每个约 2.5B)。细粒度更多专家 的设计在 DeepSeekMoE 的对照实验里表现更优——更细的分工让专家学得更专。
2. Top-K 也从 2 涨到 6-8。专家切细之后,为了保持每 token 计算量不变,激活的专家数要按同样倍数增加(DeepSeekMoE 的细粒度切分正是这么做的);可选的专家组合因此多得多,组合更灵活。
3. Shared experts 出现。DeepSeek 引入 shared experts—— 一两个专家「always on」(不通过 router,每个 token 都过它们)。共享专家学习「通用语言模式」,剩下的 routed experts 学习「专业化技能」——这种分层设计让 routed experts 的工作更聚焦。
4. 总 / 激活参数比从 4 涨到 18。Mixtral 8x7B 是 47B 总 / 13B 激活(约 3.6×),DeepSeek-V3 是 671B / 37B(约 18×)。稀疏率越来越高——DeepSeek-V2/V3、GLaM 这一代每次只激活 5%-10% 的总参数。
flowchart TB
subgraph "Mixtral 8x7B<br/>粗粒度 MoE"
direction LR
M_T[8 大专家<br/>跨层合计每个 ~5.6B]
M_K[Top-2]
M_R[参数激活率 ~28%]
end
subgraph "DeepSeek-V3<br/>细粒度 MoE"
direction LR
D_T[256 小专家<br/>跨层合计每个 ~2.5B]
D_K[Top-8]
D_R[参数激活率 ~5.5%]
D_S[+ 1 shared expert<br/>所有 token 都过]
end
12.6 MoE 的工程难点:All-to-All 通信
到这里讲的都是单 GPU 视角。MoE 真正的工程复杂度是多 GPU 训练——专家分布在不同 GPU 上时,token 必须从「自己的 GPU」流到「目标专家的 GPU」,然后流回来。这需要一种特殊的集合通信叫 All-to-All。
设想 8 张 GPU、64 个专家、每张 GPU 装 8 个专家。一个 token 经过 router 后被分配给某 K 个专家——这些专家可能分布在任何 GPU 上。流程:
flowchart LR GPU1[GPU 1<br/>有 8 个 token<br/>每个 token 选 2 个专家] --> AA[All-to-All] GPU2[GPU 2<br/>同上] --> AA GPU3[GPU 3<br/>同上] --> AA AA --> ROUTE[各 GPU 收到<br/>『发往自己 GPU 上某个专家』<br/>的 token] ROUTE --> EXP[GPU 各自计算自己的<br/>专家 FFN] EXP --> AA2[All-to-All 反向] AA2 --> RESULT[每张 GPU 拿回<br/>自己原本 token 的输出]
每个 MoE 层的 forward、backward 各要做两次 All-to-All(一次发出、一次收回)。这是 MoE 训练比稠密模型多出的主要开销。
All-to-All 的特点:带宽瓶颈。每张 GPU 同时给所有其他 GPU 发数据、同时收所有其他 GPU 的数据——网络带宽必须很高才不被打瘪。
主流大规模 MoE 训练用的硬件:
- 同机内 GPU 之间走 NVLink(H100 单卡双向 900 GB/s;GB200 NVL72 到 1.8 TB/s),跨机走 InfiniBand(NDR 400 Gbps ≈ 单向 50 GB/s)——同按单向算(NVLink 450 GB/s),两者差约 9 倍,这个落差直接决定了专家该怎么摆(DeepSeek-V3 为此限制每个 token 最多发往 4 个节点)
- 软件上:DeepSpeed-MoE、Tutel、FastMoE 都对 All-to-All 做了大量优化(管道化、压缩、合并通信)
- DeepSeek-V3 把通信和计算重叠(在做 All-to-All 的同时计算其他 token),把通信 bubble 压到很小
这套工程栈是大模型训练真正的「门槛」——开源代码再多,没有工程团队你训不起来 MoE 大模型。
12.7 推理时的 MoE:批处理友好度
训练时 MoE 主要痛点是 All-to-All 通信。推理时痛点不同——主要是批处理友好度。
稠密模型推理时,一次 batch 进来 64 条 query,每条经过 FFN 时全部 4d 神经元都激活、batch 内所有 token 共享同一组权重——非常 GPU 友好。
MoE 推理时,64 条 query 的 token 在路由后被分散到不同专家,每个专家只处理一小撮 token——单个 GEMM 变小,GPU 利用率下降。
具体地,假设有 64 个专家、每个 token 选 Top-2、batch 里有 200 个 token:
- 平均每个专家收到 个 token
- 这 6 个 token 的 FFN 计算量太小,时间主要花在把整个专家的权重从显存读进来(memory-bound)
- 单个专家的 GEMM 退化成「瘦长条」,Tensor Core 根本喂不饱,算力利用率相比同等 batch 的稠密模型明显下降
解决方案:
- 更大 batch:把 batch 做到几千 token,每个专家平均收到 100+ 个,单 kernel 计算量回到合理范围。
- Expert Parallelism + 专家 Group:把同 GPU 上的几个专家合并成一组,统一调度。
- 路由预测 / 预调度(研究中):提前预测路由结果,预先调度专家和通信。
vLLM、TensorRT-LLM、SGLang 都对 MoE 推理做了专门优化。large batch 下 MoE 推理的 GPU 利用率可以做得较高,但小 batch 仍然不友好——所以 MoE 模型部署给「在线低延迟」场景比稠密模型麻烦。
12.8 MoE vs 稠密:什么时候选 MoE?
把两者的取舍放一起:
| 维度 | 稠密 | MoE |
|---|---|---|
| 模型容量 | 受限于训练算力 | 同算力下容量可以大得多 |
| 训练复杂度 | 简单 | 复杂(负载均衡、All-to-All) |
| 训练算力 | 高 | 同等模型「能力」下更低 |
| 显存占用 | 高 | 高(专家全部要在显存里) |
| 推理 FLOPs | 高 | 低(只激活 K 个专家) |
| 推理 batch 友好 | 友好 | 大 batch 友好,小 batch 不友好 |
| 训练稳定性 | 好 | 差(需要专门技巧) |
| 工程门槛 | 中 | 高 |
什么时候选 MoE?
- 目标是「最大化能力 / 单次推理 FLOPs 比」:MoE 用更少推理算力换更大容量。公开资料里,Google(Gemini 1.5 技术报告)、DeepSeek、Mistral、Qwen 等都走了这条路。
- 训练算力充足、能容忍工程复杂度:MoE 训练成本不低,且对工程团队要求高。
- 场景是大 batch 服务:API 后端、批量推理。
什么时候不选?
- 小模型(< 10B):稀疏化的收益往往抵不过多出来的工程复杂度,这一档多数模型仍是稠密。
- 小 batch 在线服务:MoE 在小 batch 下硬件利用率低。
- 工程团队规模小:MoE 的训练和推理调优工作量都比稠密大很多。
主流开源生态目前的选择:普通规模(7B、13B、70B)大多用稠密;超大规模(200B+)的新模型大多是 MoE(Llama 3.1 405B 是少见的稠密例外)。
12.9 MoE 的训练稳定性
MoE 训练有几个特别容易掉的坑:
坑一:Router 的 logits 爆。路由器的输出经过 softmax,logits 太大会让 softmax 一面倒地选某个专家,剩下的几乎为零——选择多样性消失,模型退化。解决办法:
- 给 router 输出加 entropy regularization(鼓励熵不要太低)
- 用 z-loss 约束 logits 的尺度(让
log(sum(exp(logits)))不要太大)
坑二:Dead experts。某个专家从初始化开始就没被选过,永远拿不到梯度更新,永远学不到东西。解决办法:
- Auxiliary loss / DeepSeek bias 强制均匀使用
- 小初始化 + warmup(Switch Transformer 把默认初始化尺度缩小 10 倍,让训练初期更稳定、router 输出更接近均匀)
坑三:训练不稳定 spike。MoE 模型经常在训练中途 loss 突然飙升(spike)。成因没有定论,一种常见解释是某些专家进入「重新分工」阶段——一个专家因为分布漂移,被频繁切换 token 来源,loss 高度震荡。解决办法:
- 训练 checkpoint 频繁,spike 时回滚
- 路由器计算保持 float32(Switch Transformer 的 selective precision),路由器单独用更小 lr
- 做到位的话可以不靠回滚:DeepSeek-V3 报告称整个训练过程没有出现不可恢复的 loss spike,也没有做任何回滚
坑四:跨语言 / 跨模态的不平衡。如果训练数据是「英文 + 中文 + 代码」混合,模型可能让某些专家「专攻英文」、某些专攻中文——某个 batch 内英文比例高时,对应专家被打爆,剩下的空闲。解决办法:
- 在数据采样时按比例混合
- 用 packing 把不同语言的 token 打散到 batch 里
这些问题在 ST-MoE 论文和 DeepSeek 系列技术报告里都有讨论。读 DeepSeek-V2、V3 技术报告会让你看到「真正训出 MoE 大模型」的复杂度。
12.10 关于 MoE 的几个误解
误解一:MoE = 把模型拆成独立子模型
不对。所有专家共享同一个 attention 层、同一个 embedding、同一组归一化层——只有 FFN 部分被分成专家。整个模型仍然是「一个模型」,只是 FFN 部分稀疏激活。
误解二:每个专家学习一个特定领域
基本不对。Mixtral 论文专门做过路由分析:在 The Pile 的 ArXiv、PubMed、PhilPapers 等子集上,专家分配的分布非常相似,没有观察到按主题分工的明显模式;能看到的更多是语法层面的规律——比如 Python 里的 self、代码里的缩进,常被路由到同一个专家。所以专家的分工是模糊的、统计的,不是「这个专家专做 Python、那个专家专做 SQL」这种明确边界。Top-K 路由让每个 token 多路出击,分工不会完全清晰。
误解三:MoE 显存比稠密小
不对。所有专家的参数都要在显存里——MoE 的总参数甚至比同等能力的稠密模型大。MoE 节省的是计算量,不是显存量。这就是为什么部署 MoE 模型的硬件门槛和总参数量绑定(DeepSeek-V3 671B 推理仍然需要多卡)。
误解四:稀疏激活 = 推理加速 K/N 倍
不完全。理论上 K=2、N=64 时计算量是稠密的 2/64=3%,但实际上:
- Router 本身有计算(虽然小)
- 专家分组后 GEMM 变小,GPU 利用率下降
- All-to-All 或者 routing 操作本身有开销
实际加速远达不到 N/K 这个理论上界,具体差多少取决于 batch 大小、专家粒度和通信实现——只有在足够大的 batch 下,MoE 才能把理论上的稀疏优势兑现出一大半。
12.11 一个新视角:MoE 和模型记忆容量
我们在 5.2 节提到,FFN 是 Transformer 的「记忆容量」(key-value memory)。MoE 把 FFN 拆成 N 个专家,相当于把记忆容量拆成 N 个独立的「记忆库」——每个 token 根据内容在某些库里查。
这个视角让 MoE 的设计变得直观:
- 专家越多 + 越细粒度 → 记忆库越多越细,能存的「专门知识」越多
- Top-K 越大 → 每次查询能跨多个库聚合,覆盖更复杂语义
- Shared experts → 一个「公共图书馆」存通用知识,所有 token 都先过它
DeepSeek-V3 的 256 routed + 1 shared 设计恰好对应这个直觉:1 个公共图书馆 + 256 个专科图书馆,每个 token 从 256 个里挑 8 个最相关的查。这也为 DeepSeek 细粒度设计的优势提供了一种直观解释——记忆库更细,知识存得更整齐。
本章小结
- MoE 解耦了模型容量和单次推理算力——通过条件计算让总参数量远超激活参数量。
- MoE Layer = N 个独立 FFN(专家)+ 路由器(Top-K 选择)——结构上替换稠密 FFN,其余不变。
- 负载均衡是核心难点:少数专家被打爆、其他 dead 是常见 failure mode。Auxiliary loss 或 DeepSeek-style bias 是主流解决方案。
- 细粒度专家 + 共享专家是 2024 趋势:DeepSeekMoE 的对照实验里,这种设计优于传统的少量大专家 + Top-2;DeepSeek-V3 走到了 256 routed + 1 shared。
- All-to-All 通信是分布式训练的瓶颈——需要 InfiniBand / NVLink + 专门通信库。
- MoE 推理在小 batch 下不友好——专家分组让 GEMM 变小,GPU 利用率掉。生产部署需要大 batch。
- MoE 不省显存只省计算——所有专家的参数都要在显存里。
- 训练稳定性是另一道墙:router logits 爆、dead experts、loss spike——需要专门工程经验。
- 何时选 MoE:需要超大容量但要控制推理算力、有大 batch 场景、有强工程团队。
- 何时不选:小模型(<10B)、低延迟在线服务、工程团队小。
下一章我们看长上下文之战——从 4K 到 1M,Transformer 是如何把上下文窗口推到这种量级的。这一章会用到第 4 章的位置编码、第 5 章的 attention 计算复杂度,作为综合应用。
延伸阅读
- Shazeer et al., Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer, ICLR 2017(arXiv:1701.06538)——MoE 在深度学习的奠基作。
- Lepikhin et al., GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding, ICLR 2021(arXiv:2006.16668,2020)——MoE 在大模型上的早期落地。
- Fedus et al., Switch Transformers: Scaling to Trillion Parameter Models with Simple and Efficient Sparsity, JMLR 2022(arXiv:2101.03961,2021)——Switch Transformer。
- Jiang et al., Mixtral of Experts, 2024(arXiv:2401.04088)——开源 MoE 起点。
- Dai et al., DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models, 2024(arXiv:2401.06066)——细粒度专家 + 共享专家。
- DeepSeek-AI, DeepSeek-V2(arXiv:2405.04434), DeepSeek-V3 Technical Report(arXiv:2412.19437)——细粒度 MoE + Auxiliary-free balancing 的工业实战。
- Zoph et al., ST-MoE: Designing Stable and Transferable Sparse Expert Models, 2022(arXiv:2202.08906)——MoE 训练稳定性深度讨论。
- Chen et al., Towards Understanding the Mixture-of-Experts Layer in Deep Learning, NeurIPS 2022(arXiv:2208.02813)——MoE 理论分析。