Skip to content

[PyTorch] 將模型刪除後,釋放 GPU / CPU 的記憶體空間

問題描述

昨晚,我在改進一段將模型融合的程式碼時,由於個人設備資源不足,我採取分層合併的方法,一次只取一層的記憶體進行合併,以此減少系統同時保存的模型記憶體大小。然而,我發現模型雖然在 GPU 中的記憶體很容易被刪除、但是 CPU 中的記憶體被回收是十分不容易的。這涉及到了 Python 的資源回收器的設計。

我查了網路上許多資料,僅僅有一個方法對我有用、並且我還在偶然的情況下發現了另一個有用的方法。以下紀錄在下方。


解決方法

首先先來提及大家最常提到的 GPU 記憶體釋放。

model.to("cuda:0")
del model
torch.cuda.empty_cache()


我們只需要使用這一行就能成功釋放掉被刪除的模型記憶體。但是這顯然對 CPU 毫無效果。

當模型還在 CPU 模式的記憶體時,許多人會推薦使用以下的程式碼進行記憶體釋放:

import gc

del model
gc.collect()


在過去一天裡,這個方法僅僅只成功過一次。但由於我需要提交可靠性足夠高的程式碼,所以我不能賭運氣。

有些人分享說將模型包裝起來,成為一個 wrapper(包裝器)後再次刪除是有效的;我嘗試了他們推薦的 lambda 但是對我沒用;而偶然之間看到使用 List 包裝起來再刪除的作法卻成功了!

import gc
from transformers import AutoModelForCausalLM

# Init
models = []
models.append(AutoModelForCausalLM.from_pretrained("gpt2"))

# Operation
models[0].generate(...)

# Delete
del models
gc.collect()


這個方法我嘗試了許多次,每次都能正常地清空記憶體。

而後來,當我在各種優化我的程式碼時,偶然又發現了另外一種方法會清除記憶體,那就是將其丟到 meta 設備(元設備)上:

model.to("meta")


這個方法會建立空的模型架構,不包含任何權重。通常用於特殊的目的,但在我需要釋放記憶體時意外地幫了大忙。

以上,是兩種將 CPU 中的模型記憶體釋放掉的方法紀錄。


References


Read More

Leave a Reply