如何使用 Tensorflow 的数据集将数据移动到多个 GPU 塔 API

How does one move data to multiple GPU towers using Tensorflow's Dataset API

我们正在 Tensorflow 上 运行 宁多 GPU 作业,并评估从基于队列的模型(使用 string_input_producer 接口)到新的 Tensorflow 数据集 API 的迁移。后者似乎提供了一种更简单的方法来同时在训练和验证之间切换。

下面的一段代码展示了我们是如何做到这一点的。

    train_dataset, train_iterator = get_dataset(train_files, batch_size, epochs)
    val_dataset, val_iterator = get_dataset(val_files, batch_size, epochs)


    is_validating = tf.placeholder(dtype=bool, shape=())
    next_batch = tf.cond(is_validating,
               lambda: val_iterator.get_next(),
               lambda: train_iterator.get_next())

    validation_tower = self.num_gpus - 1
    tower_grads = []

    for i in range(self.num_gpus):
        with tf.variable_scope(tf.get_variable_scope(),reuse=(i > 0)):
            with tf.device('/gpu:%d' % i), tf.name_scope('%s_%d' % ('gpu_', i)) as scope:
                if i == validation_tower:
                    images, labels = next_batch
                    # Loss funcs snipped out
                else:
                    images, labels = next_batch
                    # Loss funcs snipped out

get_dataset函数构建数据集,设置地图函数和批量大小。它还构建了一个迭代器,但不对其进行初始化。迭代器的初始化发生在会话开始之前。

在会话 运行ning 时提供 is_validating 布尔值,每隔几步我们通过 feed_dict 将 is_validating 作为 True 传递以使用验证数据集

我的问题是:

假设我有 8 个 GPU,所以我们 运行 在 7 个 GPU 上训练。迭代器是否从这 7 个 GPU 中的每一个的相同点前进,从而为所有 7 个 GPU 提供相同的数据?

目前主要有三个选项,它们具有不同的可用性和性能权衡:

  1. Dataset.batch() transform, create a single large batch containing examples for all of your GPUs. Then use tf.split(..., self.num_gpus) 的输出上 Iterator.get_next() 为每个 GPU 创建子批次。这可能是最简单的方法,但它确实将拆分放在了关键路径上。

  2. Dataset.batch() 转换中,创建一个大小适合单个 GPU 的小批量。然后每个 GPU 调用一次 Iterator.get_next() 以获得多个不同的批次。 (相比之下,在您当前的代码中,相同的 next_batch 值被发送到每个 GPU,这可能不是您想要的。)

  3. 创建多个迭代器,每个 GPU 一个。在管道的早期使用 Dataset.shard() 对数据进行分片(例如,如果您的数据集已分片,则在文件列表中)。请注意,此方法会消耗主机上的更多资源,因此您可能需要调低任何缓冲区大小and/or 并行度

请注意,当前 tf.data 流水线 运行 仅在 CPU 上,高效流水线的一个重要方面是将训练输入暂存到 GPU,而上一步是还是运行宁。请参阅 TensorFlow CNN benchmarks 示例代码,其中显示了如何高效地将数据暂存到 GPU。我们目前正在努力将此支持直接添加到 tf.data API。