由于pytorch的DataLoader的部分初始化参数之间存在互斥关系,如果自定义了sampler,那么这些参数batch_size、shuffle、batch_sampler、drop_last都必须使用默认值。所以我们重写batch_sampler,将分布式的sampler作为参数传入新构造的batch_sampler。
Horovod内部实现了广播操作,使模型在所有工作进程中实现一致性初始化。在加载模型权重的时候,只要在rank0的机器上加载,然后使用广播机制,就可以将参数同步到其他机器上进行权重初始化。
在训练过程中,计算损失函数时需要涉及到allreduce操作,将所有worker的损失规约,然后再进行梯度传播。最后在保存模型时,只要指定一台机器保存模型即可。
五、实验结果
分布式训练除了训练阶段的通信要尽可能的快,数据的IO也是需要考虑的地方。扫一扫识物的检索模型是基于大量的图像数据训练的。在进行分布式训练时,每个机器都需要能够读取这些训练数据,图片文件存到微信自研分布式存储系统上。
在训练时,分布式训练的加速比和GPU数目正相关。在mnist数据集上基于resnet50测试分布式训练运行时间, 单机运行mnist 100个epoch需要78min,多机使用4块GPU训练100个epoch 23min。
在我们实际项目的模型训练中,基于分布式训练可以将以往需要训练5天甚至一周的时间缩短到1天以内,在同样的时间内,算法开发者可以探索更多的实验,快速反馈更新,大大提高了算法研发的效率。
六、总结与展望
目前扫一扫识物在微信自研训练平台上能够成功进行分布式训练,但仍然存在以下问题:如何能够高效地存放读取大量图片小文件,减少IO的耗时。道阻且长,行则将至,在后续工作中我们将针对这些问题进行探索。
参考文献:
[1] Li M, Andersen D G, Park J W, et al. Scaling distributed machine learning with the parameter server[C]//11th {USENIX} Symposium on Operating Systems Design and Implementation ({OSDI} 14). 2014: 583-598.
[2]https://mpitutorial.com/tutorials/
[3]https://developer.nvidia.com/nccl
[4]https://eng.uber.com/horovod/