介绍

Lora,是微软出的一种在低资源场景下进行微调大模型的实现方式,在transformers里有peft这个包进行调用,它通过固定预训练模型权重并只训练新增lora层来实现微调,目前其在比如Baichuan2、ChatGLM上都有相关资料,更多介绍可自行搜索了解。

简单理解

其简单理解实现方式为,比如qkv的linear为768*768(更大模型可能会更大),那lora通过新增两个linear(lora_A和lora_B),引入一个超参r来降低训练参数量,其伪代码如下:

1
2
3
4
5
6
7
8
9
10
11

in_feature, out_feature = 768, 768

# old
self.q = nn.Linear(in_feature, out_feature)

# Lora

self.lora_A = nn.Linear(in_feature, r)
self.lora_B = nn.Linear(r, out_feature)

比如当r设置为1时,是否可以明显感受到训练参数量的变化。

注意:Lora本质只有在微调阶段生效,其加速了微调,但是对于推理阶段不会加速,而且因引入了新的计算会导致推理速度略有下降。

paddle实现

注意,此篇文章通过介绍LoraLinear的实现,来说明Lora的工作原理。

其实现在这里

注意点1

LoraLinear继承自nn.Linear,所以是在Linear的基础上进行改动。

注意点2

Linear的weight不进行训练,这也符合Lora的原理说明。

1
self.weight.stop_gradient=True

注意点3

forward部分,代码如下:

1
2
3
4
5
6
def forward(self, input: paddle.Tensor):
result = F.linear(x=input, weight=self.weight, bias=self.bias, name=self.name)
if not self.merged:
result += (self.lora_dropout(input) @ self.lora_A @ self.lora_B) * self.scaling
return result

我们看如果pretrained model和lora不进行merge的时候,其推理是pretrained model先计算,拿到result,然后和lora计算结果进行相加获取最终结果。

总结

对于Parameter Efficient fine-tune,Lora是其中一个实现方式,其他还有比如p-tuning等。但是通过Lora,我们大致理解了从原来直接对pretrained model fine-tune到现在的引入新的参数(比如)来使得我们能用低资源来使用LLM的能力。