如何通过Tensorflow-GPU和Keras解决GPU利用率低的问题?

11

我有一台4个GPU的机器,在上面使用Keras运行Tensorflow(GPU版本)。我的一些分类问题需要几个小时才能完成。

nvidia-smi命令返回Volatile GPU-Util,但任何一个GPU的利用率都不会超过25%。如何提高GPU利用率和加速训练? NVIDIA GPU Util


2
根据性能指南,输入管道可能成为瓶颈。 - kww
2个回答

25

如果您的GPU利用率低于80%,通常这是输入管道瓶颈的迹象。这意味着GPU大部分时间处于空闲状态,等待CPU准备数据:enter image description here

您想要的是在GPU进行训练时,CPU继续准备批处理的数据以保持GPU充电。这称为预取:enter image description here

但是,如果批处理仍然比模型训练时间长得多,GPU仍将处于空闲状态,等待CPU完成下一批次。为了加快批处理速度,我们可以并行化不同的预处理操作: enter image description here

我们甚至可以通过并行化I / O来进一步优化: enter image description here

现在,要在Keras中实现此操作,您需要使用Tensorflow Data API和Tensorflow版本> = 1.9.0。这里是一个例子:

假设为了简单起见,您有两个numpy数组x和y。您可以对任何类型的数据使用tf.data,但这更容易理解。

def preprocessing(x, y):
     # Can only contain TF operations
     ...
     return x, y

dataset = tf.data.Dataset.from_tensor_slices((x, y)) # Creates a dataset object 
dataset = dataset.map(preprocessing, num_parallel_calls=64) # parallel preprocessing
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(None) # Will automatically prefetch batches

....

model = tf.keras.model(...)
model.fit(x=dataset) # Since tf 1.9.0 you can pass a dataset object

tf.data非常灵活,但是和TensorFlow中的其他内容(除了eager外)一样,它使用静态图。有时候这可能会很麻烦,但加速效果是值得的。

如果想进一步了解,可以查看性能指南TensorFlow数据指南


4
我遇到了类似的问题 - Keras分配了所有GPU的内存,但易失性内存的使用率约为0%,训练时间几乎与CPU相同。我正在使用ImageDataGenerator,结果发现这是瓶颈。当我将fit_generator方法中默认值1个worker的数量增加到所有可用的CPU时,训练时间迅速下降。

您也可以将数据加载到内存中,然后使用flow方法准备具有增强图像的批处理。


嗨@Konrad,你能否详细说明一下如何增加flow_from_directory中的工作人员数量? - Sharanya Arcot Desai
@SharanyaArcotDesai,我不小心提到了flow_from_directory,但是工作线程数是通过fit_generator方法的参数设置的。对此我感到抱歉,我会更新我的上面的答案。 - Konrad
@Konrad 谢谢你。你的修复方法在某种程度上帮了我。然而,我并没有看到持续利用GPU。目前我将批量大小设置为32,我应该减少它吗? - KK2491
@KK2491 如果你的批次适合GPU内存 - 我会保持原样。正如Olivier在他的回答中提到的,如果GPU没有被充分利用,那么可能是由于输入瓶颈 - CPU无法及时为GPU准备数据。因此,你可能需要进行一些预处理优化来充分利用GPU。 - Konrad
@Konrad,有没有预处理优化技术的建议? - KK2491
@KK2491,很抱歉,目前我无法在这个话题上提供帮助。 - Konrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接