【发布时间】:2020-09-10 12:33:17
【问题描述】:
使用 Horovod,您基本上可以运行 N 个独立实例(因此它是一种图间复制),它们通过特殊的 Horovod 操作(基本上是广播 + 减少)进行通信。
现在假设实例 0 或其他一些外部实例加载您的数据(通过 tf.data.Dataset)。您将如何将iterator.get_next() 分配给每个实例?使用 Horovod 广播效率低下,因为您会将所有数据复制到所有实例。
在每个实例中都有数据集,并在那里进行所有加载,然后在数据集上使用shard 也会效率低下,因为您将在任何地方加载数据,然后丢弃 (N-1)/ N个。
所以这就是为什么也不想要分片,而是只在单个(生产者/数据集工作人员)实例中加载数据集,然后将批次分配给所有火车工作人员。
我猜 TF MultiDeviceIterator 提供了一些类似的功能(或基本上完全一样),但我不确定这是否与 Horovod 一起使用,以及您将如何设置它?
或者也许您可以通过 TF 工作人员以某种方式进行分发(guide?(也许这也是您配置 MultiDeviceIterator 的方式?)
如果可能,这应该通过 TensorFlow 操作/函数(有许多相关函数可能已经给了我这个,但我可能不知道它们,或者误解了它的工作原理)。 或者答案可能是 TensorFlow 还没有提供任何此类功能? (知道这点还是有用的。然后我会用 C++ 实现我自己的解决方案,包装成 TensorFlow。但在这样做之前,最好知道这是否真的有必要。)
(相关也是this Horovod issue。)
(这个问题实际上比 Horovod 更通用,虽然 Horovod 可能是一个很好的例子。分布式 TensorFlow 可能总是有这个问题?)
(我收集了所有分布式 TensorFlow 术语和方面的概述here,主要是为了澄清。)
【问题讨论】:
-
我认为 Horovod 不可能做到这一点,而且绝对不能使用普通的 TensorFlow。你需要的是一个MPI scatter operation,但Horovod 只实现了all-reduce、all-gather 和broadcast 语义。如果您将数据存储为 TFRecord 文件,您最好的选择可能是 split them into many files 并从每个实例中读取一个分片,如答案中所建议...
-
@jdehesa 正如你提到的,我添加了一个feature request about adding MPI scatter support for Horovod。
-
TensorFlow 2.3.0 正在引入
tf.dataservice 用于分布式训练。我不确定它是否能特别解决您的问题,但可能值得您关注。 -
@jdehesa 哦,谢谢。当您使用共享作业(设置
job_name)时,这看起来与我正在寻找的完全一样。或者至少差不多,因为它不会均匀分布,而是按照先到先得的原则(这可能没问题)。有趣的是,当作业不共享时,这是我目前已经实施的另一种解决方案,让每个工作人员只使用不同的随机种子进行数据集洗牌。 -
阿尔伯特,看看粉丝商店。如果您有兴趣,那么我可以发布一个答案,这是如何工作的。 github.com/TACC/FanStore
标签: python tensorflow tensorflow-datasets horovod