Skip to content

Commit 5ac3980

Browse files
luomaiRudysheeppig
andauthored
Fix AllGather. (#442)
* Update collective.md * Update overview.md --------- Co-authored-by: Tanzhipeng <[email protected]>
1 parent ff453ad commit 5ac3980

File tree

2 files changed

+6
-6
lines changed

2 files changed

+6
-6
lines changed

chapter_distributed_training/collective.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@
4242
#### Gather
4343
Gather算子可以将全部设备的数据全部收集(Gather)到编号为$i$的设备上。 :numref:`ch10-collective-operators`展示了设备1调用Gather来收集全部设备的数据的初始和结束状态。
4444

45-
在收集函数(Gather Function)符合结合律和交换律的情况下,可以通过将其设为Reduce算子中的$f$来实现Gather算子。但是,在这种情况下,无论是基于链表还是数组的实现,在每一步的Reduce操作中$f$的时间复杂度和输出长度$l$都发生了改变。因此,Gather的时间复杂度是$a \times \log p + (p-1) \times b \times l$。这是因为在算法的每一阶段$t$,传输的信息长度为$ 2^t \times l$。
45+
在收集函数(Gather Function)符合结合律和交换律的情况下,可以通过将其设为Reduce算子中的$f$来实现Gather算子。但是,在这种情况下,无论是基于链表还是数组的实现,在每一步的Reduce操作中$f$的时间复杂度和输出长度$l$都发生了改变。因此,Gather的时间复杂度是$a \times \log p + (p-1) \times b \times l$。这是因为在算法的每一阶段$t$,传输的信息长度为$2^{t} \times l$。
4646

4747
#### AllGather
4848
AllGather算子会把收集的结果分发到全部的设备上。 :numref:`ch10-collective-operators`展示了设备1,设备2和设备3共同调用AllGather的初始和结束状态。
4949

50-
在这里,一个简单的方法是使用Gather和Broadcast算子把聚合结果先存到编号为1的设备中,再将其广播到剩余的设备上。这会产生一个$a \times \log p + (p-1) \times b \times l + (a+p \times l \times b) \times \log p$的时间复杂度,因为在广播时,如果忽略链表/数组实现所带来的额外空间开销,每次通信的长度为$pl$而不是$l$。简化后,得到了一个$a \times \log p + p \times l \times b \times \log p$ 的时间复杂度。在一个基于超立方体\footnote{可参考网址为:\url{https://link.springer.com/book/10.1007/978-3-030-25209-0}}的算法下,可以将其进一步优化到和Gather算子一样的时间复杂度$a \times \log p + (p-1) \times b \times l$,由于篇幅问题此处便不再赘述。
50+
在这里,一个简单的方法是使用Gather和Broadcast算子把聚合结果先存到编号为1的设备中,再将其广播到剩余的设备上。这会产生一个$a \times \log p + (p-1) \times b \times l + (a+p \times l \times b) \times \log p$的时间复杂度,因为在广播时,如果忽略链表/数组实现所带来的额外空间开销,每次通信的长度为$pl$而不是$l$。简化后,得到了一个$a \times \log p + p \times l \times b \times \log p$ 的时间复杂度。在一个基于[超立方体](https://link.springer.com/book/10.1007/978-3-030-25209-0)的算法下,可以将其进一步优化到和Gather算子一样的时间复杂度$a \times \log p + (p-1) \times b \times l$,由于篇幅问题此处便不再赘述。
5151

5252
#### Scatter
5353

chapter_distributed_training/overview.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
分布式训练系统主要为了解决单节点的算力和内存不足的问题。
66

7-
![对比机器学习模型参数量增长和计算硬件的算力增长](../img/ch09/ch10-computation-increase.png)
8-
:width:`800px`
9-
:label:`ch10-computation-increase`
10-
117
#### 算力不足
128

139
单处理器的算力不足是促使人们设计分布式训练系统的一个主要原因。一个处理器的算力可以用**每秒钟浮点数操作**(Floating Point Operations Per Second,FLOPS)来衡量。:numref:`ch10-computation-increase`分析了机器学习模型对于算力的需求以及同期处理器所提供算力在过去数年中变化。其中,用千万亿运算次数/秒—天(Petaflop/s—day )这一指标来衡量算力。这个指标等价于每秒$10^{15}$次神经网络操作执行一天,也就是总共大约$10^{20}$次计算操作。如图所示,根据摩尔定律(Moore's Law),中央处理器的算力每18个月增长2倍。虽然计算加速卡(如GPU和TPU)针对机器学习计算提供了大量的算力。这些加速卡的发展最终也受限于摩尔定律,增长速度停留在每18个月2倍。而与此同时,机器学习模型正在快速发展。短短数年,机器学习模型从仅能识别有限物体的AlexNet,一路发展到在复杂任务中打败人类的AlphaStar。这期间,模型对于算力需求每18个月增长了56倍。解决处理器性能和算力需求之间鸿沟的关键就在于利用分布式计算。通过大型数据中心和云计算设施,可以快速获取大量的处理器。通过分布式训练系统有效管理这些处理器,可以实现算力的快速增长,从而持续满足模型的需求。
1410

11+
![对比机器学习模型参数量增长和计算硬件的算力增长](../img/ch09/ch10-computation-increase.png)
12+
:width:`800px`
13+
:label:`ch10-computation-increase`
14+
1515
#### 内存不足
1616

1717
训练机器学习模型需要大量内存。假设一个大型神经网络模型具有1000亿的参数,每个参数都由一个32位浮点数(4个字节)表达,存储模型参数就需要400GB的内存。在实际中,我们需要更多内存来存储激活值和梯度。假设激活值和梯度也用32位浮点数表达,那么其各自至少需要400GB内存,总的内存需求就会超过1200GB(即1.2TB)。而如今的硬件加速卡(如NVIDIA A100)仅能提供最高80GB的内存。单卡内存空间的增长受到硬件规格、散热和成本等诸多因素的影响,难以进一步快速增长。因此,我们需要分布式训练系统来同时使用数百个训练加速卡,从而为千亿级别的模型提供所需的TB级别的内存。

0 commit comments

Comments
 (0)