使用LORA微调RoBERTa

模型微调是指在一个已经训练好的模型的基础上,针对特定任务或者特定数据集进行再次训练以提高性能的过程。微调可以在使其适应特定任务时产生显着的结果。

RoBERTa(Robustly optimized BERT approach)是由Facebook AI提出的一种基于Transformer架构的预训练语言模型。它是对Google提出的BERT(Bidirectional Encoder Representations from Transformers)模型的改进和优化。

“Low-Rank Adaptation”(低秩自适应)是一种用于模型微调或迁移学习的技术。一般来说我们只是使用LORA来微调大语言模型,但是其实只要是使用了Transformers块的模型,LORA都可以进行微调,本文将介绍如何利用🤗PEFT库,使用LORA提高微调过程的效率。

LORA可以大大减少了可训练参数的数量,节省了训练时间、存储和计算成本,并且可以与其他模型自适应技术(如前缀调优)一起使用,以进一步增强模型。

但是,LORA会引入额外的超参数调优层(特定于LORA的秩、alpha等)。并且在某些情况下,性能不如完全微调的模型最优,这个需要根据不同的需求来进行测试。

首先我们安装需要的包:

 !pip install transformers datasets evaluate accelerate peft

数据预处理

 import torchfrom transformers import RobertaModel, RobertaTokenizer, AutoModelForSequenceClassification, TrainingArguments, Trainer, DataCollatorWithPaddingfrom peft import LoraConfig, get_peft_modelfrom datasets import load_datasetpeft_model_name = 'roberta-base-peft'modified_base = 'roberta-base-modified'base_model = 'roberta-base'dataset = load_dataset('ag_news')tokenizer = RobertaTokenizer.from_pretrained(base_model)def preprocess(examples):tokenized = tokenizer(examples['text'], truncation=True, padding=True)return tokenizedtokenized_dataset = dataset.map(preprocess, batched=True,  remove_columns=["text"])train_dataset=tokenized_dataset['train']eval_dataset=tokenized_dataset['test'].shard(num_shards=2, index=0)test_dataset=tokenized_dataset['test'].shard(num_shards=2, index=1)# Extract the number of classess and their namesnum_labels = dataset['train'].features['label'].num_classesclass_names = dataset["train"].features["label"].namesprint(f"number of labels: {num_labels}")print(f"the labels: {class_names}")# Create an id2label mapping# We will need this for our classifier.id2label = {i: label for i, label in enumerate(class_names)}data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="pt")

训练

我们训练两个模型,一个使用LORA,另一个使用完整的微调流程。这里可以看到LORA的训练时间和训练参数的数量能减少多少

以下是使用完整微调

 training_args = TrainingArguments(output_dir='./results',evaluation_strategy='steps',learning_rate=5e-5,num_train_epochs=1,per_device_train_batch_size=16,)

然后进行训练:

 def get_trainer(model):return  Trainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=eval_dataset,data_collator=data_collator,)full_finetuning_trainer = get_trainer(AutoModelForSequenceClassification.from_pretrained(base_model, id2label=id2label),)full_finetuning_trainer.train()

下面看看PEFT的LORA

 model = AutoModelForSequenceClassification.from_pretrained(base_model, id2label=id2label)peft_config = LoraConfig(task_type="SEQ_CLS", inference_mode=False, r=8, lora_alpha=16, lora_dropout=0.1)peft_model = get_peft_model(model, peft_config)print('PEFT Model')peft_model.print_trainable_parameters()peft_lora_finetuning_trainer = get_trainer(peft_model)peft_lora_finetuning_trainer.train()peft_lora_finetuning_trainer.evaluate()

可以看到

模型参数总计:125,537,288,而LORA模型的训练参数为:888,580,我们只需要用LORA训练~0.70%的参数!这会大大减少内存的占用和训练时间。

在训练完成后,我们保存模型:

 tokenizer.save_pretrained(modified_base)peft_model.save_pretrained(peft_model_name)

最后测试我们的模型

 from peft import AutoPeftModelForSequenceClassificationfrom transformers import AutoTokenizer# LOAD the Saved PEFT modelinference_model = AutoPeftModelForSequenceClassification.from_pretrained(peft_model_name, id2label=id2label)tokenizer = AutoTokenizer.from_pretrained(modified_base)def classify(text):inputs = tokenizer(text, truncation=True, padding=True, return_tensors="pt")output = inference_model(**inputs)prediction = output.logits.argmax(dim=-1).item()print(f'\n Class: {prediction}, Label: {id2label[prediction]}, Text: {text}')# return id2label[prediction]classify( "Kederis proclaims innocence Olympic champion Kostas Kederis today left hospital ahead of his date with IOC inquisitors claiming his ...")classify( "Wall St. Bears Claw Back Into the Black (Reuters) Reuters - Short-sellers, Wall Street's dwindling\band of ultra-cynics, are seeing green again.")

模型评估

我们还需要对PEFT模型的性能与完全微调的模型的性能进行对比,看看这种方式有没有性能的损失

 from torch.utils.data import DataLoaderimport evaluatefrom tqdm import tqdmmetric = evaluate.load('accuracy')def evaluate_model(inference_model, dataset):eval_dataloader = DataLoader(dataset.rename_column("label", "labels"), batch_size=8, collate_fn=data_collator)device = torch.device("cuda" if torch.cuda.is_available() else "cpu")inference_model.to(device)inference_model.eval()for step, batch in enumerate(tqdm(eval_dataloader)):batch.to(device)with torch.no_grad():outputs = inference_model(**batch)predictions = outputs.logits.argmax(dim=-1)predictions, references = predictions, batch["labels"]metric.add_batch(predictions=predictions,references=references,)eval_metric = metric.compute()print(eval_metric)

