訓練大模型時,顯存都哪去了? 原創(chuàng)
GPT-2(XL)有15億個參數(shù),使用16位精度,一個參數(shù)占用2個字節(jié)的內(nèi)存,因此這些參數(shù)大約占用3GB的內(nèi)存。
按照如下超參數(shù)設(shè)置:
- 優(yōu)化器 → Adam
- 批量大小 → 32
- 變換層數(shù)量 → 48
- 序列長度 → 1000
要想在單個GPU上訓練GPT-2,所需的最小內(nèi)存大概是多少?
答案可能會嚇到你。
在一個擁有32GB內(nèi)存的單個GPU上,幾乎無法訓練一個3GB的GPT-2模型。
但這怎么可能呢?內(nèi)存都去哪了?讓我們來了解一下。
模型在訓練過程中有很多方面會持續(xù)占用內(nèi)存。
#1)優(yōu)化器狀態(tài),梯度,模型參數(shù)
混合精度訓練廣泛用于加速模型訓練。
顧名思義,這個方法的思想是在訓練過程中同時使用float16低精度(在卷積和矩陣乘法等操作中)和高精度(如32位浮點數(shù),float32)。
這就是“混合精度”名稱的由來。
前向傳播和反向傳播都使用16位浮點數(shù)表示權(quán)重和梯度。
因此,如果模型有Φ個參數(shù),那么:
● 權(quán)重將占用2 * Φ字節(jié)的內(nèi)存。
● 梯度將占用2 * Φ字節(jié)的內(nèi)存。
這里的“2”表示每個參數(shù)占用2個字節(jié)的內(nèi)存(16位)。
Adam 是最受歡迎的模型訓練優(yōu)化器之一。
雖然許多實踐者僅僅因為它流行而使用它,但他們沒有意識到,在訓練過程中,Adam 會存儲兩種優(yōu)化器狀態(tài)來計算更新——梯度的動量和方差。
因此,如果模型有Φ個參數(shù),那么這兩個優(yōu)化器狀態(tài)將消耗:
● 4 * Φ 字節(jié)用于動量。
● 另需 4 * Φ 字節(jié)用于方差。
這里的“4”表示每個參數(shù)占用 4 個字節(jié)的內(nèi)存(32 位)。
此外,反向傳播結(jié)束時的更新仍然在32位精度下進行,以確保有效的計算。這導(dǎo)致:
● 另需 4 * Φ 字節(jié)用于模型參數(shù)。
讓我們把它們加起來:
這就是 16 * Φ,或者 24GB 的內(nèi)存,遠遠高于 16 位參數(shù)所使用的 3GB 內(nèi)存。
而且我們還沒有考慮到所有的因素。
2#)激活值
對于像大型深度學習模型(如大語言模型,LLMs)來說,激活值在訓練過程中占用了大量內(nèi)存。
更確切地說,在GPT-2的一個Transformer塊中計算的激活值總數(shù)是:
因此,在所有的Transformer塊中,總計就是:
這是 GPT-2-XL 的配置:
總共大約是 300 億個激活值。由于每個激活值使用 16 位表示,所有激活值總共占用 60GB 的內(nèi)存。
通過使用像梯度檢查點(在上一章討論過的)這樣的技術(shù),可以將內(nèi)存消耗降低到大約 8-9GB,但這也會帶來額外 25-30% 的計算開銷。
除了可以計算的內(nèi)存開銷外,還有一些額外的開銷,例如內(nèi)存碎片化。
內(nèi)存碎片化是指在分配的內(nèi)存塊之間存在小的未使用間隙,導(dǎo)致可用內(nèi)存的低效使用。
內(nèi)存分配請求失敗是因為沒有足夠的連續(xù)內(nèi)存塊可用。
在上述討論中,我們考慮了一個相對較小的模型——GPT-2(XL),它有 15 億個參數(shù),與如今訓練的模型規(guī)模相比非常小。
然而,這個討論可能幫助你反思構(gòu)建大規(guī)模語言模型(LLMs)時的固有挑戰(zhàn)。很多人常說,GPT 模型只是簡單地堆疊更多的層并使網(wǎng)絡(luò)變得更大。
如果真是那么簡單,大家都會在做了。從這個討論中,你可能已經(jīng)理解到,這并不像僅僅添加更多層那么簡單。
即便是增加一層,也可能導(dǎo)致額外數(shù) GB 的內(nèi)存需求。多 GPU 訓練是這些模型的核心技術(shù),我們將在另一篇文章中討論。
本文轉(zhuǎn)載自公眾號人工智能大講堂
原文鏈接:??https://mp.weixin.qq.com/s/PFQZnqJJ-tjFcv6oSjaV-A??
