跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Python运行时怎样降低PyTorch显存占用_配置CUDA内存分配器与环境变量

PyTorch默认caching_allocator缓存释放的显存块而不归还CUDA驱动,导致nvidia-smi显存居高不下;需用PYTORCH_CUDA_ALLOC_CONF切换分配器或禁用缓存,torch.cuda.empty_cache()仅清PyTorch缓存池中无引用的块。 PyTorch默认显存分配器为什么吃得多又不释放? PyTorch默认用的是
caching_allocator
,它会把释放掉的显存块缓存起来供后续复用,而不是还给CUDA驱动。这导致
nvidia-smi
看到的显存占用长期居高不下,哪怕你已经
del tensor
、
torch.cuda.empty_cache()
,甚至退出
with torch.no_grad():
作用域——缓存池还在。 真正释放显存给系统,得靠 环境变量 强制切换分配器或关闭缓存行为:
CUDA_VISIBLE_DEVICES=0
:先确认只暴露目标卡,避免跨卡隐式分配
PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128
:限制最大内存块切分粒度,防止碎片化后无法复用(值太小会增加分配开销) 更激进的做法是禁用缓存:
PYTORCH_CUDA_ALLOC_CONF=allocator:cudaMallocAsync
(仅CUDA 11.8+,需驱动≥525),它用异步分配器,释放即归还,
nvidia-smi
读数更“诚实” torch.cuda.empty_cache()到底有没有用? 有用,但只清空PyTorch缓存池里“未被任何tensor引用”的显存块,不碰CUDA驱动层。如果模型还在运行、梯度没清、
requires_grad=True
的中间变量仍存活,
empty_cache()
基本没效果。 实操建议: 立即学习 “ Python免费学习笔记(深入) ”; Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 在
torch.no_grad()
上下文里推理时调用,比训练中调用更有效 配合
del
显式删除大tensor,再
gc.collect()
,最后
torch.cuda.empty_cache()
别在循环里频繁调用——它本身有开销,且不能解决持续增长的缓存池问题 训练中显存暴涨却找不到泄漏点?检查这几个地方 显存不降往往不是分配器问题,而是Python对象生命周期失控: 日志或可视化里意外保留了
loss
、
output
等GPU tensor(比如写进
list.append(loss)
)
model.train()
模式下
BatchNorm
和
Dropout
会缓存中间状态;若误在验证阶段没切到
.eval()
,这些状态持续累积 使用
torch.utils.checkpoint
时,若
use_reentrant=False
未设好,可能引发梯度图重复驻留 Dataloader的
num_workers>0
且
pin_memory=True
时,worker进程可能持有GPU张量副本(罕见,但多卡调试时出现过) 如何验证显存配置是否生效? 光看
nvidia-smi
不够,得交叉验证: 启动前加
echo $PYTORCH_CUDA_ALLOC_CONF
确认环境变量已加载 代码开头打印
torch.cuda.memory_summary()
,关注
allocated
vs
reserved
两列——前者是PyTorch实际用掉的,后者是缓存池向驱动申请的总量;切换
cudaMallocAsync
后,这两者应趋近一致 用
torch.cuda.memory_allocated()
在关键节点打点,比依赖
nvidia-smi
更准(后者含驱动开销、其他进程干扰) 注意
cudaMallocAsync
在某些旧版cuDNN或自定义CUDA扩展里可能触发兼容性报错,错误信息通常是
CUDA driver version is insufficient for CUDA runtime version
或
invalid device pointer
,此时退回
max_split_size_mb
微调更稳妥。

相关文章