在Linux系统下微调Llama2(MetaAI)大模型教程—Qlora

Llama2是Meta最新开源的语言大模型,训练数据集2万亿token,上下文长度是由Llama的2048扩展到4096,可以理解和生成更长的文本,包括7B、13B和70B三个模型,在各种基准集的测试上表现突出,最重要的是,该模型可用于研究和商业用途。

一、准备工作

1、本文选择微调的基础模型Llama2-chat-13B-Chinese-50W( 如何部署Llama2大模型,可以转到在Linux系统下部署Llama2(MetaAI)大模型教程-CSDN博客)

2、由于大部分笔记本电脑无法满足大模型Llama2的微调条件,因此可以选用autodl平台(算力云)作为部署平台。注:显存选择40GB以上的,否则微调过程会报错。

二、创建新实例(需要对数据盘进行扩容20GB)

基础的数据盘内存无法满足微调要求,因此需要对数据盘进行扩容。点击已经部署好Llama2大模型实例的“更多”中的“克隆实例”

勾选“数据盘”

选择可扩容的主机。

选择“需要扩容”,填写“20”GB。

填写完成后,点击“立即创建”。创建完成后,不要着急,等待一会儿。状态栏的“运行中”下面会出现“正在拷贝数据集”字样,等待数据集拷贝完成

“正在拷贝数据集”字样消失后,说明拷贝完成,点击JupyterLab。

三、下载、预处理微调数据集

cd到数据盘autodl-tep,并设置学术加速,然后运行以下代码下载数据集

如果你有自己的数据集,那么可以选择使用自己的数据集。

wget https://huggingface.co/datasets/BelleGroup/train_0.5M_CN/resolve/main/Belle_open_source_0.5M.json

原始数据集共有50万条数据,格式:{"instruction":"xxxx", "input":"", "output":"xxxx"}

数据集下载完毕之后,需要对数据集进行预处理新建一个文件:split_json.py. 右击,点击“新建文件”,然后将文件名改为split_json.py即可。

接下来,将以下代码复制粘贴至文件split_json.py中。这段程序的作用是对数据集进行拼接,只使用introduction和output,并仅选择1000条数据作为演示。但在正常生产环境中,我们就需要更大的数据量。

import random,jsondef write_txt(file_path,datas):with open(file_path,"w",encoding="utf8") as f:for d in datas:f.write(json.dumps(d,ensure_ascii=False)+"\n")f.close()with open("/root/autodl-tmp/Belle_open_source_0.5M.json","r",encoding="utf8") as f:lines=f.readlines()changed_data=[]for l in lines:l=json.loads(l)changed_data.append({"text":"### Human: "+l["instruction"]+" ### Assistant: "+l["output"]})r_changed_data=random.sample(changed_data, 1000)write_txt("/root/autodl-tmp/Belle_open_source_0.5M_changed_test.json",r_changed_data)

运行以下代码对split_json.py进行执行

python split_json.py

生成了一个新的json文件Belle_open_source_0.5M_changed_test.json,说明运行成功。

拼接好的数据格式:{"text":"### Human: xxxx ### Assistant: xxx"}

四、运行微调文件

1、返回启动页,新建一个notebook。

2、安装相关包

输入之后,按Shift+Enter运行。

!pip install -q huggingface_hub
!pip install -q -U trl transformers accelerate peft
!pip install -q -U datasets bitsandbytes einops wandb

左上角由 [*] 变为 [1] 后,说明安装成功。

3、设置学术加速

4、登录huggingface的notebook

这里需要到:https://huggingface.co/settings/tokens 中复制tokentoken获取方式可以参考:如何获取HuggingFace的Access Token;如何获取HuggingFace的API Key-CSDN博客

然后执行下列语句:

from huggingface_hub import notebook_login
notebook_login()

将token复制进去:

5、初始化wandb

首先需要先到:https://wandb.me/wandb-server 注册wandb。进入网址后,点击右上角进行登录注册。

注册完毕后在https://wandb.ai/authorize中复制Key

运行代码:

import wandb
wandb.init()

复制的Key粘贴进去,然后再Enter。如果左侧出现文件夹wandb说明运行成功。

6、导入相关包

from datasets import load_dataset
import torch,einops
from transformers import AutoModelForCausalLM, BitsAndBytesConfig, AutoTokenizer, TrainingArguments
from peft import LoraConfig
from trl import SFTTrainer

7、加载上面拼接好之后的1000条数据

dataset = load_dataset("json",data_files="/root/autodl-tmp/Belle_open_source_0.5M_changed_test.json",split="train")

8、配置本地模型

