文章目录
论文:DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models
迈向混合专家语言模型的终极专家专业化:通过在传统 MoE 架构中加入细粒度专家分割和共享专家隔离两种策略,减少专家的知识混杂和冗余现象,提高专家的专业化水平。
MoE_6">Transformers 中的 MoE
Transformer语言模型
一个标准的常见的 Transformer 语言模型是通过堆叠 L L L 层 Transformer 块来构建的,每一个块可以表示如下:
u 1 : T l = Self-Att ( h 1 : T l − 1 ) + h 1 : T l − 1 , h t l = FFN ( u t l ) + u t l , \begin{aligned} \mathbf{u}_{1:T}^l &= \text{Self-Att} \left( \mathbf{h}_{1:T}^{l-1} \right) + \mathbf{h}_{1:T}^{l-1}, \\ \mathbf{h}_t^l &= \text{FFN} \left( \mathbf{u}_t^l \right) + \mathbf{u}_t^l, \end{aligned} u1:Tlhtl=Self-Att(h1:Tl−1)+h1:Tl−1,=FFN(utl)+utl,
其中 T T T表示序列长度, Self-Att ( ⋅ ) \text{Self-Att}(\cdot) Self-Att(⋅) 表示自注意力模块, FFN ( ⋅ ) \text{FFN}(\cdot) FFN(⋅) 表示 Feed-Forward Network 或者全连接网络, u 1 : T l ∈ R T × d \mathbf{u}_{1:T}^l \in \R^{T\times d} u1:Tl∈RT×d 是所有 tokens 经过了第 l l l 个注意力模块后得到的隐藏状态(hidden states), h t l ∈ R d \mathbf{h}_t^l \in \R^d htl∈Rd 指第 t t t 个 token 经过第 l l l 个 Transformer 模块后输出的隐藏状态。为了简单起见,这里忽略了 layer normalization。
MoE_14">通用的MoE架构
构建 MoE 语言模型通常是以一定的间隔将 Transformer 中的 FFN 替换为 MoE 层。一个 MoE 层是由多个专家组成,其中每个专家在结构上和标准的 FFN 一样。然后,每个 token 会被分配给一个或两个专家。如果第 l l l 个 FFN 被替换为 MoE 层,其输出隐藏状态 h t l \mathbf{h}_t^l htl 的计算可以表示为:
h t l = ∑ i = 1 N ( g i , t FFN i ( u t l ) ) + u t l , g i , t = { s i , t , s i , t ∈ Topk ( { s j , t ∣ 1 ≤ j ≤ N } , K ) , 0 , otherwise , s i , t = Softmax i ( u t l ⊤ e i l ) , \begin{aligned} \mathbf{h}_t^l &= \sum_{i=1}^N \left( g_{i,t} \text{FFN}_i \left( \mathbf{u}_t^l \right) \right) + \mathbf{u}_t^l, \\ g_{i,t} &= \begin{cases} s_{i,t}, & s_{i,t} \in \text{Topk}(\{s_{j,t}|1 \leq j \leq N\}, K), \\ 0, & \text{otherwise}, \end{cases} \\ s_{i,t} &= \text{Softmax}_i \left( \mathbf{u}_t^{l^\top} \mathbf{e}_i^l \right), \end{aligned} htlgi,tsi,t=i=1∑N(gi,tFFNi(utl))+utl,={si,t,0,si,t∈Topk({sj,t∣1≤j≤N},K),otherwise,=Softmaxi(utl⊤eil),
其中 N N N 表示总的专家数量, FFN i ( ⋅ ) \text{FFN}_i(\cdot) FFNi(⋅) 表示第 i i i 个专家 FFN, g i , t g_{i,t} gi,t 表示第 i i i 个专家的门控值(或者可以理解为权重), s i , t s_{i,t} si,t 表示 token 与专家的相关性, Topk ( ⋅ , K ) \text{Topk}(\cdot, K) Topk(⋅,K) 表示由第 t t t 个 token 和所有 N N N 个专家计算出的相关性得分中最高的 K K K 个组成的集合。 e i l \mathbf{e}_i^l eil 是第 l l l 层中第 i i i 个专家的中心(centroid)。请注意, g i , t g_{i,t} gi,t 是稀疏的,表示 N N N 个门控值中只有 K K K 个为非零值。这种稀疏性可确保 MoE 层内的计算效率,即每个 token 只会分配给 K K K 个专家并在其中计算。同样,为了简洁起见,上述公式中也忽略了 layer normalization。
关于混合专家模型架构的介绍,也可以参考:混合专家模型 (MoE) 详解
DeepSeekMoE_29">DeepSeekMoE架构
DeepSeekMoE架构" />
DeepSeekMoE 在通用的 MoE 架构上加入了两种主要的策略:细粒度专家分割与共享专家隔离。这两种策略都是为了提高专家的专业化水平。
细粒度专家分割
<<DeepSeek R1生成>>
【研究背景】在专家混合模型中,当专家数量受限时:
- 知识集中现象:分配到单个专家的tokens更加可能承载多元化的知识类型
- 学习困境:专家参数需要同时掌握差异巨大的知识类型,且不同的知识类型很难同时使用
【解决方案】增加专家数量:
- 可选专家更多:单个token能够分配的专家更多
- 知识分解优势:不同知识类型可被解耦到不同专家独立学习
- 保持专业聚焦:每个专家仍能维持高度专业化的知识表征
【核心结论】这种路由机制通过增加知识分配的灵活性,在保持专家专业深度的同时,有效解决了有限专家容量下的知识混杂问题,最终实现更优化的知识分布结构。
因此,DeepSeekMoE 对专家进行更细粒度的划分,使得激活专家的组合更加灵活和适应性更强。具体地说,在经典的 MoE 架构上,其将每个专家 FFN 分成 m m m 个更小的专家,这是通过将 FFN 的中间隐藏层维度减少为其原始大小的 1 m \frac{1}{m} m1 来实现的。由于每个专家变小了,作为回应,激活专家的数量则增加到 m m m 倍,以保持相同的计算成本。通过细粒度专家分割,MoE 层的输出可以表示为:
h t l = ∑ i = 1 m N ( g i , t FFN i ( u t l ) ) + u t l , g i , t = { s i , t , s i , t ∈ Topk ( { s j , t ∣ 1 ≤ j ≤ m N } , m K ) , 0 , otherwise , s i , t = Softmax i ( u t l ⊤ e i l ) , \begin{aligned} \mathbf{h}_t^l &= \sum_{i=1}^{mN} \left( g_{i,t} \, \text{FFN}_i \left( \mathbf{u}_t^l \right) \right) + \mathbf{u}_t^l, \\ g_{i,t} &= \begin{cases} s_{i,t}, & s_{i,t} \in \text{Topk}(\{s_{j,t}|1 \leq j \leq mN\}, mK), \\ 0, & \text{otherwise}, \end{cases} \\ s_{i,t} &= \text{Softmax}_i \left( \mathbf{u}_t^{l^\top} \, \mathbf{e}_i^l \right), \end{aligned} htlgi,tsi,t=i=1∑mN(gi,tFFNi(utl))+utl,={si,t,0,si,t∈Topk({sj,t∣1≤j≤mN},mK),otherwise,=Softmaxi(utl⊤eil),
其中, m N mN mN 表示细粒度专家的总数,而非零门控值的数量也增加到 m K mK mK。
从组合的角度来看,细粒度的专家分割策略显著增强了激活专家的组合灵活性。以一个示例来说明,假设专家总数 N = 16 N = 16 N=16,传统的 Top-2 路由策略可以产生 ( 16 2 ) = 120 \binom{16}{2} = 120 (216)=120 种组合。相比之下,如果将每个专家分割为 4 4 4 个更小的专家,细粒度路由策略可以产生 ( 64 8 ) = 4 , 426 , 165 , 368 \binom{64}{8} = 4,426,165,368 (864)=4,426,165,368 种潜在组合。这种组合灵活性的显著提升,增强了实现更精准和针对性知识获取的潜力。
共享专家隔离
<<DeepSeek R1生成>>
【研究背景】传统路由策略的局限性:
- 知识重叠问题:分配到不同专家的token可能需要共享某些基础知识
- 参数冗余现象:导致多个专家在参数空间中重复学习相似知识
【解决方案】引入共享专家机制:
- 设立专用共享专家:专注于捕获跨上下文的共性知识
- 分层知识处理架构:基础共性知识由共享专家统一处理
- 路由专家专业化:其他专家可专注于领域特异性知识学习
<<下述生成内容中的数据是上下文中没有、大模型自己编造出来的,但它又在后面备注了模拟数据😓🤔>>【核心结论】通过构建共享知识整合层:
- 有效降低参数冗余度达30-50%(模拟数据)
- 提升模型参数利用率,专家专业化程度提高40%+
- 在保持模型性能的同时减少15-20%的总参数量
<<DeepSeek生成>>
在传统路由架构中,分配给不同专家的 tokens 往往需要处理某些共享知识或通用信息,导致不同专家在其参数中都会学习类似的公共知识,形成专家参数的冗余。通过引入专门的共享专家机制,可以:
- 由共享专家统一捕获并整合跨场景的通用知识
- 显著减少其他路径专家的参数重复学习现象
- 达成双重优化效果:既提升参数利用效率(参数高效),又促使各路径专家更专注于其专属领域的专业化学习
(总结关键点:路由冗余问题 ——> 共享专家解决方案 ——> 专业化与参数高效的双重优化)
因此,除了细粒度专家划分策略之外,DeepSeekMoE 进一步隔离了 K s K_s Ks 个专家作为共享专家。无论路由器模块如何,每个 token 都将确定性地分配给这些共享专家。为了保持计算成本不变,其他路由专家中激活专家的数量将减少 K s K_s Ks。集成共享专家隔离策略后,完整的 DeepSeekMoE 架构中的 MoE 层公式如下:
h t l = ∑ i = 1 K s FFN i ( u t l ) + ∑ i = K s + 1 m N ( g i , t FFN i ( u t l ) ) + u t l , g i , t = { s i , t , s i , t ∈ Topk ( { s j , t ∣ K s + 1 ≤ j ≤ m N } , m K − K s ) , 0 , otherwise , s i , t = Softmax i ( u t l ⊤ e i l ) . \begin{aligned} \mathbf{h}_t^l &= \sum_{i=1}^{K_s} \text{FFN}_i \left( \mathbf{u}_t^l \right) + \sum_{i=K_s+1}^{mN} \left( g_{i,t} \text{FFN}_i \left( \mathbf{u}_t^l \right) \right) + \mathbf{u}_{t}^l, \\ g_{i,t} &= \begin{cases} s_{i,t}, & s_{i,t} \in \text{Topk}(\{s_{j,t}|K_s+1 \leq j \leq mN\}, mK-K_s), \\ 0, & \text{otherwise}, \end{cases} \\ s_{i,t} &= \text{Softmax}_i \left( \mathbf{u}_t^{l^\top} \text{e}_i^l \right). \end{aligned} htlgi,tsi,t=i=1∑KsFFNi(utl)+i=Ks+1∑mN(gi,tFFNi(utl))+utl,={si,t,0,si,t∈Topk({sj,t∣Ks+1≤j≤mN},mK−Ks),otherwise,=Softmaxi(utl⊤eil).
最后,在 DeepSeekMoE 中,共享专家的数量为 K s K_s Ks,路由专家的总数为 m N − K s mN-K_s mN−Ks,非零门控值的数量为 m K − K s mK-K_s mK−Ks。
负载均衡考虑
自动学习的路由策略可能会遇到负载不平衡的问题,这一问题表现为两个显著的缺陷。首先,存在路由崩溃的风险,即模型总是只选择少数专家,导致其他专家无法得到充分的训练。其次,如果专家分布在多个设备上,负载不平衡会降低计算效率。
专家级别的平衡损失
这主要是为了缓解路由崩溃的风险,平衡损失的计算如下:
L ExpBal = α 1 ∑ i = 1 N ′ f i P i , f i = N ′ K ′ T ∑ t = 1 T I ( Token t selects Expert i ) , P i = 1 T ∑ t = 1 T s i , t , \begin{aligned} \mathcal{L}_{\text{ExpBal}} &= \alpha_1 \sum_{i=1}^{N^\prime} f_i P_i, \\ f_i &= \frac{N^\prime}{K^\prime T} \sum_{t=1}^T \mathbb{I} (\text{Token } t \text{ selects Expert } i), \\ P_i &= \frac{1}{T} \sum_{t=1}^T s_{i,t}, \end{aligned} LExpBalfiPi=α1i=1∑N′fiPi,=K′TN′t=1∑TI(Token t selects Expert i),=T1t=1∑Tsi,t,
其中, α 1 \alpha_1 α1 是一个称为专家级平衡因子的超参数, N ′ = m N − K s N^\prime = mN - K_s N′=mN−Ks, K ′ = m K − K s K^\prime = mK - K_s K′=mK−Ks, I ( ⋅ ) \mathbb{I}(\cdot) I(⋅) 表示指示函数。可以看出, f i f_i fi 表示专家 i i i 被选择的频率, P i P_i Pi 表示专家 i i i 的平均选择概率。
设备级别的平衡损失
除了专家级别的平衡损失外,还引入了设备级别的平衡损失。为了缓解计算瓶颈,在专家级别强制执行严格的平衡约束变得不必要,因为过多的负载平衡约束会损害模型性能(另外,我理解设备级别的平衡约束也包含了一定程度的专家级别平衡约束,也能在一定程度上缓解路由崩溃)。相反,我们的主要目标是确保设备之间的计算平衡。如果我们将所有路由的专家划分为 D D D 组 { E 1 , E 2 , … , E D } \{\mathcal{E}_1, \mathcal{E}_2, \dots,\mathcal{E}_D\} {E1,E2,…,ED},并将每组部署在单个设备上,那么设备级别的平衡损失计算如下:
L DevBal = α 2 ∑ i = 1 D f i ′ P i ′ , f i ′ = 1 ∣ E i ∣ ∑ j ∈ E i f j , P i ′ = ∑ j ∈ E i P j . \begin{aligned} \mathcal{L}_{\text{DevBal}} &= \alpha_2 \sum_{i=1}^D f_i^{\prime} P_i^{\prime}, \\ f_i^{\prime} &= \frac{1}{|\mathcal{E}_i|} \sum_{j \in \mathcal{E}_i} f_j, \\ P_i^{\prime} &= \sum_{j \in \mathcal{E}_i} P_j. \end{aligned} LDevBalfi′Pi′=α2i=1∑Dfi′Pi′,=∣Ei∣1j∈Ei∑fj,=j∈Ei∑Pj.
其中, α 2 \alpha_2 α2 是一个称为设备级平衡因子的超参数。在实践中,通常会设置一个较小的专家级平衡因子来减轻路由崩溃的风险,同时设置了一个较大的设备级平衡因子来促进跨设备的平衡计算。
模型预训练
不同尺寸模型超参数概览
DeepSeekMoE_2B_129">DeepSeekMoE 2B
主要是用于验证模型架构的有效性,为后续扩展模型参数打好基础
训练数据
训练数据是从 DeepSeek-AI 创建的多语言语料库中采样的,包含 100B tokens。
基础设施
模型训练基于高效和轻量的训练框架 HAI-LLM,集成了多种平行策略,包括张量并行、ZeRO 数据并行、管道并行和专家并行等。
实验均在配备 NVIDIA A100 或 H800 GPU 的集群上进行。A100 集群中的每个节点包含 8 个通过 NVLink 桥成对连接的 GPU。H800 集群每个节点也具有 8 个 GPU,使用节点内的 NVLink 和 NVSwitch 进行互连。对于 A100 和 H800 集群,均使用 InfiniBand 互连来促进跨节点通信。
超参数
模型设置
Transformer 层数为 9,隐藏维度为 1280。
采用多头注意力机制,总共 10 个注意力头,每个头的维度为 128。
所有可学习参数均以 0.006 的标准差随机初始化。
所有的 FFN 都替换为 MoE 层。
训练设置
采用 AdamW 优化器,超参数设置为 β 1 = 0.9 , β 2 = 0.95 , weight_decay = 0.1 \beta_1 = 0.9, \beta_2 = 0.95, \text{weight\_decay} = 0.1 β1=0.9,β2=0.95,weight_decay=0.1。
学习率使用预热和步进衰减(warmup-and-step-decay)策略进行调度:最初,在前 2000 步中,学习率从 0 线性增加到最大值(warmup)。随后,在 80% 的训练步骤后,学习率乘以 0.316;在 90% 的训练步骤后,学习率再乘以 0.316。最大学习率设置为 1.08 × 1 0 − 3 1.08 \times 10^{−3} 1.08×10−3,梯度裁剪范数设置为 1.0。
批次大小设置为 2K,最大序列长度为 2K,每个训练批次包含 4M 个 token。
由于模型规模相对较小,所有参数(包括专家参数)都部署在单个 GPU 设备上,以避免计算不平衡
DeepSeekMoE_16B_148">DeepSeekMoE 16B
借助 DeepSeekMoE 架构将 MoE 模型扩展到更大的规模,总共有 16B 个参数,并在 2T 个 token 上进行训练。结果表明,DeepSeekMoE 16B 仅用大约 40% 的计算量就实现了与 LLaMA2 7B 相当的性能。
训练数据
从同一个语料库中采样训练数据,总共包含 2T tokens,这是与 LLaMA2 7B 的训练 token 数对齐的。
超参数
模型设置
Transformer 层的数量为 28,隐藏维度为 2048。
采用多头注意力机制,总共有 16 个注意力头,每个头的维度为 128。
所有可学习参数均以 0.006 的标准差随机初始化。
用 MoE 层替换除第一层之外的所有 FFN(观察到第一层的负载平衡状态收敛速度特别慢)。
每个 MoE 层包含 2 个共享专家和 64 个路由专家,每个专家的大小是一个标准 FFN 的 0.25 倍。
在这个配置下,DeepSeekMoE 16B 总共有大约 16.4B 个参数,其中激活参数的数量约为 2.8B。
训练设置
采用 AdamW 优化器,超参数设置为 β 1 = 0.9 , β 2 = 0.95 , weight_decay = 0.1 \beta_1 = 0.9, \beta_2 = 0.95, \text{weight\_decay} = 0.1 β1=0.9,β2=0.95,weight_decay=0.1。
学习率也是使用预热和步进衰减(warmup-and-step-decay)策略进行调度:最初,在前 2000 步中,学习率从 0 线性增加到最大值(warmup)。随后,在 80% 的训练步骤后,学习率乘以 0.316;在 90% 的训练步骤后,学习率再乘以 0.316。最大学习率设置为 4.2 × 1 0 − 4 4.2 \times 10^{−4} 4.2×10−4,梯度裁剪范数设置为 1.0。
批次大小设置为 4.5K,最大序列长度为 4K,每个训练批次包含 18M 个 token。
DeepSeekMoE_16B__165">DeepSeekMoE 16B 的对齐
为了评估 DeepSeekMoE 16B 是否可以从微调中受益,基于 DeepSeekMoE 16B 进行了监督微调以构建聊天模型。实验结果表明,DeepSeekMoE Chat 16B 也达到了与 LLaMA2 SFT 7B 和 DeepSeek Chat 7B 相当的性能。
训练数据
基于内部整理的数据构建了监督微调(SFT)数据集,包括 1.4M 个训练样本,其中大部分都是英文和中文。该数据集涵盖了广泛的类别,包括数学、代码、写作、问答、推理、总结等。
超参数
在 SFT 期间,批大小设置为 1024,使用 AdamW 优化器进行了 8 个 epoch 的训练。
训练时最大序列长度为 4K,并尽可能密集地打包训练样本,直到达到序列长度限制。
没有使用 dropout,设置了一个恒定的学习率为 1 0 − 5 10^{-5} 10−5,没有采用任何学习率调度策略。
总结
基于创新的 MoE 架构,先训练了 2B 参数量的模型,验证了该架构的有效性,然后扩展到 16B 规模,评测结果同样展示了该架构的有效性和可扩展性。基于 DeepSeekMoE 16B 进行监督微调 SFT 构建了聊天模型证明了对 MoE 模型进行 SFT 能够进一步提升效果。最后更进一步将模型扩展到 145B 的规模。