Python 在PyTorch中,当GPU张量被分配一个新值时,GPU内存是否被释放?

Python 在PyTorch中,当GPU张量被分配一个新值时,GPU内存是否被释放?,python,pytorch,Python,Pytorch,当PyTorch中的Cuda变量被分配一个新值时,它再次成为CPU变量(如下面的代码所示)。在这种情况下,GPU上的变量所持有的内存是否会自动释放 import torch t1 = torch.empty(4,5) if torch.cuda.is_available(): t1 = t1.cuda() print(t1.is_cuda) t1 = torch.empty(4,5) print(t1.is_cuda) 上述代码的输出为: True False 在python中,

当PyTorch中的Cuda变量被分配一个新值时,它再次成为CPU变量(如下面的代码所示)。在这种情况下,GPU上的变量所持有的内存是否会自动释放

import torch

t1 = torch.empty(4,5)

if torch.cuda.is_available():
  t1 = t1.cuda()

print(t1.is_cuda)

t1 = torch.empty(4,5)
print(t1.is_cuda)
上述代码的输出为:

True
False

在python中,只要没有对对象的剩余引用,对象就会被释放。由于将
t1
指定为引用一个全新的张量,因此不再引用原始GPU张量,因此将释放张量。这就是说,当PyTorch被指示释放GPU张量时,它倾向于将GPU内存缓存一段时间,因为通常情况下,如果我们使用一次GPU内存,我们可能会希望再次使用一些,而GPU内存分配相对较慢。如果要强制清除GPU内存的缓存,可以使用。使用它不会直接增加单个PyTorch实例中可用的GPU内存,因为PyTorch会自动调用它,以避免GPU内存不足错误

重申一下,GPU张量实际上并没有“变成”CPU张量。在python中,变量名是对对象的引用。您的代码真正做的是分配
t1
以引用新的CPU张量对象。在内部,python统计每个对象的引用数。当该计数为零时,该对象立即被释放

警告(参考周期):在无法达到参考周期的情况下,参考计数失败。当对象包含对彼此的引用,但对循环中任何对象的引用都不可访问时,就会发生不可访问的引用循环。为了处理这个问题,python使用了一个间歇执行的垃圾收集模块。该模块使用更复杂的算法来检测和释放不可到达参考周期中的对象。在这些情况下,当循环变得不可访问时,内存不一定被释放,而是在内部垃圾收集器被激活后被释放。这是自动发生的,而且相对不可预测。如果需要,可以使用python内置的垃圾收集接口查询、配置或手动执行垃圾收集器

根据前面的讨论,如果您真的想确保在PyTorch中释放不可访问的GPU内存(即使在不可访问的引用周期的情况下),您可以使用

导入gc
gc.collect()
torch.cuda.empty_cache()