2 架构

本文为论文《DeepSeek-V3:强大高效的开源混合专家大模型》「中文全文翻译」板块的对应章节,与「论文原文」板块同一章节一一对应,层级保持一致。

我们首先介绍 DeepSeek-V3 的基础架构,其特点是采用多头潜在注意力(MLA)(DeepSeek-AI, 2024c)以实现高效推理,以及采用 DeepSeekMoE(Dai et al., 2024)以实现经济高效的训练。然后,我们提出一个多词元预测(MTP)训练目标,我们观察到它能够提升在评估基准上的整体性能。对于其他未明确提及的细节,DeepSeek-V3 遵循 DeepSeek-V2(DeepSeek-AI, 2024c)的设置。

图

图 2:DeepSeek-V3 基础架构示意图。遵循 DeepSeek-V2,我们采用 MLA 和 DeepSeekMoE 以实现高效推理和经济高效的训练。

2.1 基础架构

DeepSeek-V3 的基础架构仍处于 Transformer(Vaswani et al., 2017)框架之内。为了实现高效推理和经济高效的训练,DeepSeek-V3 同样采用了 MLA 和 DeepSeekMoE,它们已经在 DeepSeek-V2 中得到了充分验证。与 DeepSeek-V2 相比的一个例外是,我们额外为 DeepSeekMoE 引入了无辅助损失的负载均衡策略(Wang et al., 2024a),以减轻为确保负载均衡而带来的性能下降。图 2 展示了 DeepSeek-V3 的基础架构,我们将在本节简要回顾 MLA 和 DeepSeekMoE 的细节。

2.1.1 多头潜在注意力

在注意力方面,DeepSeek-V3 采用 MLA 架构。令 $d$ 表示嵌入维度,$n_{h}$ 表示注意力头数,$d_{h}$ 表示每个头的维度,$\mathbf{h}_{t}\in\mathbb{R}^{d}$ 表示在给定注意力层中第 $t$ 个词元的注意力输入。MLA 的核心是对注意力键和值进行低秩联合压缩,以减少推理过程中的键值(KV)缓存:

$\displaystyle\boxed{\color[rgb]{0,0,1}\mathbf{c}_{t}^{KV}}$ $\displaystyle=W^{DKV}\mathbf{h}_{t},$ (1)
$\displaystyle[\mathbf{k}{t,1}^{C};\mathbf{k}{t,2}^{C};...;\mathbf{k}{t,n{h}}^{C}]=\mathbf{k}_{t}^{C}$ $\displaystyle=W^{UK}\mathbf{c}_{t}^{KV},$ (2)
$\displaystyle\boxed{\color[rgb]{0,0,1}\mathbf{k}_{t}^{R}}$ $\displaystyle=\operatorname{RoPE}({W^{KR}}\mathbf{h}_{t}),$ (3)
$\displaystyle\mathbf{k}_{t,i}$ $\displaystyle=[\mathbf{k}{t,i}^{C};\mathbf{k}{t}^{R}],$ (4)
$\displaystyle[\mathbf{v}{t,1}^{C};\mathbf{v}{t,2}^{C};...;\mathbf{v}{t,n{h}}^{C}]=\mathbf{v}_{t}^{C}$ $\displaystyle=W^{UV}\mathbf{c}_{t}^{KV},$ (5)

其中 $\mathbf{c}{t}^{KV}\in\mathbb{R}^{d{c}}$ 是键和值的压缩潜在向量; $d_{c}(\ll d_{h}n_{h})$ 表示 KV 压缩维度; $W^{DKV}\in\mathbb{R}^{d_{c}\times d}$ 表示下投影矩阵; $W^{UK},W^{UV}\in\mathbb{R}^{d_{h}n_{h}\times d_{c}}$ 分别是键和值的上投影矩阵; $W^{KR}\in\mathbb{R}^{d_{h}^{R}\times d}$ 是用于生成携带旋转位置嵌入(RoPE)(Su et al., 2024)的解耦键的矩阵; $\operatorname{RoPE}(\cdot)$ 表示应用 RoPE 矩阵的操作; $[\cdot;\cdot]$ 表示拼接。注意,对于 MLA,在生成过程中仅需缓存蓝色框中的向量(即 $\color[rgb]{0,0,1}\mathbf{c}{t}^{KV}$ 和 $\color[rgb]{0,0,1}\mathbf{k}{t}^{R}$),这使得 KV 缓存显著减少,同时保持与标准多头注意力(MHA)(Vaswani et al., 2017)相当的性能。

对于注意力查询,我们也执行低秩压缩,这可以减少训练过程中的激活内存:

