Appearance
LoRA / PEFT
不修改原始模型的 99.9% 参数,只训练极少量新增参数,却能让一个通用 LLM 变成专业领域专家。LoRA 是 LLM 微调领域最重要的工程突破——它让普通开发者也能在消费级 GPU 上定制大模型。
Overview
PEFT(Parameter-Efficient Fine-Tuning,参数高效微调)是一类技术的统称,目标是在保持预训练模型大部分参数固定的前提下,通过训练少量额外参数来适配模型到特定任务。LoRA(Low-Rank Adaptation,低秉适配)是 PEFT 中最流行、最实用的方法。
传统全量微调(Full Fine-tuning)需要更新模型的所有参数(如 Llama 3 70B 有 700 亿参数),需要多张 A100/H100 和大量内存。LoRA 只需训练数百万到数十亿级别的参数,即可在单张消费级 GPU 上完成。
How LoRA Works
核心思想
假设模型某层的权重矩阵为 W ∈ ℝ^(d×k),全量微调学习的是一个更新量 ΔW。LoRA 假设这个更新量是低秉的(即可以分解为两个小矩阵的乘积):
W' = W + ΔW = W + BA
其中:
B ∈ ℝ^(d×r),A ∈ ℝ^(r×k)
r << min(d, k) → 低秉约束关键观察:原始模型参数 W 被冻结,只训练 B 和 A 两个小矩阵。当 r=8 时,参数量仅为原始的 0.1% 不到。
训练与推理
训练阶段:
python
# 只计算 BA 的梯度
loss = criterion(model(x), target)
loss.backward()
optimizer.step() # 只更新 A 和 B推理阶段:
python
# 将 BA 合并回原始权重
W_merged = W + BA
# 然后用 W_merged 进行正常推理合并的好处:推理时没有额外开销,与原始模型速度相同。
Key Hyperparameters
| 参数 | 含义 | 常见设置 | 影响 |
|---|---|---|---|
| rank (r) | 低秉维度 | 4, 8, 16, 32, 64 | 越大容量越高,过大可能过拟合 |
| alpha (α) | 缩放系数 | 通常 = r 或 r/2 | 控制 LoRA 适配强度,α/r 是实际缩放比 |
| target_modules | 应用 LoRA 的层 | q_proj, v_proj 或 所有 linear | 更多层 → 更强表达力,但参数更多 |
| dropout | LoRA 层的 dropout | 0.0 – 0.1 | 防止过拟合 |
| learning rate | 学习率 | 1e-4 – 1e-3 | 通常比全量微调高 10倍 |
Variants of PEFT
| 方法 | 原理 | 参数量 | 适用场景 |
|---|---|---|---|
| LoRA | 低秉矩阵分解 | 极少 | 通用,最广泛使用 |
| QLoRA | LoRA + 4-bit 量化 | 极少 + 低精度 | 单张消费级 GPU 训练百亿级模型 |
| DoRA | 权重分解为方向和大小分别适配 | 少 | 比 LoRA 更稳定,性能稍好 |
| AdaLoRA | 动态分配 rank 到不同层 | 少 | 自适应重要性分配 |
| IA³ | 学习元素级缩放向量 | 很少 | 与 LoRA 结合使用效果最好 |
| Prefix Tuning | 训练前缀嵌入向量 | 少 | 生成任务 |
| Prompt Tuning | 训练软提示嵌入 | 极少 | 超大模型上效果与全量微调接近 |
QLoRA: 消费级 GPU 上训练百亿模型
QLoRA 是 LoRA 的重要扩展,通过 4-bit NormalFloat 量化 + 双量化 + 分页优化,实现了:
- Llama 2 65B 在 48GB GPU 上训练(原本需要 >780GB 显存)
- 量化模型的性能损失极小(<1% 准确度下降)
- 支持完整的 16-bit 梯度计算(通过双量化 buffer)
Practical Workflow
python
from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM
# 1. 加载预训练模型
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b")
# 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=TaskType.CAUSAL_LM,
)
# 3. 包装模型
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 输出: trainable params: 33M || all params: 6.7B || trainable%: 0.49%
# 4. 训练(只更新 LoRA 参数)
trainer = Trainer(model=model, ...)
trainer.train()
# 5. 保存适配器(只有几十 MB)
model.save_pretrained("./lora-adapter")
# 6. 推理时合并或动态加载When to Use What
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 快速实验/原型验证 | LoRA (r=8) | 最快速度看效果 |
| 生产级部署 | QLoRA 或 LoRA + 量化 | 最低硬件要求 |
| 极端性能追求 | DoRA 或 AdaLoRA | 比标准 LoRA 稳定性更好 |
| 多任务适配 | LoRA + IA³ | 更强的表达能力 |
| 超大模型(>100B) | Prompt Tuning | 参数效率最高 |
Why It Matters
- 民主化模型定制:让个人开发者和小团队能在消费级硬件上定制大模型
- 多租户架构:一个基座模型 + 多个小适配器 = 多个专用模型,极大降低部署成本
- 迅速迭代:适配器训练只需分钟到小时,而非天/周
- 避免灾难性遗忘:全量微调可能覆盖预训练知识,LoRA 保留基座能力
Relationships
- 比较分析:Full FT vs LoRA vs QLoRA — 三种微调方法的全面对比
- 基础概念:Fine-tuning — 微调的基本原理与实践
- 量化关联:Model Quantization — QLoRA 依赖于 4-bit 量化技术
- 工具生态:Hugging Face PEFT 库是 LoRA 的事实标准实现
- 训练方法:Synthetic Data — LoRA 训练数据的质量决定适配效果
Open Questions
- LoRA 的 rank 上限在哪?当某些任务需要 r=256 甚至更高时,是否还比全量微调更有优势?
- 多适配器组合(如 Mixture of Adapters)能否达到模型合并的效果?
- LoRA 在多模态模型(图文混合)上的表现如何?是否需要为视觉编码器单独设计适配策略?
- 当基座模型更新时,旧适配器是否仍然有效?适配器版本管理的最佳实践是什么?
Sources
LoRA: Low-Rank Adaptation of Large Language Models (Hu et al., Microsoft, 2021)
QLoRA: Efficient Finetuning of Quantized LLMs (Dettmers et al., 2023)
DoRA: Weight-Decomposed Low-Rank Adaptation (Liu et al., 2024)
The Power of Scale for Parameter-Efficient Prompt Tuning (Lester et al., 2021)
Large Language Model (LLM) — 大语言模型的核心定义、技术原理与发展历程