2017-08-31 306 views
1

我正在试验Cloud ML Engine上的分布式培训选项,并观察了一些特殊的结果。我基本上改变了人口普查定制估算例子,以包含稍微不同的模型,并将我的损失函数更改为AdamOptimizer作为唯一真正的变化。基于其他thread,我的理解是,任何分布式培训都应该是数据并行异步培训,这将提示“如果您在10个工作节点中分发10,000个批次,则每个节点的工作量大约为1,000个批次。”在我的实验中,我有〜650k个训练实例,并且我正在运行下列实验,批处理量为128个1个时期。给定650k个训练实例和128个批处理大小,我预计会有~5.1k个步骤时代。下面是我看到的性能不同--scale-tiertf.estimator的分布式培训导致更多的培训步骤

尚未发放

  • BASIC:8步/秒,5.1K步骤,11分钟挂钟时间
  • BASIC_GPU:24步/秒,5.1K步骤,3.5分钟壁时间

分布式

  • 标准_1:14.5步/秒 - 26K步骤(26K * 128 =〜3.3M比所述训练样本实际上是在数据多路),29分钟壁时间

  • CUSTOM - 5 complex_model_m工人,2 large_model参数服务器:27步/秒,31K的步骤(128 * 31K =〜3.9M其比650K训练样本实际上是在数据路以上),壁时间20分钟

我期望的是,基于该文章的数据平行分布式培训将在所有工人中分配批次,所以如果我有5名工人在〜5k蝙蝠那么每个工人就会执行〜1,000个批次。然而,我观察到的实际行为是,似乎更接近每5个工人进行1个时代的每一个人。在分布式环境下进行训练时,在一个时代中所采用的步数是训练样例的6倍 - 我知道每次梯度的更新都会对步骤的真实定义产生影响,但我对数据并行训练的理解是:这只是分割批次,所以应该有相同数量的梯度更新 - 有什么理由可以预期这种行为?在数据并行异步培训分布式环境中需要更多的培训步骤是否合理?任何人都可以解释我正在观察的行为吗?

回答

3

以前的答案是解释性能瓶颈的工作做得很好。让我解释一下“时代”以及TensorFlow如何处理数据集。

,在TensorFlow分布式训练的工作方式是,每个工人独立完成整个数据集进行迭代。这是一种常见的误解,认为训练集是在工人之间进行分配的,但事实并非如此。

与队列(见this tutorial)一个典型的设置,会发生什么情况是每个劳动者创造它自己的队列。该队列中充满了所有训练文件的所有文件名列表(通常列表被混洗,每当队列耗尽时,它就会被重新填充并重新组合)。每个文件在逐个实例中读取,数据被解析,预处理,然后被馈送到另一个队列中,在该队列中进行混洗和批处理。一旦读取了任何文件的最后一个实例,下一个文件名就会从文件名队列中弹出。如果没有更多文件可以弹出,则“纪元”已经完成。

这里重要的一点是,所有这些队列默认为本地 - 不共享。所以每个工作人员都独立地重复相同的工作 - 为所有文件创建队列并遍历整个数据集。那么,一个完整的时代大致等于完整数据集中的实例数*工人数。 (我不确定你的standard_1结果,但CUSTOM的结果意味着你的主人+5名工人= 6名工人* 650K个例子*(1批/ 128个例子)= 31K步)。

仅供参考使用时期的,不鼓励使用参数化的分布式训练,因为它太混乱,甚至有可能出现在一般与它的问题。只要坚持max_steps。

请注意,由于TensorFlow的设计,“批量大小”是指每个工人的批量大小。但是每个工作人员将以大致相同的速率向参数服务器发送更新,因此在一段时间内大致相当于处理一个“批量”所需的时间,参数发生更新的次数大致为batch_size * num_workers。这就是我们所说的有效的批量大小。这反过来有一些实际后果:

  1. 您倾向于使用更小的batch_sizes,特别是如果你有大量的工人,使有效批量大小保持理智。
  2. 如果增加工人的数量,你的有效批量大小的增加,因此你需要降低你的学习速度,使用“香草”随机梯度下降时,至少。具有自适应学习速率的优化器(如Adagrad,Adam等)往往对最初的学习速率很稳健,但是如果添加足够多的工作人员,您仍然可能需要调整学习速率。