$\displaystyle\mathbf{c}_{t}^{Q}$ $\displaystyle=W^{DQ}\mathbf{h}_{t},$ (6)
$\displaystyle[\mathbf{q}{t,1}^{C};\mathbf{q}{t,2}^{C};...;\mathbf{q}{t,n{h}}^{C}]=\mathbf{q}_{t}^{C}$ $\displaystyle=W^{UQ}\mathbf{c}_{t}^{Q},$ (7)
$\displaystyle[\mathbf{q}{t,1}^{R};\mathbf{q}{t,2}^{R};...;\mathbf{q}{t,n{h}}^{R}]=\mathbf{q}_{t}^{R}$ $\displaystyle=\operatorname{RoPE}({W^{QR}}\mathbf{c}_{t}^{Q}),$ (8)
$\displaystyle\mathbf{q}_{t,i}$ $\displaystyle=[\mathbf{q}{t,i}^{C};\mathbf{q}{t,i}^{R}],$ (9)

其中 $\mathbf{c}{t}^{Q}\in\mathbb{R}^{d{c}^{\prime}}$ 是查询的压缩潜在向量; $d_{c}^{\prime}(\ll d_{h}n_{h})$ 表示查询压缩维度; $W^{DQ}\in\mathbb{R}^{d_{c}^{\prime}\times d},W^{UQ}\in\mathbb{R}^{d_{h}n_{h}\times d_{c}^{\prime}}$ 分别是查询的下投影和上投影矩阵; $W^{QR}\in\mathbb{R}^{d_{h}^{R}n_{h}\times d_{c}^{\prime}}$ 是用于生成携带 RoPE 的解耦查询的矩阵。

最终,注意力查询($\mathbf{q}{t,i}$)、键($\mathbf{k}{j,i}$)和值($\mathbf{v}{j,i}^{C}$)被结合起来以产生最终的注意力输出 $\mathbf{u}{t}$:

$\displaystyle\mathbf{o}_{t,i}$ $\displaystyle=\sum_{j=1}^{t}\operatorname{Softmax}{j}(\frac{\mathbf{q}{t,i}^{T}\mathbf{k}{j,i}}{\sqrt{d{h}+d_{h}^{R}}})\mathbf{v}_{j,i}^{C},$ (10)
$\displaystyle\mathbf{u}_{t}$ $\displaystyle=W^{O}[\mathbf{o}{t,1};\mathbf{o}{t,2};...;\mathbf{o}{t,n{h}}],$ (11)

其中 $W^{O}\in\mathbb{R}^{d\times d_{h}n_{h}}$ 表示输出投影矩阵。

2.1.2 采用无辅助损失负载均衡的 DeepSeekMoE

DeepSeekMoE 的基础架构。

对于前馈网络(FFN),DeepSeek-V3 采用 DeepSeekMoE 架构(Dai et al., 2024)。与 GShard(Lepikhin et al., 2021)等传统 MoE 架构相比,DeepSeekMoE 使用了更细粒度的专家,并将部分专家隔离为共享专家。令 $\mathbf{u}{t}$ 表示第 $t$ 个词元的 FFN 输入,我们按如下方式计算 FFN 输出 $\mathbf{h}{t}^{\prime}$:

$\displaystyle\mathbf{h}_{t}^{\prime}$ $\displaystyle=\mathbf{u}{t}+\sum{i=1}^{N_{s}}{\operatorname{FFN}^{(s)}{i}\left(\mathbf{u}{t}\right)}+\sum_{i=1}^{N_{r}}{g_{i,t}\operatorname{FFN}^{(r)}{i}\left(\mathbf{u}{t}\right)},$ (12)
$\displaystyle g_{i,t}$ $\displaystyle=\frac{g^{\prime}{i,t}}{\sum{j=1}^{N_{r}}g^{\prime}_{j,t}},$ (13)
$\displaystyle g^{\prime}_{i,t}$ $\displaystyle=\begin{cases}s_{i,t},&s_{i,t}\in\operatorname{Topk}({s_{j,t}|1\leqslant j\leqslant N_{r}},K_{r}),\ 0,&\text{otherwise},\end{cases}$ (14)
$\displaystyle s_{i,t}$ $\displaystyle=\operatorname{Sigmoid}\left({\mathbf{u}{t}}^{T}\mathbf{e}{i}\right),$ (15)

其中 $N_{s}$ 和 $N_{r}$ 分别表示共享专家和路由专家的数量; $\operatorname{FFN}^{(s)}{i}(\cdot)$ 和 $\operatorname{FFN}^{(r)}{i}(\cdot)$ 分别表示第 $i$ 个共享专家和第 $i$ 个路由专家; $K_{r}$ 表示被激活的路由专家数量; $g_{i,t}$ 是第 $i$ 个专家的门控值; $s_{i,t}$ 是词元到专家的亲和度分数; $\mathbf{e}_{i}$ 是第 $i$ 个路由专家的中心向量; $\operatorname{Topk}(\cdot,K)$ 表示由为第 $t$ 个词元与所有路由专家计算出的亲和度分数中 $K$ 个最高分数组成的集合。与 DeepSeek-V2 略有不同,DeepSeek-V3 使用 sigmoid 函数来计算亲和度分数,并在所有选中的亲和度分数之间应用归一化以生成门控值。

