从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题 原创

发布于 2025-6-11 09:41
浏览
0收藏

身为一名AI工程师,我过去的工作主要集中在应用层开发,对算法的理解并不深入。然而,近期我开始对算法产生了浓厚的兴趣,并转向研究模型微调。在众多微调算法中,Lora以其普遍应用引起了我的关注,我计划在本文中对它进行详细介绍。将Lora仅仅视为一种算法可能并不准确,它更像是一种精妙的技巧或策略。下文将围绕几个核心问题,全面探讨和解析Lora技术,希望这些内容能为对模型微调感兴趣的你提供有用的参考和帮助。

Lora是什么

假设大模型的原始的权重矩阵w是:

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

全量微调需要更新 5 * 4 = 20个参数,假设微调后的参数是:

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

这个可以转化为:

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

其中ΔW 可以分解为

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

  • 矩阵 ( A ):尺寸 ( 5 * 2 ),共10个参数
  • 矩阵 ( B ):尺寸 ( 2 * 4 ),共8个参数
  • LoRA总参数:( 10 + 8 = 18 ) 个

也就是说通过LoRA微调,调参对象从 W 变为 A、B,使得参数量从20个减少为18个,这是简化的例子。在实际案例中,参数量可以减少为0.01%~3%左右。

为什么需要LoRA

LoRA最早出现在2021年由微软研究院提出的一篇论文中(《LoRA: Low-Rank Adaptation of Large Language Models》),LoRA的核心思路是:与其每次都复制整个模型,不如只调整一小部分参数,把成本降下来。它的目标是解决大模型微调中的两大痛点:

  1. 资源消耗太大:大型语言模型动辄几亿甚至几千亿参数,全参数微调需要为每个新任务保存一份完整的模型副本。比如,一个10亿参数的模型,假设每个参数用4字节(float32),光存储就得4GB。多个任务下来,硬盘和显存都吃不消。
  2. 训练效率低下:全参数微调不仅占空间,还需要大量计算资源和时间。每次训练都得更新所有参数。

LoRA的核心亮点

  1. 参数少
  • 在GPT-3上,​​r = 8​​的LoRA参数量占全微调的0.01%-0.1%,性能却达到全微调的95%-99%。
  • 在GLUE任务(BERT),​​r = 16​​的LoRA用0.1%参数,平均得分仅比全微调低0.5-1分。
  • 它只微调原始参数的1%甚至更少。
  1. 速度快
  • 训练和部署都比全参数微调省时省力。
  1. 模块化
  • 训练好的LoRA“插件”可以随时加载或卸载,不影响原始模型,特别适合多任务场景。

模块化设计的优点

  • 避免灾难性遗忘
    直接修改​​​W​​​ 可能导致模型在新任务上表现良好,但在原始任务上性能下降(即“灾难性遗忘”)。LoRA通过冻结核心​​W​​,保留了原始模型的能力。
  • 存储高效
    一个大模型可以搭配多个LoRA模块,每个模块只占用MB级空间,相比全模型微调动辄几GB,节省显著。
  • 快速切换任务
    任务切换只需加载不同LoRA文件,几秒钟搞定,不用重新训练。
  • 兼容性强
    原始模型完全不动,多个团队可以共享同一个基础模型,只开发自己的LoRA模块。

为什么可以对增量权重 ΔW 低秩分解?

低秩分解的核心思想是:矩阵里的信息往往不是均匀分布的,很多维度是冗余的,只需要抓住"主要方向"就够了。

1. 什么是矩阵的秩(Rank)?

在线性代数中,一个矩阵的秩(rank)是它的线性独立行或列的数量。如果一个矩阵是"低秩"的,意味着它的信息可以用少量独立方向表达,而不是需要完整的维度。

比如下述矩阵,第5行 ​​[1, 2, 0, 3, 0]​​​ 是第1行 ​​[1, 0, 0, 2, 0]​​​ 和第2行 ​​[0, 2, 0, 1, 0]​​ 的线性组合(第5行=第1行+第2行),第5行没有提供更多的信息,理论上这个矩阵有前4行就能提供所有信息了,因此矩阵的行秩为4(列秩也为4,第5列全为0,没有信息增量)。

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

2. 低秩分解的原理

奇异值分解(SVD)可以把任意矩阵分解成三个矩阵的乘积。对于一个形状 ( d * k ) 的矩阵 ( W ),SVD可以写成:

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区


  • ( U ) 是 ( d * d ) 的正交矩阵
  • (Σ ) 是 ( d * k ) 的对角矩阵(奇异值按降序排列)
  • ( V^T ) 是 ( k * k ) 的正交矩阵(( V ) 的转置)

其中 ( r ) 是矩阵的秩(非零奇异值的数量)。通过保留前 ( r ) 个最大的奇异值(低秩近似),可以用更少的参数近似原矩阵 ( W )。

