低参数微调原理
LORA:LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
原理:INTRINSIC DIMENSIONALITY EXPLAINS THE EFFECTIVENESS OF LANGUAGE MODEL FINE-TUNING
前人的肩膀:Adapter: Parameter-Efficient Transfer Learning for NLP
我们之前在解密Prompt系列3. 冻结LM微调Prompt介绍过一些soft-prompt,包括P-Tunning和Prompt-Tunning也属于低参数微调。这些方案是通过参数拼接的方案引入额外参数。这里介绍另一类方案,同样是冻结LLM的参数,通过参数相加的方案引入额外参数, 相较soft-prompt最明显的优势,就是不会占用输入token的长度。
LoRA的原理比较简单,原始全量微调其实就是在原始模型参数上通过微调加入增量W=W0+ΔW,那我们可以通过冻结原始参数W00,并且把增量部分通过低秩分解方式进一步降低参数量级ΔW=A∗BTΔ,原始参数的维度是d∗d, 则低秩分解后的参数量级是2∗r∗d2∗,因为这里的r<<d,因此可以起到大幅降低微调参数量级的效果,如下图
核心代码如下
## 初始化低秩矩阵A和B self.lora_A.update(nn.ModuleDict({adapter_name: nn.Linear(self.in_features, r, bias=False)})) self.lora_B.update(nn.ModuleDict({adapter_name: nn.Linear(r, self.out_features, bias=False)})) self.scaling[adapter_name] = lora_alpha / r ## 向前计算 result = F.linear(x, transpose(self.weight, self.fan_in_fan_out), bias=self.bias) result += ( self.lora_B[self.active_adapter]( self.lora_A[self.active_adapter](self.lora_dropout[self.active_adapter](x)) ) * self.scaling[self.active_adapter] )
论文测试了在多数场景下适当的LORA微调和全量微调的效果不相上下。一个可能原因是INTRINSIC DIMENSIONALITY论文中提出,虽然语言模型整体参数空间很大,但具体到每个任务其实有各自的隐表征空间(intrisic dimension),这个隐表征空间的维度并不高, 因此在微调过程中加入低秩分解并不一定会影响微调效果。使用LORA微调有以下几个细节
-
对哪些参数进行微调:基于Transformer结构,LORA只对每层的Self-Attention的部分进行微调,有Wq,Wk,Wv,WO四个映射层参数可以进行微调。消融实验显示只微调Wq效果略差,微调Wq,Wv的效果和微调Wq,Wk,Wv,WO的效果相似。需要注意不同模型参数名称不同,像chatglm对应的参数名称就是query_key_value
-
Rank的选取:Rank的取值作者对比了1-64,效果上Rank在4-8之间最好,再高并没有效果提升。不过论文的实验是面向下游单一监督任务的,因此在指令微调上根据指令分布的广度,Rank选择还是需要在8以上的取值进行测试。
-
alpha参数:alpha其实是个缩放参数,本质和learning rate相同,所以为了简化我默认让alpha=rank,只调整lr,这样可以简化超参
-
初始化:A和Linear层的权重相同Uniform初始化,B是zero初始化,这样最初的Lora权重为0。所以Lora参数是从头学起,并没有那么容易收敛。
Lora的优点很明显,低参数,适合小样本场景;可以拔插式的使用,快速针对不同下游任务训练不同的lora权重;完全没有推理延时,这个在后面代码中会提到推理时,可以预先把lora权重merge到原始权重上。
但Lora微调虽好,个人在尝试中感受到的局限性就是adapter类的微调方案可能更适合下游单一任务类型/生成风格。至于是否适合作为通用指令微调的解决方案,有个问题我也没有搞懂,就是通用的指令样本是否真的有统一的低秩空间表征?这个表征又是什么含义?因为指令微调阶段的样本其实是混合的多任务指令样本,这种情况下lora是否合适,感觉需要更全面的评估(当前出来的众多LLama们都缺少合理统一全面可比的Evaluation),当前就我们的尝试情况lora的效果并不及预期。
环境配置
我用了featurize和揽睿星舟。云服务厂商的选择主要看是否有jupyter,存储够大,下载快,能连git,有高配torch环境。这两家在众多小厂里脱颖而出,4090的卡一个小时也就3块钱,来来来盆友辛苦把推广费结一下~
强调下环境配置,想跑通微调,搞定环境你就成功了80%!运气好1分钟,运气差1天都在原地打转
-
实例环境:TRX4090 + py38 + torch2.0 + CUDA12
-
python环境: