Distributed TensorFlow [Async, Between-Graph Replication]:这是工作人员和服务器之间关于变量更新的确切交互
Distributed TensorFlow [Async, Between-Graph Replication]: which are the exactly interaction between workers and servers regarding Variables update
我读过 Distributed TensorFlow Doc and 但我仍然对可以使用 TensorFlow 及其参数服务器架构完成的分布式训练背后的动态有一些疑问。
这是分布式 TensorFlow 文档中的代码片段:
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)
这里是我阅读的 Whosebug 问题的部分答案:
The worker reads all of the shared model parameters in parallel from
the PS task(s), and copies them to the worker task. These reads are
uncoordinated with any concurrent writes, and no locks are acquired:
in particular the worker may see partial updates from one or more
other workers (e.g. a subset of the updates from another worker may
have been applied, or a subset of the elements in a variable may have
been updated).
The worker computes gradients locally, based on a batch
of input data and the parameter values that it read in step 1.
The
worker sends the gradients for each variable to the appropriate PS
task, and applies the gradients to their respective variable, using an
update rule that is determined by the optimization algorithm (e.g.
SGD, SGD with Momentum, Adagrad, Adam, etc.). The update rules
typically use (approximately) commutative operations, so they may be
applied independently on the updates from each worker, and the state
of each variable will be a running aggregate of the sequence of
updates received.
我必须在另一个环境中重现这种参数服务器架构,我需要深入了解工作人员和 PS 任务如何在 TensorFlow 框架内相互交互。
我的问题是,PS 任务是在从工作人员那里收到值后进行某种合并或更新操作,还是只存储最新值?只存储最新的值可以是合理的吗?查看 TensorFlow 文档中的代码,我看到 PS 任务只是执行一个 join() 我想知道这个方法调用背后是 PS 任务的完整行为。
还有一个问题,计算梯度和应用梯度有什么区别?
让我们倒过来从你的最后一个问题开始:计算梯度和应用梯度有什么区别?
计算梯度意味着运行网络上的反向传播,在计算了损失之后。对于梯度下降,这意味着估计下面公式中的 gradients
值(注意:这是计算梯度实际需要的 巨大 简化,查看更多关于反向传播和梯度的信息下降以正确解释其工作原理)。 应用梯度意味着根据您刚刚计算的梯度更新参数。对于梯度下降,这(大致)意味着执行以下操作:
weights = weights - (learning_step * gradients)
请注意,根据 learning_step
的值,weights
的新值取决于先前的值和计算的权重。
考虑到这一点,就更容易理解 PS/worker 架构。让我们做一个简单的假设,即只有一个 PS(稍后我们将看到如何扩展到 multi-PS)
A PS (parameter server) 在内存中保存weights
(即参数)并接收gradients
, 运行 我在上面的代码中写的更新步骤。每次从工作人员那里收到梯度时,它都会这样做。
另一方面,工作人员在 PS 中查找 weights
的 当前 值是什么,并在本地复制它,在一批数据上运行网络的前向和反向传递并获得新的 gradients
,然后发送回 PS.
注意 "current" 的强调:worker 和 PS 之间没有锁定或 inter-process 同步。如果工作人员在更新过程中读取 weights
(例如,一半已经有了新值,一半仍在更新),这就是他将在下一次迭代中使用的权重。这使事情变得快速。
如果有更多 PS 怎么办? 没问题!网络的参数在 PS 中 partitioned,worker 只需联系所有参数以获得每个参数块的新值,并仅发回梯度与每个特定的相关 PS.
我读过 Distributed TensorFlow Doc and
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)
这里是我阅读的 Whosebug 问题的部分答案:
The worker reads all of the shared model parameters in parallel from the PS task(s), and copies them to the worker task. These reads are uncoordinated with any concurrent writes, and no locks are acquired: in particular the worker may see partial updates from one or more other workers (e.g. a subset of the updates from another worker may have been applied, or a subset of the elements in a variable may have been updated).
The worker computes gradients locally, based on a batch of input data and the parameter values that it read in step 1.
The worker sends the gradients for each variable to the appropriate PS task, and applies the gradients to their respective variable, using an update rule that is determined by the optimization algorithm (e.g. SGD, SGD with Momentum, Adagrad, Adam, etc.). The update rules typically use (approximately) commutative operations, so they may be applied independently on the updates from each worker, and the state of each variable will be a running aggregate of the sequence of updates received.
我必须在另一个环境中重现这种参数服务器架构,我需要深入了解工作人员和 PS 任务如何在 TensorFlow 框架内相互交互。 我的问题是,PS 任务是在从工作人员那里收到值后进行某种合并或更新操作,还是只存储最新值?只存储最新的值可以是合理的吗?查看 TensorFlow 文档中的代码,我看到 PS 任务只是执行一个 join() 我想知道这个方法调用背后是 PS 任务的完整行为。
还有一个问题,计算梯度和应用梯度有什么区别?
让我们倒过来从你的最后一个问题开始:计算梯度和应用梯度有什么区别?
计算梯度意味着运行网络上的反向传播,在计算了损失之后。对于梯度下降,这意味着估计下面公式中的 gradients
值(注意:这是计算梯度实际需要的 巨大 简化,查看更多关于反向传播和梯度的信息下降以正确解释其工作原理)。 应用梯度意味着根据您刚刚计算的梯度更新参数。对于梯度下降,这(大致)意味着执行以下操作:
weights = weights - (learning_step * gradients)
请注意,根据 learning_step
的值,weights
的新值取决于先前的值和计算的权重。
考虑到这一点,就更容易理解 PS/worker 架构。让我们做一个简单的假设,即只有一个 PS(稍后我们将看到如何扩展到 multi-PS)
A PS (parameter server) 在内存中保存weights
(即参数)并接收gradients
, 运行 我在上面的代码中写的更新步骤。每次从工作人员那里收到梯度时,它都会这样做。
另一方面,工作人员在 PS 中查找 weights
的 当前 值是什么,并在本地复制它,在一批数据上运行网络的前向和反向传递并获得新的 gradients
,然后发送回 PS.
注意 "current" 的强调:worker 和 PS 之间没有锁定或 inter-process 同步。如果工作人员在更新过程中读取 weights
(例如,一半已经有了新值,一半仍在更新),这就是他将在下一次迭代中使用的权重。这使事情变得快速。
如果有更多 PS 怎么办? 没问题!网络的参数在 PS 中 partitioned,worker 只需联系所有参数以获得每个参数块的新值,并仅发回梯度与每个特定的相关 PS.