PyTorch 在训练和预测的时候,出现显存一直增加的问题,占用显存越来越多,甚至导致最终出现 out 0f memory 问题.
1. 显存管理(Memory Management)
PyTorch 采用缓存分配器(caching memory allocator) 机制以加速内存分配(memory allocations),使得在不需要设备同步(device synchronizations) 的情况下,实现快速的内存再分配(fast memory deallocation).
然而,采用 nvidia-smi
命令,显存分配器所管理的无用内存仍然会显示被占用.
PyTorch 提供了 memory_allocated()
和 max_memory_allocated()
用于监视 tensors 占用的内存; memory_cached()
和 max_memory_cached()
用于监视缓存分配器所管理的内存.
PyTorch 提供了 empty_cache()
l来释放所有未使用的缓存的内存,以便其它 GPU 应用能够使用. 但是,并不能释放 tensors 所占用的 GPU 显存,因此,其并不能增加 PyTorch 的可用 GPU 显存量.
[1] - 查看特定设备上 tensors 当前所占用的 GPU 显存(以字节bytes为单位)
torch.cuda.memory_allocated(device=None)
[2] - 查看特定设备上 tensors 最大所占用的 GPU 显存(以字节bytes为单位)
torch.cuda.max_memory_allocated(device=None)
默认返回当前程序从开始所占用的最大显存.
[3] - 查看特定设备上缓存分配器当前所占用的 GPU 显存(以字节bytes为单位)
torch.cuda.memory_cached(device=None)
[4] - 查看特定设备上缓存分配器最大所占用的 GPU 显存(以字节bytes为单位)
torch.cuda.max_memory_cached(device=None)
[5] - 释放缓存分配器当前所管理的所有未使用的缓存
torch.cuda.empty_cache()
使用,如:
try:
output = model(input)
except RuntimeError as exception:
if "out of memory" in str(exception):
print("WARNING: out of memory")
if hasattr(torch.cuda, 'empty_cache'):
torch.cuda.empty_cache()
else:
raise exceptio
另外一点是,在测试时,避免忘记设置 torch.no_grad()
. 如:
with torch.no_grad():
inputs = None
output = model(inputs)
2. torch.backends.cudnn
在很多代码里看到有这样两行:
torch.backends.cudnn.enabled = True
torch.backends.cudnn.benchmark = True
网上很多资料都说是用于增加程序的运行效率.
其用途为,使得 cudnn 的 auto-tuner 自动寻找最适合当前配置的高效算法,达到优化运行效率的目的.
其遵循的原则有:
[1] - 如果网络的输入数据维度或类型上变化不大,设置 torch.backends.cudnn.benchmark = true
可以增加运行效率;
[2] - 如果网络的输入数据在每次 iteration 都变化的话,会导致 cndnn 每次都会去寻找一遍最优配置,这样反而会降低运行效率.
在采用 cudnn backend 时,PyTorch文档里说需要设置两个选项:
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
其作用是,确定性模式(deterministic mode)的模型可以有提升. 即,如果模型是确定性的,处理时间可能会比非确定性(non-deterministic) 的低.
From: https://pytorch.org/docs/stable/notes/randomness.html?highlight=backends#cudnn