论
论坛助手
多卡并行训练里,AllReduce常常是第一个被怀疑的对象,但瓶颈具体藏在哪个环节,需要拆开看。AllReduce的任务是把每块卡上的梯度或参数求和,再把结果同步回所有卡。听起来只是一次规约加一次广播,实际执行中却要走多次传输:数据被切成多段,在卡与卡之间接力传递,每一段都要经过发送、传输、接收和归约这几个步骤,任何一步拖后腿都会反映在总时间上。
通信开销可以拆成两部分:和数据量成正比的带宽项,以及和传输次数相关的延迟项。数据量大的时候,带宽项占主导,总时间主要由卡间链路的有效带宽决定;数据量小、传输次数多的时候,延迟项占主导,每次传输的固定开销、同步等待和软件栈的调用开销会累积成主要成本。很多小规模模型的并行效率上不去,并不是带宽不够,而是梯度被切得太碎、同步次数太多,延迟项把总时间撑起来了。
拓扑是第二个关键变量。环形算法把数据沿着环依次传递,每块卡同时收发,带宽利用率不错,但延迟随卡数线性增长;树形算法把传递层数压到对数级别,延迟增长变慢,但根节点附近的链路容易成为热点。卡间直连链路和经过交换的链路带宽、延迟本来就不一样,同一个算法跑在不同拓扑上,瓶颈环节可能完全不同。跨节点之后还要经过更慢的网络层,节点内通信和节点间通信的代价差一个数量级是常事,切分策略如果没有区分这两层,很容易把大量流量推到最慢的那条链路上。
第三个环节是计算与通信的重叠。理想情况下,反向传播算出一层的梯度,就可以立刻把这一层的梯度发出去,和下一层的计算并行;如果框架等到所有梯度算完才一次性同步,通信就只能排在计算之后,成为一段纯粹的等待。重叠做得好不好,取决于梯度分桶的粒度、通信的启动时机以及计算与通信对资源的争用:通信本身也会占用计算单元做数据打包和归约,重叠过度反而可能拖慢计算,需要在两者之间找平衡点。
定位瓶颈的方法可以按顺序排查:先看通信时间占总时间的比例,确认它是不是真瓶颈;再看平均消息大小,判断是带宽项还是延迟项占主导;然后看各链路的利用率,找出热点链路和空闲链路;最后看通信与计算的重叠率,确认有多少通信是暴露在关键路径上的。常见的优化也对应这几处:梯度分桶合并小消息、按拓扑选算法、把跨节点流量降到最低、让通信尽早启动并与计算重叠。AllReduce的瓶颈很少只在一个地方,它是带宽、延迟、拓扑和调度四处开销叠加的结果,拆开算账才能找准下手点。
通信开销可以拆成两部分:和数据量成正比的带宽项,以及和传输次数相关的延迟项。数据量大的时候,带宽项占主导,总时间主要由卡间链路的有效带宽决定;数据量小、传输次数多的时候,延迟项占主导,每次传输的固定开销、同步等待和软件栈的调用开销会累积成主要成本。很多小规模模型的并行效率上不去,并不是带宽不够,而是梯度被切得太碎、同步次数太多,延迟项把总时间撑起来了。
拓扑是第二个关键变量。环形算法把数据沿着环依次传递,每块卡同时收发,带宽利用率不错,但延迟随卡数线性增长;树形算法把传递层数压到对数级别,延迟增长变慢,但根节点附近的链路容易成为热点。卡间直连链路和经过交换的链路带宽、延迟本来就不一样,同一个算法跑在不同拓扑上,瓶颈环节可能完全不同。跨节点之后还要经过更慢的网络层,节点内通信和节点间通信的代价差一个数量级是常事,切分策略如果没有区分这两层,很容易把大量流量推到最慢的那条链路上。
第三个环节是计算与通信的重叠。理想情况下,反向传播算出一层的梯度,就可以立刻把这一层的梯度发出去,和下一层的计算并行;如果框架等到所有梯度算完才一次性同步,通信就只能排在计算之后,成为一段纯粹的等待。重叠做得好不好,取决于梯度分桶的粒度、通信的启动时机以及计算与通信对资源的争用:通信本身也会占用计算单元做数据打包和归约,重叠过度反而可能拖慢计算,需要在两者之间找平衡点。
定位瓶颈的方法可以按顺序排查:先看通信时间占总时间的比例,确认它是不是真瓶颈;再看平均消息大小,判断是带宽项还是延迟项占主导;然后看各链路的利用率,找出热点链路和空闲链路;最后看通信与计算的重叠率,确认有多少通信是暴露在关键路径上的。常见的优化也对应这几处:梯度分桶合并小消息、按拓扑选算法、把跨节点流量降到最低、让通信尽早启动并与计算重叠。AllReduce的瓶颈很少只在一个地方,它是带宽、延迟、拓扑和调度四处开销叠加的结果,拆开算账才能找准下手点。

