如何計算顯存的佔用,常常遇到out of memory?

如何計算顯存的佔用,預防out of memory?

最近一次組會上,師兄點評一篇文章顯存佔用過多,突然發現還不知道如何具體的計算顯存,只好去學習一下。

顯存類似於內存,可以存放模型數據,參數等等;顯存越大,所能運行的網絡也就越大

torch.FatalError: cuda runtime error (2) : out of memory at /opt/conda/.......

out of memory: 顯存裝不下你那麼多的模型權重還有中間變量

GPU計算單元用來進行數值計算,衡量計算量的單位是flop,浮點數先乘後加算一個flop計算能力越強大,速度越快。衡量計算能力的單位是 flops: 每秒能執行的 flop數量。

2*2+2 :1個flop

2*2+3*3+4*4 : 3個flop

1、 存儲指標

1 Byte = 8 bit
1 K = 1024 Byte
1 M = 1024 K
1 G = 1024 M

除此之外,

1 Byte = 8 bit
1 KB = 1000 Byte
1 MB = 1000 KB
1 GB = 1000 MB
1TB = 1000 GB

常用的數值類型:

若一張256*256的RGB圖片存儲在顯存中佔有顯存爲(float):

3*256*256*4=0.75M,若batchsize=100,也就佔用75M,顯存,顯然,佔用顯存較大的不是輸入圖片數據,那會是什麼呢?

什麼佔用了顯存?

首先,瞭解神經網絡的構成,我們當然知道神經網絡只是一種類似神經的架構,主要由構成網絡層的各種參數構成,以及神經網絡的各種中間輸出。

網絡模型的參數:

看一個例子:

  • 模型權重:各種網絡層的參數
  • 卷積層,通常的conv2d
  • 全連接層,也就是Linear層
  • BatchNorm層
  • Embedding層
  • 中間變量:各種網絡層的輸出

而不佔用顯存的則是:

  • 剛纔說到的激活層Relu等
  • 池化層
  • Dropout層

具體計算方式:

  • Conv2d(Cin, Cout, K): 參數數目:Cin × Cout × K × K
  • Linear(M->N): 參數數目:M×N
  • BatchNorm(N): 參數數目: 2N
  • Embedding(N,W): 參數數目: N × W

參數佔用顯存:

參數佔用顯存 = 參數數目×n

n = 4 :float32
n = 2 : float16
n = 8 : double64

優化器的顯存佔用:

例如SGD優化器:

除了保存W之外還要保存參數對應的梯度,因此顯存佔用等於參數佔用的顯存的2倍。

Momentum-SGD:保存參數、梯度、動量------3倍

Adam:------------------------------------------4倍

輸入輸出的顯存佔用:

特點:

  • 需要計算每一層的feature map的形狀(多維數組的形狀)
  • 模型輸出的顯存佔用與 batch size 成正比
  • 需要保存輸出對應的梯度用以反向傳播(鏈式法則)
  • 模型輸出不需要存儲相應的動量信息(因爲不需要執行優化)

具體計算:

顯存佔用 = 模型顯存佔用 + batch_size × 每個樣本的顯存佔用

注意 : 輸入數據不用計算梯度;激活函數不用保存輸入;

如何減小顯存佔用?出現out of memory如何處理?

  • 儘量不使用全連接層
  • 下采樣
  • 減小batchsize

最簡單處理方法,也是最常用的方法

減小batchsize

一般模型參數與batchsize成一定的不嚴格的正比關係。

參考資料:https://blog.csdn.net/liusandian/article/details/79069926

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章