DualPipe学习记录
Deepseek V3选择仍使用ZeRO-1
采用了16路流水并行和64路专家并行
1.Zero Bubble Pipeline Parallelism

这里B是做梯度计算,W是做梯度更新,往常来说,是所有backward做完,才一次性做所有的参数更新,分开后,即一个b一个w
B对应输入的activation x求导(在模型中可以看做隐藏层结果计算这一步,对隐藏层yi求导),W即对权重w求导,backward过程中,第i-1层的梯度计算,只需要得到第i层输入xi(等价第i-1层输出,yi-1)的梯度,因此第i-1层的B阶段依赖于第i层的B阶段,而只依赖于,在计算完成后即可。
ZeRO-1即使用的zero_bubble策略

ZB1(上图)即峰值显存约为4个micro_batch,ZB2(下图)即峰值显存增加为8个micro_batch
2.专家并行
读Gshard理解专家并行:GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding:链接:2006.16668] GShard: Scaling Giant Models with Conditional Computation and Automatic Sharding
在MoE(mixture of expert)网络中,包含expert部分,门控网络,以及all to all操作, FFN的输入为attention层的输出归一化后的结果。

2.1 门控网络
使用softmax或者sigmoid(选这个要做归一化),用于计算传入的token相对于每个expert的权重,门控函数满足两个目标:
- 负载均衡:直接根据softmax的概率分布选择最优秀的k个专家这种方法容易出现负载不均衡现象,即大多数令牌被分配到少部分专家,而其它专家都没有被分配过,即未训练到。
- 规模效率:在大规模数据(百万级输入)和专家数量(千级专家)下,通过高效的并行设计和资源利用,保持系统整体计算效率和资源利用率的能力。
门控网络中的设计:
-
专家容量:会限制专家处理的令牌数量低于某个阈值,N为训练批次中的总token数,E为专家数,则专家容量设置为O(N/E),当有专家被选中的token数超出阈值时,token会被认为是溢出的,此时g(s,E),即第E个专家对于第s个token的门控网络输出为零向量,也就是设置为未选中该专家,这些溢出的token会根据残差连接和MOE层的输出结合,输入到下一层。因此可以看出来,最终MOE输出的结果和每一层输入的数据的size是保持一致的(在deepseek-v3开源出来的模型代码中,有用counts记录该批次中所有token分配给专家后,每个专家拥有几个token,但是未使用counts做这样约束)
-
本地组分发:将训练批中的所有token均匀分配到G组中的本地组,每组包含S=N/G个令牌,并行处理,每组每个专家能分配的token数为2N/(G・E),E为每组中的专家数。
-
辅助损失:,被添加到模型的总损失函数中,
,k为常数因子,为原损失,中E为专家数,Ce/S 表示输入路由到每个专家上的分数,me表示平均门限分数。
-
随机路由选择:MOE最终输出为选中专家(topk,deepseek-v3给的代码中是6)的加权平均数,在GSshard论文中说的是tok为2时,次优专家以其权重成比例的概率决定是否分配给第二个专家,分配则该token分配了两个专家,否则只分配了一个专家。
2.2 Expert网络
输入为 attention经过标准化后的输出,一般为全连接层
2.3 Attention层
一般就是transformer的attention层
3.Deepseek-v3中的模型层
3.1 基础模型结构
RMSNorm为均方根标准化,公式如3.1所示,其中RMS(x)如公式3.2所示,γ为可学习参数。FFN即为DeepSeekMoE,Attention部分,即为MLA。
公式3.1
公式3.2

3.2 DeepSeekMoE
其中,shared Expert为Worker之间共享的,参数也会同步共享,而Routed Expert则是路由专家,每个Worker独有的,在门控网络部分,即如图的Router部分,Deepseek-V3中引入了无辅助损耗负载均衡,同时使用sigmoid函数作为亲和力得分的计算。具体公式如下:

这里的 的每一项分别为 input hidden 、共享专家输出之和,以及路由专家的加权求和,这里的权重是通过对每个归一化得到的,除了tok个最大的亲和力得分的为,其它均为0,这里的即门限值,即与FFN输出相乘的权重。是第i个专家的质心向量:在特征空间中,一个类别或簇的所有样本的特征向量的平均值,代表该类别/簇的中心位置。
而无辅助损耗负载均衡(Auxiliary-Loss-Free Load Balancing),对应公式如下,在训练步骤的每个批次,会对专家负荷进行监控,每一步结束时,对应的专家超载,则将偏差项减小γ,若负载不足,则增大,其中 γ 是一个称为偏差更新速度的超参数,偏置b只用于负载均衡。

