tensorflow 2.x默认占满gpu显存是因为启动时预分配全部可见显存以避免碎片,非bug而是性能策略;需在import后、任何tf操作前对每张gpu调用tf.config.experimental.set_memory_growth(true)启用按需分配。

为什么TensorFlow默认占满GPU显存
TensorFlow 2.x(尤其是CUDA后端)启动时会默认调用 tf.config.experimental.set_memory_growth 以外的分配策略,即“一次性申请几乎全部可见GPU显存”,哪怕你只跑一个 tf.constant(1)。这不是bug,是为避免后续内存碎片——但对多任务调试、小模型实验或Jupyter反复运行极其不友好。
set_memory_growth=True 是最常用解法
它让TensorFlow在首次使用GPU时只分配少量显存,后续按需增长。关键点在于:必须在任何 tf.* 操作(包括 import tensorflow as tf 后的首次张量创建)之前调用,且对每个GPU单独设置。
实操建议:
- 把配置代码放在
import tensorflow as tf之后、任何模型定义或数据加载之前 - 遍历所有可见GPU设备,逐个启用:
gpus = tf.config.list_physical_devices('GPU') if gpus: try: for gpu in gpus: tf.config.experimental.set_memory_growth(gpu, True) except RuntimeError as e: print(e) # 若已初始化则报错,不可再修改 - 注意:该设置仅对当前Python进程有效;子进程(如多进程训练)需各自重复设置
set_memory_limit() 更适合资源隔离场景
当你明确要限制某GPU最多用多少MB(比如在共享服务器上跑多个实验),set_memory_limit() 比 set_memory_growth 更可控。但它不是“软上限”——超出会直接抛出 ResourceExhaustedError: OOM when allocating tensor。
使用要点:
- 单位是字节,别写错成MB或GB(例如限制4GB:
1024 * 1024 * 1024 * 4) - 必须在GPU设备未被占用前调用(同
set_memory_growth的时机要求) - 若同时设置了
set_memory_growth=True,后者会失效——两者互斥 - 示例:
gpus = tf.config.list_physical_devices('GPU') if gpus: tf.config.set_logical_device_configuration( gpus[0], [tf.config.LogicalDeviceConfiguration(memory_limit=4096)] # 单位 MB )
常见失败原因和绕过方式
即使代码位置正确,仍可能无效。典型现象是 nvidia-smi 显示显存占用没变,或报 Failed to initialize GPU device。
排查方向:
- 确认没有其他进程(包括已 detach 的 Jupyter kernel、残留的 Python 进程)占着同一块GPU
- 检查是否启用了
TF_FORCE_GPU_ALLOW_GROWTH=true环境变量——它会覆盖代码中的set_memory_growth行为 - Windows 上 WSL2 用户需额外设置
export CUDA_VISIBLE_DEVICES=0,否则list_physical_devices('GPU')可能返回空列表 - TensorFlow 2.10+ 对 CUDA 11.8+ 支持更严格,若驱动版本低(如 set_memory_growth 可能静默失败——此时降级TF或升级驱动更可靠
实际生效与否,得看 nvidia-smi 输出里“Memory-Usage”列是否从启动就卡在高位;如果第一次 tf.random.normal((1000,1000)) 就崩,大概率是 set_memory_limit 设太小,或 set_memory_growth 根本没执行成功。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