无辅助损失的负载均衡。

对于 MoE 模型,不均衡的专家负载会导致路由崩溃(Shazeer et al., 2017),并在专家并行的场景下降低计算效率。传统的解决方案通常依赖辅助损失(Fedus et al., 2021; Lepikhin et al., 2021)来避免负载不均衡。然而,过大的辅助损失会损害模型性能(Wang et al., 2024a)。为了在负载均衡和模型性能之间取得更好的权衡,我们首创了无辅助损失的负载均衡策略(Wang et al., 2024a)来确保负载均衡。具体而言,我们为每个专家引入一个偏置项 $b_{i}$,并将其加到相应的亲和度分数 $s_{i,t}$ 上以确定 Top-K 路由:

| | $\displaystyle g^{\prime}{i,t}$ | $\displaystyle=\begin{cases}s{i,t},&s_{i,t}+b_{i}\in\operatorname{Topk}({s_{j,t}+b_{j}|1\leqslant j\leqslant N_{r}},K_{r}),\ 0,&\text{otherwise}.\end{cases}$ | | (16) |

注意,偏置项仅用于路由。将与 FFN 输出相乘的门控值,仍然源自原始的亲和度分数 $s_{i,t}$。在训练过程中,我们持续监控每个训练步骤整个批次上的专家负载。在每个步骤结束时,如果某个专家对应的专家过载,我们就将其偏置项减少 $\gamma$;如果其对应的专家欠载,则将其增加 $\gamma$,其中 $\gamma$ 是一个称为偏置更新速度的超参数。通过这种动态调整,DeepSeek-V3 在训练过程中保持均衡的专家负载,并取得了比通过纯辅助损失来鼓励负载均衡的模型更好的性能。

互补的序列级辅助损失。

尽管 DeepSeek-V3 主要依赖无辅助损失策略来实现负载均衡,为了防止任何单一序列内部出现极端失衡,我们还采用了一个互补的序列级均衡损失:

$\displaystyle\mathcal{L}_{\mathrm{Bal}}$ $\displaystyle=\alpha\sum_{i=1}^{N_{r}}{f_{i}P_{i}},$ (17)
$\displaystyle f_{i}=\frac{N_{r}}{K_{r}T}\sum_{t=1}^{T}\mathds{1}$ $\displaystyle\left(s_{i,t}\in\operatorname{Topk}({s_{j,t}|1\leqslant j\leqslant N_{r}},K_{r})\right),$ (18)
$\displaystyle s^{\prime}_{i,t}$ $\displaystyle=\frac{s_{i,t}}{\sum_{j=1}^{N_{r}}s_{j,t}},$ (19)
$\displaystyle P_{i}$ $\displaystyle=\frac{1}{T}\sum_{t=1}^{T}{s^{\prime}_{i,t}},$ (20)

其中平衡因子 $\alpha$ 是一个超参数,对于 DeepSeek-V3 将被赋予一个极小的值; $\mathds{1}(\cdot)$ 表示指示函数; $T$ 表示一个序列中的词元数量。序列级均衡损失鼓励每个序列上的专家负载保持均衡。

受限节点路由。

与 DeepSeek-V2 使用的设备受限路由类似,DeepSeek-V3 也采用了一种受限路由机制,以限制训练过程中的通信成本。简而言之,我们确保每个词元最多被发送到 $M$ 个节点,这些节点是根据分布在每个节点上的专家的最高 $\frac{K_{r}}{M}$ 个亲和度分数之和来选择的。在此约束下,我们的 MoE 训练框架几乎可以实现完全的计算-通信重叠。

无词元丢弃。

由于有效的负载均衡策略,DeepSeek-V3 在整个训练过程中保持了良好的负载均衡。因此,DeepSeek-V3 在训练期间不丢弃任何词元。此外,我们还实施了特定的部署策略以确保推理负载均衡,因此 DeepSeek-V3 在推理期间也不会丢弃词元。

图

图 3:我们的多词元预测(MTP)实现示意图。我们在每个深度上为每个词元的预测保持了完整的因果链。

2.2 多词元预测