为了防止任何单个序列内的极端不平衡,还采用了一种互补的顺序平衡损耗,

如公式(19)所示,为第i个专家对于第t个token的亲和力得分在所有专家对于该token的亲和力得分下的标准化,而公式(20)得到的即为第i个专家对于所有的token的亲和力得分标准化后的均值,对于,T表示序列中标记的数量,因此该公式表示(整个序列的所有token对于第i个专家的平均最大亲和力得分,以top_k和T值做平均),即路由专家的个数。α是一个超参数,会设置为一个很小的值。
3.3 MTP Modules

4.DualPipe
首先注意,DualPipe算法是专家并行与流水并行的结合。其次dualpipe只需要保证pp_degree(pp_stage_nums)和acc_step(micro_batch_nums)被2整除,不需要acc_step被pp_degree整除。同时bubble和activation memory都不会随着acc_step的数量增加而增加。模型隐藏层层数>=pp_degree
基于多篇专家并行和流水并行论文以及deep-seek-v3代码解读后的总结,包含个人观点,不一定完全正确,仅供参考。
4.1 forward阶段

forward过程中,包括了四个主要的步骤:
- multi-head Latent attention层的计算;
- all-to-all dispatch,信息分发到各个node;为的是计算moe做准备(总是需要把token分发到M个机器上)
- model parallel MOE,模型并行MOE,也就是deepseekMOE;各专家独立执行FFN,即多个Experts,(仅仅前n_dense_layers个为MLP层,其它都为MOE层,一般n_dense_layers=1,在671B模型中,n_dense_layers=3);
- all-to-all combine,M个机器的MOE计算完成之后,将各专家的输出加权求和,返回最终结果。
即 ATTN(F)->DISPATCH(F)->MLP(F)->COMBINE(F)
forward具体数据流:路由专家必须能均分到各个设备上
前向过程的整体流程是输入一个batch的数据,紧接着对每个token进行embedding,接着输入到MLA层进行注意力的计算,接着采用RMSNorm做归一化
4.2 backward阶段
与前向过程反过来求梯度
COMBINE(B)->MLP(B)->DISPATCH(B)->ATTN(B)

而deepseek_V3又将其backward阶段分为了B和W,即B对应输入的activation x求导(在模型中可以看做隐藏层结果计算这一步,对隐藏层yi求导),W即对权重w求导,backward过程中,第i-1层的梯度计算,只需要得到第i层输入xi(等价第i-1层输出,yi-1)的梯度,因此第i-1层的B阶段依赖于第i层的B阶段,而只依赖于,在计算完成后即可。
4.3 编排方式

相比于ZB-PP,除了F,B,W的拆分外,DualPipe还在通信/计算的维度上拆分任务,将F和B过程进一步拆分为:
- 计算:MLP(F),MLP(B),ATTN(F),ATTN(B)
- 通信:DISPATCH(F)DISPATCH(B),COMBINE(F),COMBINE(B)
(猜测:图中紫色的PP部分是在流水并行时的通信)
通过调节GPU的流处理器的分配比例,可以保证通信部分的时间和计算的时间匹配上(即途中的上下两行对齐的效果),从而省去因通信而产生的GPU计算空闲。
在模型层分配的设计上,DualPipe中采用了如下的设计:

这样的设计使得在前向和后向计算时卡间的顺序都可以保持一致,不同卡上的同一组参数其更新时间也可以保持一致(由图中的上下对称性可知)。同时从两端输入批次进行训练。
以下是dualpipe的编排情况,如下图所示:

其中:
对应

这样做可以在执行过程中,完全隐藏: all to all和 PP 通信
选用all to all 的原因
- 动态路由的不可预测性,无法提前确定通信目标。
- 批次内专家覆盖的全局性,导致设备间需交换全量数据。
- 硬件优化的集体通信效率,远高于动态点对点通信。
- 反向传播的对称性需求,确保梯度正确传递。
5.1 DualPipe的

红色箭头和蓝色箭头分别代表一个micro_batch,因为每个设备上保留了两个模型块,所以分别是从设备0 和设备 7 对称开始,在某个阶段,在同一个设备上,出现一个模型块做forward,另一个模型块做backward,并且编排后可重叠计算与通信。