尽管数据集上有多线程设置,但 TF 时间线显示串行执行
Posted
技术标签:
【中文标题】尽管数据集上有多线程设置,但 TF 时间线显示串行执行【英文标题】:TF Timeline shows serial execution despite multithreading settings on Dataset 【发布时间】:2017-12-01 15:37:00 【问题描述】:我对 Tensorflow 比较陌生,仍在努力了解如何提高性能。我使用 TF Timeline 工具检查了我的代码的执行,我惊讶地发现执行看起来像是串行的,如下图所示:
下面的代码是我用来设置数据输入的:
filenames = tf.placeholder(tf.string, shape=[None])
dataset = tf.data.TFRecordDataset(filenames, "ZLIB", 128 * 1024 * 1024)
dataset = dataset.map(_parse_function, 13)
dataset = dataset.batch(8192)
dataset = dataset.prefetch(8192 * 3)
iterator = dataset.make_initializable_iterator()
X, y = iterator.get_next()
特别是,考虑到我已将map
上的工作线程数设置为 13(与我的硬件一致)并且还设置了等于 3 倍批量大小的预取,我本来希望 CPU 与GPU 和 CPU/GPU 传输时间。所以我的问题是:
-
为什么这看起来是连续的?我是否误读了我所看到的内容?
我使用数据集的方式有问题吗?我知道最终应该调整批处理大小和预取大小以获得最佳性能,但是如果我根本看不到 CPU 与 GPU 的并行使用,那又有什么意义呢?
【问题讨论】:
我认为将.prefetch(8192*3)
放在 .batch(8192)
之后会导致它缓冲 24000 个批次或 2000 万个样本。尝试颠倒顺序,使prefetch
在batch
之前或仅在prefetch(3)
批次之前。这就是我这样做的方式,但是我在这里看到了一些问题,这些问题都是按照您发布的方式进行的,这开始让我自己怀疑。所以让我知道你发现了什么。
【参考方案1】:
配置文件看起来是连续的,因为_parse_function()
(的并行调用)中的任何操作都未包含在时间线跟踪中。 IteratorGetNext
跟踪区域将与管道中的一些操作重叠,但 dataset.prefetch(8192 * 3)
意味着大部分工作将在后台线程中异步执行。
David Parks' comment 提出了一个很好的观点:8192 * 3
batches 的预取缓冲区大小可能比您需要的要大,并且可能会导致内存压力。通常将预取缓冲区大小设置为较小的值(例如 1 或 2)足以将预处理与训练重叠;我预计在那之后不久收益会递减。尝试将 num_parallel_calls
参数增加到 Dataset.map()
以查看这是否会增加训练的吞吐量。
【讨论】:
以上是关于尽管数据集上有多线程设置,但 TF 时间线显示串行执行的主要内容,如果未能解决你的问题,请参考以下文章
获取 InvalidArgumentError:NewRandomAccessFile 在自定义图像数据集上使用 tf.data 时无法创建/打开