受 Gloeckle et al.(2024)启发,我们研究并设定了 DeepSeek-V3 的多词元预测(MTP)目标,该目标将每个位置的预测范围扩展到多个未来词元。一方面,MTP 目标使训练信号更加密集,并可能提高数据效率。另一方面,MTP 可能使模型能够预先规划其表征,以更好地预测未来词元。图 3 展示了我们 MTP 的实现。与 Gloeckle et al.(2024)使用独立输出头并行预测 $D$ 个额外词元不同,我们按顺序预测额外词元,并在每个预测深度上保持完整的因果链。我们在本节介绍 MTP 实现的细节。

MTP 模块。

具体而言,我们的 MTP 实现使用 $D$ 个顺序模块来预测 $D$ 个额外词元。第 $k$ 个 MTP 模块由一个共享嵌入层 $\operatorname{Emb}(\cdot)$、一个共享输出头 $\operatorname{OutHead}(\cdot)$、一个 Transformer 块 $\operatorname{TRM}{k}(\cdot)$ 和一个投影矩阵 $M{k}\in\mathbb{R}^{d\times 2d}$ 组成。对于第 $i$ 个输入词元 $t_{i}$,在第 $k$ 个预测深度上,我们首先通过线性投影将第 $i$ 个词元在第 $(k-1)$ 个深度上的表征 $\mathbf{h}{i}^{k-1}\in\mathbb{R}^{d}$ 与第 $(i+k)$ 个词元的嵌入 $Emb(t{i+k})\in\mathbb{R}^{d}$ 组合起来:

| | $\mathbf{h}{i}^{\prime k}=M{k}[\operatorname{RMSNorm}(\mathbf{h}{i}^{k-1});\operatorname{RMSNorm}(\operatorname{Emb}(t{i+k}))],$ | | (21) |

其中 $[\cdot;\cdot]$ 表示拼接。特别地,当 $k=1$ 时,$\mathbf{h}{i}^{k-1}$ 指的是由主模型给出的表征。注意,对于每个 MTP 模块,其嵌入层与主模型共享。组合后的 $\mathbf{h}{i}^{\prime k}$ 作为第 $k$ 个深度上 Transformer 块的输入,以产生当前深度上的输出表征 $\mathbf{h}_{i}^{k}$:

| | $\mathbf{h}{1:T-k}^{k}=\operatorname{TRM}{k}(\mathbf{h}_{1:T-k}^{\prime k}),$ | | (22) |

其中 $T$ 表示输入序列长度,i:j 表示切片操作(左右边界均包含)。最后,以 $\mathbf{h}{i}^{k}$ 作为输入,共享输出头将计算第 $k$ 个额外预测词元的概率分布 $P{i+1+k}^{k}\in\mathbb{R}^{V}$,其中 $V$ 是词表大小:

| | $P_{i+k+1}^{k}=\operatorname{OutHead}(\mathbf{h}_{i}^{k}).$ | | (23) |

输出头 $\operatorname{OutHead}(\cdot)$ 将表征线性映射到 logits,随后应用 $\operatorname{Softmax}(\cdot)$ 函数来计算第 $k$ 个额外词元的预测概率。同样,对于每个 MTP 模块,其输出头与主模型共享。我们保持预测因果链的原则类似于 EAGLE(Li et al., 2024b),但其主要目标是推测解码(Xia et al., 2023; Leviathan et al., 2023),而我们则利用 MTP 来改进训练。

MTP 训练目标。

对于每个预测深度,我们计算一个交叉熵损失 $\mathcal{L}_{\text{MTP}}^{k}$:

| | $\mathcal{L}{\text{MTP}}^{k}=\operatorname{CrossEntropy}(P{2+k:T+1}^{k},t_{2+k:T+1})=-\frac{1}{T}\sum_{i=2+k}^{T+1}\log P_{i}^{k}[t_{i}],$ | | (24) |

其中 $T$ 表示输入序列长度,$t_{i}$ 表示第 $i$ 个位置上的真实词元,$P_{i}^{k}[t_{i}]$ 表示由第 $k$ 个 MTP 模块给出的 $t_{i}$ 的相应预测概率。最后,我们计算所有深度上 MTP 损失的平均值,并将其乘以一个加权因子 $\lambda$,得到总体 MTP 损失 $\mathcal{L}_{\text{MTP}}$,它作为 DeepSeek-V3 的一个附加训练目标:

| | $\mathcal{L}{\text{MTP}}=\frac{\lambda}{D}\sum{k=1}^{D}\mathcal{L}_{\text{MTP}}^{k}.$ | | (25) |

MTP 在推理中的应用。

我们的 MTP 策略主要旨在提升主模型的性能,因此在推理过程中,我们可以直接丢弃 MTP 模块,主模型可以独立且正常地运行。此外,我们也可以将这些 MTP 模块重新用于推测解码,以进一步改善生成延迟。