并行训练
预训练阶段。让模型在超大规模的通用数据集上进行无监督或者自监督训练,以掌握基础的语言规律、世界知识或图像特征的过程。
关于集体通信
集体通信 collective communication 是分布式训练中一系列 GPU 间的数据操作。
All-Reduce
Before:
GPU0: [1, 2]
GPU1: [3, 4]
After:
GPU0: [4, 6]
GPU1: [4, 6]
每张 GPU 的对应元素进行 reduction,然后每张 GPU 都得到完整结果。适用于梯度同步等场合。
All-Gather
Before:
GPU0: [A]
GPU1: [B]
After:
GPU0: [A, B]
GPU1: [A, B]
每张 GPU 原本只保存部分数据,经过 All-Gather 后,所有 GPU 都得到完整数据。ZeRO-3 临时获取完整参数的时候有用到。
Reduce-Scatter
Before:
GPU0: [1, 2]
GPU1: [3, 4]
Reduce:
[4, 6]
After:
GPU0: [4]
GPU1: [6]
先做 reduction,然后把结果切分给不同 GPU。ZeRO 梯度同步的时候用到。
All-to-All
Before:
GPU0: [A0, A1]
GPU1: [B0, B1]
After:
GPU0: [A0, B0]
GPU1: [A1, B1]
每张 GPU 把自己的数据切分成若干块,分别发送给其他 GPU,同时接收其他 GPU 发来的数据块。
DP,TP 和 PP
总之就是模型越来越大,预训练的时候单个 GPU 显存不够,要找各种方法把超级大的 Transformer 装到一堆 GPU 上。
Data Parallelism
DP 的话就是每张 GPU 放一份完整模型,把训练数据切成多个 mini batch,每个 GPU 负责一个,然后同步 gradient(叫做 all-reduce gradients)。
Model Parallelism: TP
但是模型已经大到一张 GPU 已经装不下了,所以要想办法把模型本身也给切了,分到多个 GPU 上。切模型就是 Model Parallelism(MP)。
有两种切法,一种是在 layer 里面内切,叫做
矩阵乘法
也可以横切
如果在一些机器学习框架中看到参数 TP=8 的话,意思就是把 layer 切成 8 份。
不过 TP 有个问题就是需要频繁的 GPU 间通信,毕竟每一层都被切成几份放在不同 GPU 上,做 all-reduce、all-gather、reduce-scatter 这些拼结果的操作都依赖通信。所以一个实用的原则是做 TP 的训练尽量放在一个 node 里面(一般同一个 node 里的 GPU 有高速通信比如 NVLink)。
Model Parallelism: PP
另一种切法是按 layer 来切,每张 GPU 负责若干层 layers,这叫做
就像这样:
time →
GPU0: M1 M2 M3 M4 M5 ...
GPU1: M1 M2 M3 M4 ...
GPU2: M1 M2 M3 ...
GPU3: M1 M2 ...
GPU idle 的区域被称为
1F1B Megatron
Deepak Narayanan et al., “Efficient Large-Scale Language Model Training on GPU Clusters Using Megatron-LM,” SC 2021.
这篇论文干了什么呢,就是设计了一个算法,把 DP、TP 和 PP 全用上,也就是所谓的 3D Parallelism。并且还研究了各种 pipeline 的调度,提出了 interleaved(一张 GPU 负责不连续的 layer chunk)1F1B(forward batch 和 backward batch 交替处理)调度算法,显著缩减了 pipeline bubble,提高 throughput。他们试过最后在 3072 张 A100 上训了一个 1T 的模型(壕。。。)。
GPipe
ZeRO
想起三年前被 ZeRO 和 OOM 支配的恐惧。。。
Samyam Rajbhandari et al., “ZeRO: Memory Optimizations Toward Training Trillion Parameter Models,” SC 2020.
ZeRO 主要是针对 DP 的。DP 的话,每张 GPU 都要拥有一份模型状态的完整拷贝,实在是太浪费了。
ZeRO-1 先把 optimizer states(比如说 Adam 的 moment)给切了,每张 GPU 只存
ZeRO-2 进一步把 gradients 也给切了。它可以省 8x 显存。ZeRO-1 和 ZeRO-2 可以做到和普通 DP 大体相同的通信 volume。
ZeRO-3 再把参数也给切了。这下模型状态的所有东西都被切成了
那么有人会问了,那都是切模型,为什么 ZeRO-3 属于 DP,而 TP 属于 MP 呢?因为 TP 的话,一个矩阵乘法是真的被分给多个 GPU 共同计算的,而 ZeRO-3 只是在切模型状态的存储,真的在算 layer 的时候,每张 GPU 会通过 all-gather 暂时得到完整的模型状态,各自做各自的计算。简单来说,ZeRO-3 只切 storage,而 TP 把 computation 也给切了。
ZeRO-3 还设计了通信的调度,据说只会增加大约一半的通信 volume。