LLM学习笔记-从全量微调到LoRA再到QLoRA

 

前言

来自: https://huggingface.co/blog/mlabonne/sft-llama3从全量微调LoRA再到QLoRA,核心是为了解决在有限显存资源下微调大模型的问题。

方法 核心理念 一句话概括
全量微调 更新全部参数 搬整个图书馆,效果好但显存爆炸
LoRA 冻结原模型,只训练旁路小矩阵 A×B 不搬书,只做索引卡,显存省10倍+
QLoRA LoRA + 4-bit量化 先把书压缩成口袋书,再做索引卡,显存再省60%

技术细节对比

维度 全量微调 LoRA QLoRA
模型精度 FP16/FP32 FP16 4-bit NF4
训练参数 全部(70亿) 仅A和B(~800万) 仅A和B(~800万)
显存占用(7B) 56+ GB 14-16 GB 6-8 GB
训练速度 基准 更快(量化后计算量小)
精度损失 极小(~1%)
硬件要求 A100/H100 RTX 3090/4090 RTX 3060(12GB即可)

为什么 QLoRA 比 LoRA 还快? 数据变小了,计算自然变快。QLoRA计算4-bit数据,虽然多了“临时反量化”步骤,但整体计算量小,速度反而快20-50%。


📐 LoRA 核心技术原理

1. 核心思想:低秩分解

不碰原始权重W,在旁边加可训练的小补丁 A×B

输出 = 输入 × W + 输入 × A × B

2. 为什么拆成 A 和 B?(数学原理)

将增量更新 ΔW 分解为两个小矩阵:ΔW (d×k) = A (d×r) × B (r×k),其中 r « d, k

参数对比(d=4096, k=4096, r=8)

  • 全量微调 (整个W):1600万参数/层
  • LoRA (A+B):6.6万参数/层 (节省240倍)

3. 训练与推理流程

  • 训练时:W冻结,梯度只流向A和B并更新。
  • 推理时:计算新权重 W’ = W + A × B,使用W’推理,零额外开销。

⚙️ LoRA 三大核心参数详解

这三个参数共同决定了LoRA的容量、影响力和作用位置。

1. Rank(秩 r)

  • 作用:决定LoRA补丁的“大小”或“容量”,即能存储多少信息。
  • 影响:r越大,补丁越厚,参数量越大,表达能力越强,但显存占用也越高。
  • 选择建议
    • r=4 ~ 8:数据少(几百条),追求极致速度。
    • r=16✅ 最常用、性价比最高,大多数任务首选。
    • r=32 ~ 64:数据多(数万条)、任务复杂。
    • 经验法则:从 r=16 开始尝试。

2. Alpha(α)—— 缩放因子

  • 作用:控制LoRA补丁对最终输出的“影响力”。
  • 实际计算实际补丁贡献 = (α / r) × (输入 × A × B)关键在于 α/r 这个比值
  • 影响:α越大,补丁影响力越大,模型“更听LoRA的话”;反之则更保守。
  • 选择建议
    • 常见配置:α = r(缩放系数=1)或 α = 2×r(缩放系数=2,学习更激进)。
    • 经验法则:从 α = rα = 2×r 开始。

3. Target Modules(目标模块)

  • 作用:指定在模型的哪些“部位”(如注意力层的Q、K、V投影)挂载LoRA补丁。
  • 各策略对比
策略 Target Modules 可训练参数(7B, r=16) 推荐度
极致轻量 ["q_proj"] ~210万 ⭐⭐
✅ 保守推荐 ["q_proj", "v_proj"] ~420万 ⭐⭐⭐⭐
✅ 标准推荐 ["q_proj", "k_proj", "v_proj"] ~630万 ⭐⭐⭐⭐⭐
激进 更多模块(如Q,K,V,O,FFN) ~1500万+ ⭐⭐
  • 经验法则:从 ["q_proj", "v_proj"]["q_proj", "k_proj", "v_proj"] 开始。

🧩 参数间的协同关系:α 与 r 的本质

核心结论α和r共同决定缩放因子(α/r),但分开设计是为了独立控制LoRA的“容量”(r)和“强度”(α/r)。

  • r(秩):控制 “容量”——补丁能存多少信息。比喻:笔记本的页数
  • α(缩放系数):控制 “强度”——补丁对模型的影响有多大。比喻:每页字号大小
  • α/r(缩放因子):实际训练中补丁的最终影响力

为什么这样设计? 为了解耦“容量”和“强度”,获得更高的调参自由度和可解释性。

实际应用场景

  • 增大容量,保持强度:同步增大 r 和 α(如 r: 8→16, α: 8→16)。
  • 保持容量,增大强度:只增大 α(如 r=16, α: 16→32)。
  • 保持容量,降低强度:只减小 α(如 r=16, α: 16→8)。

🚀 新手起步配置建议

从以下经典配置中二选一,可覆盖90%的微调场景:

python

# 配置一:标准稳定
from peft import LoraConfig
lora_config = LoraConfig(
    r=16,
    lora_alpha=16,  # 比值 = 1.0
    target_modules=["q_proj", "v_proj"],  # 或 ["q_proj", "k_proj", "v_proj"]
)

# 配置二:效果通常更好,学习更激进
lora_config = LoraConfig(
    r=16,
    lora_alpha=32,  # 比值 = 2.0
    target_modules=["q_proj", "v_proj"],
)

💡 补充说明:SFT的局限性

你提供的资料也提到,监督微调(SFT) 最适合利用基座模型已有的知识。若要模型学习完全全新的信息(如未知语言),SFT效果不佳且易产生幻觉,此时建议先进行持续预训练(继续预训练)

进阶阅读:

Finetuning LLMs with LoRA and QLoRA: Insights from Hundreds of Experiments - Lightning AI