第4讲 · Stanford CS336:从零开始的语言建模|:注意力的替代方案

课程信息

课程 Stanford CS336 Language Modeling from Scratch(2026 春季)
本讲 Lecture 4 — Attention Alternatives(注意力的替代方案:线性时间注意力与混合专家)
视频 https://www.youtube.com/watch?v=cKSwj_qZ8Jg
时长 约 86 分钟(5180 秒)
本书定位 面向 CS 初学者的课堂重构稿。本书是课堂口语记录的重构,保留讲师的推理链、类比与案例;凡编者补充的内容一律以「编者说明 / 编者拓展」明确标注,不冒充讲师原话。

对应讲次:第4讲(Stanford CS336 语言建模)

制作模型:deepseek-flash(vb compose,据 run.log)


导览

这是一张帮助你在 3–5 分钟内建立全局理解的问题地图。导览只给地图,不复述结论、不剧透推导。

① 讲师真正想回答的核心问题

② 难点在哪——最容易卡住的地方

  1. 线性注意力的「丢 softmax」这一步:把 $\mathrm{softmax}(QK^\top)V$ 改写成 $Q(K^\top V)$,是有损的(丢掉了 softmax 的行归一化);而紧接着的「线性形式 ⇄ RNN 形式」却是精确等价的。学生容易把这两步混为一谈,误以为整个改造无损。(讲师在 [00:20:56]–[00:21:36] 专门澄清了这一点)
  2. 门控与状态依赖的边界:在把线性注意力「续命」成 Mamba 2、Gated DeltaNet 时,什么可以门控、什么不可以(只能用「依赖输入」的门,不能用「依赖状态」的门),决定了你还能不能保留「训练可并行、推理可串行」的双重性。(见 [00:14:31])
  3. MoE 的稀疏性与可微性冲突:训练时若只激活 top-K 专家,被选中的专家吃梯度、没被选中的永远不被观测,路由就变成了一个统计意义上的 bandit 问题,而 top-K 本身又不可微。(见 [00:42:44]、[00:59:09])
  4. 专家坍缩(expert collapse):若只做普通梯度下降,会出现「强者愈强」的正反馈,最终少数专家吃掉几乎所有 token。(见 [01:03:31])

③ 读者可能带着什么疑问进来

(A)讲师在课上实际提出的问题(来自字幕,按他抛出的顺序):

(B)编者预判的读者疑问(标注为「编者预判」,与上一组区分):

④ 本讲路线

讲师先谈注意力侧:从「乘法结合律」这一个核心想法出发([00:05:58]),逐步搭出线性注意力 → 加门控的 Mamba 2 → 加第二个门与「投影式更新」的 Gated DeltaNet,并强调它们几乎全部是混合(hybrid)架构([00:11:03])。随后给出正交的另一条降本思路——DeepSeek 稀疏注意力(DSA),用「轻量索引器 + top-K + 全注意力」的分层结构省算力([00:23:13])。然后,在同一个「top-K 选择」的想法上,自然过渡到MoE:先讲动机与产业现状,再讲路由器设计空间、共享专家与细粒度专家、负载均衡损失的来历,最后落到系统侧(专家并行、通信投影、稳定性)与 DeepSeek V1→V2→V3 的演化脉络。


1. 引言:两条改造 Transformer 的路线

(参考时间: 00:00:25)

上一讲讨论的是基础 Transformer,以及如何微调它的各个部件,拼装出一个现代语言模型。本讲要更进一步,谈两个我认为「更高级、更复杂」的架构发展——它们都建立在常规 Transformer 之上。

今天的两个主题:

编者说明:本讲把「省算力」拆成两条正交的路线。一条动注意力(改变 token 之间如何互相看),一条动FFN/MLP(改变每个 token 内部如何处理信息)。这两条线都可以叠加使用,很多前沿模型(如 DeepSeek V3、Qwen 系列)同时采用了二者。

graph TD
    A[Transformer Block] --> B[注意力块 Attention]
    A --> C[MLP / FFN 块]
    B --> D["路线一:注意力替代方案<br/>线性时间 / 稀疏注意力<br/>→ 更长上下文"]
    C --> E["路线二:混合专家 MoE<br/>参数↑ 但 FLOPs 不变<br/>→ 更高效投入参数"]
    D --> F[混合架构 Hybrid]
    E --> G[专家并行 Expert Parallel]
    style D fill:#dbeafe
    style E fill:#fef3c7

2. 长上下文的动机与成本结构

(参考时间: 00:01:32)

现在的趋势很明确:人们想要更长的上下文长度。你需要把大量信息塞进上下文,让模型拥有更多知识;也许它是一个要操作许多事情的 agent。

讲师展示了一张图:横轴是时间(不同模型随时间的演化),纵轴是上下文窗口大小(对数刻度)。可以看到几乎所有顶级语言模型厂商都在竞赛式地提供越来越大的上下文窗口,以支撑更复杂的 workload。

2.1 谁在吃掉算力:FFN 还是注意力?

同一张图的右侧还画了一条计算成本比例曲线:它展示了随序列长度增加,前馈网络(feed-forward)部分与注意力(attention)部分的计算成本之比。

