【问题标题】:Which is better when reading from remote hosts like HDFS, TFRecordDataset+num_parallel_read? Or parallel_interleave从 HDFS、TFRecordDataset+num_parallel_read 等远程主机读取时哪个更好?或 parallel_interleave
【发布时间】:2019-01-26 17:49:28
【问题描述】:

目标是高效地从远程(例如 HDFS)读取数据。使用 tensorflow 数据集,我可以按照指南 here 并使用 parallel_interleave 从远程主机中的不同文件中读取,就像这样

def input_fn():
  files = tf.data.Dataset.list_files("hdfs:///path/to/dataset/train-*.tfrecord")
  dataset = filenames.apply(
      tf.data.experimental.parallel_interleave(
          lambda filename: tf.data.TFRecordDataset(filename),
          cycle_length=4))
  dataset = dataset.map(map_func=parse_fn)
  dataset = dataset.batch(batch_size=FLAGS.batch_size)
  dataset = dataset.prefetch(buffer_size=FLAGS.prefetch_buffer_size)
  return dataset

或者我可以使用num_parallel_readslink 来读取远程主机中的不同文件,就像这样

def input_fn():
  files = tf.data.Dataset.list_files("hdfs:///path/to/dataset/train-*.tfrecord")
  dataset = tf.data.TFRecordDataset(files, num_parallel_reads=4)
  dataset = dataset.map(map_func=parse_fn)
  dataset = dataset.batch(batch_size=FLAGS.batch_size)
  dataset = dataset.prefetch(buffer_size=FLAGS.prefetch_buffer_size)
  return dataset

我假设它们都有相同的用途,我的 cpu 的 4 个线程将从 4 个不同的文件中获取数据,因此比读取 1 个文件具有更好的吞吐量。在这种情况下,两种方法都有区别吗?

我还假设第一种方法会从每批的不同文件中读取,更像是对我的远程文件的广度优先搜索,而第二种方法更像是对我的远程文件的深度优先搜索。当它是具有低延迟的本地文件系统时,也许没关系,但是对于像 HDFS 这样的远程文件系统,这应该是首选的方式吗?

【问题讨论】:

    标签: python tensorflow hdfs tensorflow-datasets tfrecord


    【解决方案1】:

    我刚刚浏览了TFRecordDatasetparallel_interleave 的源代码。请注意,我正在查看 tf.data.experimental,因为不推荐使用 tf.contrib.data。有趣的是,他们都在同一个班级ParallelInterleaveDataset 上使用并行阅读。我想它会成为你如何更好地优化你的管道的选项,因为你可以在使用parallel_interleave时使用block_length、sloppy、buffer_output_elements和prefetch_input_elements等参数来潜在地加速你的管道,同时也赋予一些随机性排序。

    【讨论】:

    • 感谢您的意见。我在我的环境中做了一些实验,发现“本地化数据然后用数据集读取它”的运行时间比“用数据集读取远程文件”快很多倍。 15 秒对 1 分 15 秒。我没有对参数进行广泛的调整,但我有所有建议让它变得更流畅,比如prefetchbatch 等。将继续阅读代码并尝试参数,因为数据集处理时间只是与 IO 时间相比非常小。 14.5 秒 vs 500 毫秒。
    • 好的,我想我明白了。按照上面的直觉,我需要将TFRecordDatasetbuffer_size 设置得非常大,比如 1024**3 (1GB) 以减少从远程主机读取的时间,因为显然开销很大。因此,我将在类似情况下提供给其他人的底线/最佳实践——如果内存允许,请设置一个大的buffer_size
    • 听起来不错。如果您在上面的实验中使用了 parallel_interleave,那么 block_length 参数是否有助于进一步改善这一点?比如,如果您可以一次从每个文件中读取更多元素,这是否有助于进一步减少读取时间?
    • 我试图通过在TFRecordDataset 中设置num_parallel_reads 来实现这一点,甚至根本不进行交错。数据集将打开多个文件流,例如 4,为每个文件创建/获取一个巨大的缓冲区,并且仅在当前批次文件完成后才转到下一批文件。考虑到TFRecordDataset 所需的缓冲区大小,似乎内存效率更高。
    • 还要添加以供将来参考,buffer_size 不必是 1GB,我的情况是每条记录都很大。根据记录大小选择缓冲区大小。
    猜你喜欢
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多