卷2 · LLM 内功
2.6 参数高效微调:LoRA 与 QLoRA
展开本章目录与同卷章节
1. 显存对账:为什么需要 PEFT2. LoRA 原理(低秩假设的胜利)3. 手写 LoRA 层(peft 的内核就这么多)4. QLoRA:4bit 底座上的 LoRA5. 训练完之后:merge 还是留 adapter6. 其他 PEFT 一句话扫盲7. 自测题8. 动手作业(寒假里程碑第二段)案例 · 数值:算清一次 LoRA 的参数账9. 延伸资源同卷章节2.1 语言模型前史:n-gram → RNN → 注意力(20 分钟走完 30 年)2.2 BPE tokenizer 原理与实现2.3 GPT 架构工程版:从 TinyGPT 到 nanoGPT2.4 预训练:数据、Scaling Law 与训练稳定性2.5 SFT 与指令微调实战2.6 参数高效微调:LoRA 与 QLoRA2.7 对齐技术:RLHF → DPO → GRPO2.8 推理优化与 vLLM:把模型变成服务2.9 架构前沿:MoE、长上下文与注意力变体2.10 小模型时代的科研机会:1B–7B 甜点区本章目标:彻底吃透 LoRA——你未来两年用得最多的训练技术。学完标准:能手写 LoRA 层,会算它的显存账,知道 rank/alpha/target_modules 怎么选,能用 QLoRA 在单张 24G 卡上微调 7B。
1. 显存对账:为什么需要 PEFT
0.2 章的公式:全参微调显存 ≈ 16 字节/参数(bf16 权重 2 + 梯度 2 + AdamW 状态 8 + fp32 主权重 4)。7B 模型全参 ≈ 112GB——单卡无解。
LoRA 的账:冻结权重(只存 2 字节/参数,bf16),训练的只有低秩增量(参数量 ~0.1–1%)。7B 模型:权重 14GB + 少量梯度和优化器状态 ≈ 24GB 卡能跑。这就是消费级卡微调时代开启的原因。
2. LoRA 原理(低秩假设的胜利)
核心假设(0.1 章 SVD 的直接应用):微调引起的权重变化 近似低秩——不需要动整个 矩阵,用两个瘦矩阵的乘积表达增量:
参数量从 降到 。例:4096×4096 的矩阵,r=16 → 从 16.8M 降到 131K(0.8%)。
初始化的讲究: 高斯初始化、 置零——保证训练起点 ,模型从预训练状态平滑出发(不破坏已学能力),这是”微调不该踢翻原解”哲学(0.1 章 §4.3)的架构化实现。
缩放系数 α:实际增量是 。α 固定(常取 2r),调 r 时学习率尺度自动稳定——你只需记配比 α = 2r。
3. 手写 LoRA 层(peft 的内核就这么多)
class LoRALinear(nn.Module):
def __init__(self, base: nn.Linear, r=16, alpha=32):
super().__init__()
self.base = base # 冻结的原层
for p in self.base.parameters(): p.requires_grad = False
self.A = nn.Parameter(torch.randn(r, base.in_features) * 0.01)
self.B = nn.Parameter(torch.zeros(base.out_features, r)) # B 置零!
self.scale = alpha / r
def forward(self, x):
return self.base(x) + self.scale * (x @ self.A.T @ self.B.T)
实战用 peft 库:
from peft import LoraConfig, get_peft_model
cfg = LoraConfig(r=16, lora_alpha=32, lora_dropout=0.05,
target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"])
model = get_peft_model(model, cfg)
model.print_trainable_parameters() # trainable params: ~0.5% || 100%
选择指南:
target_modules:现代默认全挂(attention 四件套 + MLP 三件套)。早期只挂 q/v,实验证明 MLP 也很重要;- rank:数据少/任务简单 r=8–16;任务复杂/数据多 r=32–64;r 加大要配合数据量,否则过拟合更快;
- 学习率:LoRA 比全参大 10 倍左右(1e-4 ~ 2e-4)——只有增量在学习,敢迈大步。
4. QLoRA:4bit 底座上的 LoRA
LoRA 之后显存大头是冻结的权重本体(7B bf16 = 14GB)。QLoRA(2023)把它也压下去:
- NF4 量化:4bit 存储底座权重(NF4 是为正态分布权重定制的 4bit 数据类型,比均匀 int4 更贴分布);
- 反量化计算:前向时按需反量化到 bf16 做矩阵乘(存储 4bit,计算 bf16);
- 双重量化 + 分页优化器:量化常数本身再量化;显存峰值时优化器状态分页到内存——防 OOM 的保险。
结果:7B 模型 4bit 权重 ≈ 3.5GB + LoRA 参数与状态 + 激活 → 单张 24G 卡舒服微调,甚至 16G 卡能跑 7B。代价:训练速度慢 20–30%(反量化开销),精度损失实验上可忽略。LLaMA-Factory 里就是 quantization_bit: 4 一行配置。
5. 训练完之后:merge 还是留 adapter
- merge_and_unload():把 BA 乘积加回 W,得到独立模型——部署简单、推理零开销;但每个任务一个完整副本(7B bf16 = 14GB/个);
- 保留 adapter 文件(几十 MB):同一底座动态挂载多任务 adapter(多租户服务的做法);
- 上传 HF/ModelScope:LoRA 权重 + base 模型名 + 配置即可复现——寒假里程碑的交付形态。
常见坑清单:① 训练后忘 merge 或忘写 base model 名,加载直接报错;② dtype 混用(4bit 底座 + fp16 LoRA 会静默精度错乱,统一 bf16);③ target_modules 拼错名字静默不生效——print_trainable_parameters() 是 0 时及时发现;④ merge 时忘了 eval() 和dtype转换,输出乱码。
6. 其他 PEFT 一句话扫盲
Adapter(串联小瓶颈层,推理有额外延迟,已过气)|Prefix-tuning / P-tuning v2(在每层前加可学习软 token,全量推理开销,已边缘化)|DoRA(把权重分解为幅度+方向,方向上做 LoRA,小幅提升,可关注)。LoRA 家族是唯一的主流——理解它就理解了整个类别。
7. 自测题
- LoRA 的低秩假设是什么?为什么 B 初始化为零?(ΔW≈低秩;保证起点等于原模型)
- α/r 的作用?(学习率尺度的稳定器;α=2r 是惯例)
- 算账:Qwen2.5-7B(d=3584, 28 层)全挂 r=16 的 LoRA,可训练参数约多少?(7 个模块 × 2×16×(3584+3584)×28 ≈ 22M,约 0.3%——量级对即可)
- QLoRA 三件套?(NF4 量化底座 / bf16 反量化计算 / 双重量化+分页优化器)
- LoRA 学习率为什么比全参大 10 倍?(训练参数少一个数量级、B 起点为零——梯度小步长小,需放大)
- 多任务部署为什么留 adapter 不 merge?(几十 MB/任务 vs 14GB/任务;动态挂载)
- r 加大但不加数据的后果?(可训练容量↑ + 数据不变 → 过拟合加快;配合早停或降 r)
8. 动手作业(寒假里程碑第二段)
- 用第 3 节手写 LoRA 给一个预训练 ViT 的 attention 层加增量,在 CIFAR 微调,与全参微调对比精度和可训练参数量;
- LLaMA-Factory 用 QLoRA 微调 Qwen2.5-7B(租一张 4090):接续 2.5 的数据集,跑通 4bit 训练;
- 合并 adapter 并用 vLLM 起服务(2.8 预告,先跑通再说);
- 上传 HF/ModelScope:README 写清 base 模型、数据构造、训练配置、复现命令——这是你作品集的第一个大件;
- 实验记录:r=8/16/32 三档的验证 loss 曲线——亲手看到 rank 与过拟合的关系。
案例 · 数值:算清一次 LoRA 的参数账
案例:7B 模型全挂 r=16 的 LoRA,可训练参数是多少
LLaMA 式 7B:L=32,d=4096,每层挂 7 个线性层(q/k/v/o + gate/up/down),r=16。
每个模块: 参数。
全模型: 7B 的 0.42%。
训练状态(bf16 梯度 + fp32 AdamW 双动量):——对照全参微调约 70 GB 的梯度+优化器状态(7.1 的账),这就是 24G 卡能跑 7B 的完整解释。
验证手段:
model.print_trainable_parameters()应显示 ~29.4M / 0.42%——显示 0% 说明 target_modules 拼错了(7.2 案例群的经典静默失败)。
9. 延伸资源
- LoRA 论文(Hu et al., 2021)/ QLoRA 论文(Dettmers et al., 2023)——必读,各精读一遍
- peft 官方文档——API 速查
- Sebastian Raschka《LoRA 实操指南》博客系列——超参选择的工程视角
