大模型微調實驗報告*
實驗目標
梳理大模型微調方法,評估各種基座和微調方法的實驗效果。
基礎模型
\1.Llama
\2.Qwen
\3.Chatglm4
\4.
微調策略
LoRA系列
低秩適配(LoRA)的核心思想是凍結原始參數,通過低秩分解引入可訓練參數。
LoRA假設預訓練模型的參數矩陣的更新可以表示為一個低秩矩陣。具體來說,對于一個預訓練好的權重矩陣W(d*e),LoRA引入兩個低秩矩陣A(d*r)和B(r*e),其中r是秩,遠小于d和e向量為度。在微調過程中,只需優化A和B,而W保持不變。更新后的權重矩陣為:
W0=W+BA
偽代碼示例:
importtorch
importtorch.nnasnnclassLoRALayer(nn.Module):
def__init__(self,in_dim,out_dim,rank):
super().__init__()
self.A=nn.Parameter(torch.randn(in_dim,rank))
self.B=nn.Parameter(torch.zeros(rank,out_dim))
self.rank=rank**#秩的大小**
defforward(self,x):
returnx@(self.A@self.B)**#低秩矩陣乘積
關鍵技術演進
AdaLoRA:
- 核心思想:AdaLoRA旨在動態調整各層的秩分配。
- 實現方式:AdaLoRA通過一些指標(例如,梯度范數)來評估不同層的重要性,并根據重要性動態地調整LoRA的秩。更重要的層分配更高的秩,從而獲得更好的性能。
QLoRA:
- 核心思想:QLoRA將4-bit量化與LoRA相結合,以進一步降低顯存占用。
- 實現方式:QLoRA首先將預訓練模型的權重量化為4-bit精度,然后在此基礎上應用LoRA。由于4-bit量化可以顯著降低顯存占用,因此QLoRA可以在有限的GPU資源上微調更大的模型。
- 顯存節省:QLoRA可以節省高達70%的顯存。
Delta-LoRA:
- 核心思想:Delta-LoRA引入參數更新量的動量機制。
- 實現方式:Delta-LoRA在更新LoRA參數時,考慮之前的更新方向和幅度,從而更穩定地進行微調。
提示微調技術
提示微調(Prompt-Tuning)是一種通過設計合適的提示(Prompt)來引導預訓練模型完成下游任務的技術。與全參數微調和LoRA不同,提示微調通常不直接修改預訓練模型的參數(注意不是完全不修改參數),而是通過優化提示相關的向量來調整模型的行為。
核心思想:
- 人工設計到可學習:提示工程(Prompt-Engineering)經歷了從人工設計提示到可學習提示的演進過程。
- 利用預訓練知識:通過優化提示,引導模型利用預訓練知識,從而減少對標注數據的依賴。
位置選擇策略:
Prefix-Tuning:
-
核心思想:只在每層的開頭插入可訓練的提示向量。在Prefix層加了MLP結構,然后切分為key和value矩陣,然后和每一層的key-value矩陣拼接。訓練完成后,只保留Prefix的參數。
-
數學形式:
h l = T r a n s f o r m e r ( [ P r e f i x l ; x l ] ) h^l = Transformer([Prefix^l;x^l]) hl=Transformer([Prefixl;xl]) -
參數量:每層新增參數d*r(d為維度,r為前綴長度)
-
優點:Prefix-Tuning可以有效地影響模型的每一層,從而更好地調整模型的行為。
-
缺點:Prefix-Tuning需要插入大量的提示向量,可能會增加計算成本。
P-Tuning v2:
- 核心思想:分層插入位置可學習。
- 實現方式:P-Tuning v2首先將提示向量插入到不同的層中,然后通過訓練來確定每個提示向量的最佳位置。
- 數學形式:
- 優點:P-Tuningv2可以更靈活地調整提示向量的位置,從而更好地適應不同的任務。
Prompt-Tuning(藍色):
- 核心思想:僅在輸入層添加可訓練提示詞。
- 參數量:僅需(為提示詞數量)
- 數學形式:
- 優點:Prompt-Tuning的實現簡單,計算成本低。
- 缺點:Prompt-Tuning的效果可能不如Prefix-Tuning和P-Tuningv2。
實驗設計
數據集
數據來源與規模(如領域專用語料、人工標注數據)
來自于CHIP2023-PromptCBLUE-參數高效微調賽道數據集,原始數據集有15個任務,包括分類、ner、總結、生成等基本任務,本實驗選取其中三類任務,描述如下:
任務類型 | 數據集 | 數量 | |
---|---|---|---|
train | cls | IMCS-V2-DAC | 1536 |
train | ner | CMeEE-V2 | 1492 |
train | report_generation | IMCS-V2-MRG | 872 |
valid | cls | IMCS-V2-DAC | 547 |
valid | ner | CMeEE-V2 | 496 |
valid | report_generation | IMCS-V2-MRG | 269 |
數據預處理(清洗、格式轉換)
格式轉換為json,字段包括instruction、input、output、history,樣例如下:
{"instruction": "根據對話內容,判斷最后一句話的意圖類別是:\n問診對話歷史:\n患者:就是早晨起床干咳的那種,咳一陣\n醫生:化驗過肺炎支原體感染嗎\n患者:不是支原體感染,化驗過\n醫生:肺炎治療后,復查過嗎\n患者:掛完水醫生建議不用繼續掛水,吃藥,吃了一個星期的金振口服液,匹多莫得,鹽酸西替利滴劑還有睡前咀嚼的\n患者:一個星期吃這么多,后來又去醫院復查,醫生說就吃匹多莫得和睡前咀嚼的就可以了,\n患者:但是現在白天也咳嗽了\n醫生:目前看醫生給用了抗氣道過敏藥物\n醫生:這個對于改善目前氣道高反應狀態,還是很對癥。\n醫生:目前考慮按療程治療后,基本的炎癥,都已經消下去了\n醫生:目前咳嗽,還主要是一個氣道高反應,過敏狀態\n患者:那怎么辦呢\n患者:過敏癥狀吃什么呢?\n患者:滴劑要不要繼續吃\n醫生:可以做做霧化\n選擇:關于病因的回答,關于注意事項的提問,關于用藥建議的提問,關于用藥建議的解答,關于癥狀的回答,關于個人基本信息的回答,關于已有檢查和治療的回答,關于病因的詢問,關于就醫建議的解答,關于注意事項的解答,給出診斷,關于已有檢查和治療的提問,關于癥狀的詢問,關于就醫建議的提問,關于個人基本信息的詢問\\","input":"", "target": "關于用藥建議的解答", "history": ""}
環境配置
1.硬件配置(GPU型號、顯存占用)
- linux ubuntu
- nvidia v100 32G
2.軟件配置、環境依賴
1. peft==0.14.0
2. transformers==4.49.0
3. trl==0.15.2
4. torch==2.4.0
5. bitsandbytes==0.45.3
*基本參數*
優化器與超參數(學習率、batch size、epoch數)
超參數 | 描述 | 備注 |
---|---|---|
num_train_epochs | 10 | |
lora_target | ‘q_proj,k_proj,v_proj,out_proj,fc1,fc2’ | lora系列 |
learning_rate | 1e-3 | |
use_ntk | linear | |
padding_side | left | |
torch_dtype | float16 | |
quantization | bnb | |
max_input_token | 2048 | |
use_firefly_loss | True | |
gradient_accumulation_steps | 4 | |
optim | adamw_torch | |
lr_scheduler_type | cosine | |
num_virtual_tokens | 20 | prompt_tuning |
prompt_encoder_hidden_size | 128 | prompt_tuning |
實驗結果與分析
性能對比
基座 | 微調方法 | rouge-1 | rouge-2 | rouge-l |
---|---|---|---|---|
Qwen | qlora | 71.758 | 59.341 | 11.761 |
Qwen | lora | 73.526 | 60.519 | 11.897 |
Qwen | prefix | 71.328 | 58.594 | 17.857 |
Qwen | prompt | 59.118 | 43.109 | 10.048 |
Qwen | ptuning | 71.122 | 57.709 | 11.529 |
Qwen上lora最優