上下文窗口增长与注意力成本占比

📷 上下文窗口增长与注意力成本占比
回到原视频 (00:01:32)

换句话说:过去在大模型 + 较短序列的场景下,FFN 是主要成本;而当序列变得很长时,注意力越来越成为瓶颈。

2.2 控制成本的基本工具箱

(参考时间: 00:02:49)

对付注意力成本,有两类手段:

  1. 局部注意力 + 混合(hybrid)拼接:如果你只在每八层里做一次全局注意力、其余层都做很局部的注意力,你就能极大地控制成本。
  2. 系统工程(systems engineering):常数因子极其重要。讲师强调,这是一个很容易被「理论导向的计算机科学传统」忽视的点——大家容易只盯着大 O(线性还是二次),而忘记常数因子。

编者拓展|Flash Attention 为什么重要 讲师在这里点名了 Flash Attention([00:03:43])。它的核心思想是:不把巨大的 $N \times N$ 注意力矩阵真正写进显存,而是把注意力运算重排成对内存层级(SRAM / HBM)更友好的分块(tiling)计算,最大限度减少显存带宽上的搬运开销。 - 它没有解决二次复杂度问题; - 但它是一个纯粹的常数因子优化,却带来了「货真价实的戏剧性提升」。

讲师展示的对照中([00:04:07]):基础 PyTorch 实现在较短序列上大约每秒 30–40 万亿次浮点运算(TFLOPs),而 Flash Attention 常常能带来两倍以上的提升;在某些规模下,朴素实现甚至已经放不进显存,而 Flash Attention 因为不物化(materialize)大矩阵,还能继续跑——哪怕慢一点。

这一讲会在后续的系统课(约三讲之后)和系统作业中更详细地展开。

Flash Attention 相较基础 PyTorch 的性能提升

📷 Flash Attention 相较基础 PyTorch 的性能提升
回到原视频 (00:04:07)

但讲师也提醒:如果上下文要到 500 万、1000 万 token,这些技巧就不够用了。我们想要的是更激进、更大的能力提升——这就引出了核心问题:有没有办法让复杂度对序列长度线性?


3. 线性注意力:乘法结合律的魔法

(参考时间: 00:05:08)

多年来很多人尝试过各种方案,也有一些「错误的开局」。但最近大概两年,出现了一批相当有效、并已在规模上被反复验证(battle-tested)的线性时间注意力配方——这也是为什么这是第一年讲师愿意在课上讲线性时间注意力:因为它现在明确地在生产规模上work。([00:05:24])

讲师强调:要理解所有有效方法,你只需要先理解一个核心想法,然后在其上不断扩展。这个想法就是:

乘法的结合律(associativity of multiplication)。

3.1 从 QK^T V 到 Q(K^T V)

(参考时间: 00:06:01)

标准注意力可以写成紧凑形式。设 $Q \in \mathbb{R}^{N \times d_k}$、$K \in \mathbb{R}^{N \times d_k}$、$V \in \mathbb{R}^{N \times d_v}$,其中 $N$ 是序列长度:

$$ \text{Attn}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}}\right)V $$

其中 $QK^\top$ 产生一个 $N \times N$ 的全对全(all-to-all)交互矩阵,这就是二次复杂度的来源($O(N^2 d_k)$)。

标准注意力的矩阵记号

📷 标准注意力的矩阵记号
回到原视频 (00:06:06)

现在,暂时忘掉 softmax,把那一行丢开。如果没有 softmax,我们就能重排括号:

$$ (QK^\top)V \;\longrightarrow\; Q\,(K^\top V) $$

这一步改变了「哪一部分是二次的」([00:07:04]):

因此,依赖 $N$ 的那一项从 $N^2$ 变成了 $N$,且系数是良性的 $d_k d_v$。这就是第一件必须知道的事:乘法结合律让我们能改变复杂度对序列长度的依赖。

编者说明:注意这一步的「代价」是丢掉了 softmax 的行归一化。讲师在后面的问答里([00:20:56])反复强调:这一步是有损的(lossy),softmax 一旦丢掉,就意味着模型少了「选择性关注」的能力。而下一步的 RNN 等价则是精确的。这是本讲最容易被混淆的两个「等价/不等价」,务必记牢。

3.2 线性注意力与 RNN 的对偶性

(参考时间: 00:07:56)

线性注意力一个非常好的性质:右侧的矩阵乘法在自注意力场景下和 RNN 长得一模一样。

不用稠密形式,我们可以从左向右增量地扫描上下文。定义状态 $S$:

$$ S_t = S_{t-1} + k_t^\top v_t, \qquad o_t = q_t\, S_t $$

也就是说,我们增量地累加 K 与 V 的外积,得到状态 $S$,再用当前的 $Q$ 去乘它得到输出 $o_t$。

编者说明:这里用外积 $k_t^\top v_t$($d_k \times d_v$ 的矩阵)不断累加,正是「把所有历史 KV 汇总到一个固定大小的状态里」的过程。稠密形式($Q(K^\top V)$)与递归形式(上式)是数学上精确等价的。

这就是「双重性(duality)」的精髓([00:09:05]):

