互联网络(二)

什么是伴随通信算子

在神经网络的自动微分过程中,通信算子有一个特别重要的规律:

如果前向传播过程中使用通信算子 $A$,存在: $$ y = Ax $$

根据链式法则,反向传播时:

$$ \nabla x = A^\top \nabla y $$ [1]

其中 $\nabla y=\frac{\partial L}{\partial y}$, $\nabla x=\frac{\partial L}{\partial x}$

其中 $A^\top$ 就是 $A$ 的伴随通信算子。

常用通信算子及其伴随算子汇总如下[2]

前向通信算子 伴随/反向通信算子 说明与简单举例
AllReduce AllReduce 所有 rank 的张量先求和/平均,再把结果发给所有 rank。反向仍是全局规约。例:数据并行中,各 GPU 计算本地梯度后用 AllReduce 得到全局平均梯度。
Broadcast Reduce 前向是一到多,反向是多到一。例:rank 0 将参数 W 广播给所有 GPU;反向时各 GPU 上关于 W 的梯度需要 Reduce 回 rank 0。
Reduce Broadcast 前向是多到一,反向是一到多。例:多个 GPU 的 loss 被 Reduce 到 rank 0;反向时 rank 0 上的梯度信号需要 Broadcast 回其他 rank。
Scatter Gather 前向是把一个完整张量切分后分发到多个 rank;反向要把各分片梯度收集回来。例:rank 0 将输入 batch 切成多份 Scatter 给各 GPU;反向时各 GPU 的输入梯度用 Gather 收回。
Gather Scatter 前向是多个 rank 的数据收集到一个 rank;反向要把梯度切开再分发回去。例:评估时各 GPU 的预测结果 Gather 到 rank 0;若参与反向,rank 0 上的梯度需 Scatter 回各 GPU。
AllGather ReduceScatter 前向是各 rank 的分片被收集成完整张量,并且每个 rank 都拿到完整结果;反向时完整梯度需要规约后再按分片分发。例:FSDP 中前向前用 AllGather 收集完整参数,反向后用 ReduceScatter 得到各自的梯度分片。
ReduceScatter AllGather 前向是先对所有 rank 的张量规约,再把结果切分给各 rank;反向需要把分片梯度重新收集成完整梯度。例:ZeRO/FSDP 中用 ReduceScatter 同步并切分梯度;反向对应路径需要 AllGather 汇集分片梯度。
AllToAll AllToAll 前向是所有 rank 之间互相交换分片;反向通常也是一次相反方向或相反维度的 AllToAll。例:MoE 中先用 AllToAll 把 token 分发给不同专家,反向时再用 AllToAll 把梯度送回原 token 所在 rank。
Send Recv 前向点对点发送数据,反向对应接收梯度。例:流水线并行中 stage 0 前向 Send 激活到 stage 1;反向时 stage 0 需要 Recv 来自 stage 1 的激活梯度。
Recv Send 前向点对点接收数据,反向对应发送梯度。例:流水线并行中 stage 1 前向 Recv stage 0 的激活;反向时 stage 1 需要 Send 激活梯度回 stage 0。

伴随通信算子的作用

当前向传播使用通信算子 $A$ 时,反向传播就必须使用伴随通信算子 $A^\top$。

然而,这似乎有一个例外,如下图的 tensor parallelism 架构

根据论文中的说法,有:

  • $g$ 正向传播使用 all-reduce,反向传播使用 identity。
  • $f$ 正向传播使用 identity,反向传播使用 all-reduce。

然而,以 $g$ 举例,在它反向传播过程中使用的所谓 "identity",其实就是 all-reduce:即每台设备 $i$ 都收到所有上游梯度 $\nabla Z$ 的总和。只是上游梯度 $\nabla Z$ 已经汇总到了一台设备上,所以表现为所谓的 "identity"。

所以,在 Megatron-LM 论文中的表述,并不算是纯粹通信算子的描述。

评论