这个参数服务器方法同样可以应用在本地训练中,在这种情况下,它们不是在参数服务器之间传播变量的主副本,而是在 CPU 上或分布在可用的 GPU 上。 由于该设置的简单性,这种架构在社区中获得广泛的推广。 通过传递参数 variable_update=parameter_server,也可以在脚本中使用此模式。
带有 3 个变量的参数服务器模式中,变量读取和更新的单个工作器。 变量复制 在这种设计中,服务器中的每个 GPU 都有自己的变量副本。通过将完全聚合的梯度应用于变量的每个 GPU 副本,使得这些值在 GPU 之间保持同步。 因为变量和数据在训练的初始阶段就准备好了,所以训练的前向计算可以立即开始。聚合各个设备的梯度以得到一个完全聚合的梯度,并将该梯度应用到每个本地副本中。 服务器间的梯度聚合可通过不同的方法实现: 使用 Tensorflow 标准操作在单个设备上(CPU 或 GPU)累加整和,然后将其拷贝回所有的 GPU。 使用英伟达 NCCL,这个将在下面的 NCCL 章节阐述。 分布式训练中的变量复制 上述变量复制的方法可扩展到分布式训练中。一种类似的方法是:完全地聚合集群中的梯度,并将它们应用于每个本地副本。这种方法在未来版本的脚本中可能会出现,但是当前的脚本采用不同的方法。描述如下。 在这一模式中,除了变量的每一个 GPU 副本之外,主副本被存储在参数服务器之中。借助这一复制模式,可使用变量的本地副本立刻开始训练。 随着权重的梯度可用,它们会被送回至参数服务器,并所有的本地副本都会被更新: 同一个工作器中把 GPU 所有的梯度聚合在一起。 将来自各个工作器的聚合梯度发送至自带变量的参数服务器中,其中使用特殊的优化器来更新变量的主副本。 每个工作器从主副本中更新变量的本地副本。在示例模型中,这是在一个拥有交叉副本的负载中在等待所有的模块完成变量更新后进行的,并且只有在负载被所有副本释放以后才能获取新的变量。一旦所有的变量完成复制,这就标志着一个训练步骤的完成,和下一个训练步骤的开始。 尽管这些听起来与参数服务器的标准用法很相似,但是其性能在很多案例中表现更佳。这很大程度因为计算没有任何延迟,早期梯度的大部分复制延迟可被稍后的计算层隐藏。 通过传递参数 variable_update=distributed_replicated 可以在脚本中使用该模式。
带有 3 个变量的分布式复制模式中,变量读取和更新的单个工作器。每一步骤标上了数字,所有步骤被用于每一个变量。 NCCL 为了在同一台主机的不同 GPU 上传播变量和聚合梯度,我们可以使用 Tensorflow 默认的隐式复制机制。 然而,我们也可以选择 NCCL(tf.contrib.nccl)。NCCL 是英伟达的一个库,可以跨不同的 GPU 实现数据的高效传输和聚合。它在每个 GPU 上分配一个协作内核,这个内核知道如何最好地利用底层硬件拓扑结构,并使用单个 SM 的 GPU。 通过实验证明,尽管 NCCL 通常会加速数据的聚合,但并不一定会加速训练。我们的假设是:隐式副本基本是不耗时的,因为它们本在 GPU 上复制引擎,只要它的延迟可以被主计算本身隐藏起来,那么。虽然 NCCL 可以更快地传输数据,但是它需要一个 SM,并且给底层的 L2 缓存增加了更多的压力。我们的研究结果表明,在 8 个 GPU 的条件下,NCCL 表现出了更优异的性能;但是如果 GPU 更少的情况下,隐式副本通常会有更好的表现。 分段变量 我们进一步介绍一种分段变量模式,我们使用分段区域来进行变量读取和更新。与输入管道中的软件流水线类似,这可以隐藏数据拷贝的延迟。如果计算所花的时间比复制和聚合的时间更长,那么可以认为复制本身是不耗时的。 这种方法的缺点是所有的权重都来自之前的训练步骤,所以这是一个不同于 SGD 的算法,但是通过调整学习率和其他超参数,还是有可能提高收敛性。 脚本的执行 这一节将列出执行主脚本的核心命令行参数和一些基本示例(tf_cnn_benchmarks.py) 注意:tf_cnn_benchmarks.py 使用的配置文件 force_gpu_compatible 是在 Tensorflow 1.1 版本之后引入的,直到 1.2 版本发布才建议从源头建立。 主要的命令行参数 model:使用的模型有 resnet50、inception3、vgg16 和 alexnet。 num_gpus:这里指所用 GPU 的数量。 (责任编辑:本港台直播) |