前言
微調(diào)是指調(diào)整大型語言模型(LLM)的參數(shù)以適應(yīng)特定任務(wù)的過程。這是通過在與任務(wù)相關(guān)的數(shù)據(jù)集上訓(xùn)練模型來完成的。所需的微調(diào)量取決于任務(wù)的復(fù)雜性和數(shù)據(jù)集的大小。
在深度學(xué)習(xí)中,微調(diào)是一種重要的技術(shù),用于改進(jìn)預(yù)訓(xùn)練模型的性能。除了微調(diào)ChatGPT之外,還有許多其他預(yù)訓(xùn)練模型可以進(jìn)行微調(diào)。
PEFT是什么
PEFT(Parameter-Efficient Fine-Tuning)是hugging face開源的一個參數(shù)高效微調(diào)大模型的工具,里面集成了4種微調(diào)大模型的方法,可以通過微調(diào)少量參數(shù)就達(dá)到接近微調(diào)全量參數(shù)的效果,使得在GPU資源不足的情況下也可以微調(diào)大模型。
微調(diào)方法
微調(diào)可以分為全微調(diào)和重用兩個方法:
??全微調(diào)(Full Fine-tuning):全微調(diào)是指對整個預(yù)訓(xùn)練模型進(jìn)行微調(diào),包括所有的模型參數(shù)。在這種方法中,預(yù)訓(xùn)練模型的所有層和參數(shù)都會被更新和優(yōu)化,以適應(yīng)目標(biāo)任務(wù)的需求。這種微調(diào)方法通常適用于任務(wù)和預(yù)訓(xùn)練模型之間存在較大差異的情況,或者任務(wù)需要模型具有高度靈活性和自適應(yīng)能力的情況。Full Fine-tuning需要較大的計算資源和時間,但可以獲得更好的性能。
??部分微調(diào)(Repurposing):部分微調(diào)是指在微調(diào)過程中只更新模型的頂層或少數(shù)幾層,而保持預(yù)訓(xùn)練模型的底層參數(shù)不變。這種方法的目的是在保留預(yù)訓(xùn)練模型的通用知識的同時,通過微調(diào)頂層來適應(yīng)特定任務(wù)。Repurposing通常適用于目標(biāo)任務(wù)與預(yù)訓(xùn)練模型之間有一定相似性的情況,或者任務(wù)數(shù)據(jù)集較小的情況。由于只更新少數(shù)層,Repurposing相對于Full Fine-tuning需要較少的計算資源和時間,但在某些情況下性能可能會有所降低。
微調(diào)預(yù)訓(xùn)練模型的方法:
??微調(diào)所有層:將預(yù)訓(xùn)練模型的所有層都參與微調(diào),以適應(yīng)新的任務(wù)。
??微調(diào)頂層:只微調(diào)預(yù)訓(xùn)練模型的頂層,以適應(yīng)新的任務(wù)。
??凍結(jié)底層:將預(yù)訓(xùn)練模型的底層固定不變,只對頂層進(jìn)行微調(diào)。
??逐層微調(diào):從底層開始,逐層微調(diào)預(yù)訓(xùn)練模型,直到所有層都被微調(diào)。
??遷移學(xué)習(xí):將預(yù)訓(xùn)練模型的知識遷移到新的任務(wù)中,以提高模型性能。這種方法通常使用微調(diào)頂層或凍結(jié)底層的方法。
Fine tuning
經(jīng)典的Fine tuning方法包括將預(yù)訓(xùn)練模型與少量特定任務(wù)數(shù)據(jù)一起繼續(xù)訓(xùn)練。在這個過程中,預(yù)訓(xùn)練模型的權(quán)重被更新,以更好地適應(yīng)任務(wù)。所需的Fine-tuning量取決于預(yù)訓(xùn)練語料庫和任務(wù)特定語料庫之間的相似性。如果兩者相似,可能只需要少量的Fine tuning。如果兩者不相似,則可能需要更多的Fine tuning。
Prompt Tuning(P-tuning)
Prompt Tuning 是2021年谷歌在論文《The Power of Scale for Parameter-Efficient Prompt Tuning》中提出的微調(diào)方法。參數(shù)高效性微調(diào)方法中實現(xiàn)最簡單的方法還是Prompt tuning(也就是我們常說的P-Tuning),固定模型前饋層參數(shù),僅僅更新部分embedding參數(shù)即可實現(xiàn)低成本微調(diào)大模型。
經(jīng)典的Prompt tuning方式不涉及對底層模型的任何參數(shù)更新。相反,它側(cè)重于精心制作可以指導(dǎo)預(yù)訓(xùn)練模型生成所需輸出的輸入提示或模板。主要結(jié)構(gòu)是利用了一個prompt encoder(BiLSTM+MLP),將一些pseudo prompt先encode(離散token)再與input embedding進(jìn)行拼接,同時利用LSTM進(jìn)行 Reparamerization 加速訓(xùn)練,并引入少量自然語言提示的錨字符(Anchor,例如Britain)進(jìn)一步提升效果。然后結(jié)合(capital,Britain)生成得到結(jié)果,再優(yōu)化生成的encoder部分。
但是P-tuning v1有兩個顯著缺點:任務(wù)不通用和規(guī)模不通用。在一些復(fù)雜的自然語言理解NLU任務(wù)上效果很差,同時預(yù)訓(xùn)練模型的參數(shù)量不能過小。具體的效果論文中提到以下幾點:
? Prompt 長度影響:模型參數(shù)達(dá)到一定量級時,Prompt 長度為1也能達(dá)到不錯的效果,Prompt 長度為20就能達(dá)到極好效果。
? Prompt初始化方式影響:Random Uniform 方式明顯弱于其他兩種,但是當(dāng)模型參數(shù)達(dá)到一定量級,這種差異也不復(fù)存在。
??預(yù)訓(xùn)練的方式:LM Adaptation 的方式效果好,但是當(dāng)模型達(dá)到一定規(guī)模,差異又幾乎沒有了。
??微調(diào)步數(shù)影響:模型參數(shù)較小時,步數(shù)越多,效果越好。同樣隨著模型參數(shù)達(dá)到一定規(guī)模,zero shot 也能取得不錯效果。當(dāng)參數(shù)達(dá)到100億規(guī)模與全參數(shù)微調(diào)方式效果無異。
代碼示例:
from?peft?import?PromptTuningConfig,?get_peft_model peft_config?=?PromptTuningConfig(task_type="SEQ_CLS",?num_virtual_tokens=10) model?=?AutoModelForCausalLM.from_pretrained(model_name_or_path,?return_dict=True) model?=?get_peft_model(model,?peft_config)
Prefix Tuning
2021年論文《Prefix-Tuning: Optimizing Continuous Prompts for Generation》中提出了 Prefix Tuning 方法。與Full-finetuning 更新所有參數(shù)的方式不同,該方法是在輸入 token 之前構(gòu)造一段任務(wù)相關(guān)的 virtual tokens 作為 Prefix,然后訓(xùn)練的時候只更新 Prefix 部分的參數(shù),而 Transformer 中的其他部分參數(shù)固定。
prefix-tuning技術(shù),相對于fine-tuning,在調(diào)節(jié)模型的過程中只優(yōu)化一小段可學(xué)習(xí)的continuous task-specific vector(prefix)而不是整個模型的參數(shù)。該方法其實和構(gòu)造 Prompt 類似,只是 Prompt 是人為構(gòu)造的“顯式”的提示,并且無法更新參數(shù),而Prefix 則是可以學(xué)習(xí)的“隱式”的提示。手動嘗試最優(yōu)的提示無異于大海撈針,于是便有了自動離散提示搜索的方法,但提示是離散的,神經(jīng)網(wǎng)絡(luò)是連續(xù)的,所以尋找的最優(yōu)提示可能是次優(yōu)的。
代碼示例:
peft_config?=?PrefixTuningConfig(task_type="CAUSAL_LM",?num_virtual_tokens=20) model?=?AutoModelForCausalLM.from_pretrained(model_name_or_path,?return_dict=True) model?=?get_peft_model(model,?peft_config)
GPT在P-tuning的加持下可達(dá)到甚至超過BERT在NLU領(lǐng)域的性能。下圖是細(xì)致的對比:
P-tuning v2
V2版本主要是基于P-tuning和prefix-tuning技術(shù),引入Deep Prompt Encoding和Multi-task Learning等策略進(jìn)行優(yōu)化的。實驗表明,僅精調(diào)0.1%參數(shù)量,在330M到10B不同參數(shù)規(guī)模LM模型上,均取得和Fine-tuning相比肩的性能。
論文《P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks》從標(biāo)題就可以看出,P-Tuning v2 的目標(biāo)就是要讓 Prompt Tuning 能夠在不同參數(shù)規(guī)模的預(yù)訓(xùn)練模型、針對不同下游任務(wù)的結(jié)果上都達(dá)到匹敵 Fine-tuning 的結(jié)果。也就是說當(dāng)前 Prompt Tuning 方法在這兩個方面都存在局限性。
不同模型規(guī)模:Prompt Tuning 和 P-tuning 這兩種方法都是在預(yù)訓(xùn)練模型參數(shù)規(guī)模夠足夠大時,才能達(dá)到和Fine-tuning 類似的效果,而參數(shù)規(guī)模較小時效果則很差。
不同任務(wù)類型:Prompt Tuning 和 P-tuning 這兩種方法在 sequence tagging 任務(wù)上表現(xiàn)都很差。
v1到v2的可視化:藍(lán)色部分為參數(shù)凍結(jié),橙色部分為可訓(xùn)練部分,可以看到右側(cè)的p-tuning v2中,將continuous prompt加在序列前端,并且每一層都加入可訓(xùn)練的prompts。在左圖v1模型中,只將prompt插入input embedding中,會導(dǎo)致可訓(xùn)練的參數(shù)被句子的長度所限制。此外P-Tuning v2還包括以下改進(jìn):
??移除了Reparamerization加速訓(xùn)練方式;
??采用了多任務(wù)學(xué)習(xí)優(yōu)化:基于多任務(wù)數(shù)據(jù)集的Prompt進(jìn)行預(yù)訓(xùn)練,然后再適配的下游任務(wù)。
??舍棄了詞匯Mapping的Verbalizer的使用,重新利用[CLS]和字符標(biāo)簽,跟傳統(tǒng)finetune一樣利用cls或者token的輸出做NLU,以增強(qiáng)通用性,可以適配到序列標(biāo)注任務(wù)。
P-Tuning v2幾個關(guān)鍵設(shè)計因素:
? Reparameterization:Prefix Tuning 和 P-tuning 中都有 MLP 來構(gòu)造可訓(xùn)練的 embedding。論文發(fā)現(xiàn)在自然語言理解領(lǐng)域,面對不同的任務(wù)以及不同的數(shù)據(jù)集,這種方法可能帶來完全相反的結(jié)論。
? Prompt Length:不同的任務(wù)對應(yīng)的最合適的 Prompt Length 不一樣,比如簡單分類任務(wù)下 length=20 最好,而復(fù)雜的任務(wù)需要更長的 Prompt Length。
? Multi-task Learning 多任務(wù)對于 P-Tuning v2 是可選的,但可以利用它提供更好的初始化來進(jìn)一步提高性能。
? Classification Head 使用 LM head 來預(yù)測動詞是 Prompt Tuning 的核心,但我們發(fā)現(xiàn)在完整的數(shù)據(jù)設(shè)置中沒有必要這樣做,并且這樣做與序列標(biāo)記不兼容。P-tuning v2 采用和 BERT 一樣的方式,在第一個 token 處應(yīng)用隨機(jī)初始化的分類頭。
代碼示例:
peft_config?=?PrefixTuningConfig(task_type="SEQ_CLS",?num_virtual_tokens=20) model?=?AutoModelForSequenceClassification.from_pretrained(model_name_or_path,?return_dict=True) model?=?get_peft_model(model,?peft_config)
AdaLoRA
預(yù)訓(xùn)練語言模型中的不同權(quán)重參數(shù)對下游任務(wù)的貢獻(xiàn)是不同的。因此需要更加智能地分配參數(shù)預(yù)算,以便在微調(diào)過程中更加高效地更新那些對模型性能貢獻(xiàn)較大的參數(shù)。
具體來說,通過奇異值分解將權(quán)重矩陣分解為增量矩陣,并根據(jù)新的重要性度量動態(tài)地調(diào)整每個增量矩陣中奇異值的大小。這樣可以使得在微調(diào)過程中只更新那些對模型性能貢獻(xiàn)較大或必要的參數(shù),從而提高了模型性能和參數(shù)效率。
代碼示例:
peft_config?=?AdaLoraConfig(peft_type="ADALORA",?task_type="SEQ_2_SEQ_LM",?r=8,?lora_alpha=32,?target_modules=["q",?"v"],lora_dropout=0.01) model?=?AutoModelForCausalLM.from_pretrained(model_name_or_path,?return_dict=True) model?=?get_peft_model(model,?peft_config)
GPT4模型微調(diào)分類
1. Adapter-based Methods(基于適配器的方法):
《Parameter-Efficient Transfer Learning for NLP》提出針對 BERT 的 PEFT微調(diào)方式,拉開了 PEFT 研究的序幕。他們指出,在面對特定的下游任務(wù)時,如果進(jìn)行 Full-Fintuning(即預(yù)訓(xùn)練模型中的所有參數(shù)都進(jìn)行微調(diào)),太過低效;而如果采用固定預(yù)訓(xùn)練模型的某些層,只微調(diào)接近下游任務(wù)的那幾層參數(shù),又難以達(dá)到較好的效果。
于是他們設(shè)計了如下圖所示的 Adapter 結(jié)構(gòu),將其嵌入 Transformer 的結(jié)構(gòu)里面,在訓(xùn)練時,固定住原來預(yù)訓(xùn)練模型的參數(shù)不變,只對新增的 Adapter 結(jié)構(gòu)進(jìn)行微調(diào)。同時為了保證訓(xùn)練的高效性(也就是盡可能少的引入更多參數(shù)),他們將 Adapter 設(shè)計為這樣的結(jié)構(gòu):
首先是一個 down-project 層將高維度特征映射到低維特征;然后過一個非線形層之后,再用一個 up-project 結(jié)構(gòu)將低維特征映射回原來的高維特征;同時也設(shè)計了 skip-connection 結(jié)構(gòu),確保了在最差的情況下能夠退化為identity(類似殘差結(jié)構(gòu))。
這種方法節(jié)省了資源,因為它不需要對整個模型進(jìn)行微調(diào)。示例有AdapterDrop、Parallel Adapter、Residual Adapter等。
2. Prompt-based Methods(基于提示的方法):
這個分支側(cè)重于使用連續(xù)的提示(如嵌入向量)來調(diào)整模型的行為,而不是直接修改模型的權(quán)重。這類方法通常用于生成任務(wù),例如文本生成。提示可以視為模型輸入的一部分,它們會被訓(xùn)練以激發(fā)模型生成特定的輸出。示例包括Prefix-tuning、Prompt tuning等,參加上文介紹。
3. Low-rank Adaptation(低秩適配):
低秩適配方法致力于將模型權(quán)重的改變限制在一個低秩子空間內(nèi)。這通常涉及對模型的權(quán)重矩陣進(jìn)行分解,只微調(diào)其中的一小部分參數(shù)。這樣可以有效減少計算資源的消耗,同時仍然允許模型有足夠的靈活性來學(xué)習(xí)新任務(wù)。LoRA和它的變種,如Q-LoRA、Delta-LoRA、LoRA-FA等,都屬于這個類別。
4. Sparse Methods(稀疏方法):
這個分支包括那些僅更新模型中一小部分參數(shù)的方法。這些參數(shù)被選為最有可能影響到任務(wù)性能的,而其他參數(shù)則保持不變。稀疏方法的優(yōu)點在于它們通常能夠更高效地利用資源。例如有Intrinsic SAID、Fish Mask、BitFit等。
5. Others(其他方法):
這一分支可能包括不易歸類到上述任何一類的其他方法,或者是結(jié)合了多種技術(shù)的混合方法。這些方法可能包括特定的結(jié)構(gòu)改變、算法優(yōu)化等,用以提高微調(diào)過程的效率或者效果。
大模型微調(diào)步驟總結(jié)
大模型微調(diào)如上文所述有很多方法,并且對于每種方法都會有不同的微調(diào)流程、方式、準(zhǔn)備工作和周期。然而大部分的大模型微調(diào),都有以下幾個主要步驟,并需要做相關(guān)的準(zhǔn)備:
準(zhǔn)備數(shù)據(jù)集:
收集和準(zhǔn)備與目標(biāo)任務(wù)相關(guān)的訓(xùn)練數(shù)據(jù)集。確保數(shù)據(jù)集質(zhì)量和標(biāo)注準(zhǔn)確性,并進(jìn)行必要的數(shù)據(jù)清洗和預(yù)處理。
選擇預(yù)訓(xùn)練模型/基礎(chǔ)模型:
根據(jù)目標(biāo)任務(wù)的性質(zhì)和數(shù)據(jù)集的特點,選擇適合的預(yù)訓(xùn)練模型。
設(shè)定微調(diào)策略:
根據(jù)任務(wù)需求和可用資源,選擇適當(dāng)?shù)奈⒄{(diào)策略??紤]是進(jìn)行全微調(diào)還是部分微調(diào),以及微調(diào)的層級和范圍。
設(shè)置超參數(shù):
確定微調(diào)過程中的超參數(shù),如學(xué)習(xí)率、批量大小、訓(xùn)練輪數(shù)等。這些超參數(shù)的選擇對微調(diào)的性能和收斂速度有重要影響。
初始化模型參數(shù):
根據(jù)預(yù)訓(xùn)練模型的權(quán)重,初始化微調(diào)模型的參數(shù)。對于全微調(diào),所有模型參數(shù)都會被隨機(jī)初始化;對于部分微調(diào),只有頂層或少數(shù)層的參數(shù)會被隨機(jī)初始化。
進(jìn)行微調(diào)訓(xùn)練:
使用準(zhǔn)備好的數(shù)據(jù)集和微調(diào)策略,對模型進(jìn)行訓(xùn)練。在訓(xùn)練過程中,根據(jù)設(shè)定的超參數(shù)和優(yōu)化算法,逐漸調(diào)整模型參數(shù)以最小化損失函數(shù)。
模型評估和調(diào)優(yōu):
在訓(xùn)練過程中,使用驗證集對模型進(jìn)行定期評估,并根據(jù)評估結(jié)果調(diào)整超參數(shù)或微調(diào)策略。這有助于提高模型的性能和泛化能力。
測試模型性能:
在微調(diào)完成后,使用測試集對最終的微調(diào)模型進(jìn)行評估,以獲得最終的性能指標(biāo)。這有助于評估模型在實際應(yīng)用中的表現(xiàn)。
模型部署和應(yīng)用:
將微調(diào)完成的模型部署到實際應(yīng)用中,并進(jìn)行進(jìn)一步的優(yōu)化和調(diào)整,以滿足實際需求。
審核編輯:黃飛
?
評論
查看更多