QLoRA:在單張消費級顯示卡上微調的實際配置
4-bit 量化加 LoRA,讓 24GB 顯示記憶體就能微調中型模型。這是可跑通的設定。
QLoRA 的組合是:把底座模型以 4-bit 載入凍結,只用 16-bit 訓練 LoRA 介面卡。記憶體佔用大幅下降,品質損失在多數任務上很小。
載入設定
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch
bnb = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type='nf4', # 對常態分布權重較友善
bnb_4bit_use_double_quant=True, # 再省一點記憶體
bnb_4bit_compute_dtype=torch.bfloat16, # 計算仍用 bf16
)
model = AutoModelForCausalLM.from_pretrained(BASE, quantization_config=bnb, device_map='auto')記憶體不夠時的調整順序
- 降低
per_device_train_batch_size到 1,改用gradient_accumulation_steps維持等效批次。 - 開啟梯度檢查點(gradient checkpointing),用時間換記憶體。
- 縮短
max_seq_length,這通常是佔用最大的變數。 - 減少
target_modules。 - 最後才考慮降 rank。
args = TrainingArguments(
per_device_train_batch_size=1,
gradient_accumulation_steps=16, # 等效批次 16
gradient_checkpointing=True,
learning_rate=2e-4,
num_train_epochs=3,
lr_scheduler_type='cosine',
warmup_ratio=0.03,
bf16=True,
logging_steps=10,
)合併與部署
訓練完可以選擇保留介面卡分開載入,或合併回底座輸出完整權重。線上服務通常合併後再量化部署,推論速度較好;要同時服務多個任務時則保留介面卡動態切換。
4-bit 訓練出來的介面卡,合併回 16-bit 底座時可能有些微落差。上線前務必用合併後的實際成品重跑評測,不要只信訓練時的驗證分數。