graph LR
    A["逐步累加外积<br/>Sₜ = Sₜ₋₁ + kₜᵀvₜ"] --> B["得到固定大小状态 S"]
    B --> C["乘以当前 query<br/>oₜ = qₜ · Sₜ"]
    D["稠密形式<br/>Q(KᵀV)"] -.->|精确等价| A
    D --> E["训练:并行 ✅"]
    A --> F["推理:串行 RNN ✅"]
    style D fill:#dbeafe
    style E fill:#dcfce7
    style F fill:#dcfce7

讲师特别指出:到目前为止,还没有人真正在规模上验证过「纯线性」的注意力机制。他后面要讲的一切,几乎都是混合(hybrid)——即若干线性层配一个全 softmax 层。([00:11:03])

3.3 一个真实案例:MiniMax M1 的 7:1 混合

(参考时间: 00:09:55)

讲师给了一个已经在规模上跑通的例子:MiniMax M1——一个规模较大、性能较高的中文开源模型。它采用了 7:1 的混合:7 层线性注意力 + 1 层完整 softmax 注意力。

结果显示:性能相当强,能与 OpenAI o3 或 DeepSeek R1 等强模型相比,相当有竞争力;而且由于大部分层是线性注意力,对上下文长度的依赖远远更温和(不是完全线性,因为有那几层 softmax,但曲线明显更平缓)。

MiniMax M1 的 7:1 混合架构性能

📷 MiniMax M1 的 7:1 混合架构性能
回到原视频 (00:10:07)

编者拓展|为什么「几乎全线性 + 偶尔全注意力」能行? 全 softmax 注意力提供「全对全」的精确信息检索能力;线性注意力则提供廉价的、固定状态容量的信息压缩。混合架构的本质是:让少数层负责昂贵的精确检索,让多数层负责廉价的压缩与累积。这也是讲师后面解释「为什么纯 RNN 会掉点、混合则几乎不掉」的核心直觉([00:32:44])。


4. Mamba 2:给状态更新加上门控

(参考时间: 00:11:11)

有人可能会说:「线性注意力太朴素太简单了,我想要更『认真』的神经网络结构。」那么就在线性注意力的 RNN 形式上做小扩展,于是得到 —— Mamba 2。

编者说明:Mamba、Mamba 2、Mamba 3 是由 Albert Gu 与 Tri Dao 等人提出的状态空间模型(State Space Model, SSM)家族([00:11:51])。它们最初从状态空间理论推导而来,但讲师指出:看它的实际机制,Mamba 2 完全可以被看成一个对线性注意力机制的、非常简单的扩展。

4.1 为什么要加门控:灵感来自 LSTM

我们回顾一下线性注意力的状态更新:我们总是在把状态 S 一路向前传。但从古老的 LSTM 时代我们就知道:知道什么时候该传递信息、什么时候不该传递,是非常重要的——要会「遗忘」,把信息清零。

于是 Mamba 2 引入一个门 $\gamma_t$:

$$ S_t = \gamma_t \odot S_{t-1} + K_t V_t^\top $$

关键性质([00:12:53]):

正因为 $\gamma_t$ 不依赖状态,这个更新计算非常简单,而且对偶性得以保留:你既可以把 Mamba 2 写成大矩阵乘法(用于训练),也可以在推理时用递归形式(用于推理)。

Mamba 2 的门控状态更新

📷 Mamba 2 的门控状态更新
回到原视频 (00:11:47)

4.2 门控的「铁律」

(参考时间: 00:14:31)

讲师给出一条经验法则:只要你用纯输入依赖(input-dependent)的项去门控 RNN 里的各项——不引入状态依赖——那么「并行(训练)/串行(推理)」的双重性就依然成立。这几乎是你能对操作做的「边界」:一旦门控开始依赖状态,双重性就可能被破坏。

graph TD
    A["线性注意力状态更新<br/>Sₜ = Sₜ₋₁ + KₜVₜᵀ"] --> B{"门控依赖什么?"}
    B -->|"只依赖输入 Xₜ"| C["保留对偶性 ✅<br/>训练并行 + 推理串行"]
    B -->|"依赖状态 S"| D["对偶性可能被破坏 ⚠️"]
    style C fill:#dcfce7
    style D fill:#fee2e2

编者说明:Mamba 2 在状态更新之外,还对输出 $y_t$ 加了一个残差式的 $D \cdot v_t$ 项(讲师在 [00:15:33] 补充说这是为了呈现「真正的 Mamba 2 更新」而非简版)。讲师说这一项「不是状态更新的核心,可以暂时忽略」。

4.3 规模验证:NeMo Tron 3

(参考时间: 00:13:27)

NeMo Tron 3 采用了「把 Mamba 2 作为轻量层、再周期性插入大 softmax 注意力」的混合设计,在推理成本与表达力之间做权衡。它取得了不错的性能(与 Qwen 3、GPT-OSS 等对比),并且因为有了这些 Mamba 2 层,在较大上下文长度下有很好的吞吐(throughput)。

NeMo Tron 3 结合 Mamba 2 与 softmax 注意力的混合设计

📷 NeMo Tron 3 结合 Mamba 2 与 softmax 注意力的混合设计
回到原视频 (00:13:27)

