一、微调方法介绍
1.1 Lora原理
通过低秩矩阵来降低模型训练的参数量,有点‘给我一个支点,就可以撬动地球’的感觉,其中矩阵的秩(rank)就有点像这个‘支点’的意思,大致原理如下:
LoRA 的核心思想是:在不改变原始模型权重的情况下,通过引入低秩矩阵的增量来进行微调。也就是说,LoRA 不直接更新原模型的参数,而是为其特定的层添加额外的可训练参数,从而实现对模型的适应调整。一方面知识对部分层进行微调,另一方面还对需要更新的矩阵层ΔW进行了分解,进一步减少了参数量和计算量。
原文链接:https://blog.csdn.net/qq_42755230/article/details/142853955
(1)原论文中的lora原理图,左边蓝色部分是你使用的LLM,模型中的参数是不同的矩阵,比如Qwen2.5-1.5B的模型,就是所有参数量(所有矩阵大小相加)为15亿。
(2)上图中我们简化为一个矩阵W,大小为in_shape,out_shape,可想而知,in_shapeout_shape是巨大的,如果像以往正常的微调,需要付出巨大的算力资源,以及大量的数据,如果数据量小的话,不足以微调其中的模型具体参数。
(3)lora引入低秩矩阵的想法和矩阵的积:
(4)lora引入两个低秩矩阵A和B,AB的大小为LLM参数矩阵W的大小即可实现“撬动地球”的想法,矩阵的秩为rank,如下如
(5)所以使用lora方法对大模型进行微调时,训练过程中冻结原LLM模型权重,只对外部的AB两个权重进行学习微调,这样的话训练的参数量只有A和B两个矩阵,即:
in_shape * rank + rank * out_shape
秩rank越大,就越接近LLM原本的大小,训练起来算力越大;rank越小时,训练的参数量就越小,但是rank过于小的时候,则无法更好的学习到微调的数据。
(6)现在让我们直观地感受一下lora微调减少的训练参数量,比如一个12B的大模型:
LLM 12B W(30000 * 40000)
我们设置rank为8,则A和B的大小为:
A(30000 * 8)
A(8 * 40000)
我们需要训练的参数量只有:
A+B = 30000 * 8 + 8 * 40000
只有原LLM 12B的 0.047 %,只需要训练56万的参数。
(30000 * 8 + 8 * 40000) / 30000 * 40000 = (8 * 7) / 120000 = 0.047 %
1.2 Lora与Adapter对比
特性 | LoRA (低秩适应) | Adapter (适配器) |
---|---|---|
定义 | 通过添加低秩矩阵来修改预训练模型的权重,以实现特定任务的微调。 | 在预训练模型的基础上插入小型的、可训练的网络模块(即Adapters),这些模块用于学习特定任务的知识。 |
参数量 | 较少,因为只引入了低秩矩阵。 | 也较少,但通常比LoRA多,因为Adapters可能包含多个层。 |
计算成本 | 相对较低,由于更新的参数较少。 | 中等,取决于Adapter的设计复杂度。 |
微调速度 | 快,因为需要优化的参数较少。 | 较快,但由于可能有更多层,所以比LoRA慢一些。 |
模型性能 | 可能会有所下降,尤其是在资源非常有限的情况下。 | 通常能保持较好的性能,因为Adapter有能力捕捉更复杂的模式。 |
泛化能力 | 由于参数量少,可能会有较好的泛化能力,尤其是在小数据集上。 | 泛化能力较好,因为它能够学习到更丰富的特征表示。 |
迁移学习 | 易于迁移,因为主要调整的是少量的参数。 | 也易于迁移,但可能需要根据新任务调整Adapter的设计。 |
模型大小 | 微调后的模型大小增加不大。 | 模型大小增加相对较大,取决于Adapter的复杂度。 |
适应场景 | 非常适合资源受限的环境或快速原型设计。 | 适用于需要较高准确性的场景,尤其是当有足够的计算资源时。 |
Adapter
插入位置:LoRA 是以残差连接的形式 “并联” 在 Transformer 的 W 矩阵上,而 Adapter 是插入在 Feed-forward Layer 后面。
推理延迟:LoRA 在训练完后其参数可以与原有预训练模型直接合并,变回单分支结构,不会引入额外的延迟;而 Adapter 由于引入了额外的串联网络层,因此会带来额外的延迟。
参数存储:使用 LoRA 进行微调,在训练完毕后只需要保存 LoRA 本身的参数;而使用 Adapter 则要保存整个原有模型的参数。
下一章讲解使用llama-factory来进行lora微调