CUDA out of memory 解決辦法

2021-10-23 11:39:37 字數 2107 閱讀 9310

一般,占用視訊記憶體分為三部分:

網路模型自身引數占用的視訊記憶體。

模型計算時(包括forward/backward/optimizer)所產生的中間變數或引數也有占用視訊記憶體。

程式設計框架自身一些額外的開銷。

減少 batch_size …

犧牲計算速度減少視訊記憶體佔用量,將計算分為兩半,先計算一半模型的結果,儲存中間結果再計算後面一半的模型

# 輸入

input

= torch.rand(1,

10)# 假設我們有乙個非常深的網路

layers =

[nn.linear(10,

10)for _ in

range

(1000)]

model = nn.sequential(

*layers)

output = model(

input

)### 可進行如下更改

# 首先設定輸入的input=>requires_grad=true

# 如果不設定可能會導致得到的gradient為0

input

= torch.rand(1,

10, requires_grad=

true

)layers =

[nn.linear(10,

10)for _ in

range

(1000)]

# 定義要計算的層函式,可以看到我們定義了兩個

# 乙個計算前500個層,另乙個計算後500個層

defrun_first_half

(*args)

: x = args[0]

for layer in layers[

:500]:

x = layer(x)

return x

defrun_second_half

(*args)

: x = args[0]

for layer in layers[

500:-1

]:x = layer(x)

return x

# 我們引入新加的checkpoint

from torch.utils.checkpoint import checkpoint

x = checkpoint(run_first_half,

input

)x = checkpoint(run_second_half, x)

# 最後一層單獨調出來執行

x = layers[-1

](x)

x.sum

.backward(

)# 這樣就可以了

使用 pooling,減小特徵圖的 size

減少全連線層的使用

盡可能使用 inplace 操作,比如 relu 可以使用 inplace=true ,乙個簡單的使用方法,如下:

def

inplace_relu

(m):

classname = m.__class__.__name__

if classname.find(

'relu')!=

-1: m.inplace=

true

model.

(inplace_relu)

每次迴圈結束時刪除 loss,可以節省很少視訊記憶體,但聊勝於無

使用 float16 精度混合計算,可以節省將近 50% 的視訊記憶體,但是要小心一些不安全的操作,如 mean 和 sum,溢位 fp16

對於不需要 bp 的 forward,如 validation,test 請使用torch.no_grad(),注意model.eval()不等於torch.no_grad()

torch.cuda.empty_cache() 是 del 的高階版。

optimizer 的變換使用,理論上 sgd < momentum < adam,可以從計算公式中看出有額外的中間變數

depthwise convolution

不要一次性把資料載入進來,而是部分地讀取,這樣就基本不會出現記憶體不夠的問題

Could not launch app 解決辦法

xcode 的bug 解決方法一 targets general signing 下重新勾選automatically manage signing 解決方法二 1 拔掉裝置,刪除之前build的內容 2 退出xcode,不是關閉視窗 3,刪除下面目錄下的資料夾 users library deve...

gem install redis報錯解決辦法

redis cluster安裝需要通過gem install redis來安裝相關依賴。否則報錯。通過gem install redis會報如下錯誤1 error loading command install loaderror cannot load such file zlib error w...

daemon not running的解決辦法

有時候,當我們執行 adb devices 或者 adb start server 的時候,會出現下面的情況 daemon not running.starting it now on port 5037 adb server didn t ack failed to start daemon 查一...