讲师指出:这些还是小型的前沿模型(不是真正超大规模的前沿模型),但它们是开源的,足以证明这条路走得通。


5. Gated DeltaNet:第二个门与投影式更新

(参考时间: 00:15:01)

我们继续「把递归做得越来越复杂」。在 Gated DeltaNet 中,除了 Mamba 2 那样的 $\gamma_t$ 之外,还加入了第二个门 $\beta_t$,并且把更新方向本身也改了。

5.1 第二个门 βₜ:一个「是否写入」的门

讲师把 $\beta_t$ 理解为「是否输入」的门(no-input operation gate)([00:16:14]):

5.2 投影式更新:不只是写,还要擦

(参考时间: 00:16:55)

Gated DeltaNet 真正有意思的地方(来自 DeltaNet 而非「Gated」部分)是更新方向。

在经典做法里,你可能会写成 $1 - \beta_t$。而 Gated DeltaNet 做的是:当你用 $\beta_t$ 写入新信息时,同时要把当前的 key 方向投影出去——也就是既「写入」,又「擦除」曾经写入的旧 key。

数学上,这体现为一个投影算子:

$$ \bigl(I - \beta_t\, k_t k_t^\top\bigr) $$

这个蓝色项 $\bigl(I - \beta_t k_t k_t^\top\bigr)$ 大致上扮演了一个投影器,把 $k_t$ 方向上的分量投影出去。

编者说明:讲师在这里非常谨慎地加了一句「这不完全准确,因为这里并没有做单位归一化(unit normalization),但你能大致 get 到这个直觉」([00:17:38])。真正的 DeltaNet 更新来自求解一个「元学习式最小二乘问题」,其形式在细节上和这个直觉版本略有出入。

Gated DeltaNet 的投影式更新

📷 Gated DeltaNet 的投影式更新
回到原视频 (00:15:01)

5.3 「同一个解」在多处被重新发明

(参考时间: 00:17:53)

讲师指出一个耐人寻味的现象:这个投影式更新在不同领域被反复「重新发明」:

5.4 规模验证:Qwen 3.5 / Qwen Next

(参考时间: 00:18:21)

目前最好的开源模型之一 —— Qwen 3.5 及其前身 Qwen Next —— 就采用了恰好这套架构:3:1 的 Gated DeltaNet / 注意力混合。表现:

Qwen Next 的 3:1 Gated DeltaNet 混合与解码吞吐

📷 Qwen Next 的 3:1 Gated DeltaNet 混合与解码吞吐
回到原视频 (00:18:21)


6. 混合架构的性能研究

(参考时间: 00:19:04)

讲师提醒:关于混合架构的受控研究并不多。有一个由 ByteDance Seed 与 UC Santa Cruz 合作的研究([00:19:13]),系统比较了 Mamba 2、Gated DeltaNet 等架构作为「非全注意力层比例」的函数。

结果如下:

同样的故事在其他评测中也出现:

混合比例与长上下文性能退化

📷 混合比例与长上下文性能退化
回到原视频 (00:19:13)

graph LR
    A["全注意力基线<br/>虚线"] --> B["低混合比例<br/>性能几乎不损失 ✅"]
    B --> C["越过某点<br/>长上下文显著退化 ⚠️"]
    C --> D["纯 RNN<br/>所有架构均明显退化 ❌"]
    style A fill:#dcfce7
    style D fill:#fee2e2

6.1 课堂问答:精确定义与边界

这一段问答澄清了几个容易被混淆的点([00:20:49]):


7. DeepSeek 稀疏注意力(DSA)

(参考时间: 00:22:52)

讲完「复杂度理论味道很浓」的线性注意力,讲师转到另一条正交的降本路线:DSA(DeepSeek Sparse Attention,DeepSeek 稀疏注意力),出自 DeepSeek 3.2。

编者说明:讲师顺带开了个玩笑——DSA 里的「Sparse」并不是在玩「稀疏注意力」的谐音梗([00:23:28])。这是个不经意的双关。

7.1 核心思想:轻量索引器先筛选

(参考时间: 00:23:25)

不再对所有 token 计算注意力,而是:

  1. 先跑一个轻量索引器(lightweight indexer);
  2. 索引器从很长的上下文中挑出一个子集(远小于完整序列);
  3. 只在这个较小的子集上做全 softmax 注意力。
DSA:轻量索引器 + top-K + 全注意力

📷 DSA:轻量索引器 + top-K + 全注意力
回到原视频 (00:23:17)

7.2 前向流程

(参考时间: 00:23:52)

前向过程(至少前向)机制上相当简单:

graph TD
    A["长上下文输入<br/>N 个 token"] --> B["计算 Q、K"]
    B --> C["轻量索引器<br/>内积 → ReLU → 权重"]
    C --> D["每个位置得到激活分数"]
    D --> E["Top-K 选择<br/>保留得分最高的 K 个位置"]
    E --> F["仅在这 K 个位置<br/>做全 softmax 注意力"]
    F --> G["输出 key-value"]
    style C fill:#dbeafe
    style E fill:#fef3c7

7.3 关键工程技巧:不动主预训练

