【问题标题】:Tensorflow: GPU Utilization is almost always at 0%Tensorflow:GPU 利用率几乎总是为 0%
【发布时间】:2016-11-12 20:21:11
【问题描述】:

我将 tensorflow 与 Titan-X GPU 一起使用,我注意到,当我运行 CIFAR10 示例时,Volatile GPU-utilization 几乎恒定在 30% 左右,而当我训练自己的模型时,Volatile GPU-utilization远非稳定,它几乎总是 0% 并在 80/90% 处达到峰值,然后一遍又一遍地回到 0%。

我认为这种行为是由于我将数据提供给网络的方式(我在每一步之后都获取数据,这需要一些时间)。但是在实现了一个队列来提供数据并避免步骤之间的这种延迟之后,问题仍然存在(请参阅下面的排队系统)。

有什么想法吗?

batch = 128 # size of the batch
x = tf.placeholder("float32", [None, n_steps, n_input])
y = tf.placeholder("float32", [None, n_classes])

# with a capacity of 100 batches, the bottleneck should not be the data feeding
queue = tf.RandomShuffleQueue(capacity=100*batch,
                  min_after_dequeue=80*batch,
                  dtypes=[tf.float32, tf.float32],
                  shapes=[[n_steps, n_input], [n_classes]])
enqueue_op = queue.enqueue_many([x, y])
X_batch, Y_batch = queue.dequeue_many(batch)

sess = tf.Session()

def load_and_enqueue(data):
    while True:
        X, Y = data.get_next_batch(batch)
        sess.run(enqueue_op, feed_dict={x: X, y: Y})

train_thread = threading.Thread(target=load_and_enqueue, args=(data))
train_thread.daemon = True
train_thread.start()

for _ in xrange(max_iter):
    sess.run(train_op)

【问题讨论】:

  • data.get_next_batch相对于其他操作多长时间?它似乎是唯一在 CPU 上运行的,它可能会减慢管道。
  • 对于大小为 128 的批次,get_next_batch 的运行时间大约是 sess.run(train_op) 的 14 倍。但是,在开始训练之前,我向队列提供了 100 * 个批处理示例,所以至少在开始时我应该有一些良好的 GPU 利用率,不是吗?
  • 如果training比feeding快一个数量级,很有可能dequeuing操作大部分时间都在等待,这意味着GPU-run部分(train_op)等待CPU -运行线程(用于load_and_enqueue)。不过,我还不清楚与min_after_dequeue 的相互作用是什么。不如全部在 CPU 上运行(无线程),看看使用是否更流畅?
  • 所以这个问题现在似乎明白了。一个解决方案可能是对数据进行预处理,以便喂食与训练一样快或更快。请注意,复杂的模型可能会慢很多...
  • 是的,谢谢。我删除了我的 cmets,并将发布我的问题的正确答案。再次感谢您帮助我解决问题。

标签: neural-network gpu tensorflow nvidia deep-learning


【解决方案1】:

在做了一些实验之后,我找到了答案,所以我发布了它,因为它可能对其他人有用。

首先,get_next_batchtrain_op 慢大约 15 倍(感谢 Eric Platon 指出这一点)。

但是,我认为队列已经被 capacity 填满了,而且只有在训练应该开始之后。因此,我认为即使get_next_batch 慢得多,队列也应该隐藏这种延迟,至少在开始时,因为它包含capacity 示例,并且只有在到达min_after_dequeue 之后才需要获取新数据低于capacity 并且它会导致某种稳定的 GPU 利用率。

但实际上,一旦队列到达min_after_dequeue 示例,训练就开始了。因此,一旦队列到达min_after_dequeue 示例以运行train_op,队列就会出队,并且由于提供队列的时间比train_op 的执行时间慢15 倍,因此在train_op 的第一次迭代之后,队列立即降至min_after_dequeue 以下,train_op 必须等待队列再次到达min_after_dequeue 示例。

当我强制train_op 等到队列填满capacity(使用capacity = 100*batch)而不是在达到min_after_dequeue(使用min_after_dequeue=80*batch)时自动启动时,GPU 利用率是稳定的大约 10 秒后回到 0%,这是可以理解的,因为队列在不到 10 秒的时间内到达 min_after_dequeue 示例。

【讨论】:

  • 那么解决方案是什么。我面临同样的问题。知道我正在使用 tf.keras 运行我的代码。我的缓冲区大小是 1000 + 4 * 批量大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 2022-11-03
相关资源
最近更新 更多