首先是没有进行微调的模型,也就是原始模型

 evaluate_model(AutoModelForSequenceClassification.from_pretrained(base_model, id2label=id2label), test_dataset)

accuracy: 0.24868421052631579‘

下面是LORA微调模型

 evaluate_model(inference_model, test_dataset)

accuracy: 0.9278947368421052

最后是完全微调的模型:

 evaluate_model(full_finetuning_trainer.model, test_dataset)

accuracy: 0.9460526315789474

总结

我们使用PEFT对RoBERTa模型进行了微调和评估,可以看到使用LORA进行微调可以大大减少训练的参数和时间,但是在准确性方面还是要比完整的微调要稍稍下降。

本文代码:

https://avoid.overfit.cn/post/26e401b70f9840dab185a6a83aac06b0

作者:Achilles Moraites

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468345.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【王道数据结构】【chapter5树与二叉树】【P158t8】

设树B是一颗采用链式结构存储的二叉树&#xff0c;编写一个把树B种所有节点的左、右子树进行交换的函数。 #include <iostream> #include <stack> typedef struct treenode{char data;struct treenode *left;struct treenode *right; }treenode,*ptreenode;ptreeno…

docker磁盘不足!已解决~

目录 &#x1f35f;1.查看docker镜像目录 &#x1f9c2;2.停止docker服务 &#x1f953;3.创建新的目录 &#x1f32d;4.迁移目录 &#x1f37f;5.编辑迁移的目录 &#x1f95e;6.重新加载docker &#x1f354;7.检擦docker新目录 &#x1f373;8.删掉旧目录 1.查看doc…

Linux系统之部署File Browser文件管理系统

Linux系统之部署File Browser文件管理系统 一、File Browser介绍1.1 File Browser简介1.2 File Browser功能1.3 File Browser使用场景 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、安装File Browser4…

11-OpenFeign-实现负载均衡策略

2021.0.1版本使用 spring-cloud-loadbalancer 1、默认开启负载均衡策略 使用default RoundRobinLoadBalancer策略 无需yaml文件配置&#xff0c;openfeignclient配置 RandomLoadBalancer &#xff1a;基于随机访问的负载均衡策略NacosLoadBalancer&#xff1a;基于Nacos权重…

Java:什么是向上转型与向下转型(详细图解)

目录 一、什么是向上转型 1、概念 2、代码示例 3、向上转型的优缺点 二、什么是向下转型 1、向下转型的概念 ​编辑 2、代码示例 三、向下转型的缺点及 instanceof 的使用 1、向下转型的缺点 2、instanceof的使用 一、什么是向上转型 1、概念 向上转型就是创建一个…

【MySQL进阶之路】通过实操理解 explain 执行计划

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

重复导航到当前位置引起的。Vue Router 提供了一种机制,阻止重复导航到相同的路由路径。

代码&#xff1a; <!-- 侧边栏 --><el-col :span"12" :style"{ width: 200px }"><el-menu default-active"first" class"el-menu-vertical-demo" select"handleMenuSelect"><el-menu-item index"…

Python算法题集_LRU 缓存

Python算法题集_LRU 缓存 题146&#xff1a;LRU 缓存1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【队列字典】2) 改进版一【有序字典】3) 改进版二【双向链表字典】 4. 最优算法 本文为Python算法题集之一的代码示例 题146&#xff1a;LRU …

Java面试、进阶、实践一网打尽(由电子工业出版社出版)

Java面试、进阶、实践一网打尽 准备好应对Java开发的新挑战吗&#xff1f;我们为您精选了五本核心书籍&#xff0c;一站式满足您在Java面试准备、技能进阶和实战应用的需求。 这套书籍包括《Offer来了&#xff1a;Java面试核心知识点精讲&#xff08;第2版&#xff09;》、《…

电脑数据误删如何恢复?9 个Windows 数据恢复方案

无论您是由于软件或硬件故障、网络犯罪还是意外删除而丢失数据&#xff0c;数据丢失都会带来压力和令人不快。 如今的企业通常将其重要数据存储在云或硬盘上。但在执行其中任何一项操作之前&#xff0c;您很有可能会丢失数据。 数据丢失的主要原因是意外删除&#xff0c;任何…

python算法之 Dijkstra 算法

文章目录 基本思想&#xff1a;步骤&#xff1a;复杂度&#xff1a;注意事项&#xff1a;代码实现K 站中转内最便宜的航班 Dijkstra 算法是一种用于解决单源最短路径问题的经典算法。该问题的目标是找到从图中的一个固定顶点&#xff08;称为源点&#xff09;到图中所有其他顶点…

“从根到叶:深入理解堆数据结构“

一.堆的概念及实现 1.1堆的概念 在数据结构中&#xff0c;堆是一种特殊的树形数据结构。堆可以分为最大堆和最小堆两种类型。 最大堆&#xff1a;对于堆中的任意节点&#xff0c;其父节点的值都不小于它的值。换句话说&#xff0c;最大堆中的根节点是堆中的最大值。并且&…