Memory leaks PyTorch CPU内存泄漏,但仅在特定机器上运行时发生

Memory leaks PyTorch CPU内存泄漏,但仅在特定机器上运行时发生,memory-leaks,pytorch,Memory Leaks,Pytorch,我正在运行一个模型,我注意到在模型的训练过程中,RAM的使用率缓慢增加。每个历元大约有200mb-400mb,但随着时间的推移,它会填满我机器上的所有RAM,最终导致操作系统终止作业。然而,奇怪的是,只有在特定的机器上运行时才会出现这种情况。我在不同的机器上运行了相同的代码,没有任何内存泄漏 这两台机器之间的区别是,一台运行的是带有cuda 10.2的Pytork 1.7.1(没有内存泄漏的机器),另一台运行的是Pytork 1.8.1。这两台机器都使用conda运行,并且仅在CPU上运行。我曾

我正在运行一个模型,我注意到在模型的训练过程中,RAM的使用率缓慢增加。每个历元大约有200mb-400mb,但随着时间的推移,它会填满我机器上的所有RAM,最终导致操作系统终止作业。然而,奇怪的是,只有在特定的机器上运行时才会出现这种情况。我在不同的机器上运行了相同的代码,没有任何内存泄漏

这两台机器之间的区别是,一台运行的是带有cuda 10.2的Pytork 1.7.1(没有内存泄漏的机器),另一台运行的是Pytork 1.8.1。这两台机器都使用conda运行,并且仅在CPU上运行。我曾尝试在内存泄漏的机器上使用Pytork的旧版本,但内存泄漏仍然存在,因此我怀疑这是由于Pytork版本造成的

我一直在使用
psutil
来监控CPU上的RAM使用情况,并且我一直在使用
tracemalloc
包来打印训练循环期间的快照,以查看内存使用情况从一个历元到下一个历元的变化。然而,当打印出这些差异时,我的代码中没有任何与200mb-400mb内存增加量相匹配的内容

这方面的一个例子是

Epoch     25/  1000 Loss 1428.8508 RAM:  9.910GB
~/Model.py:46: size=1136 B (-96 B), count=2 (+0), average=568 B
~/utils.py:14: size=1040 B (+24 B), count=8 (+1), average=130 B
~/calc_loss.py:79: size=2128 B (+0 B), count=24 (+0), average=89 B
~/calc_loss.py:78: size=2056 B (+0 B), count=23 (+0), average=89 B
~/utils.py:6: size=1920 B (+0 B), count=21 (+0), average=91 B
Epoch     26/  1000 Loss 1426.0033 RAM: 10.254GB
~/Model.py:46: size=1232 B (+96 B), count=2 (+0), average=616 B
~/utils.py:14: size=1016 B (-24 B), count=7 (-1), average=145 B
~/calc_loss.py:79: size=2128 B (+0 B), count=24 (+0), average=89 B
~/calc_loss.py:78: size=2056 B (+0 B), count=23 (+0), average=89 B
~/utils.py:6: size=1920 B (+0 B), count=21 (+0), average=91 B
~/Layers.py:71: size=992 B (+0 B), count=11 (+0), average=90 B
Epoch     27/  1000 Loss 1436.8241 RAM: 10.606GB
~/utils.py:14: size=1040 B (+24 B), count=8 (+1), average=130 B
~/calc_loss.py:79: size=2128 B (+0 B), count=24 (+0), average=89 B
~/calc_loss.py:78: size=2056 B (+0 B), count=23 (+0), average=89 B
~/utils.py:6: size=1920 B (+0 B), count=21 (+0), average=91 B
~/Model.py:46: size=1232 B (+0 B), count=2 (+0), average=616 B
~/Layers.py:71: size=992 B (+0 B), count=11 (+0), average=90 B
Epoch     28/  1000 Loss 1428.6560 RAM: 10.968GB
~/calc_loss.py:79: size=2128 B (+0 B), count=24 (+0), average=89 B
~/calc_loss.py:78: size=2056 B (+0 B), count=23 (+0), average=89 B
~/utils.py:6: size=1920 B (+0 B), count=21 (+0), average=91 B
~/Model.py:46: size=1232 B (+0 B), count=2 (+0), average=616 B
~/utils.py:14: size=1040 B (+0 B), count=8 (+0), average=130 B
Epoch     29/  1000 Loss 1435.2988 RAM: 11.321GB
~/calc_loss.py:79: size=2128 B (+0 B), count=24 (+0), average=89 B
~/calc_loss.py:78: size=2056 B (+0 B), count=23 (+0), average=89 B
~/utils.py:6: size=1920 B (+0 B), count=21 (+0), average=91 B
~/Model.py:46: size=1232 B (+0 B), count=2 (+0), average=616 B
~/utils.py:14: size=1040 B (+0 B), count=8 (+0), average=130 B
~/Layers.py:71: size=992 B (+0 B), count=11 (+0), average=90 B
显示当前历元的行之间打印的信息是通过使用此功能创建的

def compare_snaps(snap1, snap2, limit=50):
  top_stats=snap1.compare_to(snap2, "lineno")
  
  for stat in top_stats[:limit]:
    line=str(stat)
    if("~/" in line): #filter only lines from my own code
      print(line)
此函数从当前纪元和上一纪元的
tracemalloc.take_snapshot()
中获取两个快照,并比较内存使用情况的变化。它接受前50个内存密集型操作,只过滤我编写的操作(即,它排除anaconda3中的任何更改),并将这些更改打印到屏幕上。可以看出,内存中的变化可以忽略不计。事实上,当比较两台机器的快照输出时,它们几乎相同

PyTorch代码在一台机器上有内存泄漏而在另一台机器上没有,这看起来真的很奇怪。。。这可能是康达的环境问题吗?我试着从一个pip安装运行这个,但泄漏仍然存在。我知道这有点含糊(因为没有源代码),但是有没有办法检查泄漏的来源?编译代码会想到Valgrind之类的东西,但解释性代码不会想到。这个内存泄漏问题似乎超出了我的技能范围,因此任何帮助都将不胜感激


谢谢!:)

尝试在您的流程中包含以下内容:

import gc

# add this after computing one complete operation
gc.collect()

当我在许多历代中反复运行这个程序时,我想你的意思是在历代结束时添加
gc.collect()
?是的,这就是你要做的。对,所以我在我的训练循环结束时添加了
gc.collect()
,以及RAM使用情况(正如psutil所说的)每一个历元仍会增加大约200mb。您认为导致此泄漏的可能是环境问题吗?另外,在打印内存使用量快照之间的差异时,没有一行与200mb内存增加相匹配。。。在浏览了gc库之后,确实很奇怪,似乎gc.get_objects()命令可能很有用,因为它会在每个对象上打印出脚本中的对象数。而且,我可以看到慢慢增加。。。(每个时代大约200人左右)。有没有办法比较两个不同的gc.get_objects()调用?我试着打印出来,但它只是抛出了一个不同的错误