Caffe2 Synchronous SGD

以下内容翻译自 Synchronous SGD

利用多个GPU或机器来训练模型的方法有很多。而同步SGD(使用了Caffe2的数据并行模型)是最简单并且最容易理解的:每个GPU以完全相同的代码处理其在mini-batch中分得的数据。在mini-batch之间对每个GPU的梯度求均值,并且每个GPU以完全相同的方式执行参数更新。在任何时间点上,参数在每个GPU上具有相同的值。同步SGD的另一种理解是它允许增加mini-batch大小。使用8个GPU,每卡运行批量为32,相当于一个GPU运行256大小的mini-batch。

编程指南

示例代码:

模块caffe2.python.data_parallel_model完成模型的并行。模型必须使用ModelHelper创建,例如 model_helper.ModelHelper

为单个GPU构建ResNet-50,然后通过Parallelize_GPU用于多GPU的完整教程可以看这里。以下是Resnet-50 example code的示例:

from caffe2.python import data_parallel_model, model_helper

train_model = model_helper.ModelHelper(name="resnet50")

data_parallel_model.Parallelize_GPU(
      train_model,
      input_builder_fun=add_image_input,
      forward_pass_builder_fun=create_resnet50_model_ops,
      param_update_builder_fun=add_parameter_update_ops,
      devices=gpus,  # list of integers such as [0, 1, 2, 3]
      optimize_gradient_memory=False/True,
  )

关键是将模型创建代码分成三个函数。这些函数就像不做并行化一样构造操作符。

  • input_builder_fun:创建向网络提供输入的操作符。注意:请小心,每个GPU读取唯一的数据(他们不应该读取相同的数据)!通常他们应该共享相同的读取器来防止这种情况发生,或者数据应该按照每个读取器提供唯一数据的方式进行批处理。签名function(model)
  • forward_pass_builder_fun:该函数将操作符、层添加到网络中。它应该返回用于计算损失梯度的loss-blob列表。该函数还传递了一个内部计算的loss_scale参数,用于缩放损失从而和GPU数量相匹配。签名function(model, loss_scale)
  • param_update_builder_fun:该函数添加用于参数梯度更新的运算符。例如,简单的SGD更新、动量参数更新。你还应该在这里实例化学习率和迭代blob。如果不学习而仅做前向,则可以将此功能设置为无。签名function(model)
  • optimize_gradient_memory:如果启用,memonger 模块用于通过尽可能共享blob来优化梯度运算符的内存使用情况。 这可以节省大量的内存,并可以帮助您运行更大的批次。

注意

  • 请勿直接访问model_helper.params,而是使用 model_helper.GetParams(),它只返回当前GPU的参数。

实现说明

在底层,Caffe2使用DeviceScopeNameScope来区分每个GPU的参数。每个参数都以名称范围(例如“gpu_0/”或“gpu_5/”)作为前缀。上述函数创建的每个blob根据DeviceScope正确分配给GPU,而DeviceScope通过data_parallel_model.Parallelize_GPU函数设置。检查模型时,只需调用model.GetParams("gpu_0")即可获取前缀为“gpu_0/”的参数。我们使用CUDA NCCL-ops来同步机器之间的参数。

性能

性能将取决于型号,但是对于Resnet-50,我们在8颗M40 GPU上实现了约7倍加速。

进一步阅读和示例

Gloo是一个Facebook孵化器项目,可帮助管理多主机、多GPU的机器学习应用程序。

Resnet-50示例代码包含使用 rendezvous 的示例代码。该功能在data_parallel_model module模块中但此同步SGD示例中未明确使用。

Deep Residual Learning for Image Recognition是Resnet-50的研究源头,其中他们在ImageNet数据集上利用残差学习探索了构建更深层、更深层,直至1000多层网络的结果。Resnet-50是他们的残差网络的变体,使用了50层,在物体检测、分类和定位方面表现相当出色。

猜你喜欢

转载自blog.csdn.net/yiran103/article/details/79732870
SGD