LLM 課程文件
LoRA (低秩自適應)
並獲得增強的文件體驗
開始使用
LoRA (低秩適應)
微調大型語言模型是一個資源密集型過程。LoRA 是一種允許我們使用少量引數微調大型語言模型的技術。它透過向注意力權重新增和最佳化較小的矩陣來工作,通常可將可訓練引數減少約 90%。
理解 LoRA
LoRA(低秩適應)是一種引數高效的微調技術,它凍結了預訓練模型的權重,並將可訓練的秩分解矩陣注入到模型的層中。LoRA 不是在微調期間訓練所有模型引數,而是透過低秩分解將權重更新分解為更小的矩陣,從而顯著減少可訓練引數的數量,同時保持模型效能。例如,當應用於 GPT-3 175B 時,與完全微調相比,LoRA 將可訓練引數減少了 10,000 倍,GPU 記憶體需求減少了 3 倍。您可以在 LoRA 論文中閱讀更多關於 LoRA 的資訊。
LoRA 透過向 Transformer 層新增成對的秩分解矩陣來工作,通常側重於注意力權重。在推理過程中,這些介面卡權重可以與基礎模型合併,從而不會產生額外的延遲開銷。LoRA 對於將大型語言模型適應特定任務或領域特別有用,同時保持資源需求可管理。
LoRA 的主要優勢
記憶體效率:
- 只有介面卡引數儲存在 GPU 記憶體中
- 基礎模型權重保持凍結,並可以以較低精度載入
- 允許在消費級 GPU 上微調大型模型
訓練功能:
- PEFT/LoRA 本機整合,設定最少
- 支援 QLoRA(量化 LoRA),以獲得更好的記憶體效率
介面卡管理:
- 檢查點期間介面卡權重儲存
- 將介面卡合併回基礎模型的功能
使用 PEFT 載入 LoRA 介面卡
PEFT 是一個提供統一介面來載入和管理 PEFT 方法(包括 LoRA)的庫。它允許您輕鬆載入和切換不同的 PEFT 方法,從而更輕鬆地嘗試不同的微調技術。
介面卡可以透過 load_adapter()
載入到預訓練模型上,這對於嘗試未合併權重的不同介面卡很有用。使用 set_adapter()
函式設定活動介面卡權重。要返回基礎模型,您可以使用 unload()
解除安裝所有 LoRA 模組。這使得在不同的特定任務權重之間切換變得容易。
from peft import PeftModel, PeftConfig
config = PeftConfig.from_pretrained("ybelkada/opt-350m-lora")
model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path)
lora_model = PeftModel.from_pretrained(model, "ybelkada/opt-350m-lora")
使用 trl 和 SFTTrainer 微調 LLM 與 LoRA
trl
中的 SFTTrainer 透過 PEFT 庫提供了與 LoRA 介面卡的整合。這意味著我們可以像使用 SFT 那樣微調模型,但使用 LoRA 來減少我們需要訓練的引數數量。
我們將在示例中使用 PEFT 的 LoRAConfig
類。設定只需要幾個配置步驟
- 定義 LoRA 配置(秩、alpha、dropout)
- 建立帶有 PEFT 配置的 SFTTrainer
- 訓練並儲存介面卡權重
LoRA 配置
讓我們來了解一下 LoRA 配置和關鍵引數。
引數 | 描述 |
---|---|
r (秩) | 用於權重更新的低秩矩陣的維度。通常在 4-32 之間。較低的值提供更高的壓縮率,但表達能力可能較弱。 |
lora_alpha | LoRA 層的縮放因子,通常設定為秩值的 2 倍。較高的值會導致更強的適應效果。 |
lora_dropout | LoRA 層的 dropout 機率,通常為 0.05-0.1。較高的值有助於防止訓練期間過擬合。 |
偏差 (bias) | 控制偏差項的訓練。“none”、“all”或“lora_only”選項。“none”對於記憶體效率而言最常見。 |
target_modules | 指定要應用 LoRA 的模型模組。可以是“all-linear”或特定模組,如“q_proj,v_proj”。更多模組可實現更大的適應性,但會增加記憶體使用。 |
將 TRL 與 PEFT 結合使用
PEFT 方法可以與 TRL 結合用於微調,以減少記憶體需求。我們可以在載入模型時將 LoraConfig
傳遞給模型。
from peft import LoraConfig
# TODO: Configure LoRA parameters
# r: rank dimension for LoRA update matrices (smaller = more compression)
rank_dimension = 6
# lora_alpha: scaling factor for LoRA layers (higher = stronger adaptation)
lora_alpha = 8
# lora_dropout: dropout probability for LoRA layers (helps prevent overfitting)
lora_dropout = 0.05
peft_config = LoraConfig(
r=rank_dimension, # Rank dimension - typically between 4-32
lora_alpha=lora_alpha, # LoRA scaling factor - typically 2x rank
lora_dropout=lora_dropout, # Dropout probability for LoRA layers
bias="none", # Bias type for LoRA. the corresponding biases will be updated during training.
target_modules="all-linear", # Which modules to apply LoRA to
task_type="CAUSAL_LM", # Task type for model architecture
)
上面,我們使用了 device_map="auto"
來自動將模型分配到正確的裝置。您也可以使用 device_map={"": device_index}
手動將模型分配到特定裝置。
我們還需要使用 LoRA 配置定義 SFTTrainer
。
# Create SFTTrainer with LoRA configuration
trainer = SFTTrainer(
model=model,
args=args,
train_dataset=dataset["train"],
peft_config=peft_config, # LoRA configuration
max_seq_length=max_seq_length, # Maximum sequence length
processing_class=tokenizer,
)
✏️ 試一試! 在上一節微調的模型基礎上,使用 LoRA 對其進行微調。使用 HuggingFaceTB/smoltalk
資料集來微調 deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
模型,使用我們上面定義的 LoRA 配置。
合併 LoRA 介面卡
使用 LoRA 訓練後,您可能希望將介面卡權重合並回基礎模型,以便於部署。這會建立一個具有組合權重的單一模型,從而無需在推理期間單獨載入介面卡。
合併過程需要注意記憶體管理和精度。由於您需要同時載入基礎模型和介面卡權重,因此請確保有足夠的 GPU/CPU 記憶體可用。在 transformers
中使用 device_map="auto"
將根據您的硬體為模型找到正確的裝置。
在整個過程中保持一致的精度(例如,float16),與訓練期間使用的精度匹配,並以相同的格式儲存合併的模型以進行部署。
合併實現
訓練 LoRA 介面卡後,您可以將介面卡權重合並回基礎模型。操作方法如下:
import torch
from transformers import AutoModelForCausalLM
from peft import PeftModel
# 1. Load the base model
base_model = AutoModelForCausalLM.from_pretrained(
"base_model_name", torch_dtype=torch.float16, device_map="auto"
)
# 2. Load the PEFT model with adapter
peft_model = PeftModel.from_pretrained(
base_model, "path/to/adapter", torch_dtype=torch.float16
)
# 3. Merge adapter weights with base model
merged_model = peft_model.merge_and_unload()
如果儲存的模型出現大小不一致的情況,請確保您也儲存了分詞器
# Save both model and tokenizer
tokenizer = AutoTokenizer.from_pretrained("base_model_name")
merged_model.save_pretrained("path/to/save/merged_model")
tokenizer.save_pretrained("path/to/save/merged_model")
✏️ 試一試! 將介面卡權重合並回基礎模型。使用 HuggingFaceTB/smoltalk
資料集來微調 deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
模型,使用我們上面定義的 LoRA 配置。