文章目录
- 1. 模型微调的两种方式
- 2. LoRA 实现
LoRA是一种轻量化且效果非常突出的大模型微调方法,与使用Adam微调的GPT-3 175B相比,LoRA可以将可训练参数的数量减少10000倍,并将GPU内存需求减少3倍。
paper:LoRA: Low-Rank Adaptation of Large Language Models 《大语言模型的低秩自适应微调》
code:https://github.com/microsoft/LoRA
1. 模型微调的两种方式
模型微调的本质就是改变模型参数,假设原始模型的参数是 W 0 W_0 W0,微调后的参数是 W 1 W_1 W1,二者之间必然存在一个关系: W 0 + △ W = W 1 W_0+\triangle W=W_1 W0+△W=W1,所以模型微调就会有两种方式:
- 全量微调:直接从 W 0 W_0 W0 微调到 W 1 W_1 W1,但对于大模型来说,全量微调很困难,费时费力费钱。
- 高效微调 (Parameter Efficient Fine Tuning,PEFT):直接训练一个包含有效信息的参数矩阵 △ W \triangle W △W,可以通过各种方式使得 △ W \triangle W △W 得参数量远小于 W 0 W_0 W0,从而降低微调开销。
2. LoRA 实现
LoRA 是一种高效微调方法,它只需要训练低秩矩阵即可,而不需要直接微调 W 0 W_0 W0
LoRA 微调预训练大模型的示意图:
任何一个矩阵都可以写成两个矩阵相乘的形式,因此 △ W = B ∗ A \triangle W=B*A △W=B∗A
定义 W 0 ∈ R d ∗ k W_0 \in R^{d*k} W0∈Rd∗k, △ W ∈ R d ∗ k \triangle W \in R^{d*k} △W∈Rd∗k, B ∈ R d ∗ r B \in R^{d*r} B∈Rd∗r, A ∈ R r ∗ k A \in R^{r*k} A∈Rr∗k,其中 r ≪ m i n ( d , k ) r \ll min(d,k) r≪min(d,k),所以相比于 W 0 W_0 W0 和 △ W \triangle W △W,矩阵 A A A 和 B B B 是低秩的,这就是 LoRA 名字的由来。
LoRA 的思路很简单:
- 微调时不改变预训练模型的参数 W 0 W_0 W0,只是给预训练模型加一个支路(类似于ResNet),先降维再升维。
- 用随机高斯分布初始化降维矩阵 A A A ,用 0 矩阵初始化升维矩阵 B B B,保证训练的开始支路矩阵是 0 矩阵。
- 训练的时候固定模型参数 W 0 W_0 W0,只训练矩阵 A A A 和 B B B,得到 △ W = B ∗ A \triangle W=B*A △W=B∗A,微调后模型的参数为 W 1 = W 0 + △ W W_1=W_0+\triangle W W1=W0+△W
对于模型输入 x x x,微调后的输出 h h h 为 h = W 0 x + △ W x = W 0 x + B A x h=W_0 x+\triangle W x=W_0 x+BA x h=W0x+△Wx=W0x+BAx
LoRA 与 Transformer 的结合也很简单,仅在 QKV Attention 的计算中增加一个旁路。
实验结果显示,对于一般的任务, r = 1 , 2 , 4 , 8 r=1,2,4,8 r=1,2,4,8 就足够了(Low-Rank)。而一些领域差距比较大的任务可能需要更大的 r r r。同时,增加 r r r 值变大并不能提升微调的效果,这可能是因为参数量增加需要更多的语料。
考虑 OpenAI 对 GPT 模型的认知,GPT 的本质是对训练数据的有效压缩,从而发现数据内部的逻辑与联系,LoRA 的思想与之有相通之处,原模型虽大,但起核心作用的参数是低秩的,通过增加旁路,达到四两拨千斤的效果。
参考资料:
- 博客:LORA:大模型轻量级微调
- 视频:通俗易懂理解全量微调和LoRA微调