目录
- LoRA 的核心概念:低秩矩阵分解
- LoRA 在大模型微调中的应用
- LoRA 的计算与初始化
- LoRA 与传统微调的对比
- LoRA 的代码实现思路
- 在实践中应用 LoRA (PEFT 库)
- QLoRA:量化版的 LoRA
- LoRA/QLoRA 应用场景与注意事项
- AI 总结
1. LoRA 的核心概念:低秩矩阵分解
LoRA 全称为 Low-Rank Adaptation,是一种用于高效微调大型语言模型的技术。其核心思想源于线性代数中的 低秩 (Low-Rank) 矩阵分解。
- 矩阵分解: 一个大的矩阵可以被分解为两个或多个小矩阵的乘积。
- 示例:
- 一个形状为
[1024, 512]的大矩阵W,其参数量为1024 * 512 = 524,288。 - 它可以被近似分解为两个小矩阵的乘积:一个矩阵
B形状为[1024, r]和一个矩阵A形状为[r, 512]。 Screenshot-[00:51] - 当
r(秩) 远小于1024和512时(例如r=32),这两个小矩阵的参数量之和为(1024 * 32) + (32 * 512) = 32,768 + 16,384 = 49,152。 - 这个参数量远小于原始矩阵的
524,288。
- 一个形状为
- 意义: 通过使用两个低秩矩阵来表示原始大矩阵的更新量,可以用更少的参数来捕捉模型在微调过程中的主要特征变化,从而实现参数的高效调整。
2. LoRA 在大模型微调中的应用
在微调大模型时,我们实际上是在更新模型的权重矩阵(如 Wq, Wk, Wv 等)。
- 传统微调 (Full Fine-tuning): 直接更新模型中所有或大部分权重矩阵的每一个参数,计算成本和存储成本都非常高。
- LoRA 微调:
- 冻结原始权重: 保持预训练模型的原始权重矩阵
W不变。 - 引入低秩适配器: 在
W旁边增加两个可训练的低秩矩阵B和A。 - 只训练适配器: 在微调过程中,只更新
B和A矩阵中的参数。 - 合并结果: 模型进行前向传播时,最终的权重是原始权重
W加上低秩适配器的乘积B*A。 Screenshot-[02:55]
- 冻结原始权重: 保持预训练模型的原始权重矩阵
- 优势:
- 参数高效: 只需训练和存储极少数的参数(
B和A),相比于整个模型,参数量可能只占不到 1%。 - 原始模型无损: 由于原始模型权重被冻结,如果微调效果不佳,可以直接丢弃
B和A矩阵,模型能力不会受损。
- 参数高效: 只需训练和存储极少数的参数(
3. LoRA 的计算与初始化
3.1. 超参数 r (Rank)
r是低秩分解的中间维度,是一个关键的超参数,可以自定义。r的取值通常是2的幂,如2, 4, 8, 16, 32。- 原则:
r必须远小于权重矩阵的原始维度n和d(r << n,r << d),这样才能体现出低秩的优势。 - 选择:
- 原始论文通过实验表明,
r在4到32之间通常能取得不错的效果。 - Screenshot-[05:27]
- 在实际应用中,初次尝试时选择
r=4或r=8是一个常见的起点。r越大,可训练参数越多,模型拟合能力可能更强,但训练成本也更高。
- 原始论文通过实验表明,
3.2. 更新公式与初始化
LoRA 的权重更新可以用以下公式表示:
W_original: 预训练模型的原始权重,在训练中保持冻结。B和A: 可训练的低秩矩阵。A通常使用高斯分布进行随机初始化。B初始化为全零矩阵,确保在训练开始时ΔW为零,不对原始模型产生影响。
α(alpha): 缩放因子,也是一个超参数。- 它与
r共同调节ΔW的更新幅度。 - 常见设置: 将
alpha设置为r的两倍或与r相等。当alpha = r时,缩放系数α/r等于1,这使得学习率的调整更加直观,无需因为r的变化而额外调整学习率。 Screenshot-[06:49]
- 它与
4. LoRA 与传统微调的对比
- 传统微调:
- 直接修改原始模型的权重矩阵。
- 如果微调数据质量不高或训练过度,可能导致“灾难性遗忘”,损害模型原有的通用能力。
- 训练产物是整个模型的权重,体积庞大。
- LoRA 微调:
- 原始模型权重保持不变,通过一个“插件”(
B和A矩阵)来注入新知识。 - 训练产物只是这个小巧的“插件”,易于存储和切换。例如,可以为一个基础模型训练多个针对不同任务的 LoRA 适配器。 Screenshot-[09:32]
- 原始模型权重保持不变,通过一个“插件”(
5. LoRA 的代码实现思路
从概念上讲,实现 LoRA 意味着将原有的单个权重矩阵的初始化过程,替换为两个低秩矩阵的初始化。
- 原始实现:
# Wq 是一个 [d_model, d_model] 的大矩阵 self.Wq = nn.Linear(d_model, d_model) - LoRA 实现思路:
# 将 Wq 分解为 A 和 B self.lora_A = nn.Linear(d_model, r) # 形状 [d_model, r] self.lora_B = nn.Linear(r, d_model) # 形状 [r, d_model] # 在前向传播时,计算 Wq * x 变为 (Wq_original + lora_B * lora_A) * x
Screenshot-[11:09] 在实际操作中,我们很少手写 LoRA,而是使用成熟的第三方库。
6. 在实践中应用 LoRA (PEFT 库)
Hugging Face 的 PEFT (Parameter-Efficient Fine-Tuning) 库是应用 LoRA 的主流工具。
- 配置参数: 在使用 PEFT 时,通常需要配置一个
LoraConfig对象。 Screenshot-[12:27]r: LoRA 的秩。lora_alpha: 缩放因子α。target_modules: 一个列表,指定要将 LoRA 应用于模型的哪些层的权重矩阵。这提供了极大的灵活性。- Attention 层:
q_proj,k_proj,v_proj,o_proj - Feed-Forward 层:
gate_proj,up_proj,down_proj - Embedding 层:
embed_tokens(输入词表),lm_head(输出预测层)
- Attention 层:
- 策略: 通常,将 LoRA 应用于模型所有的线性层(权重矩阵)能获得最好的性能提升。但在特定任务中,也可以只对部分关键层进行微调,以进一步节约资源。
7. QLoRA:量化版的 LoRA
QLoRA (Quantized LoRA) 是 LoRA 的一个重要变体,其核心思想是在量化后的模型上进行 LoRA 微调。
- Q = Quantization (量化): 将模型权重从高精度浮点数(如
float32或bfloat16)转换为低精度整数(如int8或int4)。 Screenshot-[14:22] - 工作流程:
- 将基础模型(如 Llama 3 8B)的权重从
bfloat16量化到NF4(4-bit NormalFloat)。 - 在这个被量化且冻结的模型上,添加 LoRA 适配器 (
B和A矩阵)。 - 只微调这个 LoRA 适配器。
- 将基础模型(如 Llama 3 8B)的权重从
- 核心优势:
- 极大降低显存占用: 4位量化后的模型体积大幅缩小,使得在消费级 GPU(如 4090)上微调大型模型(如 Llama 3 8B)成为可能。
- 提升训练速度: 低精度计算通常比高精度计算更快。
- 当前主流: QLoRA 是目前在单卡 GPU 或资源有限环境下进行大模型微调最主流、最实用的方法。
8. LoRA/QLoRA 应用场景与注意事项
- 主要用途: 用于模型的高效微调,目的是在保持模型性能的同时,最大程度地减少可训练参数的数量。
- 实现方式: 大多通过
PEFT等第三方库实现,用户只需调整r,alpha等超参数。 - 应用范围: 建议将 LoRA 应用于模型中所有的权重层(线性层),以获得全面的性能提升。
- 不适用范围: LoRA 通常不应用于模型的偏置项 (bias) 和层归一化 (Layer Normalization) 层,这些部分的参数会保持正常的可训练状态。
- 最终建议: 在进行 LoRA 微调时,优先考虑使用 QLoRA,尤其是在单 GPU 环境下,它能显著节省 GPU 显存并加速训练。 Screenshot-[15:50]
AI 总结
LoRA (Low-Rank Adaptation) 是一种革命性的高效微调技术,其核心在于将大模型中庞大的权重矩阵更新量 ΔW,巧妙地分解为两个低秩(r 值很小)矩阵 B 和 A 的乘积。在微调时,它会冻结数十亿参数的原始模型,仅训练这些参数量极小的 B 和 A 矩阵。这种方法不仅将可训练参数数量降低了几个数量级(通常不到原始模型的1%),还极大地减少了计算和存储需求。
QLoRA 则是 LoRA 的进一步优化,它将 LoRA 技术应用于一个已经被量化(例如,从16位浮点数降至4位整数)的基础模型上。这使得模型占用的显存进一步锐减,让普通消费级 GPU 微调大型模型成为现实。总而言之,LoRA 和 QLoRA 通过“冻结大、训练小”的策略,实现了大模型微调的平民化,是当前AI领域最实用、最高效的参数微调方法之一。