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