base_model_name ="/root/autodl-tmp/Llama2-chat-13B-Chinese-50W"
bnb_config = BitsAndBytesConfig(load_in_4bit=True,#在4bit上,进行量化bnb_4bit_use_double_quant=True,# 嵌套量化,每个参数可以多节省0.4位bnb_4bit_quant_type="nf4",#NF4(normalized float)或纯FP4量化 博客说推荐NF4bnb_4bit_compute_dtype=torch.float16,
)

9、配置GPU

device_map = {"": 0}
#有多个gpu时,为:device_map = {"": [0,1,2,3……]}

10、加载本地模型

base_model = AutoModelForCausalLM.from_pretrained(base_model_name,#本地模型名称quantization_config=bnb_config,#上面本地模型的配置device_map=device_map,#使用GPU的编号trust_remote_code=True,use_auth_token=True
)
base_model.config.use_cache = False
base_model.config.pretraining_tp = 1

11、配置QLora

peft_config = LoraConfig(lora_alpha=16,lora_dropout=0.1,r=64,bias="none",task_type="CAUSAL_LM",
)

12、对本地模型,把长文本拆成最小的单元词(即token)

tokenizer = AutoTokenizer.from_pretrained(base_model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token

13、训练参数的配置

output_dir = "./results"
training_args = TrainingArguments(report_to="wandb",output_dir=output_dir,#训练后输出目录per_device_train_batch_size=4,#每个GPU的批处理数据量gradient_accumulation_steps=4,#在执行反向传播/更新过程之前,要累积其梯度的更新步骤数learning_rate=2e-4,#超参、初始学习率。太大模型不稳定,太小则模型不能收敛logging_steps=10,#两个日志记录之间的更新步骤数max_steps=100#要执行的训练步骤总数
)
max_seq_length = 512
#TrainingArguments 的参数详解:https://blog.csdn.net/qq_33293040/article/details/117376382trainer = SFTTrainer(model=base_model,train_dataset=dataset,peft_config=peft_config,dataset_text_field="text",max_seq_length=max_seq_length,tokenizer=tokenizer,args=training_args,
)

14、开始进行微调训练

trainer.train()

可以看到,随着训练的进行,损失函数在下降:

15、把训练好的模型保存下来

import os
output_dir = os.path.join(output_dir, "final_checkpoint")
trainer.model.save_pretrained(output_dir)

五、执行代码合并

把训练好的模型与原始模型进行合并。

1、新建一个merge_model.py的文件,把下面的代码粘贴进去:

from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch#设置原来本地模型的地址
model_name_or_path = '/root/autodl-tmp/Llama2-chat-13B-Chinese-50W'
#设置微调后模型的地址,就是上面的那个地址
adapter_name_or_path = '/root/autodl-tmp/results/final_checkpoint'
#设置合并后模型的导出地址
save_path = '/root/autodl-tmp/new_model'tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,trust_remote_code=True
)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path,trust_remote_code=True,low_cpu_mem_usage=True,torch_dtype=torch.float16,device_map='auto'
)
print("load model success")
model = PeftModel.from_pretrained(model, adapter_name_or_path)
print("load adapter success")
model = model.merge_and_unload()
print("merge success")tokenizer.save_pretrained(save_path)
model.save_pretrained(save_path)
print("save done.")

2、新建终端,然后执行上述合并代码,进行合并

python merge_model.py

运行结果:

六、使用gradio运行模型

进入Llama2文件夹:cd Llama2

python gradio_demo.py --base_model /root/autodl-tmp/new_model --tokenizer_path /root/autodl-tmp/new_model --gpus 0

七、可能遇到的问题

1、执行代码notebook_login()时报错

报错显示:

(MaxRetryError("HTTPSConnectionPool(host='huggingface.co', port=443): Max retries exceeded with url: /api/whoami-v2 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7fdf07ee4940>: Failed to establish a new connection: [Errno 110] Connection timed out'))"), '(Request ID: 3557b723-1341-4c75-b72a-f8ecf6c6a070)')

解决办法:

这是一个Python的错误信息,表明在使用Hugging Face的连接池时出现了最大重试误。根该错误信息,我们可以推测可能的原因是连接到huggingface.co的连接池达到了最大重试次数,但仍无法建立连接。这可能是由于网络连接问题、服务器不可用或其他问题导致的。

2、执行代码trainer.train()时报错

报错显示:

