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

2024-09-29 23:24:11 发布

您现在位置:Python中文网/ 问答频道 /正文

从零使用开始:

>>> import gc
>>> import GPUtil
>>> import torch
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  0% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |

然后我创造了一个足够大的张量,然后勾起了记忆:

^{pr2}$

然后我试了几种方法来看看张量是否消失了。在

尝试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_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:尝试全部删除torch(好像当del x不起作用时可以这样做-)

不,不….*

>>> del torch
>>> GPUtil.showUtilization()
| ID | GPU | MEM |
------------------
|  0 |  0% |  5% |
|  1 |  0% |  0% |
|  2 |  0% |  0% |
|  3 |  0% |  0% |

然后我试着检查gc.get_objects()但里面似乎还有很多奇怪的东西。。。在

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


Tags: 方法记忆importidcachegputorchmem
2条回答

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

即使使用微小的1元素张量,在del和{}之后,GPUtil.showUtilization(all=True)报告的GPU内存量与用于巨大张量的GPU内存量完全相同(并且torch.cuda.memory_cached()和{}都返回零)。在

Pythorch文档中有一部分似乎非常相关:
https://pytorch.org/docs/stable/notes/cuda.html#memory-management

Memory management

PyTorch uses a caching memory allocator to speed up memory allocations. This allows fast memory deallocation without device synchronizations. However, the unused memory managed by the allocator will still show as if used in nvidia-smi. You can use memory_allocated() and max_memory_allocated() to monitor memory occupied by tensors, and use memory_cached() and max_memory_cached() to monitor memory managed by the caching allocator. Calling empty_cache() releases all unused cached memory from PyTorch so that those can be used by other GPU applications. However, the occupied GPU memory by tensors will not be freed so it can not increase the amount of GPU memory available for PyTorch.

我加粗了一部分提到英伟达smi,据我所知,这是GPUtil使用的。在

相关问题 更多 >

    热门问题