創新實訓 (八) 大模型微調技術學習

asuldb發表於2024-06-23

1.為什麼需要微調大模型?

output_dir = "./results"
training_args = TrainingArguments(
    report_to="wandb",
    output_dir=output_dir,#訓練後輸出目錄
    per_device_train_batch_size=4,#每個GPU的批處理資料量
    gradient_accumulation_steps=4,#在執行反向傳播/更新過程之前,要累積其梯度的更新步驟數
    learning_rate=2e-4,#超參、初始學習率。太大模型不穩定,太小則模型不能收斂
    logging_steps=10,#兩個日誌記錄之間的更新步驟數
    max_steps=100#要執行的訓練步驟總數
)
max_seq_length = 512
#TrainingArguments 的引數詳解:https://blog.csdn.net/qq_33293040/article/details/117376382

trainer = SFTTrainer(
    model=base_model,
    train_dataset=dataset,
    peft_config=peft_config,
    dataset_text_field="text",
    max_seq_length=max_seq_length,
    tokenizer=tokenizer,
    args=training_args,
)

大型預訓練模型的訓練成本極高,涉及龐大的計算資源和海量資料,如果對於不同特徵的資料和任務都要重新進行大模型的訓練,那麼成本是非常高昂的。這也導致了研究成果難以被複現和驗證。為了解決這個問題,Parameter-Efficient Fine-Tuning(引數有效微調)技術應運而生,旨在透過最小化微調引數和計算複雜度,來提高預訓練模型在新任務上的效能,從而大大降低了計算和儲存成本。這樣一來,即使計算資源有限,也可以利用預訓練模型的知識來迅速適應新任務,從而高效的遷移學習。大型預訓練模型通常在廣泛的資料集上進行訓練,學習到了豐富的通用特徵。透過微調,這些通用特徵可以被遷移到新的任務上,從而在新任務上取得更好的效能,尤其是在新任務資料量有限的情況下。

Parameter-Efficient Fine-Tuning(引數有效微調) 透過在各種細化型別的任務中有效地調整大模型,提供了一種實用的解決方案。特別是,PEFT 是指調整預先訓練的大型模型的引數,使其適應特定任務或領域,同時最小化引入的額外引數或所需計算資源的數量的過程。當處理具有高引數計數的大型語言模型時,這種方法非常重要,因為從頭開始微調這些模型可能計算成本高昂且資源密集,在支援系統平臺設計中提出了相當大的挑戰。

2.PEFT 方法分類:

  • Additive PEFT

保持預先訓練的主幹不變,並且只引入在模型架構中戰略性定位的最小數量的可訓練引數。在針對特定下游任務進行微調時,僅更新這些附加模組或引數的權重,這導致儲存、記憶體和計算資源需求的顯著減少。由於這些技術具有新增引數的特性,因此可以將其稱為加性調整。常見的方法有:

加入配適器:在Transformer塊中插入小型介面卡層。

使用軟提示:在模型的輸入層引入可訓練的引數來調整模型的行為,以便更好地適應特定任務。可以被看作是一種形式的提示或指令,它們不是固定的文字,而是可以隨著訓練過程進行調整的引數。可以在模型的嵌入層中新增額外的可訓練向量。這些向量在訓練過程中與輸入資料一起被最佳化,從而影響模型的輸出。

  • Selective PEFT

Selective PEFT 不透過新增更多引數來增加模型複雜性的附加 PEFT,而是對現有引數的子集進行微調,以提高模型在下游任務中的效能。常用的方法有差分修剪,差分修剪是一種用於最佳化神經網路模型的技術,特別是在模型壓縮和加速的背景下。這種技術旨在透過移除或修剪模型中不重要的權重來減少模型的複雜性和計算需求,同時儘量保持模型的效能。

  • Reparameterized PEFT

重新引數化表示透過轉換模型的引數將模型的體系結構從一個等效地轉換到另一個,透過重新引數化模型的某些部分來減少微調過程中需要更新的引數數量,旨在提高微調的效率,同時保持或接近原始模型的效能。在傳統的微調方法中,通常需要更新整個模型的所有引數,這在處理大型模型時可能會非常耗時和計算密集。Reparameterized PEFT 引入一種新的引數化方式來解決這個問題,使得在微調時只需要更新模型的一小部分引數。

  • Hybrid PEFT

