LoRA 与 QLoRA
问题
什么是 LoRA?为什么它能用很少的参数达到接近全量微调的效果?
答案
LoRA(Low-Rank Adaptation) 通过在模型的注意力权重矩阵旁添加低秩分解矩阵来实现高效微调,只训练约 1% 的参数。
一、LoRA 原理
原始权重矩阵 的更新分解为两个低秩矩阵:
其中 ,,(秩通常为 4-64)。
| 参数 | 说明 |
|---|---|
| r(秩) | 低秩矩阵的维度,通常 8-64 |
| alpha | 缩放因子,通常等于 r 或 2r |
| target_modules | 应用 LoRA 的模块(通常是 q_proj、v_proj 等) |
二、参数量对比
以 LLaMA-3-8B 为例:
| 方式 | 训练参数量 | GPU 内存 |
|---|---|---|
| 全量微调 | 8B(100%) | ~80GB |
| LoRA (r=16) | ~40M(0.5%) | ~20GB |
| QLoRA (r=16) | ~40M(0.5%) | ~6GB |
三、QLoRA
QLoRA 在 LoRA 基础上进一步优化:将基础模型量化为 4-bit(NF4 格式),只在 LoRA 适配器上用 BF16 训练。
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model
# 1. 4-bit 量化加载基模型
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # NF4 量化
bnb_4bit_compute_dtype="bfloat16", # 计算用 BF16
bnb_4bit_use_double_quant=True, # 嵌套量化进一步省内存
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
quantization_config=bnb_config,
)
# 2. 配置 LoRA
lora_config = LoraConfig(
r=16, # 秩
lora_alpha=32, # 缩放因子
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM",
)
# 3. 应用 LoRA
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# trainable params: 41,943,040 || all params: 8,030,261,248 || trainable%: 0.52%
四、关键参数选择
| 参数 | 建议 | 说明 |
|---|---|---|
| r | 16-64 | r 越大表达能力越强,但参数越多 |
| alpha | 2 × r | 缩放系数,alpha/r 是实际缩放 |
| target_modules | 全覆盖 | q/k/v/o_proj + gate/up/down_proj |
| dropout | 0.05 | 通常保持较小 |
r 的选择
- 简单任务(分类、情感分析):r=8 足够
- 复杂任务(对话、代码生成):r=32-64
- 经验法则:先用 r=16 做基线,再根据效果调整
五、LoRA 合并与部署
from peft import PeftModel
# 训练后合并 LoRA 到基模型
model = AutoModelForCausalLM.from_pretrained("base_model")
model = PeftModel.from_pretrained(model, "lora_adapter")
merged_model = model.merge_and_unload() # 合并为完整模型
merged_model.save_pretrained("merged_model")
常见面试问题
Q1: LoRA 为什么有效?为什么低秩就够了?
答案: 研究表明,预训练模型的权重更新矩阵 具有低秩特性——即大部分信息集中在少数几个维度上。因此用低秩分解 可以近似完整的更新,同时大幅减少参数量。直觉上,微调不需要改变模型的全部知识,只需在特定方向上做微调。
Q2: LoRA 和全量微调效果差多少?
答案:
- 在大多数任务上,LoRA(r=16~64)效果可达全量微调的 95-99%
- 在数据量小(
<10K)的场景,LoRA 反而可能优于全量微调(正则化效果) - 极端任务(大幅改变模型行为)可能需要更高的 r 或全量微调