从0训练LLM · 现代大模型体系 阅读 + 实验 ≈ 45 分钟 页内实验 ×4
C11 更大更省:MoE、线性/稀疏注意力与长上下文 第 2 课

专家为什么抢活、闲置?

专家抢活与闲置:负载均衡
不管它,路由器会越来越偏心:被选中的专家拿到梯度、变好、更常被选中,没被选中的一直原地不动。Switch 用辅助损失把均衡写进 loss,系数却难调;DeepSeek 改成只在「选谁」上加一个偏置、不碰梯度;而 DeepSeek-V3 自己的消融说,真正要紧的是在多大范围里统计均衡。

本课一问:专家为什么抢活、闲置?

这一课先不碰:专家该大还是小、要不要共享专家(第 3 课);负载不均时专家并行的 all-to-all 等谁(C10 岔路 2);路由 logit 过大的稳定性问题(router z-loss,C8 第 4 课)。

从已有出发

从已有出发 · 累计数据流 点已学环节看形状与参数
解码层

第 1 课的误解三留下一句话:没被选中的专家,这一步拿不到任何梯度。这一课把这句话变成一个数。

这一课换个例子,原因是:负载是整批 token 的统计量——每个专家分到了多少比例。贯穿例句只有 5 个 token,在 8 个专家上连一个像样的分布都画不出来;要看「越来越偏」,还得有训练的时间轴。所以下面用一个在浏览器里真的训练的小 MoE:4 个线性专家、每个 token 选 1 个、每步 64 个 token、训 400 步。任务是教学构造(8 维输入来自 4 个聚类,目标 = 公共部分 + 各簇自己的部分),梯度下降是真的。

先自己设计:什么都不管,让路由器自由学

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案不做均衡:路由器和专家一起自由学
浏览器内微训练 · 不做均衡(种子 1)

塌缩是自我强化的,机制只有三步:

  1. 初始化时路由分数有一点点偏,某个专家稍多分到一些 token;
  2. 只有被选中的专家拿到梯度,它越学越好;路由器的梯度经门控值 g 回来,把这些 token 更多地推给「已经学得比较好」的它;
  3. 没被选中的专家原地不动,越来越没人选——死专家。

后果有两层。质量:死专家的参数白放了,MoE 退化成一个更小的模型(上图不均衡组的任务 loss 最高)。速度:专家并行时每个专家在一张卡上,所有卡要等最忙的那张;按容量因子截断时,挤爆的专家直接丢掉超出的 token(Switch §2.2)。

改进一:把均衡写进 loss(辅助损失)

Switch Transformer 的做法:加一项和「负载偏离均匀」挂钩的损失。逐项看:

Switch 负载均衡损失 · Fedus et al. 2021 式 (4)–(6)
= · · Σi ·
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
真数字(现算):8 个专家完全均衡时 = α × 8 × 8 × (1/8)(1/8) = α = 0.01;全部挤到 1 个专家、概率也全给它时 = α × 8 × 1 × 1 = 0.08。4 专家的微训练里,不做均衡的那一组末步这一项(未乘 α)是 1.86,均衡时是 1。

在上面的模拟器里把 α 从 1 拖到 0.01:几乎拉不平;拖到 10:负载是平了,任务 loss 却比 α = 1 时差了一截——均衡项的梯度开始和主目标抢方向。Switch 选 10⁻² 是在它自己的交叉熵量级上扫出来的 ,换一个主 loss 量级就得重扫(模拟器的主 loss 是 0.05–0.2 的均方误差,所以甜点在 1 附近)。Wang 等人 2024 把问题说得很直接:辅助损失大了会引入干扰梯度、伤性能,小了又不均衡 。

改进二:不碰梯度,只改「选谁」(无辅助损失偏置)

Wang 等人(DeepSeek,2024)换了个思路:不去拉路由器的分数,而是在选择这一步给每个专家加一个偏置 bi。DeepSeek-V3 第一次在大规模上这样训:

无辅助损失负载均衡 · DeepSeek-V3 式 (16) 与偏置更新
= , 若 ∈ TopK; ; 另加
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
偏置训练结束后就固定下来,推理时照用,训练和推理的选择方式一致。2026 年的 DeepSeek-V4 / V4.1、GLM-5.3、Kimi K3 的 config 里都能看到它(topk_method = noaux_tc 等)。

