簡體   English   中英

在 PyTorch 中,當為 GPU 張量分配新值時是否釋放了 GPU 內存?

[英]In PyTorch is GPU memory freed when a GPU tensor is assigned a new value?

當 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 內存緩存,可以使用torch.cuda.empty_cache 使用它不會直接增加單個 PyTorch 實例中可用的 GPU 內存,因為 PyTorch 會自動調用它以嘗試避免 GPU 內存不足錯誤。

重申一下,GPU 張量實際上並沒有“變成”CPU 張量。 在python中,變量名是對對象的引用。 你的代碼真正做的是分配t1來引用一個新的 CPU 張量對象。 在內部,python 計算每個對象的引用數。 當該計數變為零時,該對象立即被釋放。

警告(引用循環):在無法訪問引用循環的情況下,引用計數會失敗。 當對象包含對另一個的引用但在循環中沒有任何對象的引用是可達的時,就會出現無法訪問的引用循環。 為了解決這個問題,python 使用了一個間歇性執行的垃圾收集模塊。 該模塊使用更復雜的算法來檢測和釋放屬於不可達引用循環的對象。 在這些情況下,當循環變得不可訪問時,不一定會釋放內存,而是會在內部垃圾收集器被激活后被釋放。 這會自動且相對不可預測地發生。 如果需要,可以使用 python 的內置gc垃圾收集接口查詢、配置或手動執行垃圾收集器。

基於之前的討論,如果您真的想確保在 PyTorch 中釋放無法訪問的 GPU 內存(即使在無法訪問的引用周期的情況下),您可以使用

import gc
gc.collect()
torch.cuda.empty_cache()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM