分布式TensorFlow [异步,图之间复制]:关于变量更新的工作者和服务器之间的确切交互

时间:2018-03-07 11:16:36

标签: python asynchronous tensorflow distributed

我已阅读Distributed TensorFlow Docthis question on StackOverflow,但我仍然对使用TensorFlow及其参数服务器架构可以完成的分布式培训背后的动态有所怀疑。 这是来自Distributed TensorFlow Doc的代码剪切:

if FLAGS.job_name == "ps":
    server.join()
  elif FLAGS.job_name == "worker":

    # Assigns ops to the local worker by default.
    with tf.device(tf.train.replica_device_setter(
        worker_device="/job:worker/task:%d" % FLAGS.task_index,
        cluster=cluster)):

      # Build model...
      loss = ...
      global_step = tf.contrib.framework.get_or_create_global_step()

      train_op = tf.train.AdagradOptimizer(0.01).minimize(
          loss, global_step=global_step)

这是我读过的StackOverflow问题的部分答案:

  

worker从并行读取所有共享模型参数   PS任务,并将它们复制到工作人员任务。这些读物是   与任何并发写入不协调,并且不获取锁定:   特别是工人可能会看到一个或多个部分更新   其他工作人员(例如,来自另一名工人的更新的子集可能   已应用,或变量中的元素子集可能具有   已更新)。

     

工作人员根据批次在本地计算渐变   输入数据及其在步骤1中读取的参数值。

     

在   worker将每个变量的渐变发送到适当的PS   任务,并使用渐变将渐变应用于它们各自的变量   由优化算法确定的更新规则(例如,   新元,新元与动量,阿达格拉德,亚当等)。更新规则   通常使用(近似)可交换操作,因此它们可能是   独立应用于每个工人和州的更新   每个变量将是序列的运行聚合   收到的更新。

我必须在另一个环境中重现这种参数服务器体系结构,我需要深入了解TensorFlow框架内worker和PS任务如何相互交互。 我的问题是,PS任务在收到工作人员的价值后是否会进行某种合并或更新操作,或者只存储最新值?存储最新值可以是合理的吗?看一下TensorFlow文档中的代码,我看到PS任务只是做一个join(),我想知道这个方法调用背后是PS任务的完整行为。

还有一个问题,计算渐变和应用渐变之间有什么区别?

1 个答案:

答案 0 :(得分:5)

让我们按相反的顺序从你的上一个问题开始:计算渐变和应用渐变之间有什么区别?

计算渐变意味着在计算损失后在网络上运行反向传递。对于梯度下降,这意味着估计下面公式中的gradients值(注意:这是计算梯度实际需要的巨大简化,查看更多关于反向传播和梯度下降的信息解释这是如何工作的)。 应用渐变意味着根据刚刚计算的渐变更新参数。对于梯度下降,这(大致)意味着执行以下操作:

weights = weights - (learning_step * gradients)

请注意,根据learning_step的值,weights的新值取决于先前的值和计算的权重。

考虑到这一点,理解PS / worker架构更容易。让我们简单地假设只有一个PS(我们稍后会看到如何扩展到多PS)

PS(参数服务器)在内存中保存weights(即参数)并接收gradients,运行我在上面的代码中编写的更新步骤。它每次从工人那里收到渐变时就会这样做。

另一方面,工作人员查找PS中weights当前值,在本地复制它,运行前向和后向传递网络上的一批数据并获得新的gradients,然后发送回PS。

注意强调“当前”:工人和PS之间没有锁定或进程间同步。如果工作人员在更新过程中读取weights(例如,一半已经有新值,一半仍在更新),那就是他将用于下一次迭代的权重。这样可以保持快速。

如果有更多PS会怎么样?没问题!网络的参数在PS之间进行分区,工作人员只需联系所有参数即可获得每个参数块的新值,并仅返回与每个特定PS相关的梯度。