标题中的问题已经完成。 “如何保证训练阶段不会出现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 要求的内存超出了我的硬件所能提供的内存。我的问题是,为什么在此时而不是在进程开始时增加内存分配?
[UPDATE]
鉴于 Eager 模式的已知问题,我将对我的案例进行一些说明。我没有以急切模式编码。这是我的训练代码的样子:
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)