Keras报Allocator (GPU_0_bfc)内存不足:能否清理GPU显存或执行垃圾回收?
问题原因
- 核心原因是
on_epoch_end回调会在每轮训练结束后重复执行,你的自定义指标计算逻辑会产生大量GPU临时张量、计算图节点,这些资源默认不会被自动即时释放,累计多轮后就会占满显存触发OOM。而on_train_end仅在全量训练结束后执行1次,不会出现累计占用的问题,且执行时训练流程已经释放了大部分占用的显存,因此不会报错。 - 额外触发因素:如果你在指标计算时直接加载全量验证/训练数据到GPU运算、或者每次回调都生成新的TensorFlow计算节点/模型实例,会大幅加快显存占用的累积速度,哪怕batch size降为1也解决不了训练+回调累计的显存占用问题。
解决方案
1. 优化回调计算逻辑
- 指标计算不要一次性加载全量数据到GPU,和训练逻辑一样拆分小批量计算,若使用tf.Dataset加载数据不要直接转换为全量张量,每批计算完成后及时用
del删除临时张量变量。 - 不要在回调内重复创建模型实例、新的计算层,所有可复用的计算逻辑提前初始化好,仅在回调内做前向运算和指标累加。
- 如果指标计算不需要GPU加速,可以用
with tf.device('/CPU:0'):包裹所有指标计算逻辑,强制所有临时张量生成在内存里,完全不占用GPU显存。
2. 回调结束后显式清理显存
每次on_epoch_end的自定义逻辑执行完成后,按顺序执行以下代码即可清理未被释放的GPU显存:
import gc # 清理Keras会话缓存 tf.keras.backend.clear_session() # 重置默认计算图 tf.compat.v1.reset_default_graph() # 触发Python垃圾回收释放所有无引用的张量 gc.collect()
内容的提问来源于stack exchange,提问作者Luka
相关产品推荐
相关产品推荐

