Python 从远程主机(如HDFS、TFRecordDataset+)读取数据时,哪一个更好;并行读取数?或并行交叉
目标是高效地从远程(如HDFS)读取数据。使用tensorflow数据集,我可以按照指南,使用Python 从远程主机(如HDFS、TFRecordDataset+)读取数据时,哪一个更好;并行读取数?或并行交叉,python,tensorflow,hdfs,tensorflow-datasets,tfrecord,Python,Tensorflow,Hdfs,Tensorflow Datasets,Tfrecord,目标是高效地从远程(如HDFS)读取数据。使用tensorflow数据集,我可以按照指南,使用并行交叉从远程主机中的不同文件读取,如下所示 def input_fn(): files = tf.data.Dataset.list_files("hdfs:///path/to/dataset/train-*.tfrecord") dataset = filenames.apply( tf.data.experimental.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\u parallel\u reads
,从远程主机中的不同文件进行读取,如下所示
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),哪种方式应该是首选的方式 我刚刚浏览了和的源代码。请注意,我正在查看tf.data.experimental,因为tf.contrib.data one已被弃用。有趣的是,他们两人都在同一个班级上课,利用平行阅读。我想这会成为优化管道的最佳选择,因为在使用并行交错时,可以使用诸如块长度、松散、缓冲区输出元素和预取输入元素等参数来潜在地加快管道速度,同时在排序中也会带来一些随机性 谢谢你的意见。我在我的环境中做了一些实验,发现“本地化数据然后使用数据集读取”的运行时比“使用数据集读取远程文件”快很多倍。15秒对1米15秒。我没有广泛地调整参数,但我有所有建议使其更平滑,如
预取
,批处理
,等等。将继续读取代码并尝试参数,因为数据集处理时间与IO时间相比非常小。14.5秒对500秒。好的,我想我明白了。按照上面的直觉,我需要将TFRecordDataset
缓冲区大小设置得非常大,比如1024**3(1GB),以减少从远程主机读取的时间,因为这显然是一个巨大的开销。所以,在类似的情况下,我会给其他人一个底线/最佳实践——如果内存允许的话,设置一个大的缓冲区大小。如果您在上面的实验中使用了并行交织,那么块长度参数是否有助于进一步改进这一点?例如,如果您可以一次性从每个文件中读取更多元素,这是否有助于进一步缩短读取时间?我正在尝试通过在TFRecordDataset
中设置num\u parallel\u reads
来实现这一点,甚至根本不进行交错。数据集将打开多个文件流,例如4个,为每个文件流创建/获取一个巨大的缓冲区,并且仅在处理完当前批文件后才转到下一批文件。考虑到我需要TFRecordDataset
的缓冲区大小,似乎内存效率更高。另外,为了便于将来参考,添加buffer\u size
不必为1GB,我的情况是每个记录都很大。根据记录大小选择缓冲区大小。