(参考时间: 00:24:43)

DSA 和 GLM 都展示了一个重要的工程实践:你不需要在预训练阶段就引入索引器。

好处:这个阶段本身的计算开销相当轻。

讲师还引用 GLM 5 的说法([00:26:02]):即使在全 DSA 训练下,相对于全注意力,性能损失也很小——包括在长上下文检索这类对 RNN 式架构较难的任务上。

7.4 关键:它不是线性的

(参考时间: 00:26:43)

讲师特意回到上一张 slide 强调:DSA 不是线性时间。

课堂上有一位同学追问([00:27:31]):「既然索引器是二次的、索引器之后的注意力也是二次的,那为什么能省钱?」讲师答:这其实是一个偏系统的技巧:

这正是全讲的母题:「有时候不要过于纠结二次还是非二次,常数因子真的非常重要。」([00:28:21])

7.5 效果与流程位置

DSA 让 DeepSeek V3.2 在 prefill(处理输入)与 decode(生成)两侧都获得了比上一代(非稀疏注意力)更友好的扩展曲线,同时性能与同期前沿模型(Claude 4.5 Sonnet、Gemini 3 等)相当。([00:25:14])

关于它插在流程的哪一步([00:29:24]),标准配方是:

graph LR
    A["短上下文预训练"] --> B["长上下文扩展<br/>(插入索引器 / DSA)"] --> C["后训练 Post-training"]
    style B fill:#fef3c7

8. 混合专家(MoE):概览与动机

(参考时间: 00:34:25)

接下来进入今天的第二部分:混合专家(Mixture of Experts, MoE)。

8.1 一句话直觉:MoE 就是一个「更高效的 MLP」

"One way of thinking about mixture of experts is they are just a more efficient MLP."

概念上 MoE 并没有改变游戏规则。你可以把它想成:你的 MLP 还是那个 MLP,只是有人给了你一个更高效的版本。

那么为什么还要专门讲它?讲师给了两个理由([00:34:45]):

  1. 产业现实:如今很多模型都在用 MoE、都在发 MoE。想真正深入理解语言模型,就必须理解它。
  2. MoE 有一些非常有趣的机械部件(mechanical primitives)。当你看到 MoE 是怎么搭起来的时候,你会发现 MoE 式的原语在很多地方都能用上——「哦,我可以用神经网络做更有意思的事」。

8.2 MoE 到底改了什么

(参考时间: 00:35:26)

左边是常规 Transformer 的 MLP:注意力 → 归一化 → 前馈(FFN),「大量稠密的信息处理」发生在这里。

右边改成 MoE:把一个大的 FFN 切成若干个 FFN(这里示意为 4 个)。假设这些 FFN 大小和原来的 FFN 一样(注意:是复制,不是切碎)。然后,如果有某种魔法,能对每个输入告诉我该选哪个 FFN:

这就是 MoE 的心智模型([00:36:45]):增加参数,但不增加 FLOPs。

编者说明:原始 MoE 论文的动机是「参数中心主义」的——如果你相信参数越多越好,但又不想付更多参数的算力成本,就需要右边的这种结构。这是理解 MoE 一切的起点。

graph TD
    subgraph Dense["稠密 Transformer Block"]
        A1[注意力] --> A2[归一化] --> A3["单个大 FFN<br/>参数量 P,FLOPs ∝ P"]
    end
    subgraph MoE["MoE Transformer Block"]
        B1[注意力] --> B2[归一化] --> B3["路由器 Router"]
        B3 --> B4[专家 1]
        B3 --> B5[专家 2]
        B3 --> B6[专家 3]
        B3 --> B7[专家 N]
        B4 --> B8["只选 top-K 个专家<br/>参数 4P,FLOPs ∝ K"]
        B5 --> B8
        B6 --> B8
        B7 --> B8
    end
    style B3 fill:#dbeafe
    style B8 fill:#fef3c7

8.3 为什么这么流行:参数越多,通常越好

(参考时间: 00:36:59)

现在 Hugging Face 上超过一定规模的模型,几乎清一色是 MoE。原因似乎是:在总计算量保持不变的前提下,只增加稀疏参数的数量,模型总会变得更好。这或许是「更多参数确实普遍有益(即便只有一部分被激活)」的证据。

讲师引用了 Fedus 等人 2022 年的 Switch Transformer 论文([00:37:39]):

Switch Transformer:专家数增加、测试损失持续下降

📷 Switch Transformer:专家数增加、测试损失持续下降
回到原视频 (00:37:39)

训练和推理都是「白赚」——讲师原话是「pretty wonderful, pretty great」。

8.4 独立验证:AI2 的 OLMo 研究

(参考时间: 00:38:28)

AI2(Allen Institute for AI) 的 OLMo 论文(开源的 MoE 分析)看到了同样的现象:看训练损失、验证损失、下游基准,MoE 相对于稠密对照,大约有 2 倍左右的训练加速。

OLMo:MoE 相对稠密模型约 2 倍训练加速

📷 OLMo:MoE 相对稠密模型约 2 倍训练加速
回到原视频 (00:38:39)

8.5 真实世界证据

(参考时间: 00:39:00)

