Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么清除对象后GPU中的内存仍在使用?_Python_Memory Leaks_Garbage Collection_Gpu_Pytorch - Fatal编程技术网

Python 为什么清除对象后GPU中的内存仍在使用?

Python 为什么清除对象后GPU中的内存仍在使用?,python,memory-leaks,garbage-collection,gpu,pytorch,Python,Memory Leaks,Garbage Collection,Gpu,Pytorch,从零使用开始: >>> import gc >>> import GPUtil >>> import torch >>> GPUtil.showUtilization() | ID | GPU | MEM | ------------------ | 0 | 0% | 0% | | 1 | 0% | 0% | | 2 | 0% | 0% | | 3 | 0% | 0% | 然后我创建一个足够大的张量

从零使用开始:

>>> import gc
>>> import GPUtil
>>> import torch
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  0% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
然后我创建一个足够大的张量并占用内存:

>>> x = torch.rand(10000,300,200).cuda()
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% | 26% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
然后我尝试了几种方法来看看张量是否消失了

尝试1:分离、发送到CPU并覆盖变量

不,不起作用。

>>> x = x.detach().cpu()
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% | 26% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
尝试2:删除变量

不,这也不行

>>> del x
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% | 26% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
尝试3:使用
torch.cuda.empty\u cache()函数

似乎有效,但似乎有一些挥之不去的日常开支

>>> torch.cuda.empty_cache()
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  5% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
尝试4:可能会清除垃圾收集器

不,5%的人仍在被抢走

>>> gc.collect()
0
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  5% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
尝试5:尝试将
火炬
一起删除(好像当
del x
不起作用时,这会起作用-)

不,它没有...*

>>> del torch
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  5% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |
然后我试着检查
gc.get_objects()
,看起来里面还有很多奇怪的
THCTensor
东西


知道为什么清除缓存后内存仍在使用吗?

看起来PyTorch的缓存分配器保留了一些固定数量的内存,即使没有张量,这种分配也是由第一次CUDA内存访问触发的 (
torch.cuda.empty_cache()
从缓存中删除未使用的张量,但缓存本身仍使用一些内存)


即使使用一个很小的单元素张量,在
del
torch.cuda.empty_cache()
之后,
GPUtil.showUtilization(all=True)
报告的GPU内存使用量与使用一个大张量的GPU内存使用量完全相同(两者都
torch.cuda.memory_cached()
torch.cuda.memory_allocated()
返回零).

PyTorch文档中有一部分似乎非常相关:

内存管理

PyTorch使用缓存内存分配器来加速内存 拨款。这允许在没有设备的情况下快速释放内存 同步。但是,分配器管理的未使用内存 仍将显示为在nvidia smi中使用。你可以用 内存分配()和最大内存分配()来监视内存 被张量占用,并使用memory_cached()和max_memory_cached() 监视由缓存分配器管理的内存。使命感 empty_cache()从PyTorch中释放所有未使用的缓存内存,以便 这些可以被其他GPU应用程序使用。然而,被占用的GPU 张量产生的内存将不会被释放,因此无法增加数量 可用于PyTorch的GPU内存数量


我用粗体显示了一部分,其中提到了nvidia smi,据我所知,它是由GPUtil使用的。

首先,使用
nvidia smi
确认哪个进程正在使用GPU内存。在那里,进程id
pid
可用于查找进程。如果没有显示任何进程,但GPU内存仍在使用,您可以尝试清除内存。Torch还可以为内部系统/管理器等分配内存。可能是它的分配器。关于
空\u cache()
的句子呢?对我来说,这听起来很明显,它确实释放了内存,也就是说,它也是以“nvidia smi free”的方式释放的。的确,但不幸的是,它还声明,它只释放pytorch认为未使用的内存。。。这可能是挥之不去的5%,是的。一定也有@Tiphaine建议的内在因素。但这5%的运算量约为5千兆字节!然后,文档只知道“未使用的缓存内存”和“被张量占用的GPU内存”,这5%似乎都不属于它们。