
使用 ASP.NET Web API 構(gòu)建 RESTful API
如上所述,ΔW的分解意味著我們用兩個(gè)較小的LoRA矩陣A和B來(lái)表示大矩陣ΔW。如果A的行數(shù)與ΔW相同,B的列數(shù)與ΔW相同,我們可以將這種分解表示為ΔW = AB(即矩陣A和B的乘積)。
這種分解能節(jié)省多少內(nèi)存呢?這取決于超參數(shù)r的值。例如,如果ΔW有10,000行和20,000列,那么它需要存儲(chǔ)200,000,000個(gè)參數(shù)。如果我們選擇r = 8,那么A將有10,000行和8列,B將有8行和20,000列,這樣A和B總共需要存儲(chǔ)的參數(shù)數(shù)為10,000×8 + 8×20,000 = 240,000個(gè)參數(shù),大約是原來(lái)參數(shù)數(shù)的1/830。
當(dāng)然,A和B無(wú)法像ΔW那樣捕捉所有信息,但這是有意為之的設(shè)計(jì)。使用LoRA時(shí),我們假設(shè)模型在預(yù)訓(xùn)練階段需要W是一個(gè)全秩的大型矩陣,以包含預(yù)訓(xùn)練數(shù)據(jù)集中的所有知識(shí)。然而,在微調(diào)LLM時(shí),我們并不需要更新所有權(quán)重,也不需要用比ΔW更少的參數(shù)來(lái)捕捉適應(yīng)的核心信息;因此,我們通過AB進(jìn)行低秩更新。
在使用LoRA進(jìn)行多次實(shí)驗(yàn)后,我注意到盡管大型語(yǔ)言模型(LLM)的訓(xùn)練本身具有隨機(jī)性,尤其是在GPU上進(jìn)行模型訓(xùn)練時(shí),基準(zhǔn)測(cè)試的結(jié)果在不同運(yùn)行之間卻異常一致。這種一致性為其他比較研究提供了堅(jiān)實(shí)的基礎(chǔ)。
請(qǐng)注意,這些結(jié)果是在默認(rèn)設(shè)置下,使用較小的r=8得到的。具體的實(shí)驗(yàn)細(xì)節(jié)可以在我另一篇文章中找到。
Dettmers等人提出的QLoRA,即量化LoRA,是一種在微調(diào)過程中進(jìn)一步減少內(nèi)存使用的技術(shù)。在反向傳播階段,QLoRA將預(yù)訓(xùn)練的權(quán)重量化到4位精度,并利用分頁(yè)優(yōu)化器來(lái)管理內(nèi)存峰值。
實(shí)際上,我發(fā)現(xiàn)使用QLoRA可以節(jié)省33%的GPU內(nèi)存。然而,由于QLoRA中預(yù)訓(xùn)練模型權(quán)重的額外量化和去量化步驟,訓(xùn)練運(yùn)行時(shí)間增加了39%。
以下是使用16位浮點(diǎn)數(shù)的默認(rèn)LoRA的對(duì)比數(shù)據(jù):
而使用4位量化浮點(diǎn)數(shù)的QLoRA的數(shù)據(jù)如下:
此外,我觀察到模型性能幾乎沒有受到影響,這使得QLoRA成為常規(guī)LoRA訓(xùn)練的一個(gè)可行替代方案,特別是在面臨常見的GPU內(nèi)存瓶頸時(shí)。
學(xué)習(xí)率調(diào)度器在訓(xùn)練過程中逐漸降低學(xué)習(xí)率,這有助于優(yōu)化模型的收斂性能,并防止在最小化損失函數(shù)時(shí)超出最小值點(diǎn)。
余弦退火是一種流行的學(xué)習(xí)率調(diào)度器,它根據(jù)余弦曲線來(lái)調(diào)整學(xué)習(xí)率。這種調(diào)度器以較高的學(xué)習(xí)率開始,然后逐漸下降,最終以類似余弦函數(shù)的方式趨近于零。一個(gè)常見的變體是半周期余弦退火,它在訓(xùn)練過程中只完成一個(gè)半周期的余弦曲線,如下圖所示。
作為實(shí)驗(yàn)的一部分,我在LoRA微調(diào)腳本中加入了余弦退火學(xué)習(xí)率調(diào)度器,并發(fā)現(xiàn)它顯著提升了SGD的性能。然而,對(duì)于Adam和AdamW優(yōu)化器,余弦退火的影響較小,幾乎沒有明顯差異
關(guān)于SGD相對(duì)于Adam的潛在優(yōu)勢(shì),我將在下一節(jié)中進(jìn)一步討論。
Adam和AdamW優(yōu)化器在深度學(xué)習(xí)中仍然是熱門選擇,盡管在使用大型模型時(shí),它們會(huì)占用大量?jī)?nèi)存。這是因?yàn)锳dam優(yōu)化器為每個(gè)模型參數(shù)維護(hù)兩個(gè)移動(dòng)平均值:一個(gè)是梯度的第一個(gè)矩(平均值),另一個(gè)是梯度的第二個(gè)矩(非中心方差)。換句話說,Adam優(yōu)化器在內(nèi)存中為每個(gè)模型參數(shù)存儲(chǔ)兩個(gè)額外的值。如果我們使用的是一個(gè)擁有70億參數(shù)的模型,則在訓(xùn)練期間需要跟蹤額外的140億參數(shù)。
與此不同,SGD優(yōu)化器在訓(xùn)練過程中不需要跟蹤任何額外參數(shù)。那么,在訓(xùn)練大型語(yǔ)言模型(LLM)時(shí),將Adam替換為SGD對(duì)峰值內(nèi)存需求有什么優(yōu)勢(shì)呢?
在我的實(shí)驗(yàn)中,使用AdamW和LoRA默認(rèn)設(shè)置(r=8)訓(xùn)練的70億參數(shù)Llama 2模型需要14.18 GB的GPU內(nèi)存。相反,使用SGD訓(xùn)練相同的模型僅需14.15 GB的GPU內(nèi)存。換句話說,節(jié)省的內(nèi)存(0.03 GB)幾乎微不足道。
為什么節(jié)省的內(nèi)存如此之少?這是因?yàn)槭褂肔oRA時(shí),我們只有少量可訓(xùn)練參數(shù)。例如,當(dāng)r=8時(shí),在70億Llama 2模型的6,738,415,616個(gè)參數(shù)中,只有4,194,304個(gè)是可訓(xùn)練的LoRA參數(shù)。
如果僅從數(shù)字上看,4,194,304個(gè)可訓(xùn)練參數(shù)聽起來(lái)仍然很多,但經(jīng)過計(jì)算,我們發(fā)現(xiàn)這些參數(shù)的內(nèi)存占用為4,194,304 × 2 × 16位 = 134.22兆位 = 16.78兆字節(jié)。我們觀察到的0.03 GB(30 MB)差異是由于存儲(chǔ)和復(fù)制優(yōu)化器狀態(tài)所產(chǎn)生的額外開銷。這里的2表示Adam存儲(chǔ)的額外參數(shù)數(shù)量,16位指的是模型權(quán)重的默認(rèn)精度。
然而,如果我們將LoRA的r增加到256(我在后續(xù)實(shí)驗(yàn)中已經(jīng)這樣做),Adam和SGD優(yōu)化器之間的內(nèi)存差異將變得更加明顯:
總的來(lái)說,當(dāng)LoRA的r值較小時(shí),替換Adam優(yōu)化器為SGD可能不值得。然而,當(dāng)我們?cè)黾觬值時(shí),這種替換可能會(huì)變得更加有意義。
在傳統(tǒng)深度學(xué)習(xí)中,我們經(jīng)常對(duì)訓(xùn)練集進(jìn)行多次迭代,這種對(duì)訓(xùn)練集的重復(fù)遍歷稱為訓(xùn)練周期(epoch)。例如,在訓(xùn)練卷積神經(jīng)網(wǎng)絡(luò)時(shí),通常會(huì)執(zhí)行數(shù)百個(gè)訓(xùn)練周期。那么,多周期訓(xùn)練是否也適用于指令微調(diào)呢?
當(dāng)我將包含50k示例的Alpaca指令微調(diào)數(shù)據(jù)集的迭代次數(shù)增加一倍(相當(dāng)于兩個(gè)訓(xùn)練周期)時(shí),我注意到模型性能有所下降。
我的結(jié)論是,多周期訓(xùn)練可能對(duì)指令微調(diào)并無(wú)益處,因?yàn)樗赡軐?dǎo)致結(jié)果變差。我在包含1k示例的LIMA數(shù)據(jù)集中也觀察到了相同的現(xiàn)象。這種性能下降可能是由于過度擬合導(dǎo)致的,這還需要進(jìn)一步的研究和調(diào)查。
上表展示了僅對(duì)選定的權(quán)重矩陣(即每個(gè)轉(zhuǎn)換器層中的Key和Value權(quán)重矩陣)啟用LoRA的實(shí)驗(yàn)結(jié)果。此外,我們也有能力為Query權(quán)重矩陣、投影層、多頭注意力塊間的其他線性層以及線性輸出層啟用LoRA。
若我們?yōu)樗羞@些額外的層啟用LoRA,在7B Llama 2模型中,可訓(xùn)練參數(shù)的數(shù)量將從4,194,304增加到20,277,248,即增加了5倍。這同時(shí)會(huì)帶來(lái)更高的內(nèi)存需求,從14.18 GB提升至16.62 GB。盡管如此,這種設(shè)置仍有望顯著提升模型的性能。
然而,我的實(shí)驗(yàn)存在一個(gè)局限,即僅探索了兩個(gè)設(shè)置:一是僅對(duì)查詢和值權(quán)重矩陣啟用LoRA,二是為所有層啟用LoRA。在未來(lái)的實(shí)驗(yàn)中,探索其他組合可能會(huì)很有價(jià)值。例如,探究?jī)H為投影層啟用LoRA是否真正有益將是一個(gè)有趣的課題。
正如原始LoRA論文所描述的,LoRA引入了一個(gè)額外的縮放系數(shù),用于在前向傳遞期間將LoRA權(quán)重應(yīng)用于預(yù)訓(xùn)練權(quán)重。這個(gè)縮放過程涉及到我們之前討論過的rank參數(shù)r,以及另一個(gè)超參數(shù)α(alpha),其應(yīng)用方式如下:
scaling = alpha / r
weight += (lora_B @ lora_A) * scaling
如上代碼公式所示,LoRA權(quán)重的影響隨著縮放系數(shù)的調(diào)整而變化。
以往的實(shí)驗(yàn)通常使用r=8和α=16,這導(dǎo)致了2倍的縮放。在將LoRA應(yīng)用于LLM時(shí),選擇α作為r的兩倍是一個(gè)常見的經(jīng)驗(yàn)法則,但我好奇這是否也適用于較大的r值。換句話說,“α = 2×rank”似乎確實(shí)是一個(gè)較好的起點(diǎn)。然而,在特定模型和數(shù)據(jù)集的組合中,例如r=256和α=128(縮放0.5倍)時(shí),性能甚至更好。
我進(jìn)行了r=32、r=64、r=128和r=512的實(shí)驗(yàn),但為了簡(jiǎn)潔,我省略了這些結(jié)果,因?yàn)閞=256時(shí)性能最佳。
通常選擇α為r的兩倍可能會(huì)得到較好的結(jié)果,但嘗試不同的比例也是值得的。
一個(gè)重要的收獲是,LoRA技術(shù)使我們能夠在單個(gè)GPU上微調(diào)擁有70億參數(shù)的大型語(yǔ)言模型(LLM)。以使用最佳配置(r=256和α=512)的QLoRA為例,使用AdamW優(yōu)化器,在50k訓(xùn)練樣本(這里指的是Alpaca數(shù)據(jù)集)上進(jìn)行微調(diào)大約需要3小時(shí)(在A100 GPU上)。
在本文的后續(xù)部分,我將回答您可能存在的其他問題。
數(shù)據(jù)集可能非常關(guān)鍵。在我的實(shí)驗(yàn)中,我使用了包含50k個(gè)訓(xùn)練樣本的Alpaca數(shù)據(jù)集。選擇這個(gè)數(shù)據(jù)集是因?yàn)樗鼜V受歡迎,而且由于文章篇幅已經(jīng)很長(zhǎng),嘗試不同的數(shù)據(jù)集超出了本文的范圍。
然而,值得注意的是,Alpaca是一個(gè)通過查詢舊版本的ChatGPT生成的合成數(shù)據(jù)集,按照今天的標(biāo)準(zhǔn)可能不是最優(yōu)選擇。
數(shù)據(jù)質(zhì)量可能非常重要。例如,在六月份,我討論了LIMA數(shù)據(jù)集(領(lǐng)先于AI #9:LLM調(diào)整和數(shù)據(jù)集視角),這是一個(gè)精選的、只有1k個(gè)樣本的數(shù)據(jù)集。
根據(jù)“LIMA:對(duì)準(zhǔn)少即是多”的論文,在LIMA上微調(diào)的65B Llama模型明顯優(yōu)于在Alpaca上微調(diào)的65B Llama模型。
即使LIMA的數(shù)據(jù)集規(guī)模只有Alpaca的1/50,使用最佳配置(r=256,alpha=512)在LIMA上微調(diào),我獲得了與Alpaca數(shù)據(jù)集相似甚至更好的性能。
遺憾的是,對(duì)于這個(gè)問題,我并沒有一個(gè)確切的答案。根據(jù)經(jīng)驗(yàn),知識(shí)通常是從預(yù)訓(xùn)練數(shù)據(jù)集中吸收的,而指令微調(diào)更多的是幫助或指導(dǎo)大型語(yǔ)言模型(LLM)遵循指令。
然而,值得注意的是,如果內(nèi)存是一個(gè)問題,LoRA也可以用來(lái)在特定領(lǐng)域的數(shù)據(jù)集上進(jìn)一步預(yù)訓(xùn)練現(xiàn)有的預(yù)訓(xùn)練LLM。
請(qǐng)注意,我的實(shí)驗(yàn)還包括兩個(gè)算術(shù)基準(zhǔn)測(cè)試(這些測(cè)試包含在我其他更具技術(shù)性的文章中),其中LoRA微調(diào)模型的性能明顯不如預(yù)訓(xùn)練的基礎(chǔ)模型。我的假設(shè)是模型取消了學(xué)習(xí)算術(shù),因?yàn)锳lpaca數(shù)據(jù)集不包含相應(yīng)的示例。是模型完全丟失了知識(shí),還是因?yàn)槟P蜔o(wú)法再處理指令,這需要進(jìn)一步調(diào)查。但這里的一個(gè)要點(diǎn)是,在微調(diào)LLM時(shí),包含您關(guān)心的每項(xiàng)任務(wù)的示例可能是一個(gè)好主意。
不幸的是,我沒有任何好的啟發(fā)式方法來(lái)選擇一個(gè)好的r值,并認(rèn)為它是一個(gè)超參數(shù),需要針對(duì)每個(gè)LLM和每個(gè)數(shù)據(jù)集進(jìn)行探索。我懷疑選擇過大的r可能會(huì)導(dǎo)致更多的過擬合。另一方面,較小的r可能無(wú)法捕獲數(shù)據(jù)集中的不同任務(wù)。換句話說,我懷疑數(shù)據(jù)集中的任務(wù)越多樣化,r值應(yīng)該越大。例如,如果我只想要一個(gè)執(zhí)行基本2位運(yùn)算的模型,那么一個(gè)小的r可能就足夠了。然而,這只是一個(gè)假設(shè),需要額外的調(diào)查。
我僅探索了兩個(gè)設(shè)置:一是LoRA僅用于查詢和值權(quán)重矩陣,二是LoRA用于所有層。在未來(lái)的實(shí)驗(yàn)中,探索其他組合可能會(huì)更有價(jià)值。例如,了解為投影層激活LoRA是否真正有益會(huì)是一個(gè)有趣的課題。如果我們考慮各種設(shè)置,包括lora_query、lora_key、lora_value、lora_projection、lora_mlp和lora_head,那么就需要探索2^6=64種組合,這將是未來(lái)研究的一個(gè)有趣方向。
通常,較大的r值會(huì)導(dǎo)致更多的過擬合,因?yàn)樗鼪Q定了可訓(xùn)練參數(shù)的數(shù)量。如果模型存在過擬合問題,那么減小r值或增加數(shù)據(jù)集大小是首先要考慮的解決方案。此外,還可以嘗試在AdamW或SGD優(yōu)化器中增加權(quán)重衰減率,并考慮增加LoRA層的dropout值。我在實(shí)驗(yàn)中未探索過LoRA的dropout參數(shù)(固定使用了0.05的dropout率),這將是未來(lái)研究的一個(gè)有趣話題。
未來(lái)值得探索其他有趣的LLM(大型語(yǔ)言模型)優(yōu)化器。例如,5月發(fā)布的Sophia:一種可擴(kuò)展的隨機(jī)二階優(yōu)化器,專為語(yǔ)言模型預(yù)訓(xùn)練而設(shè)計(jì)。
Sophia作為一種二階優(yōu)化算法,對(duì)Adam和AdamW這類在LLM中通常占據(jù)主導(dǎo)地位的優(yōu)化器來(lái)說,具有特別的吸引力。據(jù)該論文所述,與Adam相比,Sophia的速度提高了2倍,且使用Sophia訓(xùn)練的模型能夠?qū)崿F(xiàn)更佳的建模性能。簡(jiǎn)而言之,Sophia通過梯度曲率(而非像Adam中的梯度方差)來(lái)標(biāo)準(zhǔn)化梯度。
除了精度和量化設(shè)置、模型大小、批量大小以及可訓(xùn)練的LoRA參數(shù)數(shù)量外,數(shù)據(jù)集本身也會(huì)影響內(nèi)存使用情況。
請(qǐng)注意,Llama 2的區(qū)塊大小為4048。這意味著,如果LLM的區(qū)塊大小設(shè)置為4048個(gè)代幣,那么它就能夠一次性處理多達(dá)4048個(gè)代幣的序列。然而,由于未來(lái)令牌的掩蓋操作,使用較短的訓(xùn)練序列可以顯著節(jié)省內(nèi)存。
以Alpaca數(shù)據(jù)集為例,其規(guī)模相對(duì)較小,且最大長(zhǎng)度僅為1304個(gè)標(biāo)記。
當(dāng)我試驗(yàn)其他長(zhǎng)度高達(dá) 2048 個(gè)令牌的數(shù)據(jù)集時(shí),我注意到內(nèi)存使用量從 17.86 GB 增加到 26.96 GB。
我沒有進(jìn)行任何RLHF實(shí)驗(yàn)(對(duì)于那些好奇的人,我在這里介紹了RLHF),但我確實(shí)考慮了全參數(shù)微調(diào)。全參數(shù)微調(diào)至少需要2個(gè)GPU,每個(gè)GPU使用36.66 GB的內(nèi)存,在3.5小時(shí)內(nèi)完成。然而,基準(zhǔn)測(cè)試結(jié)果并不理想,可能是由于過度擬合或次優(yōu)的超參數(shù)選擇。
是的,可以組合多組LoRA權(quán)重。在訓(xùn)練過程中,我們將LoRA權(quán)重與預(yù)訓(xùn)練權(quán)重分開,并在每次前向傳遞期間將它們相加。
但是,如果您有一個(gè)實(shí)際應(yīng)用,其中包含多組LoRA權(quán)重,例如,每個(gè)應(yīng)用客戶一組,則最好單獨(dú)存儲(chǔ)這些權(quán)重以節(jié)省磁盤空間。不過,可以在訓(xùn)練后將預(yù)訓(xùn)練權(quán)重與LoRA權(quán)重合并,以創(chuàng)建單個(gè)模型。這樣,我們就不必在每次前向傳遞中應(yīng)用LoRA權(quán)重:
weight += (lora_B @ lora_A) * scaling
相反,我們按照上述方式應(yīng)用權(quán)重更新并保存合并(相加的)權(quán)重。
同樣,我們可以不斷地添加多個(gè)LoRA權(quán)重集:
weight += (lora_B_set1 @ lora_A_set1) * scaling_set1
weight += (lora_B_set2 @ lora_A_set2) * scaling_set2
weight += (lora_B_set3 @ lora_A_set3) * scaling_set3
...
我還沒有進(jìn)行實(shí)驗(yàn)來(lái)評(píng)估這種方法的性能,但從Lit-GPT提供的scripts/merge_lora.py腳本來(lái)看,技術(shù)上已經(jīng)可以實(shí)現(xiàn)這一點(diǎn)。
為了簡(jiǎn)單起見,我們通常為每一層訓(xùn)練具有相同學(xué)習(xí)率的深度神經(jīng)網(wǎng)絡(luò),而學(xué)習(xí)率是我們需要優(yōu)化的超參數(shù)。更進(jìn)一步,我們還可以為每一層選擇不同的學(xué)習(xí)率(在PyTorch中,這并不復(fù)雜)。然而,在實(shí)踐中很少這樣做,因?yàn)檫@會(huì)增加額外的開銷,而在訓(xùn)練深度神經(jīng)網(wǎng)絡(luò)時(shí),通常已經(jīng)有許多參數(shù)需要調(diào)整。
類似于為不同層選擇不同學(xué)習(xí)率的做法,我們也可以為不同層選擇不同的LoRA等級(jí)。目前我還沒有找到關(guān)于這一點(diǎn)的實(shí)驗(yàn),但有相關(guān)文獻(xiàn)詳細(xì)介紹了這種方法,稱為分層最優(yōu)秩適應(yīng)(Layer-wise Optimal Rank Adaptation,簡(jiǎn)稱LORA)。從理論上講,這在實(shí)踐中聽起來(lái)是個(gè)不錯(cuò)的主意。然而,在優(yōu)化超參數(shù)時(shí),這也會(huì)增加大量的選擇和復(fù)雜性。
文章轉(zhuǎn)載自:Practical Tips for Finetuning LLMs Using LoRA (Low-Rank Adaptation)
使用 ASP.NET Web API 構(gòu)建 RESTful API
如何使用 DeepSeek 構(gòu)建 AI Agent:終極指南
DeepSeek+ima:打造高效個(gè)人知識(shí)庫(kù),提升學(xué)習(xí)與工作效率
如何獲取通義千問 API Key 密鑰(分步指南)
API 認(rèn)證:JWT、OAuth 與 API KEY對(duì)比
WordPress REST API 內(nèi)容注入漏洞分析
WebSocket和REST的區(qū)別:功能、適用范圍、性能與示例解析
模型壓縮四劍客:量化、剪枝、蒸餾、二值化
Python與Ollama的開發(fā)案例
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)