从已发布的 MoE 模型看,它们在激活参数量上都明显强于稠密模型(如果你关心推理 FLOPs,激活参数量才是关键),甚至从训练与服务的总成本看也是如此。

Qwen 1.5 MoE:小激活参数超越同期 7B 稠密模型

📷 Qwen 1.5 MoE:小激活参数超越同期 7B 稠密模型
回到原视频 (00:41:32)

8.6 MoE 是又一条并行轴

(参考时间: 00:39:49)

MoE 还给你另一条并行化轴(讲师说,并行化会在三讲之后的系统课上详述):

8.7 课堂问答:通信瓶颈与训练稀疏性


9. 路由器设计空间

(参考时间: 00:47:36)

讲完产业概览,讲师转入如何设计一个 MoE。他给出三个变化轴:

  1. 路由函数(routing function):路由器如何把 token 分派给专家;
  2. 专家大小(expert size):在给定预算下,是「多专家、小参数」还是「少专家、大参数」;
  3. 训练(training):训练一个「路由 token 到不同位置」的模型非常困难。

在所有方案里,我们都不想激活全部专家——我们永远只选 top-K。

9.1 Token 选择专家 vs 专家选择 token

(参考时间: 00:48:56)

有几种选择方式:

实践中,几乎所有 MoE 都用 token-choice top-K。OLMo 论文的对照([00:49:13])显示:

OLMo:Token-Choice vs Expert-Choice 的验证损失对比

📷 OLMo:Token-Choice vs Expert-Choice 的验证损失对比
回到原视频 (00:49:13)

9.2 路由函数的几种选择

(参考时间: 00:49:55)

方案 A:内积路由器(The inner-product router)——最经典、最主流

方案 B:哈希路由(Hashing-based routing)

方案 C:用 RL 学路由

方案 D:线性分配问题(Linear Assignment Problem)

9.3 Top-K 路由的具体形式

(参考时间: 00:53:01)

Top-K 路由现在是共识路由机制。它和之前的 DSA、以及 H-Nets 等其他论文里的模式高度相似——所以这是一个值得学会识别(recognize)的模式。

它长这样:取输入,过一遍前馈,计算得分,用 softmax 在专家之间归一化,选出 top-K 作为门(gate),控制各专家:

$$ \text{Output} = \sum_{i \in \text{TopK}(S)} g_i \, \mathrm{FFN}_i(U) \;+\; U $$

其中 $S$ 是路由得分,$g_i$ 是对应门控。门的学法是:每个专家一个权重向量,与输入做内积——非常轻量,没有任何花哨的地方。

Top-K 路由:内积得分 → top-K → 门控专家

📷 Top-K 路由:内积得分 → top-K → 门控专家
回到原视频 (00:53:58)

编者拓展|一个可用于识别的模式 「内积打分 → 取 top-K → 用归一化后的权重加权」这个模式,在 DSA 的轻量索引器、MoE 的 top-K 路由器、RetNet / H-Nets 等很多地方都出现过。讲师特意指出这是一个值得培养的模式识别能力。一旦你识别出它,你就能快速看懂很多看似不同的架构论文其实在讲同一件事。

9.4 共享专家与细粒度专家:DeepSeek 的贡献

(参考时间: 00:54:24)

在这个简单框架里,DeepSeek MoE 及其同伴做了重要的创新。

共享专家(Shared Experts)——现在是极其广泛使用的设计([00:54:37]):

DeepSeek 的消融实验([00:55:50]):

DeepSeek MoE 的共享专家消融实验

📷 DeepSeek MoE 的共享专家消融实验
回到原视频 (00:55:50)

独立验证与分歧:AI2 的 OLMo([00:56:41])认为「共享专家帮助不大」,但在「多而细的专家有益」这一点上与 DeepSeek 一致。所以两边在共享专家这个点上略有分歧。

总结:现在许多近期 MoE 基本遵循 DeepSeek 的设计([00:57:03]):

课堂追问([00:58:02]):「有共享专家时,并行化怎么办?」——答:共享专家得不到并行收益,每个激活都得过它。你可以复制共享专家,用内存开销换取通信开销的降低。


10. 训练 MoE:负载均衡的艺术

(参考时间: 00:58:31)

这是本讲「非常意外、非常深刻的深度学习内容」。

讲师坦白:初学 MoE 时,我以为这些东西根本训不好。但事实是:有一堆技巧,组合起来就能相当稳健地 work。

10.1 核心矛盾:稀疏 vs 可微

(参考时间: 00:58:57)

这两个都是大问题。解决方案有三类:

  1. 用 RL 优化门控策略——不太流行;
  2. 随机扰动(stochastic perturbations)——explore-exploit bandit 风格;
  3. 一整堆奇怪的启发式,处理稀疏门控的分配平衡。

实践中用的是第三类——一组最终会 work 的有趣启发式。

10.2 路线一与二(不流行,但值得知道)

用 RL 学路由(Clark 2020,[01:00:06]):

Clark 2020:用 RL 学路由 vs 启发式方法

📷 Clark 2020:用 RL 学路由 vs 启发式方法
回到原视频 (00:59:55)

