Run MXNet on Multiple CPU/GPUs with Data Parallelism
Data Parallelism vs Model Parallelism
默认情况下,MXNet使用数据并行在多个设备上划分工作负载。假设有n个device。然后每个device都会收到一份完整模型的副本,并根据1/n的数据对其进行训练。梯度和更新模型等结果通过这些设备进行通信。
MXNet还支持模型并行。在这种方法中,每个设备只保留模型的一部分。当模型太大而无法安装到单个设备上时,这是有用的。作为一个例子,请参阅这个教程,它展示了如何使用模型并行性来训练多层LSTM模型。而本教程将重点介绍数据并行。
Multiple GPUs within a Single Machine
Workload Partitioning - 负载分区
默认情况下,MXNet在可用的gpu之间均匀地划分数据批。假设批量大小为b,并且假设有k个GPU,那么在一次迭代中,每个GPU将对b/k示例执行正向和反向操作。然后在更新模型之前,对所有gpu上的梯度求和。
使用方法:
import mxnet as mx module = mx.module.Module(context=[mx.gpu(0), mx.gpu(2)], ...)
高级用法:
如果可用的gpu不是同一档次的,那么我们可以相应地划分工作负载。例如,如果GPU 0比GPU 2快3倍,那么我们可以使用work load选项work_load_list=[3,1],参阅Module以了解更多详细信息。
如果所有其他超参数相同,使用多个GPU的训练应产生与在单个GPU上训练相同的结果。在实际应用中,由于I/O(随机顺序或其他增强)的随机性、不同种子的权重初始化和CUDNN,结果可能会显示出很小的差异。
可以通过支持数据通信的MXNet模块KVStore来控制在哪些设备上聚合梯度,以及在哪些设备上更新模型。可以使用mx.kvstore.create(type)以获取实例或使用程序标志--kv-store type。
type值常用的有两个:
- loacl:所有梯度都被复制到CPU内存中,权重在那里更新。
- device:梯度聚合和权重更新都在gpu上运行。通过此设置,KVStore还尝试使用GPU对等通信,这可能会加速通信。注意此选项可能导致更高的GPU内存使用率。
当使用大量的gpu时,例如>=4,建议使用device以获得更好的性能。
Distributed Training with Multiple Machines
多机分布式训练
KVStore还支持在多台机器上运行的许多选项。
- dist_sync与local类似,但有一个主要的区别。使用dist_sync,batch size为每台机器上使用的批大小。因此,如果有n台机器,并且我们使用批大小b,那么dist_sync的行为与批大小n*b类似。
- dist_device_sync与dist_sync类似。它们之间的区别在于,dist_device_sync在gpu上聚合梯度并更新权重,而dist_sync在CPU内存上执行此操作。
- dist_async执行异步更新。当从任何机器接收到梯度时,权重都会更新。同一个权重不会同时有两个更新。更新顺序并不能保证。
KVStore API