在消融里,两档规模(15.7B 训 1.33T token、228.7B 训 578B token)上,换成无辅助损失的版本在多数基准上更好,例如 Pile 测试集 BPB 0.727 → 0.724、0.656 → 0.652 。DeepSeek-V3 训练全程没有丢过一个 token(报告 §2.1.2)。

但别急着下结论「辅助损失不行」。同一份报告的 §4.5.3 又做了一组:把辅助损失的统计范围从「每条序列」放宽到「每个 batch」,结果和无辅助损失的方法一样好——1B 模型的验证 loss:序列级辅助损失 2.258,无辅助损失 2.253,batch 级辅助损失 2.253;3B 模型:2.085、2.080、2.080 。报告的解释是:按单条序列强制均衡,等于逼每条序列(比如一段纯代码)把 token 平均分给所有专家,专家就没法专门学某一类内容。真正要紧的是在多大范围里统计均衡,不是「用不用 loss」。Qwen3 选的正是这条路:全局 batch 的负载均衡损失 ;Qwen3.8-2.4T 的 config 里 router_aux_loss_coef = 0.001。

我们自己的模型:4 个专家、top-2、400 步

项目里真的训了三组(每层 4 个专家、每个 token 选 2 个):不均衡、辅助损失 0.01、偏置 γ = 0.001。每 5 步记一次每层每个专家分到的 token 比例:

项目实测 · 4 个专家的负载随训练步数(每层一格)

读这张图先记住一个上限:top-2 下,单个专家最多占 0.5——每个 token 都把两个名额里的一个给了它(图里那条实线)。完整的对照表、先预测再看的练习,在实验课。

2026:近千个专家时,±γ 太慢

Kimi K3 有 896 个路由专家、每个 token 选 16 个。报告说,DeepSeek 式的固定步长 ±γ 在这个规模上「要么适应太慢、要么来回震荡」,于是提出 Quantile Balancing(QB):不一步步试探,而是直接用这一批的分数算出「每个专家的偏置该是多少,才恰好分到目标数量」。规则只有两行(报告式 14):门槛 αi 取每个 token 带偏置分数的第 k+1 名;每个专家的新偏置取「原分数 − 门槛」的第 q+1 大值的相反数,q = mk/n 是目标负载。

Quantile Balancing 逐步 · 复现 K3 图 5 的初始负载 (4,3,1,0)
Quantile Balancing 逐步 · 8 个 token × 4 个专家、top-1
每个专家分到几个 token(目标 q = m·k/n = 2)

🎯

试三件事:① 点一次「跑一步」:负载从 (4, 3, 1, 0) 变成 (4, 2, 2, 0)——E4 还是没分到;② 再点一次:(3, 2, 2, 1);③ 继续点:偏置不再变,停在 (3, 2, 2, 1)。旧版课程说「一步就改善到极差 2、饿死的专家被救活」,按这组教学分数不成立:第 1 步还有一个专家饿着,第 2 步才救活,而且停在一个不动点上,到不了 (2, 2, 2, 2)。K3 图 5 在它自己的示意分数上一步得到 (2, 2, 2, 2),那是特例,不是保证——图 5 画的是一次更新的机制;真实训练每批几百万个 token、每一步都在更新,偏差是被持续压住的。上面的微训练里把 QB 放进训练循环,4 个专家同样被拉平。

同一时期,DeepSeek-V4.1 给图像 token 和文本 token 各配一套偏置(模态分开统计,γ 仍是 0.001) ;GLM-5.3-Flash 在无辅助损失偏置之外留了系数 0.001 的辅助损失。

⚠

常见误解一:「负载均衡只是为了让 GPU 利用率高。」 那只是一半。死专家意味着花了大参数的显存,只训出了小参数的效果;均衡首先是质量问题。

常见误解二:「偏置 b 会改变专家输出的权重。」 不会:b 只决定选谁,门控值仍由原始分数得出(DeepSeek-V3 式 (16))。本章排除清单里的一篇中文面试题解析,例题把加了偏置的分数直接乘进输出,正是这个错。

常见误解三:「均衡得越细越好,每条序列都要平均。」 序列级的强制均衡会压制专家分工;DeepSeek-V3 的消融里,batch 级的辅助损失和无辅助损失一样好,序列级的差一截。

