TensorFlow 2.x 默认预分配全部GPU显存,需在导入后立即调用tf.config.experimental.set_memory_growth(gpu, True)启用按需分配,且不可晚于首次模型构建或tf.function调用。

TensorFlow 2.x 默认占满 GPU 显存,怎么限制?
TensorFlow 2.x 默认启用“内存增长”(memory growth)关闭状态,启动时会尝试预分配全部可见 GPU 显存,导致多进程或多个模型实例同时运行时直接 OOM。这不是显卡不够,而是分配策略太激进。
解决核心是显式禁用默认全占行为,改用按需分配。关键配置在 tf.config.experimental.set_memory_growth 或 tf.config.set_visible_devices:
- 先获取 GPU 设备列表:
gpus = tf.config.list_physical_devices('GPU') - 对每个 GPU 执行:
tf.config.experimental.set_memory_growth(gpus[i], True) - 必须在导入 TensorFlow 后、任何模型/计算图创建前调用,否则报错
ValueError: cannot modify GPU memory growth after initialization
为什么 set_memory_growth=True 还爆显存?
开启 memory growth 只解决“启动时全占”,不解决“运行中缓存膨胀”。常见原因包括:模型训练中梯度累积未清空、tf.function 装饰函数反复 trace 生成大量中间图、数据管道使用 cache() 把整个数据集载入显存。
排查建议:
立即学习“Python免费学习笔记(深入)”;
- 用
nvidia-smi观察显存占用曲线:如果训练几步后陡升并卡住,大概率是 tensor 缓存未释放 - 检查是否误用
dataset.cache().prefetch(tf.data.AUTOTUNE)加载了超大数据集到显存 - 避免在
@tf.function内部创建未被复用的大型临时变量,例如每次 call 都 new 一个 shape=(1024,1024) 的tf.Variable
多进程/多模型共用 GPU 时怎么隔离显存?
单卡跑多个 tf.keras.Model 实例(如 Flask API 并发请求),即使开了 memory growth,仍可能因上下文竞争导致显存碎片化或分配失败。这时不能只靠 growth,得配合可见设备控制:
- 用
tf.config.set_visible_devices(gpus[0], 'GPU')确保当前进程只看到指定 GPU(哪怕只有一块) - 更稳妥的是用环境变量控制:启动前设
CUDA_VISIBLE_DEVICES=0,再启动 Python 进程,这样tf.config.list_physical_devices('GPU')返回的就只有索引 0 的设备 - 若需硬性限制最大用量(如最多用 4GB),可用
tf.config.experimental.set_memory_limit(gpus[0], 4096)—— 注意单位是 MB,且必须在 set_memory_growth 之后调用
TensorFlow 1.x 与 2.x 显存配置差异在哪?
TF 1.x 用 tf.ConfigProto + allow_growth=True,写法是:
config = tf.ConfigProto() config.gpu_options.allow_growth = True sess = tf.Session(config=config)
TF 2.x 废弃了 Session,改用全局运行时配置。两者不可混用:allow_growth 在 TF 2.x 中已无效,继续写不会报错但不起作用;反过来,在 TF 1.x 里调用 set_memory_growth 会抛 AttributeError。
迁移时最容易漏掉的是:TF 2.x 要求配置必须在 import tensorflow as tf 之后立即执行,且不能晚于第一次 tf.function 或模型构建。延迟几行代码就可能失效。


















