根据《90分钟PaddlePaddle快速上手》整理。
分布式训练
两种模式:模型并行、数据并行
-
模型并行:
分布式系统中的不同机器或设备(CPU/GPU)负责网络的不同部分,计算和参数都可能分配在不同的节点上。 -
数据并行:
分布式系统中的不同机器都有一份完整的模型副本,每台机器分配到不同的数据,将所有机器的运算结果按照某种方式合并。 -
paddle目前主要支持数据并行的训练方式。
paddle数据并行的两种模式:- parameter server模式
有多个pserver进程和多个trainer进程
每个pserver进程会保存一部分的模型参数,接收一个从trainer发送的梯度并更新这些模型的参数。
每个trainer进程会保存一份完整的模型,并使用一部分数据进行训练,然后像pserver发送梯度,最后从pserver拉取更新后的参数。 - Colletive模式
没有pserver进程,每个trainer进程都保存一份完整的模型参数,完成梯度计算之后通过trainer之间的相互通讯,Reduce梯度数据到所有节点,然后每个节点再各自完成梯度更新。
更适合模型体积较大,需要使用同步训练和GPU训练。
- parameter server模式
-
Collective(NCCL2)模式注意事项:
要确保每个节点训练等量的数据,防止最后一轮训练中任务不退出。通常有两种方式:- 随机采样一些数据,补全分配到较少数据的节点上。(推荐)
- 在python代码中,每个节点每个pass只训练固定的batch数,如果这个节点数据较多,则不训练这些多出来的数据。
如果系统中有多个网络设备,需要手动指定NCCL2使用的设备,假设需要使用eth2为通讯设备,需要设定如下环境变量:
export NCCL_SOCKET_IFNAME=eth2
分布式程序转换器
Paddle Fluid提供一个分布式程序转换器(DistributeTranspiler)来将单机网络转换为分布式训练网络。
#定义单机网络
model()
#配置分布式程序转换器
t = fluid.DitributeTranspiler()
#生成计算图
t.transpile(
trainer_id = trainer_id,
preserver = pserver_endpointers,
trainers = trainers
)
#根据自己的角色启动parameter_server
#pserver 计算图
if training_role == "PSERVER":
pserver_prog = t.get_pserver_program(current_endpoint)
startup_prog = tf.get_startup_program(current_endpoint, pserver_prog)
exe.run(start_prog)
exe.run(pserver_prog)
#根据自己的角色启动trainer
#trainer 计算图
else training_role "TRAINER":
trainer_prog = t.get_trainer_program()
exe.run(fluid.default_startup_program())
train_loop()
配置示例:
role = "PSERVER"
trainer_id = 0
Pserver_endpoints = "192.168.1.1:6170, 192.168.1.2:6170"
Current_endpoint = "192.168.1.1:6170"
trainers = 4
具体参数和配置参考官方文档。