逃也逃不掉,并行与分布式肯定是要整起来的。本系列主要来自官方教程学习笔记。
从基本的并行化原理上来讲,分布式深度学习分为数据并行(Data Parallelism
)以及模型并行(Model Parallelism
)。
数据并行指每个设备有神经网络模型的完整拷贝并独立处理其输入数据流、每次迭代后将更新归并到参数服务器(Parameter Server
)上;
数据并行
在参数服务器策略中,worker
和parameter
进程的数量是可变的,每个worker
进程在GPU
内存中维护自己的模型独立副本。梯度更新计算如下:
- 在接收到开始信号后,每个工作进程为其特定的批处理片积累梯度。
- 这些
worker
将更新发送到参数服务器。 - 参数服务器会一直等待,直到它们拥有所有
worker
更新,然后对它们负责的梯度更新参数空间的那部分梯度求平均。 - 梯度更新被分散到
worker
上,然后将它们加起来,应用到内存中模型权重的副本上(从而保持worker模型同步)。 - 一旦每个
worker
都应用了更新,新的一批训练就可以开始了。
但是会要求n
个worker
的网络调用,速度取决于计算最慢的那个worker
。
更现代的分布式培训策略废除了参数服务器,在DistributedDataParallel
并行策略中,每个进程都是一个工作进程。每个进程仍然在内存中维护模型权重的完整副本,但是批处理片梯度更新现在是同步的,并且直接在工作进程本身上平均。这是使用从高性能计算领域借来的技术来实现的:全归约算法(all-reduce algorithm
)。
模型并行
模型并行指每个设备有模型的一部分参数、多个设备共同来处理一条输入数据流并更新各自部分的模型参数。
依据PyTorch
的1.6.0
版本,Pytorch
的并行包主要可以分为三类:
- 分布式数据并行训练(Distributed Data-Parallel Training (
DDP
))
分布式数据并行训练,在单个程序中将数据分布到多个GPU
上训练的一种范式。在DDP
中,模型会被复制到不同的进程中去,这些被复制到不同进程中的模型会被喂不同的数据样本。DDP
主要关心的是计算的梯度之间的通信,以此来保证这些复制的模型版本之间的同步关系,来保证加速训练。
- 基于
RPC
的分布式训练(RPC-Based Distributed Training (RPC
) )
基于RPC
的分布式训练是为了支持无法采用分布式数据并行这种方式而开发的一种泛化能力更强的训练结构。像分布式pipeline并行(distributed pipeline parallelism
),参数服务器并行(parameter server paradigm
),结合DDP
和其它训练的并行计算。
- 聚合通信(Collective Communication (c10d))
Collective Communication (c10d)
库支持在一个组内的各个进程之间发送 tensors
。它提供了集体通信API
(如all_reduce
和all_gather
)和P2P
通信API
(如send
和isend
)。
DDP
和RPC
(ProcessGroup Backend)从v1.6.0开始就建立在c10d
上,其中前者使用聚合通信,后者使用P2P
通信。
数据并行训练
pytorch
为数据并行训练提供了几种方式:
单机多GPU的DataParallel方式:
torch.nn.DataParallel
torch.nn.DataParallel
这种方式能够以较简单的方式实现单机多GPU
的并行训练,但是它的性能并不好,因为在多个GPU
上的数据最后汇总会有Python
解释器的GIL
导致的性能开销。因此官方推荐使用DistributedDataParallel
。
单机多GPU的DistributedDataParallel方式:
torch.nn.parallel.DistributedDataParallel
与DataParallel
相比,DistributedDataParallel
要求更多一步init_process_group
。
DistributedDataParallel
和 之间的区别DataParallel
是:DistributedDataParallel
使用multiprocessing
,即为每个GPU
创建一个进程,而DataParallel
使用多线程。因此DDP
的方式复制的各个模型之间没有GIL
的关系。关于DDP
更详细的资料,可以参考论文:PyTorch Distributed: Experiences on Accelerating Data Parallel Training
多机器的情况下只能使用DistributedDataParallel
方式。如果您使用DistributedDataParallel
,则可以使用torch.distributed.launchlaunch
程序来启动程序。参考Use nn.parallel.DistributedDataParallel instead of multiprocessing or nn.DataParallel
通用的分布式训练
在实际的应用场景中,单机并行的这种方式还是不太够用,需要上分布式。比如像parameter server paradigm
,distributed pipeline parallelism
,还有像强化学习中智能体的并行等方式。torch.distributed.rpc
就是用来解决这个问题。