1. 大模型微调
在大模型微调过程中,最简单的办法是全量的微调,也就是说把巨大的矩阵(千亿的参数规模)从头到尾重新修改一遍,对于绝大部份的用户来说,这都是不切实际的,不仅需要巨大的算力支撑,同时,有限量的微调数据对于全量的修改来说也是杯水车薪。既然这条路走起来又一些问题,那么是否有其他的办法实现对大模型的微调呢?LoRA[1] 正是这样的方法,LoRA 全称是 Low-rank adaptation。
2. LoRA 的基本原理
2.1. LoRA
LoRA 的思路也比较直接,既然全量修改不可行,那么我不改变原来的矩阵,而是在原来矩阵的基础上进行一些微调,可以用下面的公式来表示:
这一步的公式相对比较好理解,其实在残差连接中也又相关的设计。更进一步, 可以分解成两个低秩矩阵 和 ,即:。
总结来看,LoRA 的整个过程分为两步:
- 残差连接,固定好大模型中某个参数的巨大矩阵 ,并在此基础上增加一个变化量 ,以此来表示要更新的信息,更新后的巨大矩阵表示为:
- 低秩分解,将变化量 拆分成两个极低的秩的矩阵 和矩阵 的乘积,即
上述的过程,可由下图表示:

2.2. 矩阵中的秩
这里会涉及矩阵以及矩阵中秩的概念,简单来说,矩阵的秩就是衡量矩阵中行向量或者列向量的线性无关性。举个简单的例子,由一个矩阵 ,为:
这个矩阵相对要复杂一些,为方便描述,记每一行为 ,仔细研究一下会发现:
- 第二行
- 第三行
- 第四行
- 第五行
虽然矩阵 很大,是一个 的矩阵,但是其秩为 1,现在将矩阵 分解成两个矩阵的乘积:
我们发现,分解后的两个矩阵的秩都为 1,原来矩阵 中我们需要计算的数据量是 ,而现在变成了 ,极大地减少了需要计算的数据量。
2.3. LlamaFactory 中的参数设置
在大模型的 finetune 过程中,SFT 阶段通常会采用 LlamaFactory 框架来训练,在训练的过程中若要采用 LoRA[2] 的方式,需要设置以下的一些参数,参考文献[2] 中给出了一个例子:
...
### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
lora_rank: 8
lora_alpha: 16
lora_dropout: 0.1
...
- finetuning_type,选择为 lora,表明使用 LoRA 模式来训练
- lora_target,是指应用 LoRA 方法的模块名称,可以选择为"all",也可以指定模块,如
q_proj,k_proj,v_proj,o_proj,up_proj,gate_proj,down_proj - lora_rank,也就是秩的大小,这个参数直接影响模型的性能和训练时间,一般,对于小型数据集或简单任务,秩可以设置为 1 或 2;对于更复杂的任务,秩可能需要设置为 4、8 或更高
- lora_alpha,缩放系数,主要用于在训练开始时对低秩矩阵的更新进行缩放,以确保训练过程的稳定性
- lora_dropout,使用 dropout 防止过拟合
当然还有其他的参数,这里就不一一列举了,除了推荐的值之外,还需要根据实际的训练调整这些超参。
3. 总结
LoRA 技术结合了残差连接的思想,针对新的训练数据,在固定住原始的矩阵的前提下,通过残差的方式进行微调,同时为了进一步减少参数的量,对微调矩阵进行低秩分解,进一步减少了需要学习的参数的量。
参考文献
[1] Hu E J, Shen Y, Wallis P, et al. Lora: Low-rank adaptation of large language models[J]. arXiv preprint arXiv:2106.09685, 2021.
[2] LlamaFactory