你也许会奇怪,为什么TensorFlow处理以这种方式训练数据。这是因为在分布式系统中,不能依赖于速度相同的机器,或者甚至是可靠的机器。如果您将训练数据划分为不相交的集合,并将其分配给每个工作人员,然后一台或多台机器相对于另一台机器较慢,或者网络出现故障等,则您的训练过程将从“快速”/“可靠的工人比“慢”/不可靠的工人更频繁。这将结果偏向于这些情况(或者在极端情况下,一起忽略它)。

+0

令人难以置信的答案!这将成为一篇很好的博客文章,因为很难找到在线分发tensorflow文档中解释的信息。我猜这里唯一值得关注的是,如果我处理的是不平衡的数据,我喜欢使用时代来确保我遍历所有少数族裔的例子,并且似乎使用max_steps确实无法保证(尽管如果你采取足够的步骤,那么你应该从甚至最小的少数族裔中抽样)。 – reese0106

+0

我对像Adam这样的优化者的理解是,他们通常使用“开箱即用”的学习率,因为他们已经或多或少地进行了优化。是否有任何建议的启发式方法来调整学习率来处理更大的有效批量?我认识到可能需要试验/超参数调整,但希望阅读更多内容以获得更多信息 – reese0106

+0

此外,您还引用了max_steps--这与此[line](https)自定义估算人口普查样本中的train_steps相同://github.com/GoogleCloudPlatform/cloudml-samples/blob/master/census/customestimator/trainer/task.py#L201)或者这是一个完全不同的论点? – reese0106

1

有两种类型西弗斯的:

  • 工人:它执行图形计算
  • 参数服务器:用来存储参数,使所有的工人都能分享和更新参数

你可以在参数服务器中有一个瓶颈。如果模型非常大并且参数服务器很少,则需要在工作者和参数服务器之间进行更多通信。例如,如果您有2个参数服务器,则您将在一台服务器中拥有该模型的一半参数,而在另一台服务器中拥有另一半参数。如果你有很多的工人,他们必须得到并向不同的工人发送很多参数,而工人们将会有很大的滞后。如果增加参数服务器的数量,则由于每个参数服务器与工作人员之间的通信较少,所以滞后将会减少。

由于批量大小为128(相当大),并且您只能在CPU中每秒执行8个步骤,所以我认为您的模型速度如此之快,以致共享服务器参数比运行一次迭代需要更多时间。所以你也可以尝试增加批量。

+0

我很欣赏这种回应。虽然我认为我遵循你所说的大部分内容 - 但我仍然不完全确定为什么这会导致更多的训练步骤比训练的例子。您是否试图建议,因为在与参数服务器的通信中存在瓶颈,则每个批次的大小会导致多个更新?我试图理解的问题是为什么1个时代会导致CPU/GPU上的5.1k训练步骤,但分布式设置会导致同一个时期的30k +步骤。 – reese0106

+0

我没理解你。我的回答与此无关。无论分布式计算机还是单台计算机,步数应该相同。你在使用什么会议?它是“MonitoredTrainingSession”吗?你如何计算步骤?你使用global_step'tensorflow.python.training_util.get_or_create_global_step()'?你是在使用队列还是在'session.run'中提供样本? – jorgemf

+0

我正在关注可在[此处]找到的自定义估算人员示例(https://github.com/GoogleCloudPlatform/cloudml-samples/blob/master/census/customestimator/trainer/model.py#L193) - 我是使用tf.contrib.framework.get_or_create_global_step()并将其作为示例传递给train_op。我正在进行一项实验即。 learn_runner.run()并使用tf.train.batch生成输入数据。你看到样本中有什么会导致问题的吗?我相信实验功能默认使用受监控的培训课程 – reese0106