专栏名称: 36大数据
关注大数据和互联网趋势,最大,最权威,最干货的大数据微信号(dashuju36)。大数据第一科技媒体。不发软文,只做知识分享。
目录
相关文章推荐
人工智能与大数据技术  ·  AI已学会改自己代码,性能提升100%,还会 ... ·  2 天前  
内蒙古生态环境  ·  【学保密】大模型数据安全挑战与防护 ·  2 天前  
InfoTech  ·  月薪40K的思维方式 ·  3 天前  
51好读  ›  专栏  ›  36大数据

【技术】TensorFlow 官方解读:如何在多系统和网络拓扑中构建高性能模型

36大数据  · 公众号  · 大数据  · 2017-06-09 08:03

正文

请到「今天看啥」查看全文


  • 分布式复制,将每个 GPU 中的训练参数副本与参数服务器上的主副本放置在一起,在变量数据可用时,正向计算和反向计算立即开始。一台服务器上每个 GPU 的梯度会被累加,然后每个服务器中聚合的梯度会被应用到主副本中。当所有的模块都执行此操作后,每个模块都将从主副本中更新变量副本。

  • 以下是有关每种方法的其他细节。

    参数服务器变量

    在 Tensorflow 模型中管理变量的最常见方式是参数服务器模式。

    在分布式系统中,每个工作器(worker)进程运行相同的模型,参数服务器处理其自有的变量主副本。当一个工作器需要一个来自参数服务器的变量时,它可从其中直接引用。Tensorflow 在运行时会将隐式副本添加到图形中,这使得在需要它的计算设备上变量值可用。当在工作器上计算梯度时,这个梯度会被传输到拥有特定变量的参数服务器中,而相应的优化器被用于更新变量。

    以下是一些提高吞吐量的技术:

    • 为了使负载平衡,这些变量根据其大小在参数服务器之间传输。

    • 当每个工作器有多个 GPU 时,累加每个 GPU 的梯度,并把这个单一的聚合梯度发送到参数服务器。这将降低网络带宽,减少参数服务器的工作量。

    为了协调工作器,常常采用异步更新模式,其中每个工作器更新变量的主副本,而不与其他工作器同步。在我们的模型中,我们展示了在工作器中引入同步机制是非常容易的,所以在下一步开始之前所有的工作器必须完成更新。

    这个参数服务器方法同样可以应用在本地训练中,在这种情况下,它们不是在参数服务器之间传播变量的主副本,而是在 CPU 上或分布在可用的 GPU 上。

    由于该设置的简单性,这种架构在社区中获得广泛的推广。

    通过传递参数 variable_update=parameter_server,也可以在脚本中使用此模式。

    变量复制

    在这种设计中,服务器中的每个 GPU 都有自己的变量副本。通过将完全聚合的梯度应用于变量的每个 GPU 副本,使得这些值在 GPU 之间保持同步。

    因为变量和数据在训练的初始阶段就准备好了,所以训练的前向计算可以立即开始。聚合各个设备的梯度以得到一个完全聚合的梯度,并将该梯度应用到每个本地副本中。

    服务器间的梯度聚合可通过不同的方法实现:

    • 使用 Tensorflow 标准操作在单个设备上(CPU 或 GPU)累加整和,然后将其拷贝回所有的 GPU。

    • 使用英伟达 NCCL,这个将在下面的 NCCL 章节阐述。

    分布式训练中的变量复制

    上述变量复制的方法可扩展到分布式训练中。一种类似的方法是:完全地聚合集群中的梯度,并将它们应用于每个本地副本。这种方法在未来版本的脚本中可能会出现,但是当前的脚本采用不同的方法。描述如下。

    在这一模式中,除了变量的每一个 GPU 副本之外,主副本被存储在参数服务器之中。借助这一复制模式,可使用变量的本地副本立刻开始训练。

    随着权重的梯度可用,它们会被送回至参数服务器,并所有的本地副本都会被更新:

    1. 同一个工作器中把 GPU 所有的梯度聚合在一起。

    2. 将来自各个工作器的聚合梯度发送至自带变量的参数服务器中,其中使用特殊的优化器来更新变量的主副本。

    3. 每个工作器从主副本中更新变量的本地副本。在示例模型中,这是在一个拥有交叉副本的负载中在等待所有的模块完成变量更新后进行的,并且只有在负载被所有副本释放以后才能获取新的变量。一旦所有的变量完成复制,这就标志着一个训练步骤的完成,和下一个训练步骤的开始。

    尽管这些听起来与参数服务器的标准用法很相似,但是其性能在很多案例中表现更佳。这很大程度因为计算没有任何延迟,早期梯度的大部分复制延迟可被稍后的计算层隐藏。

    通过传递参数 variable_update=distributed_replicated 可以在脚本中使用该模式。

    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 的数量。

    • data_dir:数据处理的路径,如果没有被设置,那么将会使用合成数据。为了使用 Imagenet 数据,可把这些指示 (https://github.com/tensorflow/tensorflow/blob/master/tensorflow_models/inception#getting-started) 作为起点。

    • batch_size:每个 GPU 的批量大小。

    • variable_update:管理变量的方法:parameter_server 、replicated、distributed_replicated、independent。

    • local_parameter_device:作为参数服务器使用的设备:CPU 或者 GPU。

    单个实例

    # VGG16 training ImageNet with 8 GPUs using arguments that optimize for
    # Google Compute Engine.
    python tf_cnn_benchmarks.py --local_parameter_device=cpu --num_gpus=8 \
    --batch_size=32 --model=vgg16 --data_dir=/home/ubuntu/imagenet/train \
    --variable_update=parameter_server --nodistortions
    
    # VGG16 training synthetic ImageNet data with 8 GPUs using arguments that
    # optimize for the NVIDIA DGX-1.
    python tf_cnn_benchmarks.py --local_parameter_device=gpu --num_gpus=8 \
    --batch_size=64 --model=vgg16 --variable_update=replicated --use_nccl=True
    
    # VGG16 training ImageNet data with 8 GPUs using arguments that optimize for
    # Amazon EC2.
    python tf_cnn_benchmarks.py --local_parameter_device=gpu --num_gpus=8 \
    --batch_size=64 --model=vgg16 --variable_update=parameter_server
    
    # ResNet-50 training ImageNet data with 8 GPUs using arguments that optimize for
    # Amazon EC2.
    python tf_cnn_benchmarks.py --local_parameter_device=gpu --num_gpus=8 \
    --batch_size=64 --model=resnet50 --variable_update=replicated --use_nccl=False

    分布式命令行参数







    请到「今天看啥」查看全文