任意矩阵(无论是实数还是复数、方阵还是非方阵、满秩还是不满秩)都可以通过奇异值分解(SVD)精确拆分为三个特定矩阵的乘积

举个例子,针对上述矩阵 ( S ) 的SVD分解(计算过程略):

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

如果只保留前三个奇异值(7.03, 3, 2.15),重构后的矩阵 ( S' ) 与原矩阵 ( S ) 几乎一致(三个矩阵分别取前三列,前三行&前三列,前三行):

从原理到调参,小白也能读懂的大模型微调LoRA,不懂线性代数也没问题-AI.x社区

结果对比原始矩阵和重构矩阵,直观上来看,基本保持一致,这就是说:如果只保留最大的几个奇异值,就能用更少的参数近似表示w

3. 为什么可以对增量权重 ΔW 低秩分解?

研究发现:

  • 信息集中性:微调后的权重变化 ( ΔW) 的奇异值分布中,前10-20个奇异值占据了90%以上的信息(LoRA论文在GPT-3上的实验结论)。
  • 结构化特性:(ΔW ) 的变化不是随机的,而是集中在少数"任务相关方向"上(例如让模型学习法律术语只需调整少量语义方向)。
  • 高效近似:直接用低秩矩阵 ( A * B ) 构造 (ΔW ),无需完整SVD计算,参数量从 ( d * k ) 降至 ( (d + k) * r )。

直观理解:  微调类似于让一个已学会"说话"的模型掌握某种"口音"。这种调整只需修改少数关键维度(如词汇选择),而非全部语言规则,因此低秩足够。

举个例子
对一个 ( 512 * 512 ) 的权重矩阵(262,144参数):

  • 全微调:更新全部262,144个参数。
  • LoRA(( r=8 )):仅需 ( 512 * 8 + 8 *  512 = 8,192 ) 个参数,即可捕捉主要变化。

4. 对原始权重 ( W ) 可以低秩分解吗?

不行。预训练模型的权重 ( W ) 通常接近满秩(奇异值分布平滑),低秩分解会丢失关键信息。而 ( ΔW ) 的秩天然较低,适合分解。

LoRA是如何更新参数的

本质上,LoRA仍然使用反向传播算法进行参数更新,但仅针对新增的低秩矩阵 ( A ) 和 ( B ),而保持原始权重 ( W ) 冻结。

参数更新过程

(1)初始化

  • ( W ) 使用预训练模型的权重,梯度计算被禁用(不更新)。
  • ( A ) 用小的随机高斯分布初始化
  • ( B ) 初始化为全零矩阵,确保训练开始时 ( ΔW = 0 ),避免干扰原始模型。

(2)前向传播

  • 输入数据 ( X ) 通过调整后的权重计算输出
  • 根据任务目标 计算损失函数 ( L )(如交叉熵损失)。

(3)反向传播

  • 计算损失 ( L ) 对 ( A ) 和 ( B ) 的梯度
  • 不计算( W ) 的梯度(因其被冻结)。

(4)参数更新

  • 使用优化器(如Adam)更新

(5)迭代优化

  • 重复步骤2-4,直到损失收敛或达到训练轮次。
  • 训练完成后,( A ) 和 ( B ) 捕捉了任务特定的调整信息。

推理部署选项

  • 合并权重:将 ( W' = W + A * B ) 合并为单一矩阵,直接用于推理(适合固定任务)。
  • 动态加载:保持 ( W ) 和 ( A * B ) 分离,灵活切换不同任务的LoRA模块(适合多任务场景)。

关键特点

  • 参数高效:仅训练 ( A ) 和 ( B ),参数量从 ( d * k ) 降至 ( (d + k) * r )。
  • 内存节省:无需存储全参数微调的梯度,显存占用大幅降低。
  • 兼容性:原始模型 ( W ) 保持不变,支持多任务共享。

LoRA可以用在Transformer的哪些层

LoRA是"好钢要用在刀刃上"。并非模型的所有参数都需要微调,选择关键层进行适配即可达到接近全参数微调的效果。LoRA目前主要可以应用在transformer中的以下两类层:

Transformer是谷歌在2017年推出的深度学习模型,专门处理序列数据。简单来说,序列数据就像排队的小朋友,每个小朋友都有自己的位置和信息,Transformer能把这些信息处理得明明白白。后面有空我会专门出一个系列讲解一下。

1. 注意力层(Self-Attention)

Transformer的核心是多头注意力机制,每个注意力头包含4个权重矩阵:

  • ( W_q )(Query)
  • ( W_k )(Key)
  • ( W_v )(Value)
  • ( W_o )(Output)

LoRA通常应用在

  • ( W_q ) 和 ( W_v )(最高优先级):
  • 调整 ( W_q ) 可改变模型"关注哪些信息"。
  • 调整 ( W_v ) 可影响"如何编码关注的信息"。
  • ( W_o )(次优先级):
  • 调整输出投影矩阵,但收益通常不如 ( W_q ) 和 ( W_v ) 显著。

实验结论(来自LoRA原论文):

  • 仅微调 ( W_q ) 和 ( W_v ) 即可达到全参数微调效果的90%以上。
  • 添加 ( W_o ) 的LoRA对性能提升有限(<2%),但会增加参数量。

2. 前馈网络层(FFN)

FFN包含两个线性变换:

  • ( W_1 ):升维(通常放大4倍,如d_model → 4×d_model)
  • ( W_2 ):降维(4×d_model → d_model)

适用场景

  • 大模型(如GPT-3):添加FFN层的LoRA可进一步提升性能。
  • 复杂生成任务:调整FFN能增强任务特定的特征表达。

不推荐使用LoRA的层

(1)嵌入层(Embedding)

  • 参数量大但微调收益低,冻结可节省资源。

(2)LayerNorm/Bias

  • 参数少,直接全参数微调成本低。
  • LayerNorm的缩放因子和偏置本身具有低秩特性,无需LoRA。

实际配置建议

模型规模

推荐LoRA目标层

典型rank (r)

小模型(如BERT)

仅 ( W_q ), ( W_v )

8-16

大模型(如GPT-3)

( W_q ), ( W_v ), FFN的 ( W_1 )

32-64

复杂生成任务

所有注意力矩阵 + FFN

64+

模块化设计优势

  • 任务切换:不同任务可独立配置LoRA模块(如翻译任务用( W_q ), ( W_v ),摘要任务额外启用FFN)。
  • 资源分配:对关键层分配更高秩(如( r=32 )),次要层用低秩(如( r=8 ))。

LoRA训练时需要调整哪些超参数

以 LLaMA-Factory 的配置为例,说明 LoRA 的关键超参数及其调参策略:

核心参数表

参数名

类型/范围

含义

建议值

默认值

​finetuning_type​

​["full","freeze","lora"]​

微调类型选择

必须设为 ​​"lora"​

​"lora"​

​lora_rank​

 (r)

正整数

LoRA的秩,决定矩阵A/B的列数/行数

简单任务:8-16
中等任务:32
复杂任务:64+

8

​lora_alpha​

 (α)

正整数

缩放系数,控制ΔW对原始权重W的影响强度

通常设为 ​​lora_rank​​ 的1-2倍(如r=16时α=32)

None

​lora_dropout​

0.0-1.0

LoRA层的Dropout概率

大数据集:0.0
小数据集:0.05-0.1(防过拟合)

0.0

​lora_target​

逗号分隔的字符串

应用LoRA的模块名称(需匹配模型层名)

默认:​​"q_proj,v_proj"​​​复杂任务:​​"q_proj,k_proj,v_proj,o_proj"​

​"all"​

​additional_target​

逗号分隔的字符串

额外扩展的LoRA目标模块(如FFN层)

通常留空,大模型可加​​"ffn.w1,ffn.w2"​

None

调参技巧
  1. 秩(r)的选择
  • 小数据集(<5K样本):r=8
  • 大数据集(>50K样本):r=32+
  • 从小开始:优先尝试r=8或16,逐步增加直至性能饱和。
  • 数据量关联
  1. 目标层选择策略

# 简单任务(如分类)
lora_target = "q_proj,v_proj"

# 复杂任务(如生成)
lora_target = "q_proj,k_proj,v_proj,o_proj,ffn.w1,ffn.w2"

 3.改进技术的适用场景

  • LoRA+:训练速度要求高时启用(设​​lorapius_lr_ratio=8​​)。
  • DoRA:需要逼近全微调性能时开启(​​use_dora=true​​)。
  • rsLoRA:当r≥32时更稳定(​​use_rslora=true​​)。
参数影响对比

超参数

参数量影响

训练速度

性能影响

​lora_rank​

 ↑

线性增加

略微下降

先升后平

​lora_alpha​

 ↑

无影响

无影响

调节强度

​use_dora=true​

增加约10%

下降10%-20%

提升1%-3%

​pissa_init=true​

无影响

初始化耗时增加

收敛更快

经典配置示例

# GLUE任务(BERT-base)
lora_rank:16
lora_alpha:32
lora_target:"query,value"
lora_dropout:0.1

# GPT-3文本生成
lora_rank:64
lora_alpha:128
use_rslora:true
lora_target:"q_proj,v_proj,ffn.w1"

总结

LoRA是一种高效的大模型微调技术,它通过低秩矩阵分解显著地减少了参数量和计算资源的需求,同时又能保持接近全模型微调的性能。在接下来的文章中,我们将从实战角度出发,借由Llama-Factory来进行模型微调。我希望能帮助读者从零开始,全面掌握模型微调的知识和技巧。


本文转载自​AI 博物院​ 作者:longyunfeigu


©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2025-6-11 10:12:49修改
1
收藏
回复
举报
回复
相关推荐