常见误解四:「QB 一步就把负载拉平。」 见上面的实算:(4,3,1,0) → (4,2,2,0) → (3,2,2,1),然后停住。

本章演进图:每一代都被上一代的某个真数字逼出来(本课所在的一代已高亮;其余两条线可展开)
① 更多参数,不要更多算力(MoE)
  1. 朴素 dense 直接放大 算力 ∝ 参数
    解决了结构最简单:所有参数对每个 token 都生效。
    卡在锚点 Qwen3.8-27B 每 token 前向约 51.2 GFLOPs;同家族 2.4T 规模若是 dense,约 4.84 TFLOPs(94 倍)。
  2. 第一代 稀疏门控 MoE Shazeer 2017 → GShard → Switch
    解决了每个 token 只算 top-k 个专家:Qwen3.8-2.4T-A95B 每 token 约 186.5 GFLOPs,是同参数 dense 的 26 分之一。
    卡在路由会自我强化地偏心:8 个专家全挤到 1 个时,Switch 负载损失从 0.01 升到 0.08;所有专家的权重仍要常驻显存。
  3. 改进 ① 辅助损失 α·N·Σf·P Switch 2021(α = 10⁻²) 你在这里
    解决了把「均衡」写进 loss,路由器被梯度推向均匀。
    卡在α 难调:太小拉不平,太大干扰主 loss(Switch 在 10⁻¹ 到 10⁻⁵ 之间扫;Wang 2024 的出发点)。
  4. 改进 ② 无辅助损失偏置 Wang 2024 → DeepSeek-V3 你在这里
    解决了偏置只改「选谁」,不进门控、不产生干扰梯度;DeepSeek-V3 前 14.3T token 用 γ = 0.001,最后 500B 设为 0。
    卡在固定步长在近千个专家时太慢或来回震荡(Kimi K3 报告)→ Quantile Balancing;而且统计范围(整批 vs 单条序列)比「有没有 loss」更要紧。
  5. 改进 ③ 细粒度专家 + 共享专家 DeepSeekMoE 2024
    解决了同参数同计算,16 选 2 的 120 种组合变成 64 选 8 的 4,426,165,368 种;共享专家装公共知识。
    卡在显存账不减:Qwen3.8-2.4T 路由专家占主干参数 97.98%,BF16 权重 4.89 TB。
  6. 2026 极高稀疏度与分歧 Qwen3.8 · K3 · V4.1
    解决了Qwen3.8-2.4T 512 选 10 + 1 共享;K3 896 选 16 + LatentMoE + Quantile Balancing;V4.1 图文两套偏置。
    卡在共享专家 0、1、2 个都有人用(Qwen3 一个不设),稀疏度从 32 到 64 都有(GLM-5.3 与 V3 为 32、GLM-5.3-Flash 36、K2 48、Qwen3.8 51、K3 56、V4.1-Flash 64)——都是实验选择。
② 长文本:KV 与计算不再随长度等比例涨
  1. 解决了每个 token 都能精确回看任意一个前文 token。
    卡在KV ∝ 长度:锚点若 64 层全是全注意力,262,144 token 时 64 GiB。
  2. 第一步 线性注意力 Katharopoulos 2020
    解决了去掉 softmax,求和提前累加成一个固定大小的状态,与长度无关。
    卡在只加不减:同一个键写两次,读回的是两个值之和;状态最多装 d 对互不干扰的键值(C0 岔路)。
  3. 第二步 Gated DeltaNet · 3:1 混合 Schlag 2021 → Yang 2024 → Qwen3-Next、3.8
    解决了写前先擦(delta)、每步衰减(门):锚点 48 层状态共 144 MiB(FP32)、与长度无关;KV 降到四分之一(262,144 时 16 GiB 对 64 GiB)。
    卡在剩下四分之一的全注意力层仍按长度涨;容量有限,3:1 是实验选出来的。
  4. 工程化 KDA + 衰减下界 Kimi Linear → K3 → GLM-5.3-Flash 等
    解决了每通道一个衰减;g_min = −5 让 16 token 块内累积不低于 −80,e⁸⁰ ≈ 5.5 × 10³⁴ 在 BF16 范围内(上限约 3.4 × 10³⁸),慢路径删除。
    卡在MiniMax M1 用线性混合、M2 又退回全注意力:大规模下多跳推理缺陷、训练受访存限制、低精度与缓存难题(官方博客)。
  5. 另一条路 稀疏注意力 DSA DeepSeek-V3.2 2025
    解决了lightning indexer 每个 query 只挑 top-2048 条做核心注意力。
    卡在省计算不省内存:KV 一条不少,每 token 48,068 B;indexer 本身仍要扫全部前文。
  6. 2026 压序列 + 压层 + 压精度 DeepSeek-V4 CSA + HCA → V4.1 CSA2 + CED
    解决了V3.2 每 token 48,068 B → V4-Flash 3,514 B → V4.1-Flash 890 B(1M 时 0.87 GiB)。
    卡在是近似:V4.1 自陈 Bounded Replay「数学上不等价」、选择误差可能在未测过的边界情况退化。