随机近似(Stochastic Approximation)(Shazeer 等人的早期 MoE 论文,[01:00:52]):

graph TD
    A["输入 X → 路由内积 H"] --> B["注入输入尺度相关的噪声"]
    B --> C["H' = H + noise"]
    C --> D["Top-K + Softmax"]
    D --> E["被选中的专家"]
    E --> F["反向传播"]
    F -->|"有用专家 → 更高权重"| G["更鲁棒的专家<br/>(略微探索)"]

后续发现:Fit Fedus 2022 做了一种均匀乘性扰动,用于「让专家更鲁棒」,但后来被后续 Google 论文移除了。其后的消融表明:不做这些随机鲁棒性技巧,反而能改善稳定性和最终 MoE 质量。所以这些探索性项并非必须。

10.3 路线三:启发式 —— 负载均衡损失

(参考时间: 01:03:05)

现在进入真正在做的事情:一系列启发式,核心是平衡(balancing)。

问题:如果只做普通梯度下降、忽略探索/利用,会发生什么?

这是必须解决的核心问题。解决方案:往总损失里加一个启发式损失,用来平衡不同专家收到的 token。

10.4 Switch Transformer 的负载均衡损失

(参考时间: 01:04:20)

以 Switch Transformer 为例。设有 $N$ 个专家,一批 token。我们想让这两个量的内积尽量小:

$$ \text{aux loss} = N \sum_{i=1}^{N} f_i \, P_i $$

其中:

讲师说:这个损失不是能凭第一原理推出来的。看懂它最简单的办法是求导([01:05:12]):

对 $P_i$ 求导,得到的正是 $f_i$(派发给该专家的 token 占比)。

解释:你可以把它看成一个梯度空间里的惩罚——你收到的 token 越多,你得到的负梯度越强。也就是说,这个损失按 token 占比,去压低那些非常热门的专家的概率质量。

这就是它的作用:专门把热门专家往下压。

Switch Transformer 的负载均衡损失(公式 4)

📷 Switch Transformer 的负载均衡损失(公式 4)
回到原视频 (01:03:58)

10.5 用这些部件重建 DeepSeek V1 / V2

(参考时间: 01:06:00)

有了这些技术,就能重构出 DeepSeek V1、V2 的 MoE 系统:

  1. 跑正常的损失;
  2. 直接对专家反向传播——忽略所有不可微性和探索性顾虑;
  3. 加上逐专家(per-expert)的平衡损失——和 Switch Transformer 完全一样($f_i \times P_i$)。

DeepSeek 的系统工程师还加了第二层([01:06:38]):按设备(per-device)平衡。

DeepSeek V3 的进一步改进([01:07:11]):

讲师点评:DeepSeek V3 及后续逐步去掉了一些「更丑」的辅助损失——但到目前为止,还没有完全去掉它们的方案。

10.6 去掉负载均衡损失的后果:非常惨烈

(参考时间: 01:07:52)

讲师真心话:"I wish I could just get rid of the load balancing loss"——但去掉它后果是灾难性的。

来自 OLMo 论文的消融:

更说明问题的是底部的两个面板(专家使用分布):

OLMo:去掉负载均衡损失后的专家坍缩

📷 OLMo:去掉负载均衡损失后的专家坍缩
回到原视频 (01:08:11)

graph TD
    A["训练 MoE:仅做普通梯度下降"] --> B["top-K 专家获得更多梯度"]
    B --> C["热门专家权重↑"]
    C --> D["被选中频率↑"]
    D -->|"正反馈循环"| B
    D --> E["专家坍缩:少数专家吃掉所有 token ❌"]
    F["加负载均衡损失<br/>aux = N Σ fᵢPᵢ"] -.->|"抑制正反馈"| G["专家均匀使用 ✅"]
    style E fill:#fee2e2
    style G fill:#dcfce7

10.7 总结:为什么这么「朴素」的方法能 work

(参考时间: 01:09:24)

讲师认为这仍然很反直觉:

关键动态:「有用专家会得到强化」的正反馈,被「强制均匀」的力抵消——两股力互相平衡。

10.8 这个模式的未来

(参考时间: 01:09:50)

同样的技巧也用在 DSA 上(我们已经看到那个 top-K)。也用于 H-Nets(一个尝试去掉 tokenizer 的工作)。讲师预测:「top-K 选择 + 用负载均衡或其他辅助损失来使不可微部分可训练」,将成为未来架构设计的常用手法。

课堂追问([01:10:19]):「MoE 的专家真的有语义吗?」

追问([01:11:04]):「为什么既有逐专家损失、又有逐设备损失?」


11. MoE 的系统侧:专家并行

(参考时间: 01:11:37)

在收尾前,讲师谈 MoE 的系统侧。

训练 MoE 引入了额外的、有趣的系统动态。

11.1 标准并行回顾及其上限

问题是:每种并行都有自己的上限。

11.2 MoE 给的新轴

(参考时间: 01:12:36)

专家并行(expert parallelism) 给出额外的并行轴。而且:

11.3 通信投影技巧(NeMo Tron 3)

(参考时间: 01:13:59)

专家并行时,要把激活从设备发到设备(「你属于那个专家,我把你送过去」)。这可能是显著的通信开销。

