4.LoRA微调
LoRA(Low-Rank Adaptation)是目前最流行的参数高效微调方法,通过低秩分解大幅减少可训练参数,让普通 GPU 也能微调大模型。
# 4.1 LoRA 原理
# 4.1.1 核心思想
LoRA 的核心假设是:模型在适应新任务时,权重的变化具有低秩特性。
什么是低秩特性? 矩阵的秩表示其中线性无关的行(或列)的数量,反映了矩阵包含的"有效信息维度"。一个 4096×4096 的矩阵理论上秩最高为 4096,但如果秩只有 8,说明它的信息可以用 8 个基向量表示,从而可以分解为两个小矩阵的乘积:(4096×8) × (8×4096)。
LoRA 假设权重变化量 ΔW 虽然是个大矩阵,但"有效变化"集中在一个低维子空间里。直观理解:预训练模型已经学会了语言的通用规律,适配新任务只需要在少数几个"方向"上做微调,这些调整方向的数量远小于参数总数。
# 4.1.2 数学原理
对于预训练权重矩阵 W₀ ∈ ℝ^(d×k),LoRA 不直接更新 W₀,而是添加一个低秩分解的增量:
W = W₀ + ΔW = W₀ + BA
其中:
- B ∈ ℝ^(d×r):降维矩阵
- A ∈ ℝ^(r×k):升维矩阵
- r:秩(rank),远小于 d 和 k
参数量对比(以 d = k = 4096, r = 8 为例):
| 类型 | 参数量 |
|---|---|
| 原始权重 | 4096 × 4096 = 16,777,216 |
| LoRA 增量 | 8 × (4096 + 4096) = 65,536 |
| 参数减少 | 99.6% |
# 4.1.3 前向传播
训练时,前向传播变为:
h = W₀x + ΔWx = W₀x + BAx
- W₀:冻结,不更新
- B 和 A:可训练,通过梯度下降更新
# 4.1.4 初始化策略
为了保证训练开始时 LoRA 不影响原模型输出:
- A:使用高斯随机初始化
- B:初始化为零矩阵
这样初始时 BA = 0,模型输出与原模型完全一致。
# 4.1.5 缩放因子
LoRA 引入缩放因子 α 来控制增量的影响:
h = W₀x + (α/r) · BAx
通常设置 α = r 或 α = 2r。
# 4.2 LoRA 的应用位置
# 4.2.1 Transformer 中的权重矩阵
| 模块 | 权重矩阵 | 说明 |
|---|---|---|
| 注意力层 | W_q, W_k, W_v, W_o | Query、Key、Value 和输出投影 |
| 前馈层 | W_up, W_down, W_gate | 上投影、下投影、门控 |
# 4.2.2 常见配置
| 配置 | 目标模块 | 适用场景 |
|---|---|---|
| 最小 | q_proj, v_proj | 资源极限 |
| 推荐 | q, k, v, o_proj | 大多数场景 |
| 完整 | 注意力层 + 前馈层 | 追求效果 |
# 4.3 关键超参数
# 4.3.1 秩(Rank)
秩 r 决定了 LoRA 的表达能力:
| r 值 | 可训练参数 | 适用场景 |
|---|---|---|
| 4-8 | 最少 | 简单任务、资源极限 |
| 16-32 | 适中 | 大多数场景 |
| 64-128 | 较多 | 复杂任务、追求效果 |
选择建议:从 r=8 或 r=16 开始,效果不足时逐步增加。
# 4.3.2 Alpha(缩放因子)
Alpha 控制 LoRA 更新的强度。
经验法则:alpha = 2 × r 是一个不错的起点。
# 4.3.3 Dropout
LoRA Dropout 用于防止过拟合,常用值 0.05 ~ 0.1。
# 4.3.4 学习率
LoRA 通常可以使用比全量微调更大的学习率:
| 方法 | 学习率范围 |
|---|---|
| 全量微调 | 1e-5 ~ 5e-5 |
| LoRA | 1e-4 ~ 5e-4 |
# 4.4 QLoRA:量化 + LoRA
QLoRA 结合了量化和 LoRA,进一步降低显存需求。
# 4.4.1 原理
- 将基座模型量化为 4-bit(NF4 格式)
- 在量化模型上应用 LoRA
- LoRA 参数保持 FP16/BF16 精度
# 4.4.2 显存对比
| 方法 | 7B 模型显存需求 |
|---|---|
| 全量微调(FP32) | ~112GB |
| 全量微调(FP16) | ~56GB |
| LoRA(FP16) | ~28GB |
| QLoRA(4-bit) | ~6GB |
# 4.5 LoRA 变体
# 4.5.1 LoRA+
对 A 和 B 矩阵使用不同的学习率,B 的学习率是 A 的 16 倍,效果更好。
# 4.5.2 DoRA
DoRA(Weight-Decomposed Low-Rank Adaptation)将权重分解为幅度和方向,分别进行适配。
# 4.5.3 rsLoRA
使用 √r 作为缩放因子,在高秩时更稳定。
# 4.6 LoRA 的使用
# 4.6.1 训练
使用 PEFT 库或 LLaMA-Factory 等工具进行 LoRA 训练,配置好 r、alpha、target_modules 等参数即可。
# 4.6.2 推理
推理时有两种方式:
- 动态加载:基座模型 + LoRA 权重分开加载
- 合并权重:将 LoRA 权重合并到基座模型中
# 4.6.3 多任务切换
可以为不同任务训练不同的 LoRA 权重,共享同一个基座模型:
基座模型(7B)
├── LoRA-翻译(~40MB)
├── LoRA-摘要(~40MB)
├── LoRA-代码(~40MB)
└── LoRA-对话(~40MB)
2
3
4
5
运行时动态加载所需的 LoRA 权重,实现高效的多任务切换。
# 4.7 优缺点与适用场景
# 4.7.1 优点
- 显存占用低:只需存储和更新少量参数
- 训练速度快:梯度计算量大幅减少
- 存储高效:每个任务只需保存几十 MB 的权重
- 易于切换:可以快速切换不同任务的 LoRA
- 减少过拟合:参数少,正则化效果好
# 4.7.2 缺点
- 效果上限:复杂任务可能不如全量微调
- 推理开销:未合并时有额外计算
- 超参敏感:r、alpha 等参数需要调优
# 4.7.3 适用场景
| 场景 | 推荐度 |
|---|---|
| 资源有限 | ⭐⭐⭐⭐⭐ |
| 快速迭代 | ⭐⭐⭐⭐⭐ |
| 多任务场景 | ⭐⭐⭐⭐⭐ |
| 数据量少 | ⭐⭐⭐⭐ |
| 追求极致效果 | ⭐⭐⭐ |
# 4.8 超参数选择总结
| 场景 | r | alpha | target_modules |
|---|---|---|---|
| 快速实验 | 8 | 16 | q_proj, v_proj |
| 一般任务 | 16 | 32 | q, k, v, o_proj |
| 复杂任务 | 32-64 | 64-128 | 全部线性层 |
| 资源受限 | 4-8 | 8-16 | q_proj, v_proj |