基于imdb的LoRA微调分类模型 Xlnet[简单例子,小白可上手]

什么是LORA微调?

LoRA 全称为 low-rank adaptation, 低秩自适应微调方法。

paper:LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
大概思路:借鉴知乎 https://www.zhihu.com/tardis/zm/art/623543497?source_id=1005 的这个图说明一下:

  • LoRA微调什么? 预训练模型是 左边, Lora微调得到的模型是 右边。
    LoRA相当于训练一个新的额外的参数,来学习原参数的知识。
  • LoRA优点:相比于全量微调(full finetune)方法的优点是 LoRA通常只需要更新不到1%的参数就能达到与全量微调相当的效果。
    full finetune:更新所有的预训练网络参数。
    在这里插入图片描述
    例如在下面的例子中,peftmodel 显示lora微调训练的参数量是原来的0.62倍,十分小。
model.print_trainable_parameters()

在这里插入图片描述

为什么我会接触LoRA?

最近在2张40G的GPU上,想要实现基于imdb数据集微调Xlnet-large模型,发现直接load pre-trained model 全量微调压根跑不起来,内存直接爆炸。

  • 内存/存储空间不够

因此,想通过一些高效低参的微调的方法来实现,如LoRA, bitfit(只微调网络中的bias 参数,比lora效果差得多)。

接下来直接上代码介绍怎么基于LoRA微调xlnet-base-cased吧。很简单的过程,但是你要能连接Huggingface,不能连接的话就把数据和模型下到本地吧。

依赖库提供方手册
transformerHuggingfacehttps://huggingface.co/docs/transformers/pipeline_tutorial
datasetsHuggingfacehttps://huggingface.co/docs/datasets/load_hub
evaluateHuggingfacehttps://huggingface.co/docs/evaluate/transformers_integrations
peftHuggingfacehttps://huggingface.co/docs/peft/quicktour

建议在conda 虚拟环境里跑哈 使用的环境如下:

Framework versions
PEFT 0.9.0
Transformers 4.38.2
Pytorch 2.2.1
Datasets 2.18.0
Tokenizers 0.15.2
python 3.10

1. 安装库

执行以下代码安装相关的库函数,需要翻墙,能够连接上Huggingface :

pip install transformers datasets evaluate peft

2.开始LoRA微调

下载xlnet-base-cased模型-- 用peft封装模型- - 训练参数 — 训练模型 – 上传模型到hub

Train with LoRA
def train_lora():
	# 如果需要将模型推送到hub上的话,需要登录一下hub
    login(token='hf_XXX')  ##hf_XXX 替换成你自己的hub账号的token
    peft_config = LoraConfig(task_type=TaskType.SEQ_CLS,
                             target_modules=['layer_1','layer_2'],
                              inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)
   #下载xlnet-base-cased模型
    model_base = 'xlnet-base-cased'
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

    model  = AutoModelForSequenceClassification.from_pretrained(model_base, num_labels=2)
    print(model)
	#用peft封装模型
    model = get_peft_model(model,peft_config)
    model.print_trainable_parameters()
    model = model.to(device)
  
    tokenizer = AutoTokenizer.from_pretrained(model_base,max_length=350)
    def preocess_tokenize(exam):
        return tokenizer(exam['text'],truncation=True,padding=True)
    #下载数据集
    imdb = load_dataset('imdb')
    tokenized_imdb = imdb.map(preocess_tokenize,batched=True)
    #设置评估指标
    accuracy = evaluate.load("accuracy")
    def compute_metrics(eval_pred):
        predictions, labels = eval_pred
        predictions = np.argmax(predictions, axis=1)
        return accuracy.compute(predictions=predictions, references=labels)
   #设置训练参数
    bts = 1
    accumulated_step = 2
    training_args = TrainingArguments(
        output_dir=f"imdb_{model_base.replace('-','_')}",
        learning_rate=2e-5,
        per_device_train_batch_size=bts,
        per_device_eval_batch_size=bts,
        num_train_epochs=1,
        weight_decay=0.01,
        evaluation_strategy="epoch",
        save_strategy="epoch",
        load_best_model_at_end=True,
        push_to_hub=True,
        gradient_accumulation_steps=accumulated_step,
    )
   #配置训练器
    trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_imdb["train"],
    eval_dataset=tokenized_imdb["test"],
    tokenizer=tokenizer,
    compute_metrics=compute_metrics,
    )
    #训练并上传
    print(f'Start to Train {model_base}')
    trainer.train()
    print('Success!')
    trainer.push_to_hub()
    print('Success to push the model to huggingface')
