在前幾天,我們用了 Transformers 框架來實作 LLM 的 Pretrain 與 SFT,但實際上"完整"微調一個大模型成本非常高,動輒幾十億的參數,一次訓練可能就要多張的 A100 等級顯卡同時訓練,這個成本不是一般家庭電腦能負擔得起的。
因此 PEFT(Parameter-Efficient Fine-Tuning) 這項技術就誕生了,PEFT 可以不用訓練整個模型,只需要調整少量的參數,就能讓模型學會新任務。
傳統的 Full Fine-Tuning 需要更新模型中所有參數,假設模型是 70 億參數,即使只訓練一個小任務,也要保存 14GB 以上的權重副本,對於中小型團隊來說,成本實在太高。
而 PEFT 的核心概念是只動部分參數,其餘凍結,這讓模型可以保留原本知識,只針對新任務微調,進而降低訓練成本,這類方法主要分為三種:
LoRA 是 Adapt Tuning 的改良版本,是目前的主流訓練方法
LoRA 全名 Low-Rank Adaptation,是一種來自 Microsoft 的 PEFT 方法,他的原理非常直觀,把原本的大模型權重凍結不再訓練,新增一個小小的「旁路」,由兩個低秩矩陣 A 和 B 組成,在 Forward 時,加上這個旁路的輸出;Backward 時,只更新這個小模型的梯度,一般會應用在 Transformer 中的注意力層。
公式:h = W0x+BAx
而在訓練完後,LoRA 會直接把 W0+BA 合併成一個新的權重矩陣
使用 Hugging Face 官方提供的 peft 套件,讓我們能快速整合 LoRA:
import torch.nn as nn
from transformers import AutoTokenizer, AutoModel
from peft import get_peft_model, LoraConfig, TaskType
from transformers import Trainer
MODEL_PATH = "Qwen/Qwen2.5-1.5B"
tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)
model = AutoModel.from_pretrained(MODEL_PATH, trust_remote_code=True)
peft_config = LoraConfig(
task_type=TaskType.CAUSAL_LM, # 任務類型
r=8, # 秩(越小越省)
lora_alpha=32, # 縮放係數
lora_dropout=0.1, # dropout
inference_mode=False
)
model = get_peft_model(model, peft_config)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
tokenizer=tokenizer,
)
trainer.train()
LoRA 是一種非常「通用」的 PEFT 方式,可以和以下方法結合使用:
但要注意,LoRA 不適合「增加知識」的任務,因為只有改動少量的低秩矩陣,學不到新的世界知識。
參考連結:
https://datawhalechina.github.io/happy-llm/#/