③ 训练 4K,使用 128K
  1. 解决了推理时把新位置折算回训练见过的角度范围。
    卡在零样本外推有代价,方法的超参数带着它被调出来时的规模(C2 第 5 课与项目实测)。
  2. 朴素 从头就用长序列训 最直接的想法
    解决了训练与使用同一个长度,不需要任何折算。
    卡在注意力项随长度涨:Qwen3-32B(64 层全注意力)在 131,072 时注意力项是 6N 的 215%;早期长序列还带来梯度方差极端值(Li 2021)。
  3. 现代做法 先短后长 + ABF BERT → Llama 3 → DeepSeek-V3 · Qwen3
    解决了DeepSeek-V3 的 14.8T token 全在 4K,之后两段各 1,000 步扩到 32K、128K,只占全部训练 token 的 0.84%;Llama 3 405B 六段、约 800B token。
    卡在长序列阶段的数据要专门配(长度上采样、领域均衡、合成跨全文任务)。
  4. 2026 分歧 课程在缩短 Kimi K3 · DeepSeek-V4.1
    解决了K3:8K → 64K → 256K → 1M(NoPE 也照走课程);V4.1 注意力从头就是压缩稀疏的,直接从 64K 起训。
    卡在各家配方大多只公开阶段、不公开每段 token 数,无法横向比较成本。
  5. 岔路 多 token 预测 MTP Stern 2018 → Gloeckle 2024 → DeepSeek-V3
    解决了每个位置多学一个更远的目标;推理时当草稿,接受率 α 时每步期望产出 1 + α 个 token。
    卡在DeepSeek-V3 第 2 个 token 接受率 85%–90%,实测 1.8 倍 TPS;V4.1 预训练干脆去掉 MTP,没有公开消融。
数字口径:锚点、Qwen3.8-2.4T、Qwen3-32B、DeepSeek 各代的数字由 anchor-model.json / frontier-models.json(DeepSeek-V3.2、V4-Flash 取本章补充 config)在构建时现算;KV 字节按 FlashMLA 官方 README 的缓存格式计(indexer key 为推算,见第 5 课);FLOPs 只数矩阵乘,乘加记 2。Switch α、DeepSeek-V3 的 γ 与长上下文两段、K3 的 g_min 与长度课程出自各自原文(本地 PDF 已核);MiniMax 的理由出自其官方博客(2025-10-29)。

证据三问

问本课的回答
① 它解决什么问题?防止路由自我强化地塌缩:死专家浪费参数,忙专家拖慢专家并行、甚至丢 token
② 数学上为什么可能有效?辅助损失在均匀分布时取最小 ;偏置不进门控,所以不改变主目标的梯度
③ 实验上为什么最后选了它?DeepSeek-V3 两档规模上无辅助损失更好,但 batch 级辅助损失同样好;Qwen3 选全局 batch 辅助损失,K3 选 QB

一句话

📌

路由会自我强化地偏心;辅助损失能拉平却难调,偏置只改「选谁」、不碰梯度——而统计范围(整批还是单条序列)比「用不用 loss」更要紧。

🚦

先停在这里:记住「没选中 = 没梯度 → 越来越偏」和「偏置只进选择」两句。
再深一层:在微训练里换 5 个种子,看哪几个种子不均衡组塌得最狠;再读 DeepSeek-V3 的 §4.5.3。

下一个缺口

均衡解决了「谁干活」;那每个专家该多大、分多少个? → 第 3 课:专家该大还是小?

你可能会问