if __name__ =='__main__':
    train_lora()
inference

以下是我训练号一个peftmodel = Siki-77/imdb_xlnet_base_cased,使用它去判断其他样本的过程如下

from peft import PeftModel, PeftConfig
from transformers import AutoModelForSequenceClassification

config = PeftConfig.from_pretrained("Siki-77/imdb_xlnet_base_cased")
model = AutoModelForSequenceClassification.from_pretrained("xlnet-base-cased")
model = PeftModel.from_pretrained(model, "Siki-77/imdb_xlnet_base_cased")
tokenizer = AutoTokenizer.from_pretrained(model_base,max_length=350)
inputs = tokenizer("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt")

with torch.no_grad():
    logits = model(**inputs).logits
label = logits.argmax().item()  # 这里是2分类,因此 label=0 或1 

以上例子结束,代码完全跑的通,很简单的代码流程。

说明下target_modules这个参数(可选)

这一小节回答以下问题:

  • 任意的模型进行LoRA微调的话,需要怎么设置target modules 这个参数呢??
  • 省流回答:target module 只能选择以下几类层的名称
    -torch.nn.Linear, torch.nn.Embedding, torch.nn.Conv2d, transformers.pytorch_utils.Conv1D

本节主要补充一下 peft_config两个关键参数说明:

  peft_config = LoraConfig(
      task_type=TaskType.SEQ_CLS,
      target_modules=['layer_1','layer_2'],
      inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1)
  • task_type表示要微调的模型类型,TaskType.SEQ_CLS表示文本分类模型,
  • target_modules 表示用更少参数代替的层(只允许 linear
  • 其他参数默认

在这里插入图片描述
如,我用的pre-trained model = xlnet-base-cased,它的模型结构如上图所示,一般lora压缩的是堆叠好几层的模块的 linear/conv层,这里只有名为“layer-1”“layer-2”的线性层,因此

target_modules=['layer_1','layer_2'],

如果我设置了unsupport layer的名称为 target modules,将会报错,如下

peft_config = LoraConfig(
               r=16,
               lora_alpha=32,
               lora_dropout=0.05,
               target_modules=["layer_norm"],## "layer_norm" is non-linear layer
               task_type=TaskType.SEQ_CLS, # this is necessary
               )

报错信息如下

Currently, only the following modules are supported: torch.nn.Linear, torch.nn.Embedding, torch.nn.Conv2d, transformers.pytorch_utils.Conv1D

谈一下LoRA的当下的应用

随着GPT-3.5以来,越来越多大模型发布,甚至开源。如果要在本地微调这些大模型的话,基本全量微调是希望渺茫的(除非你的GPU内存真的超足),这种情况下,LoRA简直是天选之子,微调的首选方式。
真的十分有效,当然LoRA也不一定能解决存储不足的问题。
还有一个流行的“微调” promt,不微调参数,而是直接引导模型为我所用,很玄也很难定义怎么prompt才能“为我所用”。
相比于prompt微调,个人感觉LoRA还是可控性比较高的微调。

LoRA(Large-scale Reinforcement Learning from Image Pixels with Latent Actions)是一种用于微调大型模型的方法,它结合了强化学习和图像像素级别的训练。LoRA的目标是通过观察环境中的图像像素,并根据这些像素采取相应的行动来学习一个能够解决复杂任务的模型。 具体来说,LoRA使用了一个基于像素的强化学习框架,其中模型通过观察环境中的图像像素来学习如何采取最佳行动。这种方法的一个关键特点是,模型不需要任何先验知识或工设计的特征,而是直接从原始像素数据中学习。 LoRA的训练过程包括两个阶段:预训练和微调。在预训练阶段,使用自编码器来学习图像的表示。自编码器是一种无监督学习方法,它通过将输入图像压缩成低维编码,然后再将编码解压缩为重构图像。通过这种方式,自编码器可以学习到图像的有用特征。 在微调阶段,使用强化学习算法(如Proximal Policy Optimization)来优化模型的策略。模型通过观察环境中的图像像素,并根据当前的状态选择最佳的行动。通过与环境进行交互并根据奖励信号进行反馈,模型逐渐优化其策略,以实现更好的性能。 LoRA的优势在于它能够处理高维度的原始输入数据,并且不需要工设计的特征。通过使用像素级别的训练,LoRA可以学习到更丰富和复杂的特征表示,从而提高模型的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值