以微调deepseek为例,基于transformers改写实现lora+

本文介绍了一种改进版的LoRA算法,即LoRA+,通过为模型的A和B部分设置不同的学习率来优化特征学习。实验表明,LoRA+在保持与LoRA相同计算成本的同时提高了模型性能。作者提供了代码实现,展示了如何在HuggingfaceTransformers框架下的Trainer类中调整学习率以应用LoRA+。
摘要由CSDN通过智能技术生成

LoRA+: Efficient Low Rank Adaptation of Large Models

24年2月12的论文,主要思想就是对LoRA进行了一些改进,提升了模型效果。

摘要

证明了对Lora的A和B使用相同的学习率无法有效的特征学习。还证明了通过以一个良好选择的固定比率设置不同的学习速率来修正,可以提升模型效果。这种算法为LoRA+。在实验中,LoRA+提高了性能(1%的−2%的提高)和微调速度,计算成本与LoRA相同。

代码实现

完整代码均放在了git代码仓库:https://github.com/mst272/simple-lora-plus

原理了解完开始从代码部分构建一下lora+。本次我们以使用deepseek-coder进行微调为例,在原始版本中加入lora以及lora+模块。

deepseek-coder微调代码部分取自官方的实现,相关说明大家可以自行去查找。改动主要是首先实现了lora微调,基于此进行了lora+的进一步改造。

正常的lora中A和B的学习率是一样的,简单来说Lora+原理即为对 lora中的A和B设置不同的学习率,且论文中给出了一些设置推荐。

现阶段训练代码大多都是用huggingface的transformers框架,基于此修改学习率,需要对trainer中进行一些魔改。

Trainer类概览

进入huggingface 的trainer类代码,真的是很复杂,不过我们这次的话只需要了解一下其create_optimizer方法即可。如下所示:
在这里插入图片描述

我们要做的就是写一个继承Trainer的新的Trainer类,重写create_optimizer方法,调整学习率就ok了。

查看其函数走向流程,前面的就是一些判定等,直接复制即可。optimizer_grouped_parameters就到了参数的相关设定,他这个源代码在这里没有设置学习率是因为都是统一的学习率,所以其直接在get_optimizer_cls_and_kwargs函数中设置了。

我们改写的话就直接在这里筛选出你要设置不同学习率的层即可,通过get_peft_model获取lora后的模型参数一般都是带有lora_a,lora_b部分的,我们即可通过model.parameters进行筛选层,分别设置不同学习率。(关于如何通过model.named_parameters()浏览模型层,改写等操作后续计划写一篇记录一下)。这一部分的改写在git中的lora_olus.py文件中的create_lorap_optimizer函数,详细的如何改写感兴趣的可以去看一下。

其他的重点就是如下两行,通过get_optimizer_cls_and_kwargs函数获取optimizer,大家对照Trainer源码点进去看一下这两行怎么实现的,基本就对如何改有数了。

optimizer_cls, optimizer_kwargs = Trainer.get_optimizer_cls_and_kwargs(self.args)

self.optimizer = optimizer_cls(optimizer_grouped_parameters, **optimizer_kwargs)

Trainer的继承与改写

最终我们创建一个新的Trainer类,改写其create_optimizer方法,然后在模型的脚本中调用即可。改写代码如下:

class LoraPlusTrainer(Trainer):
    def create_optimizer(self):
        opt_model = self.model_wrapped if is_sagemaker_mp_enabled() else self.model
        if self.optimizer is None:
            optimizer_cls, optimizer_kwargs = Trainer.get_optimizer_cls_and_kwargs(
                self.args
            )

            lora_lr_ratio = LORA_LR_RATIO
            lora_lr_embedding = LORA_LR_EMBEDDING

            self.optimizer = create_lorap_optimizer(opt_model, lora_lr_ratio, optimizer_cls, optimizer_kwargs,
                                                    lora_lr_embedding)
        if is_sagemaker_mp_enabled():
            self.optimizer = smp.DistributedOptimizer(self.optimizer)

        return self.optimizer

使用

使用也非常简单,覆盖即可,基本都不用动。另外要注意的是如果使用deepspeed进行训练,因为官方即使用deepspeed进行训练,zero3策略中的优化器及学习率等设置要进行删除。

#原始
# trainer = Trainer(model=model, tokenizer=tokenizer, args=training_args, **data_module)
# 加入lora+ Trainer
trainer = LoraPlusTrainer(model=model, tokenizer=tokenizer, args=training_args, **data_module)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值