技巧:

具体做法:先把残差流(residual stream)下投影(down-project),再做那个把激活发送出去的集合通信调用。这样能显著节省通信,同时不必承受整个隐藏维度都变小的所有缺点。

这是一种投影技巧,用来精巧控制通信 vs 并行的权衡。

graph TD
    A["残差流<br/>高维"] --> B{"是否经共享专家?"}
    B -->|"是"| C["共享专家<br/>本地处理,无需通信"]
    B -->|"否"| D["先做下投影<br/>→ 低维激活"]
    D --> E["路由到远端专家<br/>集合通信代价 ↓"]
    E --> F["远端专家处理"]
    C --> G["汇总输出"]
    F --> G
    style C fill:#dcfce7
    style D fill:#fef3c7

12. MoE 的稳定性与微调问题

12.1 随机性:早期的一个「有趣缺点」

(参考时间: 01:15:07)

早期 MoE 推理基础设施的一个有趣但已被解决的细节:随机性(stochasticity)。

现在:dropless(不丢弃)架构已经解决了大部分这类问题。所以这已不再是真正的 issue。MegaBlocks 等常见的开源 MoE 框架已经没有这个问题了。

编者说明:MegaBlocks 是一个面向 MoE 的高效开源训练库,其核心之一是不丢弃 token(dropless)的稀疏计算与负载不均衡处理,正是讲师所说的那类基础设施。

12.2 路由 softmax 的稳定性

(参考时间: 01:16:35)

讲师回顾上一讲的观点:指数运算是危险的、除法是危险的,所以 softmax 是「危险区」。

而 MoE 引入了又一个 softmax(路由器里的那个)。人们很早就注意到 MoE 里的 softmax 可能非常危险:

OLMo:router 加 Z loss 可以缓解训练损失尖峰

📷 OLMo:router 加 Z loss 可以缓解训练损失尖峰
回到原视频 (01:17:36)

12.3 微调时的过拟合

(参考时间: 01:18:11)

MoE 微调起来很烦:

可以做的补救:

编者拓展|什么是「苦涩的教训」 这是 Rich Sutton 的著名论断:凡是依赖人类知识注入的方法,长期看总会被「简单方法 + 大规模算力 + 海量数据」击败。讲师把这条原理用在 MoE 微调上——与其费劲设计精细的微调干预,不如直接把数据堆够。


13. 模型升级(Upcycling)

(参考时间: 01:19:12)

最后一个 MoE 相关技巧:Upcycling(升级再利用)。

讲师提醒:这个技巧在过去一年已明显不再流行——他说今年没见过一个 upcycled 模型。但它是个很酷的想法,早期也有非常好的模型用它,所以要讲。

13.1 想法

(参考时间: 01:20:00)

为什么能 work?

早期论文([01:20:35])展示:upcycled 的方法,比起继续训练同一个稠密模型,能获得明显更好的语言建模(当时是准确率)性能。

13.2 规模验证

为什么不流行了?([01:21:49])现在你不会再训稠密模型再转换——你会一开始就训练大 MoE 英雄跑(hero run)。但这个想法本身在 MoE 的行动空间(action space)里仍值得知道。

graph TD
    A["已训练的稠密模型<br/>(含 MLP)"] --> B["复制多个 MLP 副本<br/>作为专家"]
    A --> C["路由器随机初始化"]
    B --> D["训练"]
    C --> D
    D --> E["不同输入随机进入不同专家"]
    E --> F["专家逐渐专业化"]
    F --> G["得到一个 MoE ✅<br/>近乎免费的性能提升"]
    style D fill:#dbeafe
    style G fill:#dcfce7

14. DeepSeek MoE 的演进:V1、V2、V3

(参考时间: 01:22:11)

讲师最后串起 DeepSeek 的 V1、V2、V3——从这三代模型的演化里可以学到很多。

14.1 DeepSeek MoE V1:现代 MoE 的原型

(参考时间: 01:22:32)

V1 已经是很多现代 MoE 的原型:

讲师评价:这是 MoE 模型的「柏拉图式理想型」。

14.2 DeepSeek V2:把系统意识加入架构

(参考时间: 01:22:56)

V2 就是把 V1 放大:

后面两个其实都是给系统加辅助损失。

讲师金句:成功的语言模型训练不仅仅关乎深度学习,也关乎真正尊重你的系统(respecting your system)。 DeepSeek V2 是这一哲学的体现。

14.3 DeepSeek V3:延续 + 系统创新

(参考时间: 01:23:24)

V3 仍然有共享 + 细粒度专家设计,但平衡方式不同:

V3 的其他系统创新(讲师「是他们的系统的忠实粉丝」):

a) 多头潜在注意力(Multi-head Latent Attention, MLA)([01:23:59])

b) 多 token 预测(Multi-Token Prediction, MTP)([01:24:12])

DeepSeek V3 的多头潜在注意力与多 token 预测

📷 DeepSeek V3 的多头潜在注意力与多 token 预测
回到原视频 (01:24:12)


15. 总结

(参考时间: 01:25:41)

把一切串起来:


附:参考与延伸阅读

编者补充

已知疑点