论文题目
DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
官方代码和模型说明见 DeepSeek-V2 GitHub。
DeepSeek-V2 是 DeepSeek 基础模型路线里非常关键的一篇。它不是只把模型参数做大,而是同时处理三个问题:
- 能力:模型要在通用、中文、代码、数学等 benchmark 上接近或超过当时强开源模型。
- 训练成本:不能让每个 token 都激活全部参数。
- 推理效率:长上下文生成时,KV Cache 不能成为显存和带宽瓶颈。
论文的核心组合是:
1 | DeepSeek-V2 = MLA + DeepSeekMoE + 8.1T tokens 预训练 + SFT/RL 后训练 + 128K 长上下文扩展 |
其中 MLA 负责降低 attention 侧的 KV Cache,DeepSeekMoE 负责降低 FFN 侧的激活计算。二者合在一起,形成论文标题里的 Strong、Economical、Efficient。
一句话看懂 DeepSeek-V2
DeepSeek-V2 是一个 MoE 语言模型:
- 总参数:236B。
- 每个 token 激活参数:21B。
- 上下文长度:128K tokens。
- 预训练数据:8.1T tokens。
- 词表:100K,使用 Byte-level BPE。
- 相比 DeepSeek 67B:训练成本节省 42.5%,KV Cache 减少 93.3%,最大生成吞吐提升到 5.76 倍。
这组数字说明 DeepSeek-V2 的定位很清楚:它希望用远大于 dense 67B 的总参数承载模型容量,但让每个 token 的实际计算成本接近一个更小的模型,同时解决长上下文推理的 KV Cache 问题。
模型结构总览
DeepSeek-V2 的结构可以拆成 attention 和 FFN 两侧。
| 模块 | 使用技术 | 主要目标 |
|---|---|---|
| Attention | Multi-head Latent Attention, MLA | 减少 KV Cache,提高长上下文推理效率 |
| FFN | DeepSeekMoE | 扩大总参数,同时控制每 token 激活参数 |
| 长上下文 | YaRN + MLA 中的 decoupled RoPE key | 从 4K 扩展到 128K |
| 后训练 | SFT + RL, RL 使用 GRPO | 提升指令跟随、推理、偏好对齐 |
论文给出的模型超参如下:
| 参数 | 数值 |
|---|---|
| Transformer 层数 | 60 |
| Hidden dimension | 5120 |
| Attention heads | 128 |
| 每个 head 维度 | 128 |
| KV compression dimension \(d_c\) | 512 |
| Query compression dimension \(d_c'\) | 1536 |
| Decoupled RoPE 维度 \(d_h^R\) | 64 |
| 每个 MoE layer 的 shared experts | 2 |
| 每个 MoE layer 的 routed experts | 160 |
| 每 token 激活 routed experts | 6 |
| 每个 expert 的 intermediate hidden dimension | 1536 |
论文还特别说明:除了第一层 FFN,其余 FFN 都替换成 MoE layers。这个设计保留了第一层 dense FFN 的稳定性,同时让后续层获得 MoE 的大容量和稀疏激活优势。
MLA:解决 Attention 侧的 KV Cache
标准 MHA 在自回归推理时,要为每一层、每个历史 token 缓存所有 heads 的 key 和 value。单 token 的 KV Cache 元素数是:
其中 \(n_h\) 是 attention heads 数,\(d_h\) 是每个 head 维度,\(l\) 是层数。对 DeepSeek-V2 的参数代入:
也就是说,如果直接采用 MHA,每个 token 仅 KV Cache 就需要约 196 万个元素。长上下文和大 batch 推理时,这会严重限制最大 batch size 和吞吐。
在 MLA 之前,常见的 KV Cache 优化是 MQA 和 GQA。MQA 让所有 query heads 共享一组 key/value,GQA 让多个 query heads 分组共享 key/value。它们都能减少 KV Cache,但代价是 key/value heads 变少,模型表达能力可能下降。
DeepSeek-V2 论文在附录 D.1 比较了 7B dense 模型中的 MQA、GQA 和 MHA。三组模型训练 1.33T tokens,主要差异是 attention 机制:
| 模型 | BBH 3-shot | MMLU 5-shot | C-Eval 5-shot | CMMLU 5-shot |
|---|---|---|---|---|
| Dense 7B w/ MQA | 33.2 | 37.9 | 30.0 | 34.6 |
| Dense 7B w/ GQA, 8 groups | 35.6 | 41.2 | 37.7 | 38.4 |
| Dense 7B w/ MHA | 37.0 | 45.2 | 42.9 | 43.5 |
这个表说明论文的出发点:不能只看 KV Cache 小不小,还要看能力损失。MLA 想要的是另一种折中:缓存接近 GQA/MQA 的小规模,但效果尽量保留甚至超过 MHA。
MLA 的核心是低秩 Key-Value joint compression。它不直接为每个 token 缓存完整 key/value,而是先把 \(\mathbf{h}_t\) 压缩到一个 latent vector:
其中 \(\mathbf{c}_{t}^{KV} \in \mathbb{R}^{d_c}\),\(d_c\) 是 KV compression dimension。然后再通过 up-projection 恢复内容 key 和 value:
推理时不缓存完整 \(\mathbf{k}_{t}^{C}\) 和 \(\mathbf{v}_{t}^{C}\),只缓存 \(\mathbf{c}_{t}^{KV}\)。这样 KV Cache 从 MHA 的 \(2n_hd_hl\) 变成 \(d_cl\)。
DeepSeek-V2 还对 query 做低秩压缩:
query 不需要缓存,所以这一步不能直接减少 KV Cache。论文中的目的主要是减少训练阶段的 activation memory。DeepSeek-V2 中 \(d_c'=1536\),比 KV compression dimension \(d_c=512\) 更大,因为 query 是当前 token 的主动查询表示,不需要像 KV 一样长期缓存。
MLA 真正麻烦的地方是 RoPE。DeepSeek-V2 仍然使用 RoPE,但 RoPE 对 query 和 key 都是位置敏感的。如果直接对压缩后恢复出的 \(\mathbf{k}_t^C\) 加 RoPE,位置相关矩阵会破坏 \(W^{UK}\) 被吸收到 query 投影中的推理优化;系统可能不得不重新计算历史 token 的 keys,KV 压缩带来的推理收益会被抵消。
所以 DeepSeek-V2 使用 decoupled RoPE,把内容信息和位置信息拆开。内容部分走低秩 KV 压缩;位置部分额外构造带 RoPE 的 query 和一个 shared key:
然后把内容向量和位置向量拼接:
注意这里的 \(\mathbf{k}_{t}^{R}\) 是所有 heads 共享的 RoPE key,而不是每个 head 单独一份。因此推理时最终需要缓存的是 \(\mathbf{c}_{t}^{KV}\) 和 \(\mathbf{k}_{t}^{R}\),对应的单 token KV Cache 元素数是:
DeepSeek-V2 中 \(d_c=512\),\(d_h^R=64\),\(l=60\),所以:
这个元素数等价于 GQA 只有 2.25 groups,但论文报告 MLA 的能力强于 MHA。这里的重点不是“简单把 KV 变小”,而是保留多头表达形式,同时改变 KV 的缓存表示。
如果用 FP16 估算,34,560 个元素约为 67.5KiB。对比 MHA 的 1,966,080 个元素,MLA 只有约 1.76%。这个比例是 MLA 结构本身的 KV Cache 元素数对比;论文摘要中“相比 DeepSeek 67B,KV Cache 减少 93.3%”还包含具体模型配置和部署优化的比较口径。
论文附录 D.2 还比较了 MLA 和 MHA,在两个 MoE 规模上训练并评估:
| 模型 | Attention | Activated Params | Total Params | KV Cache / Token | BBH | MMLU | C-Eval | CMMLU |
|---|---|---|---|---|---|---|---|---|
| Small MoE | MHA | 2.5B | 15.8B | 110.6K | 37.9 | 48.7 | 51.6 | 52.3 |
| Small MoE | MLA | 2.4B | 15.7B | 15.6K | 39.0 | 50.0 | 50.9 | 53.4 |
| Large MoE | MHA | 25.0B | 250.8B | 860.2K | 46.6 | 57.5 | 57.9 | 60.7 |
| Large MoE | MLA | 21.5B | 247.4B | 34.6K | 50.7 | 59.0 | 59.2 | 62.5 |
这组实验说明,在 DeepSeek-V2 的模型设计和训练设置下,MLA 没有表现出 MQA/GQA 那种明显能力损失,反而在多数 hard benchmarks 上优于 MHA。更稳妥地说,MLA 不是“压缩必然提升效果”,而是在这套架构里同时做到了大幅降低 KV Cache 和保持强性能。
DeepSeekMoE:解决 FFN 侧的激活计算
Transformer 里 FFN 参数占比很大。如果每个 token 都走完整 dense FFN,模型越大,训练和推理成本就越高。DeepSeek-V2 采用 DeepSeekMoE,核心是细粒度专家切分和 shared experts。
论文里的 MoE 层可以理解成:
其中:
- \(N_s\) 是 shared experts 数。
- \(N_r\) 是 routed experts 数。
- shared experts 对每个 token 都激活。
- routed experts 由 router 选择,只有 top-\(K_r\) 专家被激活。
DeepSeek-V2 的配置是:
- 每个 MoE layer 有 2 个 shared experts。
- 每个 MoE layer 有 160 个 routed experts。
- 每个 token 激活 6 个 routed experts。
- 每个 expert 的 intermediate hidden dimension 是 1536。
这套结构让 DeepSeek-V2 拥有 236B 总参数,但每个 token 只激活 21B 参数。模型容量来自大量 experts,而计算成本由激活专家数量控制。
Device-Limited Routing:MoE 不能只看路由,还要看通信
MoE 的路由如果只按 top-K 选择专家,会遇到工程问题:routed experts 分布在多个设备上时,一个 token 可能被发往很多设备,all-to-all 通信成本会上升。
DeepSeek-V2 使用 device-limited routing 来限制通信范围。具体做法是:
- 对每个 token,先选出包含高 affinity experts 的前 \(M\) 个设备。
- 再只在这 \(M\) 个设备上的 experts 中做 top-K 选择。
论文中 DeepSeek-V2 使用 8-way expert parallelism,每层 routed experts 均匀部署在 8 个设备上,即 \(D=8\);每个 token 最多发送到 3 个设备,即 \(M=3\)。
这个设计很务实:MoE 不只是数学上的稀疏激活,还必须考虑实际分布式训练和推理中的通信边界。
负载均衡与 Token Dropping
MoE 的另一个问题是负载不均衡。如果 router 总把 token 分给少数 experts,会带来两个风险:
- 少数 experts 过载,训练和推理变慢。
- 部分 experts 得不到充分训练,出现 routing collapse。
DeepSeek-V2 使用三类辅助损失:
| 损失 | 目标 |
|---|---|
| Expert-level balance loss | 防止专家级别负载失衡和 routing collapse |
| Device-level balance loss | 保证不同设备上的计算负载均衡 |
| Communication balance loss | 保证设备间通信接收负载均衡 |
训练时还使用 device-level token-dropping strategy 加速。它按设备预算丢弃低 affinity tokens,但论文也说明约 10% 的训练序列中的 tokens 永不丢弃;评估时则不 drop tokens。
这部分体现了 DeepSeek-V2 的工程取向:MoE 的有效性不只取决于专家数和激活数,还取决于负载、通信、token dropping 与评估一致性的处理。
预训练数据与训练设置
DeepSeek-V2 继续沿用 DeepSeek LLM 的数据处理流程,但扩大数据规模并提高数据质量。论文提到:
- 使用与 DeepSeek LLM 相同的 tokenizer,基于 Byte-level BPE。
- 词表大小为 100K。
- tokenized pre-training corpus 为 8.1T tokens。
- 中文 tokens 比英文 tokens 约多 12%。
- 预训练阶段没有混入 SFT 数据。
训练超参方面:
| 项 | 设置 |
|---|---|
| Optimizer | AdamW |
| \(\beta_1,\beta_2\) | 0.9, 0.95 |
| weight decay | 0.1 |
| 最大 learning rate | \(2.4\times10^{-4}\) |
| warmup | 前 2K steps 从 0 线性升到最大值 |
| learning rate decay | 训练约 60% tokens 后乘 0.316,约 90% tokens 后再乘 0.316 |
| gradient clipping norm | 1.0 |
| batch size | 前 225B tokens 从 2304 增到 9216,之后保持 9216 |
| 预训练最大序列长度 | 4K |
| 训练 tokens | 8.1T |
训练基础设施方面,论文报告使用 H800 GPU 集群,采用 16-way zero-bubble pipeline parallelism、8-way expert parallelism 和 ZeRO-1 data parallelism。由于每个 token 激活参数相对少,并且部分 operators 会重计算以节省 activation memory,DeepSeek-V2 不需要 tensor parallelism,从而减少了通信开销。
长上下文扩展:从 4K 到 128K
DeepSeek-V2 初始预训练的最大序列长度是 4K。预训练后,论文使用 YaRN 把默认上下文窗口扩展到 128K。
这里有一个和 MLA 相关的细节:YaRN 被专门应用到 decoupled shared key \(\mathbf{k}_t^R\) 上,因为它负责承载 RoPE 位置信息。
论文中的 YaRN 设置是:
- scale \(s=40\)。
- \(\alpha=1\)。
- \(\beta=32\)。
- target maximum context length 为 160K。
- 期望模型在 128K context length 下表现良好。
扩展阶段,模型额外训练 1000 steps,sequence length 为 32K,batch size 为 576 sequences。虽然训练只用 32K 序列长度,论文的 Needle In A Haystack 测试显示模型在 128K 范围内仍有稳定表现。
SFT 与 RL:把基础模型变成 Chat 模型
预训练后,DeepSeek-V2 继续做 SFT 和 RL。
SFT 阶段:
- 指令数据约 1.5M instances。
- 其中 1.2M 用于 helpfulness,0.3M 用于 safety。
- fine-tune 2 epochs。
- learning rate 为 \(5\times10^{-6}\)。
RL 阶段使用 GRPO,也就是 DeepSeekMath 中使用的 Group Relative Policy Optimization。GRPO 的一个重点是省掉与 policy model 同等规模的 critic model,用一组输出的 reward 估计 baseline,从而降低 RL 训练成本。
DeepSeek-V2 的 RL 分两步:
- reasoning alignment:针对代码和数学推理训练 reward model,并优化 policy。
- human preference alignment:使用 helpful reward model、safety reward model 和 rule-based reward model 的组合。
论文还强调了 RL 训练工程:使用 hybrid engine 区分训练和推理并行策略,用 vLLM 加速大 batch inference,并设计 CPU/GPU offloading 调度。
评测结论:不是所有方向都平均强
DeepSeek-V2 的评测对象包括 DeepSeek 67B、Qwen1.5 72B、LLaMA3 70B、Mixtral 8x22B 等开源模型。论文整体结论是:DeepSeek-V2 只激活 21B 参数,但在开源模型中达到 top-tier 表现。
论文中的几个相对判断值得分开看:
- 相比 DeepSeek 67B,DeepSeek-V2 在几乎所有 benchmark 上显著更强。
- 相比 Qwen1.5 72B,DeepSeek-V2 在多数英文、代码、数学 benchmark 上优势明显;中文多学科选择题上 Qwen1.5 72B 更强,但其他中文任务 DeepSeek-V2 可比或更好。
- 相比 Mixtral 8x22B,DeepSeek-V2 英文整体可比或更好,但 TriviaQA、NaturalQuestions、HellaSwag 这类英文常识知识相关任务上不占优;中文能力明显更强。
- 相比 LLaMA3 70B,DeepSeek-V2 的英文 tokens 少于 LLaMA3 70B 的四分之一,因此基础英文能力仍有差距;但代码、数学能力可比,中文 benchmark 明显更强。
这组结论比较克制。DeepSeek-V2 不是在每个方向都全面压过所有模型,而是在更低激活参数、更低训练成本和更高推理吞吐下,取得了很强的综合性价比。
训练和推理效率
论文对效率给了几个直接数字。
训练方面,在 H800 集群上,每训练 1T tokens:
| 模型 | GPU hours / 1T tokens |
|---|---|
| DeepSeek 67B | 300.6K |
| DeepSeek-V2 | 172.8K |
因此 DeepSeek-V2 相比 DeepSeek 67B 节省 42.5% 训练成本。
推理方面,实际部署时 DeepSeek-V2 会把参数转换成 FP8,并对 KV Cache 做量化,使每个 KV Cache 元素平均压到 6 bits。结合 MLA,实际部署的 DeepSeek-V2 可以服务更大的 batch size。
在单个 8×H800 节点上,论文报告:
- generation throughput 超过 50K tokens/s,是 DeepSeek 67B 最大生成吞吐的 5.76 倍。
- prompt input throughput 超过 100K tokens/s。
这里需要注意,吞吐提升不是 MLA 单独带来的,而是 MLA、MoE 稀疏激活、FP8 参数、KV cache quantization、通信和 kernel 优化共同作用的结果。
我的理解:DeepSeek-V2 的关键是成本结构变化
DeepSeek-V2 最重要的地方,不是某个 benchmark 数字,而是它改变了大模型的成本结构。
Dense 模型的思路是:参数越多,每个 token 计算越多。DeepSeek-V2 的思路是:
- 总参数可以很大,用来扩大容量。
- 每 token 激活参数要受控,用来降低训练和推理计算。
- KV Cache 要压缩,用来释放长上下文和大 batch 推理能力。
- MoE 路由要考虑设备限制和负载均衡,否则理论稀疏性会被通信成本吃掉。
所以 DeepSeek-V2 的核心不是“236B 参数”,而是:
用 236B 总参数承载模型容量,用 21B 激活参数控制每 token 计算,用 MLA 控制 KV Cache,用工程优化把 MoE 真正跑起来。
从 DeepSeek 基础模型线路看,DeepSeek-V2 是承前启后的一篇。它继承 DeepSeek LLM 的训练闭环和 DeepSeekMoE 的专家结构,同时把 MLA 引入基础模型;到 DeepSeek-V3,这套 MoE + MLA 路线继续被放大到 671B 总参数,并叠加更大规模训练工程。
参考资料
- DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
- DeepSeek-V2 GitHub
- DeepSeekMoE: Towards Ultimate Expert Specialization in Mixture-of-Experts Language Models
- DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models
- YaRN: Efficient Context Window Extension of Large Language Models