OutOfMemoryError: CUDA out of memory. Tried to allocate 270.00 MiB (GPU 0; 31.74 GiB total capacity; 29.60 GiB already allocated; 36.88 MiB free; 30.72 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

解决办法一:

将训练参数的配置中的 per_device_train_batch_size 参数设置为2,再执行代码trainer.train(),即可解决。

解决办法二:

报错的主要原因为显存不足,可以更换显存更大的主机。

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

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

相关文章

Centos批量删除系统重复进程

原创作者&#xff1a;运维工程师 谢晋 Centos批量删除系统重复进程 客户一台CENTOS 7系统负载高&#xff0c;top查看有很多sh的进程&#xff0c;输入命令top -c查看可以看到对应的进程命令是/bin/bash     经分析后发现是因为该脚本执行时间太长&#xff0c;导致后续执…

如何进行iOS技术博客的备案?

如何进行iOS技术博客的备案&#xff1f; 标题&#xff1a;iOS技术博客备案流程及要求解析 摘要&#xff1a; 在本篇问答中&#xff0c;我们将为iOS技术博主介绍如何进行备案。如果你的iOS应用只包含简单的页面&#xff0c;并通过蓝牙进行数据采集和传输&#xff0c;那么你可能…

线程有哪些状态

线程的生命周期 线程在Java中有以下几种状态&#xff1a; 新建&#xff08;New&#xff09;&#xff1a;初始化状态就绪&#xff08;Runnable&#xff09;&#xff1a;可运行、运行状态阻塞&#xff08;Blocked&#xff09;&#xff1a;等待状态&#xff0c;无时限等待&#…

Spring核心

Spring Framework Spring的两个核心IOC控制反转IOC容器依赖注入DIIOC容器实现注解管理BeanBean对象定义Bean对象获取 AOP面向切面编程 添加依赖入门案例注解通过Spring创建Java bean对象 xml管理Bean案例main下创建bean.XMl文件 DI依赖注入案例创建Spring配置文件 bean-di.xml …

H5游戏源码分享-网页版2048小游戏

H5游戏源码分享-网页版2048小游戏 玩过的都懂 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>分享2048到朋友圈&#xff0c;将免费参加南山郡8.17号啤酒狂欢节&#xff01;</title><link href"style/main…

Day29力扣打卡

打卡记录 美丽塔 II&#xff08;前后缀分解 单调栈&#xff09; 链接 大佬的题解 class Solution:def maximumSumOfHeights(self, a: List[int]) -> int:n len(a)suf [0] * (n 1)st [n] # 哨兵s 0for i in range(n - 1, -1, -1):x a[i]while len(st) > 1 and …

简单理解 Sentinel 滑动窗口实现原理

theme: serene-rose 1. 引言 Hi&#xff0c;你好&#xff0c;我是有清 对于刚经历过双 11 的电商人来说&#xff0c;限流这个词肯定在 10.24 的晚 20.00 点被提起过 限流作为保护我们系统不被流量冲垮的手段之一&#xff0c;建议每个电商人深入了解学习&#xff0c;什么&#x…

应急响应练习1

目录 1. 提交攻击者的IP地址 2. 识别攻击者使用的操作系统 3. 找出攻击者资产收集所使用的平台 4. 提交攻击者目录扫描所使用的工具名称 5. 提交攻击者首次攻击成功的时间&#xff0c;格式&#xff1a;DD /MM/YY:HH:MM:SS 6. 找到攻击者写入的恶意后门文件&#xff0c;提…

黑群晖断电导致存储空间已损毁修复记录

黑群晖断电2次,担心的事情还是发生了,登录后提示存储空间已损毁...... 开干!! 修复方式: 1.使用SSH登录到群晖,查看相关信息 # 登录后先获取最高权限 root@DiskStation:~# sudo -i # 检测存储池状态 root@DiskStation:~# cat /proc/mdstat Personalities : [linear] […

Java 算法篇-深入了解单链表的反转(实现:用 5 种方式来具体实现)

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 单链表的反转说明 2.0 单链表的创建 3.0 实现单链表反转的五种方法 3.1 实现单链表反转 - 循环复制&#xff08;迭代法&#xff09; 3.2 实现单链表反转 - 头插法 3…

卷积神经网络(1)

目录 卷积 1 自定义二维卷积算子 2 自定义带步长和零填充的二维卷积算子 3 实现图像边缘检测 4 自定义卷积层算子和汇聚层算子 4.1 卷积算子 4.2 汇聚层算子 5 学习torch.nn.Conv2d()、torch.nn.MaxPool2d()&#xff1b;torch.nn.avg_pool2d()&#xff0c;简要介绍使用方…

数据结构-堆和二叉树

目录 1.树的概念及结构 1.1 树的相关概念 1.2 树的概念 1.3 树的表示 1.4 树在实际中的应用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及结构 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的存储 3.堆的概念及结构 4.堆的实现 初始化堆 堆的插入…