标题中的问题已完成。 “如何确保培训阶段不会面对OOM?”
仅需注意一点,根据我的经验,有两种OOM。一种是模型和迷你批处理所需的内存大于您拥有的内存。在这种情况下,培训阶段将永远不会开始。解决此问题的解决方案是使用较小的批量。即使我能够计算出我的硬件可以为某些特定型号管理的最大批量大小,那也很棒。但是,即使我第一次尝试找不到最大的批处理大小,也总是可以通过反复试验找到它(因为该过程立即失败)。
我面对OOM的第二种情况是训练过程开始时,它持续了一段时间。甚至几个时代。但是由于某种未知的原因,它面临OOM。对我来说,这种情况令人沮丧。因为它可能随时发生,并且您永远不会知道正在进行的培训是否会结束。到目前为止,我已经失去了几天的培训时间,而我以为一切都很好。
我认为需要进行一些澄清。首先,我说的是带有GPU的个人计算机。其次,GPU专用于计算,不用于显示。如果我错了,请纠正我,但是我相信这意味着训练过程在不同的时间点需要不同的内存大小。怎么可能再一次,如何确保我的培训阶段不会面对OOM?
以这次运行为例:
3150/4073 [======================>.......] - ETA: 53:39 - loss: 0.3323
2019-10-13 21:41:13.096320: W tensorflow/core/common_runtime/bfc_allocator.cc:314] Allocator (GPU_0_bfc) ran out of memory trying to allocate 60.81MiB (rounded to 63766528). Current allocation summary follows.
经过三个小时的培训,TensorFlow要求的内存超出了我的硬件所能提供的数量。我的问题是,为什么此时而不是在流程开始时增加内存分配?
[更新]
鉴于急切模式的已知问题,我将对我的情况进行一些说明。我不是在渴望模式下编码。这是我的训练代码的样子:
strategy = tf.distribute.OneDeviceStrategy(device="/gpu:0")
training_dataset = tf.data.Dataset.from_tensor_slices(...)
validation_dataset = tf.data.Dataset.from_tensor_slices(...)
with strategy.scope():
model = create_model()
model.compile(optimizer='adam', loss='categorical_crossentropy')
pocket = EarlyStopping(monitor='val_loss', min_delta=0.001,
patience=5, verbose=1,
restore_best_weights = True)
history = model.fit(training_dataset.shuffle(buffer_size=1000).batch(30),
epochs=3,
callbacks=[pocket],
validation_data=validation_dataset.shuffle(buffer_size=1000).batch(30),
workers=3, use_multiprocessing=True)
答案 0 :(得分:1)
如果您在循环中反复训练,则会发生已知的内存泄漏[1]。解决方案是在循环中不时调用tf.keras.backend.clear_session()
,可能不时调用gc.collect()
。
尽管在TF 1.15和2.0中,该行为似乎有所不同,但这可能不足以对其进行修复。我发现tf.keras.backend.clear_session()
在我的CPU训练循环中会重置逐渐的内存泄漏,而不会影响训练。