原文链接
3、DeepSeek-V2
DeepSeek-V2 发布于 2024 年 5 月,为多领域专家(MoE)语言模型,包含总共 2360 亿个参数,其中每个词元激活 210 亿个参数,并支持 12.8 万个词元的上下文长度。DeepSeek-V2 采用包括多头潜在注意力(Multi-Head Latent Attention,MLA)和 DeepSeekMoE 在内的创新架构。MLA 通过将键值(KV)缓存显著压缩为一个潜在向量,保证了高效推理;而 DeepSeekMoE 则通过稀疏计算,能以较低成本训练出强大的模型。与 DeepSeek 670 亿参数模型相比,DeepSeek-V2 的性能显著提升,同时节省了 42.5% 的训练成本,将 KV 缓存减少了 93.3%,并将最大生成吞吐量提高到了 5.76 倍。
DeepSeek - V2 在一个由 8.1 万亿词元组成的高质量、多源语料库上进行预训练,然后进一步进行监督微调(SFT)和强化学习(RL)。即使只有 210 亿激活参数,DeepSeek-V2 及其聊天版本在开源模型中仍能达到顶尖性能。
3.1、架构
DeepSeek-V2 采用 Transformer 架构,其中每个 Transformer 模块由一个注意力模块和一个前馈网络(FFN)组成。在注意力方面,DeepSeek-V2 设计了 MLA,其利用低秩键值联合压缩来消除推理时键值缓存的瓶颈,从而支持高效推理。对于前馈网络,采用 DeepSeekMoE 架构,能够以经济的成本训练强大的模型。
3.1.1、多头潜在注意力:提升推理效率
传统的 Transformer 模型通常采用多头注意力机制(MHA),但在生成过程中,其庞大的键值(KV)缓存会成为限制推理效率的瓶颈。为了减少 KV 缓存,多查询注意力机制(MQA)和分组查询注意力机制(GQA)被提出。它们所需的 KV 缓存规模较小,但其性能却比不上 MHA。
DeepSeek-V2 设计了一种创新的注意力机制,称为 多头潜在注意力(Multi-Head Latent Attention,MLA)。通过低秩键值联合压缩,MLA 实现了比 MHA 更好的性能,同时所需的 KV 缓存量显著减少。
预备知识:标准多头注意力机制
设 d d d 为嵌入(embedding)维度, n h n_h nh 为注意力头(attention heads)的数量, d h d_h dh 为每个头(head)的维度,并且 h t ∈ R d h_t \in \mathbb{R}^d ht∈Rd 是注意力层中第 t t t 个词元(token)的注意力输入。标准的 MHA 首先通过三个矩阵 W Q W_Q WQ、 W K W_K WK、 W V ∈ R d h n h × d W_V \in \mathbb{R}^{d_h n_h \times d} WV∈Rdhnh×d 分别生成 q t q_t qt、 k t k_t kt、 v t ∈ R d h n h v_t \in \mathbb{R}^{d_h n_h} vt∈Rdhnh:
q t = W Q h t , k t = W K h t , v t = W V h t \begin{align*} q_t &= W^Q h_t, \\ k_t &= W^K h_t, \\ v_t &= W^V h_t \end{align*} qtktvt=WQht,=WKht,=WVht
然后, q t q_t qt、 k t k_t kt、 v t v_t vt 将被切分成 n h n_h nh 个头,以进行多头注意力计算:
[ q t , 1 ; q t , 2 ; … ; q t , n h ] = q t , [ k t , 1 ; k t , 2 ; … ; k t , n h ] = k t , [ v t , 1 ; v t , 2 ; … ; v t , n h ] = v t , o t , i = ∑ j = 1 t Softmax j ( q t , i T k j , i d h ) v j , i , u t = W O [ o t , 1 ; o t , 2 ; … ; o t , n h ] \begin{align*} \left[q_{t, 1}; q_{t, 2}; \ldots; q_{t, n_h}\right]&=q_t, \\ \left[k_{t, 1}; k_{t, 2}; \ldots; k_{t, n_h}\right]&=k_t, \\ \left[v_{t, 1}; v_{t, 2}; \ldots; v_{t, n_h}\right]&=v_t, \\ o_{t,i}&=\sum_{j = 1}^{t}\text{Softmax}_j\left(\frac{q_{t,i}^T k_{j,i}}{\sqrt{d_h}}\right)v_{j,i}, \\ u_t&=W^O \left[o_{t, 1}; o_{t, 2}; \ldots; o_{t, n_h}\right] \end{align*} [qt,1;qt,2;…;qt,nh][kt,1;kt,2;…;kt,nh][vt,1;vt,2;…;vt,nh]ot,iut=qt,=kt,=vt,=j=1∑tSoftmaxj(dhqt,iTkj,i)vj,i,=WO[ot,1;ot,2;…;ot,nh]
其中 q t , i q_{t,i} qt,i、 k t , i k_{t,i} kt,i、 v t , i ∈ R d h v_{t,i} \in \mathbb{R}^{d_h} vt,i∈Rdh 分别表示第 i i i 个注意力头的 query
、key
和 value
; W O ∈ R d × d h n h W_O \in \mathbb{R}^{d \times d_h n_h} WO∈Rd×dhnh 表示输出投影矩阵。在推理过程中,所有的 query
和 value
都需要被缓存以加速推理,所以对于每个词元(token),MHA 需要缓存 2 n h d h l 2n_h d_h l 2nhdhl 个元素( l l l 为注意力层数)。在模型部署中,这种庞大的键值缓存是一个很大的瓶颈,它限制了最大批量大小和序列长度。
低秩键值联合压缩
多头潜在注意力(MLA)的核心是对键值进行低秩联合压缩,以减少键值(KV)缓存:
c t K V = W D K V h t , k t C = W U K c t K V , v t C = W U V c t K V , \begin{align*} c_{t}^{KV} &= W^{DKV}h_t, \\ k_{t}^C &= W^{UK}c_{t}^{KV}, \\ v_{t}^C &= W^{UV}c_{t}^{KV}, \end{align*} ctKVktCvtC=WDKVht,=WUKctKV,=WUVctKV,
其中, c t K V ∈ R d c c_t^{KV} \in \mathbb{R}^{d_c} ctKV∈Rdc 是 key
和 value
的压缩潜在向量; d c ( ≪ d h n h ) d_c (\ll d_h n_h) dc(≪dhnh) 表示 KV
压缩维度; W D K V ∈ R d c × d W^{DKV} \in \mathbb{R}^{d_c \times d} WDKV∈Rdc×d 是下投影矩阵; W U K , W U V ∈ R d h n h × d c W^{UK}, W^{UV} \in \mathbb{R}^{d_h n_h \times d_c} WUK,WUV∈Rdhnh×dc 分别是 key
和 value
的上投影矩阵。在推理过程中,MLA 只需要缓存 c t K V c_t^{KV} ctKV,因此其 KV
缓存只有 d c l d_c l dcl 个元素,其中 l l l 表示层数。
此外,在推理过程中,由于 W U K W^{UK} WUK 可以合并到 W Q W^Q WQ 中, W U V W^{UV} WUV 可以合并到 W O W^O WO 中,即甚至无需为注意力计算出键值。
而且,为了在训练过程中减少激活(activation)内存,MLA 对 query
进行低秩压缩,即使不能减少 KV
缓存:
c t Q = W D Q h t , q t Q = W U Q c t Q \begin{align*} c_{t}^Q &= W^{DQ}h_t, \\ q_{t}^Q &= W^{UQ}c_{t}^Q \end{align*} ctQqtQ=WDQht,=WUQctQ
其中, c t Q ∈ R d c ′ c_{t}^Q \in \mathbb{R}^{d'_c} ctQ∈Rdc′ 是 query
的压缩潜在向量; d c ′ ( ≪ d h n h ) d'_c (\ll d_h n_h) dc′(≪dhnh) 表示 query
压缩维度; W D Q ∈ R d c ′ × d W^{DQ} \in \mathbb{R}^{d'_c \times d} WDQ∈Rdc′×d 和 W U Q ∈ R d h n h × d c ′ W^{UQ} \in \mathbb{R}^{d_h n_h \times d'_c} WUQ∈Rdhnh×dc′ 分别是 query
的下投影矩阵和上投影矩阵。
解耦旋转位置嵌入
DeepSeek-V2 中使用旋转位置嵌入(RoPE),然而,RoPE 与低秩键值(KV)压缩不兼容。具体而言,RoPE 对 KV
都具有位置敏感性。如果对 key
k t C k_t^C ktC 应用 RoPE,方程 k t C = W U K c t K V k_{t}^C = W^{UK}c_{t}^{KV} ktC=WUKctKV 中的 W U K W^{UK} WUK 将与位置敏感的 RoPE 矩阵耦合。这样一来,在推理过程中, W U K W^{UK} WUK 就无法再被吸收到 W Q W^Q WQ 中,因为与当前生成的词元相关的 RoPE 矩阵会位于 W Q W^Q WQ 和 W U K W^{UK} WUK 之间,而矩阵乘法不满足交换律。这样所造成的结果是,在推理过程中必须重新计算所有前缀词元的 key
,这将显著降低推理效率。
如何理解:RoPE 与低秩键值(KV)压缩不兼容?
1、第 t t t 个词元的
query
向量与第 j j j 个词元的key
向量之间的计算如下:q t , i T k j , i = ( W i U Q c t Q ) T ( W i U K c j K V ) = ( c t Q ) T ( W i U Q ) T W i U K c j K V \begin{align*} q_{t,i}^T k_{j,i} &= (W_{i}^{UQ}c_{t}^Q )^T (W_{i}^{UK}c_{j}^{KV}) \\ &= (c_{t}^Q)^T (W_{i}^{UQ})^T W_{i}^{UK} c_{j}^{KV} \end{align*} qt,iTkj,i=(WiUQctQ)T(WiUKcjKV)=(ctQ)T(WiUQ)TWiUKcjKV
其中, W i U Q W_{i}^{UQ} WiUQ 是用于生成第 i i i 个注意力头
query
的矩阵, c t Q c_{t}^Q ctQ 是与第 t t t 个词元的query
的压缩潜在向量; W i U K W_{i}^{UK} WiUK 是用于生成第 i i i 个注意力头key
的矩阵, c j K V c_{j}^{KV} cjKV 是与第 j j j 个词元的value
的压缩潜在向量。由于矩阵乘法满足结合律,可以先计算 ( W i U Q ) T W i U K (W_{i}^{UQ})^T W_{i}^{UK} (WiUQ)TWiUK 作为
query
的投影矩阵,如此只需缓存 c j K V c_{j}^{KV} cjKV,而非 ( W i U K c j K V ) (W_{i}^{UK}c_{j}^{KV}) (WiUKcjKV),从而在推理的时候压缩KV
缓存。2、加入 RoPE 后,会在 ( W i U Q ) T W i U K (W_{i}^{UQ})^T W_{i}^{UK} (WiUQ)TWiUK 之间增加融合相对位置的变量 R t − j \mathcal{R}_{t-j} Rt−j:
q t , i T k j , i = ( R t W i U Q c t Q ) T R j ( W i U K c j K V ) = ( c t Q ) T ( W i U Q ) T R t T R j W i U K c j K V = ( c t Q ) T ( W i U Q ) T R t − j W i U K c j K V \begin{align*} q_{t,i}^T k_{j,i} &= (\mathcal{R}_{t} W_{i}^{UQ}c_{t}^Q )^T \mathcal{R}_{j}(W_{i}^{UK}c_{j}^{KV}) \\ &= (c_{t}^Q)^T (W_{i}^{UQ})^T \mathcal{R}_{t}^T \mathcal{R}_{j} W_{i}^{UK} c_{j}^{KV} \\ &= (c_{t}^Q)^T (W_{i}^{UQ})^T \mathcal{R}_{t-j} W_{i}^{UK} c_{j}^{KV} \end{align*} qt,iTkj,i=(RtWiUQctQ)TRj(WiUKcjKV)=(ctQ)T(WiUQ)TRtTRjWiUKcjKV=(ctQ)T(WiUQ)TRt−jWiUKcjKV
由于 ( W i U Q ) T R t − j W i U K (W_{i}^{UQ})^T \mathcal{R}_{t-j} W_i^{UK} (WiUQ)TRt−jWiUK 随相对位置变化,无法合并为一个固定的投影矩阵,因此不能提前计算以压缩
KV
缓存。相关文章解读:
缓存与效果的极限拉扯:从MHA、MQA、GQA到MLA
deepseek技术解读(1)-彻底理解MLA(Multi-Head Latent Attention)
作为一种解决方案,DeepSeek-V2 提出解耦 RoPE 策略,即使用额外的多头查询 q t , i R ∈ R d h R q_{t,i}^R \in \mathbb{R}^{d_h^R} qt,iR∈RdhR 和一个共享 key
k t R ∈ R d h R k_t^R \in \mathbb{R}^{d_h^R} ktR∈RdhR 来承载 RoPE,其中 d h R d_h^R dhR 表示解耦后的 query
和 key
的每头维度。采用解耦 RoPE 策略后,MLA 进行以下计算:
[ q t , 1 R ; q t , 2 R ; ⋯ ; q t , n h R ] = q t R = RoPE ( W Q R c t Q ) , k t R = RoPE ( W K R h t ) , q t , i = [ q t , i C ; q t , i R ] , k t , i = [ k t , i C ; k t R ] , o t , i = ∑ j = 1 t Softmax j ( q t , i T k j , i d h + d h R ) v j , i C , u t = W O [ o t , 1 ; o t , 2 ; ⋯ ; o t , n h ] \begin{align*} [q_{t,1}^R; q_{t,2}^R; \cdots; q_{t,n_h}^R] = q_t^R &= \text{RoPE}(W^{QR} c_t^Q), \\ k_t^R &= \text{RoPE}(W^{KR} h_t), \\ q_{t,i} &= [q_{t,i}^C; q_{t,i}^R], \\ k_{t,i} &= [k_{t,i}^C; k_t^R], \\ o_{t,i} &= \sum_{j = 1}^{t} \text{Softmax}_j\left(\frac{q_{t,i}^T k_{j,i}}{\sqrt{d_h + d_h^R}}\right) v_{j,i}^C, \\ u_t &= W_O [o_{t,1}; o_{t,2}; \cdots; o_{t,n_h}] \end{align*} [qt,1R;qt,2R;⋯;qt,nhR]=qtRktRqt,ikt,iot,iut=RoPE(WQRctQ),=RoPE(WKRht),=[qt,iC;qt,iR],=[kt,iC;ktR],=j=1∑tSoftmaxj dh+dhRqt,iTkj,i vj,iC,=WO[ot,1;ot,2;⋯;ot,nh]
其中, W Q R ∈ R d h R n h × d c ′ W_Q^R \in \mathbb{R}^{d_h^R n_h \times d_c'} WQR∈RdhRnh×dc′ 和 W K R ∈ R d h R × d W_K^R \in \mathbb{R}^{d_h^R \times d} WKR∈RdhR×d 分别是用于生成解耦 query
和 key
的矩阵; RoPE ( ⋅ ) \text{RoPE}(\cdot) RoPE(⋅) 表示应用 RoPE 矩阵的操作; [ ⋅ ; ⋅ ] [\cdot; \cdot] [⋅;⋅] 表示拼接操作。在推理过程中,解耦后的 key
也应该被缓存。因此,DeepSeek-V2总共需要一个包含 ( d c + d h R ) l (d_c + d_h^R)l (dc+dhR)l 个元素的 KV
缓存。
解耦 RoPE
引入多头查询 q t , i R ∈ R d h R q_{t,i}^R \in \mathbb{R}^{d_h^R} qt,iR∈RdhR 和共享
key
k t R ∈ R d h R k_t^R \in \mathbb{R}^{d_h^R} ktR∈RdhR 后,第 t t t 个词元的query
向量与第 j j j 个词元的key
向量之间的计算如下:q t , i T k j , i = [ q t , i C ; q t , i R ] T [ k j , i C ; k t R ] = q t , i C k j , i C + q t , i R k t R \begin{align*} q_{t,i}^T k_{j,i} &= [ q_{t,i}^C;q_{t,i}^R ]^T [ k_{j,i}^C; k_{t}^{R}] \\ &= q_{t,i}^C k_{j,i}^C + q_{t,i}^R k_{t}^{R} \end{align*} qt,iTkj,i=[qt,iC;qt,iR]T[kj,iC;ktR]=qt,iCkj,iC+qt,iRktR
其中,由于矩阵乘法的结合律, q t , i C k j , i C q_{t,i}^C k_{j,i}^C qt,iCkj,iC 中, W U K W^{UK} WUK 可被 W U Q W^{UQ} WUQ 吸收(同理, W U V W^{UV} WUV 可被 W O W^{O} WO 吸收),只需缓存 c t K V c_t^{KV} ctKV。 q t , i R k t R q_{t,i}^R k_{t}^{R} qt,iRktR 可按 MQA 方式计算,只需缓存共享的 k t R k_t^R ktR。最终,避免了在推理过程中重新计算 k t C k_t^{C} ktC 和 v t C v_t^{C} vtC 带来的计算开销。
Key-Value 缓存比较
下表中展示了不同注意力机制下每个词元的键值(KV)缓存对比情况。多层注意力(MLA)仅需少量的 KV
缓存,与仅有 2.25 组的 GQA 相当,但 MLA 的性能比 MHA 更强。
其中, n h n_h nh 表示注意力头的数量, d h d_h dh 表示每个注意力头的维度, l l l 表示层数, n g n_g ng 表示 GQA 中的组数, d c d_c dc 和 d h R d_h^R dhR 分别表示 MLA 中的 KV
压缩维度以及解耦 query
和 key
的每个头的维度。KV
缓存量通过元素数量衡量,不考虑存储精度。对于 DeepSeek-V2, d c d_c dc 设置为 4 d h 4d_h 4dh, d h R d_h^R dhR 设置为 d h 2 \frac{d_h}{2} 2dh。因此,其 KV
缓存量与仅分为 2.25 组的 GQA 相当,但其性能比 MHA 更强。
3.1.2、DeepSeekMoE
3.1.2.1、基本架构
对于前馈神经网络(FFNs),DeepSeek-V2 采用 DeepSeekMoE 架构。DeepSeekMoE有两个关键理念:
- 将专家模块划分得更细粒度,以实现更高程度的专家专业化和更精准的知识获取;
- 分离出一些共享专家,以减少路由专家之间的知识冗余。
在激活的专家参数和专家总参数数量相同的情况下,DeepSeekMoE 的性能大幅优于诸如 GShard 等传统的混合专家(MoE)架构。
设 u t u_t ut 为第 t t t 个词元的前馈神经网络输入,按如下方式计算前馈神经网络的输出 h t ′ h'_t ht′:
h t ′ = u t + ∑ i = 1 N s FFN i ( s ) ( u t ) + ∑ i = 1 N r g i , t FFN i ( r ) ( u t ) , g i , t = { s i , t , s i , t ∈ Topk ( { s j , t ∣ 1 ≤ j ≤ N r } , K r ) 0 , otherwise , s i , t = Softmax i ( u t T e i ) \begin{align*} h'_t &= u_t + \sum_{i = 1}^{N_s} \text{FFN}_i^{(s)}(u_t) + \sum_{i = 1}^{N_r} g_{i,t} \text{FFN}_i^{(r)}(u_t), \\ g_{i,t} &= \begin{cases} s_{i,t}, & s_{i,t} \in \text{Topk}(\{s_{j,t} | 1 \leq j \leq N_r\}, K_r) \\ 0, & \text{otherwise} \end{cases}, \\ s_{i,t} &= \text{Softmax}_i \left( u_t^T e_i \right) \end{align*} ht′gi,tsi,t=ut+i=1∑NsFFNi(s)(ut)+i=1∑Nrgi,tFFNi(r)(ut),={si,t,0,si,t∈Topk({sj,t∣1≤j≤Nr},Kr)otherwise,=Softmaxi(utTei)
其中:
- N s N_s Ns 和 N r N_r Nr 分别表示共享专家和路由专家的数量
- FFN i ( s ) ( ⋅ ) \text{FFN}_i^{(s)}(\cdot) FFNi(s)(⋅) 和 FFN i ( r ) ( ⋅ ) \text{FFN}_i^{(r)}(\cdot) FFNi(r)(⋅) 分别表示第 i i i 个共享专家和第 i i i 个路由专家
- K r K_r Kr 表示激活的路由专家数量
- g i , t g_{i,t} gi,t 是第 i i i 个专家的门控值
- s i , t s_{i,t} si,t 是词元与专家的亲和度
- e i e_i ei 是该层第 i i i 个路由专家的质心
- Topk ( ⋅ , K ) \text{Topk}(\cdot, K) Topk(⋅,K) 表示在为第 t t t 个词元与所有路由专家计算出的亲和度分数中,由 K K K 个最高分数组成的集合
3.1.2.2、设备受限路由
通过设备受限路由机制以控制与混合专家(MoE)相关的通信成本。当采用专家并行时,被路由的专家会分布在多个设备上。对于每个词元,其与 MoE 相关的通信频率与目标专家所覆盖的设备数量成正比。由于 DeepSeekMoE 中专家的细粒度划分,激活的专家数量可能较多,因此如果采用专家并行,与 MoE 相关的通信成本会更高。
对于 DeepSeek-V2,除了对路由专家进行常规的 top-K 选择之外,还额外确保每个词元的目标专家最多分布在 M M M 个设备上。具体来说,对于每个词元,首先选择 M M M 个其中专家亲和度分数最高的设备。然后,在这 M M M 个设备上的专家中进行 top-K 选择。在实践中,当 M ≥ 3 M \geq 3 M≥3 时,设备受限路由能够实现与无限制 top-K 路由大致相当的良好性能。
3.1.2.3、负载均衡的辅助损失
对于自动学习的路由策略,DeepSeek-V2 考虑了负载均衡因素。首先,负载不均衡会增加路由崩溃的风险,导致部分专家无法得到充分训练和利用。其次,在采用专家并行时,负载不均衡会降低计算效率。在 DeepSeek-V2 的训练过程中设计了三种辅助损失,分别用于控制专家级负载均衡、设备级负载均衡和通信均衡。
1、专家级均衡损失
DeepSeek-V2 采用一种专家级均衡损失来降低路由崩溃的风险:
L ExpBal = α 1 ∑ i = 1 N r f i P i , f i = N r K r T ∑ t = 1 T 1 ( Token t selects Expert i ) , P i = 1 T ∑ t = 1 T s i , t \begin{align*} \mathcal{L}_{\text{ExpBal}} &= \alpha_1 \sum_{i = 1}^{N_r} f_i P_i, \\ f_i &= \frac{N_r}{K_r T} \sum_{t = 1}^{T} \mathbb{1}(\text{Token } t \text{ selects Expert } i), \\ P_i &= \frac{1}{T} \sum_{t = 1}^{T} s_{i,t} \end{align*} LExpBalfiPi=α1i=1∑NrfiPi,=KrTNrt=1∑T1(Token t selects Expert i),=T1t=1∑Tsi,t
其中, α 1 \alpha_1 α1 是一个称为专家级均衡因子的超参数; 1 ( ⋅ ) \mathbb{1}(\cdot) 1(⋅) 表示指示函数; T T T 表示序列中的词元数量。
2、设备级均衡损失
除了专家级均衡损失,还额外设计了设备级均衡损失,以确保不同设备间的计算负载均衡。在 DeepSeek-V2 的训练过程中,将所有路由专家划分为 D D D 组 { E 1 , E 2 , … , E D } \{E_1, E_2, \ldots, 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{align*} \mathcal{L}_{\text{DevBal}} &= \alpha_2 \sum_{i = 1}^{D} f'_i P'_i, \\ f'_i &= \frac{1}{|\mathcal{E}_i|} \sum_{j \in \mathcal{E}_i} f_j, \\ P'_i &= \sum_{j \in \mathcal{E}_i} P_j \end{align*} LDevBalfi′Pi′=α2i=1∑Dfi′Pi′,=∣Ei∣1j∈Ei∑fj,=j∈Ei∑Pj
其中, α 2 \alpha_2 α2 是一个称为设备级均衡因子的超参数。
3、通信均衡损失
最后,引入通信均衡损失,以确保每个设备的通信负载均衡。尽管设备受限路由机制保证了每个设备的发送通信量受到限制,但如果某个设备接收的词元数量多于其他设备,实际通信效率仍会受到影响。为缓解这一问题,设计如下通信均衡损失:
L CommBal = α 3 ∑ i = 1 D f i ′ ′ P i ′ ′ , f i ′ ′ = D M T ∑ t = 1 T 1 ( Token t is sent to Device i ) , P i ′ ′ = ∑ j ∈ E i P j \begin{align*} \mathcal{L}_{\text{CommBal}} &= \alpha_3 \sum_{i = 1}^{D} f''_i P''_i, \\ f''_i &= \frac{D}{MT} \sum_{t = 1}^{T} \mathbb{1}(\text{Token } t \text{ is sent to Device } i), \\ P''_i &= \sum_{j \in \mathcal{E}_i} P_j \end{align*} LCommBalfi′′Pi′′=α3i=1∑Dfi′′Pi′′,=MTDt=1∑T1(Token t is sent to Device i),=j∈Ei∑Pj
其中, α 3 \alpha_3 α3 是一个称为通信均衡因子的超参数。设备受限路由机制的运行原则是确保每个设备最多向其他设备传输 M T MT MT 个隐藏状态。同时,采用通信均衡损失来促使每个设备从其他设备接收约 M T MT MT 个隐藏状态。通信均衡损失保证了设备之间信息的均衡交换,有助于实现高效通信。
3.1.2.4、词元丢弃策略
尽管均衡损失旨在促进负载均衡,但必须承认,它们无法保证严格的负载均衡。为了进一步减少因负载不均衡导致的计算浪费,DeepSeek-V2 在训练过程中引入设备级词元丢弃策略:首先计算每个设备的平均计算预算,即每个设备的容量因子等同于 1.0。然后,在每个设备上丢弃亲和度分数最低的词元,直至达到计算预算。此外,确保大约 10% 的训练序列中的词元永远不会被丢弃。通过这种方式,可以在推理过程中根据效率要求灵活决定是否丢弃词元,并且始终保证训练和推理之间的一致性。
3.2、预训练
3.2.1、数据构建
在保持与 DeepSeek 67B 相同的数据处理阶段的同时,DeepSeek-V2 扩充了数据量并提升了数据质量。为了扩大预训练语料库,DeepSeek-V2 探索了互联网数据的潜力并优化了清洗流程,从而恢复了大量被误删除的数据。此外,纳入了更多中文数据,旨在更好地利用中文互联网上可用的语料库。
除了数据量,DeepSeek-V2 还关注数据质量。用来自各种来源的高质量数据丰富预训练语料库,同时改进基于质量的过滤算法。改进后的算法确保大量无用数据被剔除,而有价值的数据大多得以保留。此外,从预训练语料库中过滤掉有争议的内容,以减轻特定地域文化带来的数据偏差。
DeepSeek-V2 采用与 DeepSeek 67B 相同的分词器,该分词器基于字节级字节对编码(BBPE)算法构建,词汇表大小为 10 万个。经过分词的预训练语料库包含 8.1 万亿个词元,其中中文词元比英文词元大约多12%。
3.2.2、超参数
1、模型超参数
DeepSeek-V2 将 Transformer 层数设置为 60,隐藏层维度设置为 5120。所有可学习参数均以标准差 0.006 进行随机初始化。在多层注意力(MLA)中,将注意力头的数量 n h n_h nh 设置为 128,每个头的维度 d h d_h dh 设置为 128。KV
压缩维度 d c d_c dc 设置为 512,query
压缩维度 d c ′ d_c' dc′ 设置为 1536。对于解耦后的 query
和 key
,将每个头的维度 d h R d_h^R dhR 设置为 64。
DeepSeek-V2 将除第一层之外的所有前馈神经网络(FFNs)替换为混合专家(MoE)层。每个 MoE 层由 2 个共享专家和 160 个路由专家组成,每个专家的中间隐藏层维度为 1536。在路由专家中,每个词元将激活 6 个专家。此外,低秩压缩和细粒度的专家划分会影响一层的输出规模。因此,在实际操作中,在压缩后的潜在向量之后采用额外的均方根归一化(RMS Norm)层,并在宽度瓶颈处(即压缩后的潜在向量和路由专家的中间隐藏状态)乘以额外的缩放因子,以确保训练的稳定性。在此配置下,DeepSeek-V2 总共有 2360 亿个参数,每个词元激活 210 亿个参数。
2、训练超参数
DeepSeek-V2 采用 AdamW 优化器,超参数设置为 β 1 = 0.9 \beta_1 = 0.9 β1=0.9, β 2 = 0.95 \beta_2 = 0.95 β2=0.95,权重衰减为 0.1 0.1 0.1。学习率采用预热与阶梯衰减(warmup-and-step-deca)策略进行调度。最初,在前 2000 步中,学习率从 0 线性增加到最大值。随后,在训练约 60% 的词元后,学习率乘以 0.316,在训练约 90% 的词元后,再次乘以 0.316。最大学习率设置为 2.4 × 1 0 − 4 2.4×10^{-4} 2.4×10−4,梯度裁剪范数设置为 1.0。
DeepSeek-V2 还使用批量大小调度策略,在训练前 2250 亿个词元时,批量大小从 2304 逐渐增加到 9216,在剩余训练过程中保持为 9216。此外,将最大序列长度设置为 4096,并在 8.1 万亿个词元上训练 DeepSeek-V2。
DeepSeek-V2 利用流水线并行技术将模型的不同层部署在不同设备上,对于每一层,路由专家将均匀部署在 8 个设备上( D = 8 D = 8 D=8)。对于设备受限路由,每个词元最多发送到 3 个设备( M = 3 M = 3 M=3)。对于均衡损失,将 α 1 \alpha_1 α1 设置为 0.003, α 2 \alpha_2 α2 设置为 0.05, α 3 \alpha_3 α3 设置为 0.02。在训练期间采用词元丢弃策略以加速训练,但在评估时不丢弃任何词元。
3.2.3、基础设施
DeepSeek-V2 基于自主开发的高效轻量级训练框架 HAI-LLM 框架进行训练。该框架采用 16 路零气泡流水线并行、8 路专家并行以及 ZeRO-1 数据并行。鉴于 DeepSeek-V2 的激活参数相对较少,且部分操作会重新计算以节省激活内存,因此无需张量并行即可完成训练,从而降低了通信开销。此外,为进一步提高训练效率,将共享专家的计算与专家并行的全对全通信进行重叠处理。
DeepSeek-V2 针对不同专家间的通信、路由算法以及融合线性计算,定制了更快的 CUDA 内核。此外,多层注意力(MLA)也基于改进版的 FlashAttention-2 进行了优化。
所有的实验均在配备 NVIDIA H800 GPU 的集群上进行。H800 集群中的每个节点包含 8 个通过 NVLink 和节点内 NVSwitch 相连的 GPU。跨节点之间,则利用 InfiniBand 互连来实现通信。
3.2.4、长上下文扩展
在对 DeepSeek-V2 进行初始预训练后,采用 YaRN 将默认上下文窗口长度从 4K 扩展到 128K。YaRN 专门应用于解耦后的共享键 k t R k_t^R ktR,因为它负责承载旋转位置嵌入(RoPE)。对于 YaRN,将缩放因子 s s s 设置为 40, α \alpha α 设置为 1, β \beta β 设置为 32,目标最大上下文长度设置为 160K。在这些设置下,期望模型在 128K 的上下文长度下能有良好表现。由于 DeepSeek-V2 独特的注意力机制,与原始 YaRN 略有不同,DeepSeek-V2 调整了长度缩放因子来调节注意力熵。因子 t \sqrt{t} t 计算为 t = 0.0707 ln s + 1 \sqrt{t} = 0.0707 \ln s + 1 t=0.0707lns+1,目的是使困惑度最小化。
DeepSeek-V2 对模型进行了 1000 步的训练,序列长度设为 32K,批量大小为 576 个序列。尽管训练仅在 32K 的序列长度下进行,但当在 128K 的上下文长度下进行评估时,该模型仍展现出强大的性能。
YaRN
YaRN(Yet another RoPE extensioN method) 是一种用于扩展基于旋转位置嵌入(RoPE)的大型语言模型上下文窗口的高效方法,所需的训练数据和训练步骤分别比之前的方法少10倍和2.5倍。通过对 LLaMA 使用 YaRN 能够有效利用并外推到比其原始预训练所允许的更长的上下文长度,同时在上下文窗口扩展方面超越了之前的最先进技术。此外,YaRN 具备在微调数据集有限上下文之外进行外推的能力。
1、旋转位置嵌入
YaRN 基于 RoPE,在一个隐藏层上工作,其中隐藏神经元的集合由 D D D 表示。给定一个向量序列 x 1 , ⋯ , x L ∈ R ∥ D ∥ x_{1},\cdots,x_{L} \in \mathbb{R}^{\|D\|} x1,⋯,xL∈R∥D∥ ,注意力层首先将这些向量转换为查询向量和键向量:
q m = f q ( x m , m ) ∈ R ∣ D ∣ , k n = f k ( x n , n ) ∈ R ∣ D ∣ q_{m}=f_{q}(x_{m},m)\in \mathbb{R}^{|D|},\,k_{n}=f_{k}(x_{n},n)\in \mathbb{R}^{|D|} qm=fq(xm,m)∈R∣D∣,kn=fk(xn,n)∈R∣D∣
接下来,计算注意力权重为
softmax ( q m T k n ∣ D ∣ ) \operatorname{softmax}\left(\frac{q_{m}^{T} k_{n}}{\sqrt{|D|}}\right) softmax(∣D∣qmTkn)
其中 q m , k n q_{m}, k_{n} qm,kn 被视为列向量,因此 q m T k n q_{m}^{T} k_{n} qmTkn 简单地是欧几里得内积。在 RoPE 中,假设 ∥ D ∥ \|D\| ∥D∥ 是偶数,并将嵌入空间和隐藏状态识别为复向量空间:
R ∣ D ∣ ≅ C ∣ D ∣ / 2 \mathbb{R}^{|D|}\cong \mathbb{C}^{|D|/ 2} R∣D∣≅C∣D∣/2
其中内积 q T k q^{T} k qTk 变为标准厄米内积的实部 Re ( q ∗ k ) \operatorname{Re}\left(q^{*}k\right) Re(q∗k) 。更具体的,同构交错实部和虚部:
( ( x m ) 1 , ⋯ , ( x m ) ∣ D ∣ ) ↦ ( ( x m ) 1 + i ( x m ) 2 , ⋯ , ( ( x m ) ∣ D ∣ − 1 + i ( x m ) ∣ D ∣ ) ) , \left((x_{m})_{1},\cdots,(x_{m})_{|D|}\right)\mapsto\left((x_{m})_{1}+i(x_{m})_{2},\cdots,\left((x_{m})_{|D|-1}+i(x_{m})_{|D|}\right)\right), ((xm)1,⋯,(xm)∣D∣)↦((xm)1+i(xm)2,⋯,((xm)∣D∣−1+i(xm)∣D∣)),
( ( q m ) 1 , ⋯ , ( q m ) ∣ D ∣ ) ↦ ( ( q m ) 1 + i ( q m ) 2 , ⋯ , ( ( q m ) ∣ D ∣ − 1 + i ( q m ) ∣ D ∣ ) ) . \begin{align*} \left((q_{m})_{1},\cdots,(q_{m})_{|D|}\right)&\mapsto\left((q_{m})_{1}+i(q_{m})_{2},\cdots,((q_{m})_{|D|-1}+i(q_{m})_{|D|})\right). \end{align*} ((qm)1,⋯,(qm)∣D∣)↦((qm)1+i(qm)2,⋯,((qm)∣D∣−1+i(qm)∣D∣)).
为了将嵌入 x m , x n x_{m},x_{n} xm,xn 转换为查询和键向量,首先需要定义 R \mathbb{R} R 线性算子:
W q , W k : R ∣ D ∣ → R ∣ D ∣ . W_{q},W_{k}:\mathbb{R}^{|D|}\rightarrow \mathbb{R}^{|D|}. Wq,Wk:R∣D∣→R∣D∣.
在复坐标中,函数 f q , f k f_{q}, f_{k} fq,fk 由下式给出:
f q ( x m , m ) = e i m θ W q x m , f k ( x n , n ) = e i n θ W k x n , f_{q}\left(x_{m},m\right)=e^{im\theta}W_{q}x_{m},\,f_{k}\left(x_{n},n\right)=e^{in\theta}W_{k}x_{n}, fq(xm,m)=eimθWqxm,fk(xn,n)=einθWkxn,
其中 θ = diag ( θ 1 , ⋯ , θ ∥ D ∥ / 2 ) \theta=\operatorname{diag}\left(\theta_{1},\cdots,\theta_{\|D\|/ 2}\right) θ=diag(θ1,⋯,θ∥D∥/2) 是对角矩阵,且 θ d = b − 2 d / ∥ D ∥ \theta_{d}=b^{-2 d/\|D\|} θd=b−2d/∥D∥ , b = 10000 b=10000 b=10000 。这样,RoPE 将每个(复数值)隐藏神经元与一个单独的频率 θ d \theta_{d} θd 关联起来。这样做的好处是查询(query)向量和键(key)向量之间的点积仅取决于相对距离 m − n m-n m−n ,如下所示:
⟨ f q ( x m , m ) , f k ( x n , n ) ⟩ R = Re ( ⟨ f q ( x m , m ) , f k ( x n , n ) ⟩ C ) = Re ( x m ∗ W q ∗ W k x n e i θ ( m − n ) ) = g ( x m , x n , m − n ) . \begin{align*} \langle f_{q}\left(x_{m}, m\right), f_{k}\left(x_{n}, n\right)\rangle_{\mathbb{R}} &=\text{Re}(\langle f_{q}(x_{m},m),f_{k}(x_{n},n)\rangle_{\mathbb{C}}) \\ &=\operatorname{Re}\left(x_{m}^{*}W_{q}^{*}W_{k}x_{n}e^{i\theta(m-n)}\right) \\ &=g(x_{m},x_{n},m-n). \end{align*} ⟨fq(xm,m),fk(xn,n)⟩R=Re(⟨fq(xm,m),fk(xn,n)⟩C)=Re(xm∗Wq∗Wkxneiθ(m−n))=g(xm,xn,m−n).
在实坐标中,RoPE 可以用以下函数写成:
KaTeX parse error: Unknown column alignment: [ at position 59: …t(\begin{array}[̲]{cccccccc}\cos…
即:
f q = f W q , f k = f W k . f_{q}=f_{W_{q}},\,f_{k}=f_{W_{k}}. fq=fWq,fk=fWk.
注:
在 RoPE 里,每个维度 d d d 有对应旋转角度 θ d \theta_{d} θd,结合位置索引 m m m 得到旋转角度 m θ d m\theta_{d} mθd。从数学实现看,此旋转操作类似在复平面旋转位置向量。类比信号处理,不同的 m θ d m\theta_{d} mθd 使位置向量在各维度以不同 “速度” 旋转,类似不同频率。大的 θ d \theta_{d} θd 使向量旋转快,对应高频;小的 θ d \theta_{d} θd 使向量旋转慢,对应低频。
快速旋转能够捕捉输入序列中的局部细节和短期依赖关系,因为这些变化通常较为频繁且快速。慢速旋转适合捕捉长距离依赖关系,因为这些关系通常变化较慢且需要更长的上下文信息。通过这种设计,模型能够在不同维度上同时捕捉局部细节和长距离依赖。
2、位置插值(PI)
由于语言模型通常在固定的上下文长度下进行预训练,因此很自然会提出这样一个问题:如何通过相对少量的数据微调来扩展上下文长度。
对于使用 RoPE 作为位置嵌入的语言模型,有研究提出位置插值(PI)来扩展超出预训练限制的上下文长度。虽然直接外推在序列 w 1 , ⋯ , w L w_{1},\cdots,w_{L} w1,⋯,wL( L L L 大于预训练极限)中表现不佳,但在少量微调的帮助下,对预训练限制内的位置索引进行插值能取得良好效果。具体来说,给定一个使用 RoPE 的预训练语言模型:
f W ′ ( x m , m , θ d ) = f W ( x m , m L L ′ , θ d ) , \begin{align*} f^{\prime}_{W}\left(x_{m},m,\theta_{d}\right)&=f_{W}\left(x_{m},\frac{mL}{L^{\prime}},\theta_{d}\right), \tag{1} \end{align*} fW′(xm,m,θd)=fW(xm,L′mL,θd),(1)
其中 L ′ > L L^{\prime}>L L′>L 是超出预训练限制的新上下文窗口。通过原始预训练模型加上修改后的 RoPE 公式,在数量少几个数量级的词元上进一步微调了语言模型,并成功实现了上下文窗口的扩展。
3、额外的符号说明
扩展的上下文长度与原始上下文长度之间的比率特别重要,引入符号 s s s(比例因子)定义为:
s = L ′ L , s=\frac{L^{\prime}}{L}, s=LL′,
重写并简化方程(1)为以下一般形式:
f W ′ ( x m , m , θ d ) = f W ( x m , g ( m ) , h ( θ d ) ) , (2) f_{W}^{\prime}\left(x_{m},m,\theta_{d}\right)=f_{W}\left(x_{m},g(m),h\left(\theta_{d}\right)\right), \tag{2} fW′(xm,m,θd)=fW(xm,g(m),h(θd)),(2)
其中 g ( m ) , h ( θ d ) g(m), h\left(\theta_{d}\right) g(m),h(θd) 是方法相关的函数。对于 PI,有 g ( m ) = m / s , h ( θ d ) = θ d g(m)=m/ s, h\left(\theta_{d}\right)=\theta_{d} g(m)=m/s,h(θd)=θd 。
此外,定义 λ d \lambda_{d} λd 为 RoPE 嵌入在第 d d d 个隐藏维度上的波长:
λ d = 2 π θ d = 2 π b 2 d ∣ D ∣ . (3) \lambda_d=\frac{2\pi}{\theta_d}=2\pi b^{\frac{2 d}{|D|}}. \tag{3} λd=θd2π=2πb∣D∣2d.(3)
波长描述了 RoPE 嵌入在第 d d d 个维度上执行一次完整旋转( 2 π 2\pi 2π)所需的词元长度。
鉴于一些插值方法(例如 PI)不关心维度的波长,将这些方法称为“盲目”的插值方法,而其他方法(例如YaRN)则将其分类为“目标”插值方法。
4、高频信息损失 - “NTK感知” 插值法
PI 尝试通过重新定义 g ( m ) g(m) g(m) 将位置索引拉伸到预训练窗口内,PI 所描述的理论插值界限不足以预测 RoPE 与大语言模型(LLM)内部嵌入之间的复杂动态关系。
如果仅从信息编码的角度来看 RoPE,利用神经正切核(NTK)理论表明,若输入维度较低且相应的嵌入缺乏高频成分,深度神经网络在学习高频信息时会遇到困难。一个词元的位置信息是一维的,而 RoPE 将其扩展为一个 n n n 维的复数向量嵌入。
在许多方面,RoPE 与傅里叶特征极为相似,因为可以将 RoPE 定义为傅里叶特征的一种特殊一维情况。不加区分地拉伸 RoPE 嵌入会导致重要高频细节的丢失,而网络需要这些细节来分辨非常相似且位置相近的词元(描述最小距离的旋转不能太小,以便网络能够检测到)。
假设在 PI 中,在较大上下文规模上微调后,较短上下文规模的困惑度略有增加可能与该问题有关。在理想情况下,在较大上下文规模上进行微调不应降低较小上下文规模的性能。
为解决在对 RoPE 嵌入进行插值时丢失高频信息的问题,开发了 “NTK感知” 插值法。与对 RoPE 的每个维度同等按因子 s s s 进行缩放不同,通过减少高频的缩放幅度并增加低频的缩放幅度,将插值压力分散到多个维度上。可以通过多种方式获得这种变换,但最简单的方法是对 θ \theta θ 的值进行底数变换。
更准确地说,按照第 3 节中设定的符号,将 “NTK感知” 插值方案定义如下:
定义1 “NTK感知” 插值是对 RoPE 的一种修改,使用公式(2)以及以下函数:
g ( m ) = m g(m) = m g(m)=m
h ( θ d ) = b ′ − 2 d / ∣ D ∣ h(\theta_d) = b'^{-2d/|D|} h(θd)=b′−2d/∣D∣
其中,
b ′ = b ⋅ s ∣ D ∣ ∣ D ∣ − 2 b' = b \cdot s^{\frac{|D|}{|D| - 2}} b′=b⋅s∣D∣−2∣D∣
与 PI 相比,该方法在扩展非微调模型的上下文规模方面表现要好得多。然而,该方法的一个主要缺点是,由于它不仅仅是一种插值方案,一些维度会稍微外推到 “越界” 值,因此使用 “NTK感知” 插值法进行微调得到的结果不如 PI。此外,由于存在 “越界” 值,理论缩放因子 s s s 不能准确描述真实的上下文扩展比例。在实践中,对于给定的上下文长度扩展,缩放值 s s s 必须设置得高于预期比例。
5、相对局部距离的损失 - “逐部分NTK” 插值法
PI和 “NTK感知” 插值这样的盲目插值方法中对 RoPE 的所有隐藏维度一视同仁(即认为它们对网络具有相同的影响)。然而,有明显线索表明需要有针对性的插值方法。
在本节中,主要从 RoPE 公式(公式 3)中定义的波长 λ d \lambda_d λd 的角度来考虑问题。为简化起见,省略 λ d \lambda_d λd 中的下标 d d d,建议将 λ \lambda λ 视为任意周期函数的波长。
对 RoPE 嵌入的一个有趣观察是,对于给定的上下文大小 L L L,在某些维度 d d d 上,波长比预训练期间看到的最大上下文长度更长( λ > L \lambda > L λ>L),这表明某些维度的嵌入在旋转域中可能分布不均匀。在这种情况下,假定拥有所有独特的位置对意味着绝对位置信息保持完整。相反,当波长较短时,网络只能获取相对位置信息。
此外,当通过缩放因子 s s s 或使用底数变换 b ′ b' b′ 对所有 RoPE 维度进行拉伸时,所有词元彼此之间变得更加接近,因为旋转量较小的两个向量的点积更大。这种缩放严重削弱了大语言模型理解其内部嵌入之间细微局部关系的能力。假设这种压缩会导致模型对相邻词元的位置顺序感到困惑,从而损害模型的能力。
为解决这个问题,选择完全不对高频维度进行插值,而始终对低频维度进行插值。具体来说:
- 如果波长 λ \lambda λ 远小于上下文大小 L L L,不进行插值
- 如果波长 λ \lambda λ 等于或大于上下文大小 L L L,只希望仅进行插值并避免任何外推(不同于之前的 “NTK感知型” 方法)
- 介于两者之间的维度可以两者兼具,类似于 “NTK感知” 插值法
因此,引入原始上下文大小 L L L 与波长 λ \lambda λ 之间的比率 r = L λ r = \frac{L}{\lambda} r=λL 会更方便。在第 d d d 个隐藏状态中,比率 r r r 与 d d d 的关系如下:
r ( d ) = L λ d = L 2 π b ′ 2 d ∣ D ∣ r(d) = \frac{L}{\lambda_d} = \frac{L}{2\pi b'^{\frac{2d}{|D|}}} r(d)=λdL=2πb′∣D∣2dL
为了如上述定义不同插值策略的边界,引入两个额外参数 α \alpha α、 β \beta β。所有满足 r ( d ) < α r(d) < \alpha r(d)<α 的隐藏维度 d d d,按照缩放因子 s s s 进行线性插值(与 PI 完全一样,避免任何外推),而满足 r ( d ) > β r(d) > \beta r(d)>β 的维度 d d d 则完全不进行插值。定义斜坡函数 γ \gamma γ 如下:
γ ( r ) = { 0 , if r < α 1 , if r > β r − α β − α , otherwise \gamma(r)= \begin{cases}0, & \text { if } r<\alpha \\ 1, & \text { if } r>\beta \\ \frac{r-\alpha}{\beta-\alpha}, & \text { otherwise }\end{cases} γ(r)=⎩ ⎨ ⎧0,1,β−αr−α, if r<α if r>β otherwise
借助斜坡函数,“逐部分NTK” 方法可以描述如下。
定义2 “逐部分NTK” 插值是对 RoPE 的一种修改,使用公式(2)以及以下函数(对 h h h 进行线性斜坡插值可能有其他替代方法,例如对 θ d / s \theta_d/s θd/s 和从波长线性插值转换而来的 θ d \theta_d θd 取调和平均数。这里选择 h h h 是为了实现简单):
g ( m ) = m g(m) = m g(m)=m
h ( θ d ) = ( 1 − γ ( r ( d ) ) ) θ d s + γ ( r ( d ) ) θ d h(\theta_d) = \left( 1 - \gamma(r(d)) \right) \frac{\theta_d}{s} + \gamma(r(d)) \theta_d h(θd)=(1−γ(r(d)))sθd+γ(r(d))θd
α \alpha α 和 β \beta β 的值应根据具体情况进行调整。例如,通过实验发现,对于 LLaMa系列模型, α = 1 \alpha = 1 α=1 和 β = 32 \beta = 32 β=32 是较好的值。
使用本节所述的技术,由此产生的一种改进方法以 “逐部分NTK” 插值法的名称发布。无论是对于非微调模型还是微调模型,这种改进方法的表现都优于之前的 PI 和 “NTK感知”(第 4 节)插值方法。
6、动态缩放 - “动态NTK” 插值法
在许多应用场景中,会对长度从 1 到最大上下文大小不等的序列进行多次前向传播。一个典型的例子是自回归生成,其中序列长度在每一步后增加 1。对于使用缩放因子 s s s 的插值方法(包括 PI、“NTK感知” 和 “逐部分NTK”),有两种应用方式:
- 在整个推理周期中,嵌入层保持固定,包括缩放因子 s = L ′ / L s = L'/L s=L′/L,其中 L ′ L' L′ 是扩展上下文大小的固定值
- 在每次前向传播中,位置嵌入更新缩放因子 s = max ( 1 , l ′ / L ) s = \max(1, l'/L) s=max(1,l′/L),其中 l ′ l' l′ 是当前序列的长度
方式(1)的问题在于,模型在长度小于 L L L 时可能会出现性能折扣,而当序列长度大于 L ′ L' L′ 时性能会急剧下降。但是,通过像方式(2)那样进行动态缩放,它允许模型在达到训练上下文限制 L ′ L' L′ 时性能逐渐下降,而不是立即失效。将这种推理时的方法称为动态缩放方法。当它与 “NTK感知” 插值法结合时,称之为 “动态NTK” 插值法。“动态NTK” 插值法在未经任何微调、在长度 L L L 上预训练的模型( L ′ = L L' = L L′=L)上表现异常出色。
在重复的前向传播中,通常会应用
KV
缓存,以便可以重用先前的键值向量并提高整体效率。在某些实现中,当缓存 RoPE 嵌入时,为了在使用键值缓存的情况下对其进行动态缩放修改,正确的实现应该在应用 RoPE 之前缓存键值嵌入,因为当 s s s 变化时,每个词元的 RoPE 嵌入都会改变。7、YaRN
除了之前的插值技术,在注意力 softmax 操作之前的对数几率(logits)上引入一个温度参数 t t t,无论数据样本和扩展上下文窗口内的词元位置如何,都会对困惑度产生一致的影响。更确切的说,将注意力权重的计算修改为:
s o f t m a x ( q m T k n t ∣ D ∣ ) (4) \mathrm{softmax}\left(\frac{\mathbf{q}_m^T\mathbf{k}_n}{t\sqrt{|\mathcal{D}|}}\right) \tag{4} softmax(t∣D∣qmTkn)(4)
将 RoPE 重新参数化为一组二维矩阵,对于实现这种注意力缩放有明显的好处:可以采用 “长度缩放” 技巧,只需将复数形式的 RoPE 嵌入按相同比例缩放一个常数因子 1 / t \sqrt{1/t} 1/t,就可以对查询向量 q m \mathbf{q}_m qm 和键向量 k n \mathbf{k}_n kn 进行同等缩放。这样,YaRN 可以在不修改代码的情况下有效改变注意力机制。
此外,由于 RoPE 嵌入是预先生成的,并且在所有前向传播过程中都会被重复使用,因此该方法在推理和训练过程中均无额外开销。将其与 “逐部分NTK” 插值法相结合就得到了 YaRN 方法。
定义3 “YaRN方法” 指的是公式(4)中的注意力缩放方法与第 5 节中介绍的 “逐部分NTK” 插值法的结合。
对于 LLaMA 模型推荐使用以下参数值:
1 t = 0.1 ln ( s ) + 1 \sqrt{\frac{1}{t}} = 0.1 \ln(s) + 1 t1=0.1ln(s)+1
3.2.5、训练和推理效率
1、训练成本
由于 DeepSeek-V2 相较于 DeepSeek 67B,每个词元激活的参数更少,所需的浮点运算次数(FLOPs)也更少,从理论上讲,训练 DeepSeek-V2 比训练 DeepSeek 67B 更经济。尽管训练混合专家(MoE)模型会引入额外的通信开销,但通过对算子和通信的优化,DeepSeek-V2 的训练能够实现较高的模型浮点运算利用率(MFU)。在基于 H800 集群的实际训练中,每训练一万亿个词元,DeepSeek 67B 需要 30.06 万个 GPU 小时,而 DeepSeek-V2 仅需 17.28 万个 GPU 小时,即稀疏的 DeepSeek-V2 与密集的 DeepSeek 67B 相比,可节省 42.5% 的训练成本。
2、推理效率
为了高效地将 DeepSeek-V2 部署用于服务,首先将其参数转换为 FP8 精度。此外,对 DeepSeek-V2 执行键值(KV)缓存量化以进一步将其 KV
缓存中的每个元素平均压缩至 6 比特。得益于多层注意力(MLA)以及这些优化措施,实际部署的 DeepSeek-V2 相较于 DeepSeek 67B 所需的 KV
缓存显著减少,因此能够处理更大的批量。基于实际部署的 DeepSeek 67B 服务中的 prompt 和生成长度分布,在配备 8 个 H800 GPU 的单个节点上,DeepSeek-V2 的生成吞吐量超过每秒 5 万个词元,是 DeepSeek 67B 最大生成吞吐量的 5.76 倍。此外,DeepSeek-V2 的 prompt 输入吞吐量超过每秒 10 万个词元。
3.3、对齐
3.3.1、监督式微调
指令调优数据集包含 150 万个实例,包括 120 万个用于提升模型有用性的实例和 30 万个用于增强安全性的实例。与初始版本相比提高了数据质量,以减少模型产生幻觉式回复的情况,并提升其语言表达能力。DeepSeek-V2 进行 2 轮微调,学习率设置为 5 × 1 0 − 6 5×10^{-6} 5×10−6。对于 DeepSeek-V2 Chat(SFT)的评估,除了几个有代表性的多项选择题任务(如 MMLU 和 ARC),主要采用基于生成的基准测试。
3.3.2、强化学习
DeepSeek-V2 通过强化学习(RL)进一步释放 DeepSeek-V2 的潜力并使其与人类偏好对齐。
1、强化学习算法
为了节省 RL 的训练成本,DeepSeek-V2 采用群组相对策略优化(Group Relative Policy Optimization,GRPO),该方法摒弃了通常与策略模型规模相同的评论家模型,而是从组分数中估计基线。具体来说,对于每个问题 q q q,GRPO 从旧策略 π θ o l d \pi_{θ_{old}} πθold 中采样一组输出 o 1 , o 2 , . . . , o G \\{ o_1, o_2, ..., o_G \\} o1,o2,...,oG,然后通过最大化以下目标来优化策略模型 π θ \pi_{\theta} πθ:
J G R P O ( θ ) = E [ q ∼ P ( Q ) , { o i } i = 1 G ∼ π θ o l d ( O ∣ q ) ] 1 G ∑ i = 1 G ( min ( π θ ( o i ∣ q ) π θ o l d ( o i ∣ q ) A i , clip ( π θ ( o i ∣ q ) π θ o l d ( o i ∣ q ) , 1 − ε , 1 + ε ) A i ) − β D K L ( π θ ∣ ∣ π r e f ) ) , \begin{align*} \mathcal{J}_{G R P O}(\theta)=&\mathbb{E}\left[q \sim P(Q),\left\{o_i\right\}_{i=1}^G \sim \pi_{\theta_{o l d}}(O \mid q)\right] \\ &\frac{1}{G} \sum_{i=1}^G\left(\min \left(\frac{\pi_\theta\left(o_i \mid q\right)}{\pi_{\theta_{o l d}}\left(o_i \mid q\right)} A_i, \operatorname{clip}\left(\frac{\pi_\theta\left(o_i \mid q\right)}{\pi_{\theta_{o l d}}\left(o_i \mid q\right)}, 1-\varepsilon, 1+\varepsilon\right) A_i\right)-\beta \mathbb{D}_{K L}\left(\pi_\theta| | \pi_{r e f}\right)\right), \end{align*} JGRPO(θ)=E[q∼P(Q),{oi}i=1G∼πθold(O∣q)]G1i=1∑G(min(πθold(oi∣q)πθ(oi∣q)Ai,clip(πθold(oi∣q)πθ(oi∣q),1−ε,1+ε)Ai)−βDKL(πθ∣∣πref)),
D K L ( π θ ∣ ∣ π r e f ) = π r e f ( o i ∣ q ) π θ ( o i ∣ q ) − log π r e f ( o i ∣ q ) π θ ( o i ∣ q ) − 1 , \mathbb{D}_{K L}\left(\pi_\theta| | \pi_{r e f}\right)=\frac{\pi_{r e f}\left(o_i \mid q\right)}{\pi_\theta\left(o_i \mid q\right)}-\log \frac{\pi_{r e f}\left(o_i \mid q\right)}{\pi_\theta\left(o_i \mid q\right)}-1, DKL(πθ∣∣πref)=πθ(oi∣q)πref(oi∣q)−logπθ(oi∣q)πref(oi∣q)−1,
其中 ε \varepsilon ε 和 β \beta β 是超参数; A i A_i Ai 是根据每组输出对应的奖励 r 1 , r 2 , ⋯ , r G \\{r_1, r_2, \cdots, r_G\\} r1,r2,⋯,rG 计算的收益:
A i = r i − mean ( { r 1 , r 2 , ⋯ , r G } ) std ( { r 1 , r 2 , ⋯ , r G } ) . A_i=\frac{r_i-\operatorname{mean}\left(\left\{r_1, r_2,\cdots, r_G\right\}\right)}{\operatorname{std}\left(\left\{r_1, r_2,\cdots, r_G\right\}\right)}. Ai=std({r1,r2,⋯,rG})ri−mean({r1,r2,⋯,rG}).
2、训练策略
针对推理数据(如代码和数学提示)的强化学习训练展现出与一般数据训练不同的独特特征。例如,模型的数学和编码能力在较长的训练步数内能够持续提升。因此,DeepSeek-V2 采用两阶段强化学习训练策略,首先进行推理对齐,然后进行人类偏好对齐。
r i = R M reasoning ( o i ) . r_i=R M_{\text{reasoning}}\left(o_i\right). ri=RMreasoning(oi).
在第二个人类偏好对齐阶段采用了一个多奖励框架,从有帮助的奖励模型 R M h e l p f u l RM_{helpful} RMhelpful、安全奖励模型 R M s a f e t y RM_{safety} RMsafety 和基于规则的奖励模型 R M r u l e RM_{rule} RMrule 获取奖励。响应 o i o_i oi 的最终奖励为:
r i = c 1 ⋅ R M helpful ( o i ) + c 2 ⋅ R M safety ( o i ) + c 3 ⋅ R M rule ( o i ) , r_i=c_1\cdot R M_{\text{helpful}}\left(o_i\right)+c_2\cdot R M_{\text{safety}}\left(o_i\right)+c_3\cdot R M_{\text{rule}}\left(o_i\right), ri=c1⋅RMhelpful(oi)+c2⋅RMsafety(oi)+c3⋅RMrule(oi),
其中 c 1 、 c 2 c_1、c_2 c1、c2 和 c 3 c_3 c3 是相应的系数。
为了获得在 RL 训练中起关键作用的可靠奖励模型,DeepSeek-V2 仔细收集了偏好数据,并精心进行了质量过滤和比例调整。DeepSeek-V2 基于编译器反馈获得代码偏好数据,基于真实标签获得数学偏好数据。对于奖励模型的训练,使用 DeepSeek-V2 Chat(SFT)初始化奖励模型,并使用 point-wise 或 pair-wise 损失对其进行训练。
3、训练效率优化
对大型模型进行 RL 训练对训练框架提出了很高的要求,需要精心的工程优化来管理 GPU 内存和 RAM 压力,同时保持快速的训练速度。为此,DeepSeek-V2 实施了以下工程优化:
- DeepSeek-V2 提出了一种混合引擎,分别采用不同的并行策略进行训练和推理,以实现更高的 GPU 利用率
- 利用 vLLM 和设置较大的批量大小作为推理后端,以加速推理速度
- 设计了一种将模型卸载到 CPU 并重新加载回 GPU 的调度策略,在训练速度和内存消耗之间实现了近乎最优的平衡
3.3.3、讨论
1、监督微调(SFT)数据量
围绕大规模 SFT 语料库必要性的讨论一直是激烈争论的话题。先前的研究 认为,少于 10,000 个 SFT 数据实例就足以产生令人满意的结果。然而,在 DeepSeek-V2 的实验中,如果使用少于 10,000 个实例,在 IFEval 基准测试中性能显著下降。一种可能的解释是,语言模型需要一定量的数据来培养特定技能。尽管随着模型规模的增加,所需的数据量可能会减少,但它不可能完全消除。DeepSeek-V2 的观察强调了为大语言模型(LLM)配备所需能力时,充足数据的关键必要性。此外,SFT 数据的质量也至关重要,特别是对于涉及写作或开放式问题的任务。
2、强化学习的对齐代价
在人类偏好对齐过程中,DeepSeek-V2 观察到在开放式生成基准测试中,无论是人工智能还是人类评估者给出的分数,都显示出性能有显著提升。然而,DeepSeek-V2 也注意到一种 “对齐代价(alignment tax)” 现象,即对齐过程可能会对某些标准基准测试(如 BBH)的性能产生负面影响。为了减轻这种对齐代价,在强化学习阶段,DeepSeek-V2 在数据处理和改进训练策略方面做出了巨大努力,最终在标准基准测试和开放式基准测试的性能之间实现了可接受的权衡。
3、在线强化学习
在 DeepSeek-V2 的偏好对齐实验中,在线方法显著优于离线方法。因此,DeepSeek-V2 投入了大量精力来实现一个用于对齐 DeepSeek-V2 的在线强化学习框架。
参考文献
- DeepSeek LLM Scaling Open-Source Language Models with Longtermism
- DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models
- DeepSeek-V2: A Strong, Economical, and Efficient Mixture-of-Experts Language Model
- YaRN: Efficient Context Window Extension of Large Language Models
- DeepSeek-V3 Technical Report
- DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning