Tensorflow:GPU 利用率几乎总是 0%

Tensorflow: GPU Utilization is almost always at 0%

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

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

有什么想法吗?

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)

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

首先,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,队列就会被出列,并且由于填充队列的时间比 [= 的执行时间慢 15 倍11=],队列中的元素数量在 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 利用率在回到 0% 之前稳定了大约 10 秒,这是可以理解的,因为队列在不到 10 秒的时间内达到 min_after_dequeue 示例。