PyTorch内存泄漏排查实战:使用memray定位问题
最近在优化一个图像分类模型时,遇到了严重的内存泄漏问题。训练过程中,GPU内存逐渐增长直至显存溢出,即使使用了torch.cuda.empty_cache()也无法释放。为了解决这个问题,我决定使用memray工具进行深入排查。
环境准备
首先安装memray:
pip install memray
排查步骤
- 使用memray追踪内存分配:
import torch
import torch.nn as nn
from memray import AllocatorType, Tracker
# 模拟训练循环
model = nn.Sequential(
nn.Conv2d(3, 64, 3),
nn.ReLU(),
nn.AdaptiveAvgPool2d((1, 1)),
nn.Flatten(),
nn.Linear(64, 10)
).cuda()
optimizer = torch.optim.Adam(model.parameters())
with Tracker('trace.bin', allocator=AllocatorType.CUDA):
for i in range(100): # 模拟100个batch
x = torch.randn(32, 3, 224, 224).cuda()
y = model(x)
loss = y.sum()
loss.backward()
optimizer.step()
optimizer.zero_grad()
- 分析追踪结果:
memray flamegraph trace.bin --output flamegraph.html
排查结果
通过火焰图发现,内存增长主要来自于模型参数的累积梯度。在loss.backward()后,没有正确清理中间变量。解决方法是添加torch.cuda.empty_cache()并使用del显式删除不需要的张量。
性能对比
| 方法 | 内存峰值(MB) | 运行时间(s) |
|---|---|---|
| 无优化 | 2400 | 120 |
| 添加del + empty_cache | 800 | 115 |
最终问题得到解决,内存使用稳定在合理范围。这个经验对于大规模训练任务很有价值。

讨论