各種 PEFT 的方法在效果上還是存在著較大的差距,。一種非常有效的且自然的方法是結合不同 PEFT 方法的優勢,或透過分析這些方法之間的相似性來尋求建立統一的視角。PEFT 技術透過只更新模型的一小部分引數來解決這個問題,從而減少微調的成本。Hybrid PEFT 則更進一步,它結合了不同的 PEFT 技術,以期達到更好的效果。Hybrid PEFT 可以針對不同的模型部分和任務需求採用最合適的微調策略。例如,對於某些層可能使用介面卡層,而對於其他層則可能使用低秩適應或提示調優。這種混合方法可以提供更大的靈活性,使得模型能夠更有效地適應新任務,同時保持較低的計算成本。

論文:Prefix-Tuning: Optimizing Continuous Prompts for Generation

Prefix-tuning將一系列連續的特定於任務的向量新增到輸入中,這些字首向量並不能夠對映到真正的實體 token,可以理解為“虛擬 token”,這些虛擬的 token 作為 Prefix。然後,在訓練的時候只更新Prefix部分的引數,而 PLM 中的其他部分引數固定。

如上圖,更新所有 Transformer 引數(紅色方框內部分),只需為每個任務儲存字首向量,從而使字首調整模組化並節省空間。

目前程式碼生成的 LLM 主要是基於以下兩種模型:

  • 自迴歸模型:自迴歸模型是一種序列生成模型,它在生成序列的每個時間步依賴於之前生成的所有時間步。在程式碼生成中,自迴歸模型通常用於逐詞或逐符號地生成程式碼。例如,GPT(Generative Pre-trained Transformer)系列模型就是一種自迴歸模型,它們在自然語言處理任務中表現出色,會根據已生成的元素來預測下一個元素。

  • 編碼器-解碼器模型:是一種常用於序列到序列(Seq2Seq)任務的架構。在程式碼生成中,編碼器負責理解輸入的上下文或需求描述,而解碼器則負責生成相應的程式碼。這種模型通常用於需要將一種序列(如自然語言描述)轉換為另一種序列(如程式碼)的任務。

這兩種模型均常用於程式碼的生成,而我們選取的 CodeGeeX 是一個基於 Transformers 的大規模預訓練程式語言模型。它是一個從左到右生成的自迴歸解碼器,將程式碼或 token 作為輸入,預測下一個識別符號的機率分佈。所以在閱讀本文的過程中,對自迴歸模型的相關方法更加關注。

以文字摘要為例的自迴歸模型,輸入是文字,輸出是 token 序列。

如上圖,\(x\) 是 source table(源資料),\(y\) 是 target utterance(目標語言)。在 Transformers 層有分佈 \(P_{\phi}(y|x)\) 。令 \(z=[x:y]\) 是輸入和輸出 concatenation 的結果,\(h_1,h_2\dots h_n\) 為一系列啟用向量,其中 \(h_i\) 是當前時間所有啟用層的 concatenation 結果,其計算如下:

我們微調的目標是,最大化這個機率分佈的值,即:

對於自迴歸模型,Prefix-Tuning 的方法是對 \(z\) 進行調整,令 \(z=[PREFIX;x;y]\)\(h_i\) 的計算為:

其中 \(P_{idx}\) 表示字首prefix的下標。微調時,只對字首引數進行梯度更新。

直接更新 \(P_{\theta}\) 會導致最佳化不穩定,降低效能。因此透過一個大型的字首神經網路 $\rm MLP_{\theta} $ 組成的較小矩陣 $ P_{\theta}'$ ​重新引數化矩陣 \(P_{\theta}[i,:]=\mathrm{MLP}_{\theta}(P_{\theta}'[i,:])\)。這樣可訓練引數就變為了 \(P_{\theta}'\) ​和 \(\mathrm{MLP}_{\theta}\)。訓練結束後只儲存字首引數 $ P_{\theta} $。

相關文章