[大模型]Phi-3-mini-4k-Instruct Lora 微调

本节我们简要介绍如何基于 transformers、peft 等框架,对 Phi-3-mini-4k-Instruct 模型进行 Lora 微调。Lora 是一种高效微调方法,深入了解其原理可参见博客:知乎|深入浅出 Lora。

这个教程会在同目录下给大家提供一个 nodebook 文件,来让大家更好的学习。

环境准备

在 Autodl 平台中租赁一个 3090 等 24G 显存的显卡机器,如下图所示镜像选择 PyTorch-->2.1.0-->3.10(ubuntu22.04)-->12.1
接下来打开刚刚租用服务器的 JupyterLab,并且打开其中的终端开始环境配置、模型下载和运行演示。

在这里插入图片描述

环境配置

在完成基本环境配置和本地模型部署的情况下,你还需要安装一些第三方库,可以使用以下命令:

python -m pip install --upgrade pip
# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepip install modelscope==1.9.5
pip install "transformers>=4.40.0"
pip install streamlit==1.24.0
pip install sentencepiece==0.1.99
pip install accelerate==0.29.3
pip install datasets==2.19.0
pip install peft==0.10.0MAX_JOBS=8 pip install flash-attn --no-build-isolation

考虑到部分同学配置环境可能会遇到一些问题,我们在 AutoDL 平台准备了 Phi-3 的环境镜像,该镜像适用于该仓库的所有部署环境。点击下方链接并直接创建 Autodl 示例即可。
https://www.codewithgpu.com/i/datawhalechina/self-llm/Phi-3-Lora

在本节教程里,我们将微调数据集放置在根目录 /dataset。

模型下载

使用 modelscope 中的 snapshot_download 函数下载模型,第一个参数为模型名称,参数 cache_dir 为模型的下载路径。

在 /root/autodl-tmp 路径下新建 model_download.py 文件并在其中输入以下内容,粘贴代码后记得保存文件,如下图所示。并运行 python /root/autodl-tmp/model_download.py 执行下载

import torch
from modelscope import snapshot_download, AutoModel, AutoTokenizer
import osmodel_dir = snapshot_download('LLM-Research/Phi-3-mini-4k-instruct', cache_dir='/root/autodl-tmp', revision='master')

指令集构建

LLM 的微调一般指指令微调过程。所谓指令微调,是说我们使用的微调数据形如:

{"instruction": "回答以下用户问题,仅输出答案。","input": "1+1等于几?","output": "2"
}

其中,instruction 是用户指令,告知模型其需要完成的任务;input 是用户输入,是完成用户指令所必须的输入内容;output 是模型应该给出的输出。

即我们的核心训练目标是让模型具有理解并遵循用户指令的能力。因此,在指令集构建时,我们应针对我们的目标任务,针对性构建任务指令集。例如,在本节我们使用由笔者合作开源的 Chat-甄嬛 项目作为示例,我们的目标是构建一个能够模拟甄嬛对话风格的个性化 LLM,因此我们构造的指令形如:

{"instruction": "你是谁?","input": "","output": "家父是大理寺少卿甄远道。"
}

我们所构造的全部指令数据集在根目录下。

数据格式化

Lora 训练的数据是需要经过格式化、编码之后再输入给模型进行训练的,如果是熟悉 Pytorch 模型训练流程的同学会知道,我们一般需要将输入文本编码为 input_ids,将输出文本编码为 labels,编码之后的结果都是多维的向量。我们首先定义一个预处理函数,这个函数用于对每一个样本,编码其输入、输出文本并返回一个编码后的字典:

def process_func(example):MAX_LENGTH = 384    # Llama分词器会将一个中文字切分为多个token,因此需要放开一些最大长度,保证数据的完整性input_ids, attention_mask, labels = [], [], []instruction = tokenizer(f"<|user|>\n{example['instruction'] + example['input']}<|end|>\n<|assistant|>\n", add_special_tokens=False)  # add_special_tokens 不在开头加 special_tokensresponse = tokenizer(f"{example['output']}<|end|>\n", add_special_tokens=False)input_ids = instruction["input_ids"] + response["input_ids"] + [tokenizer.pad_token_id]attention_mask = instruction["attention_mask"] + response["attention_mask"] + [1]  # 因为eos token咱们也是要关注的所以 补充为1labels = [-100] * len(instruction["input_ids"]) + response["input_ids"] + [tokenizer.pad_token_id]if len(input_ids) > MAX_LENGTH:  # 做一个截断input_ids = input_ids[:MAX_LENGTH]attention_mask = attention_mask[:MAX_LENGTH]labels = labels[:MAX_LENGTH]return {"input_ids": input_ids,"attention_mask": attention_mask,"labels": labels}

Phi-3-mini-4k-Instruct 采用的Prompt Template格式如下:

<|system|>
You are a helpful assistant<|end|>
<|user|>
你是谁?<|end|>
<|assistant|>
我是一个有用的助手。<|end|>

加载 tokenizer 和半精度模型

模型以半精度形式加载,如果你的显卡比较新的话,可以用torch.bfolat形式加载。对于自定义的模型一定要指定trust_remote_code参数为True

tokenizer = AutoTokenizer.from_pretrained('/root/autodl-tmp/LLM-Research/Phi-3-mini-4k-instruct', use_fast=False, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_toke
model = AutoModelForCausalLM.from_pretrained('/root/autodl-tmp/LLM-Research/Phi-3-mini-4k-instruct', device_map="auto",torch_dtype=torch.bfloat16, trust_remote_code=True)

定义 LoraConfig

LoraConfig这个类中可以设置很多参数,但主要的参数没多少,简单讲一讲,感兴趣的同学可以直接看源码。

  • task_type:模型类型
  • target_modules:需要训练的模型层的名字,主要就是attention部分的层,不同的模型对应的层的名字不同,可以传入数组,也可以字符串,也可以正则表达式。
  • rlora的秩,具体可以看Lora原理
  • lora_alphaLora alaph,具体作用参见 Lora 原理

Lora的缩放是啥嘞?当然不是r(秩),这个缩放就是lora_alpha/r, 在这个LoraConfig中缩放就是 4 倍。

config = LoraConfig(task_type=TaskType.CAUSAL_LM,target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"],inference_mode=False, # 训练模式r=8, # Lora 秩lora_alpha=32, # Lora alaph,具体作用参见 Lora 原理lora_dropout=0.1# Dropout 比例
)

自定义 TrainingArguments 参数

TrainingArguments这个类的源码也介绍了每个参数的具体作用,当然大家可以来自行探索,这里就简单说几个常用的。

  • output_dir:模型的输出路径
  • per_device_train_batch_size:顾名思义 batch_size
  • gradient_accumulation_steps: 梯度累加,如果你的显存比较小,那可以把 batch_size 设置小一点,梯度累加增大一些。
  • logging_steps:多少步,输出一次log
  • num_train_epochs:顾名思义 epoch
  • gradient_checkpointing:梯度检查,这个一旦开启,模型就必须执行model.enable_input_require_grads(),这个原理大家可以自行探索,这里就不细说了。
args = TrainingArguments(output_dir="./output/Phi-3",per_device_train_batch_size=4,gradient_accumulation_steps=4,logging_steps=10,num_train_epochs=3,save_steps=100,learning_rate=1e-4,save_on_each_node=True,gradient_checkpointing=True
)

使用 Trainer 训练

trainer = Trainer(model=model,args=args,train_dataset=tokenized_id,data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),
)
trainer.train()

保存 lora 权重

lora_path='./Phi-3_lora'
trainer.model.save_pretrained(lora_path)
tokenizer.save_pretrained(lora_path)

加载 lora 权重推理

训练好了之后可以使用如下方式加载lora权重进行推理:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from peft import PeftModelmodel_path = '/root/autodl-tmp/LLM-Research/Phi-3-mini-4k-instruct'
lora_path = './Phi-3_lora' # lora权重路径# 加载tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_path, padding_side='left')# 加载模型
model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto",torch_dtype=torch.bfloat16)# 加载lora权重
model = PeftModel.from_pretrained(model, model_id=lora_path, config=config)prompt = "你是谁?"
messages = [{"role": "user", "content": prompt}
]text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)model_inputs = tokenizer([text], return_tensors="pt").to('cuda')generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512,eos_token_id=tokenizer.encode('<|endoftext|>')[0]
)outputs = generated_ids.tolist()[0][len(model_inputs[0]):]
response = tokenizer.decode(outputs).split('<|end|>')[0]print(response)

完整微调代码下载地址:
https://github.com/datawhalechina/self-llm/blob/master/phi-3/Phi-3-mini-4k-Instruct-Lora.ipynb

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

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

相关文章

代码随想录算法训练营day6| 哈希表理论基础,242.有效的字母异位词,349. 两个数组的交集,202. 快乐数,1. 两数之和

day5休息 1. 哈希表理论基础 要了解哈希表的内部实现原理&#xff0c;哈希函数&#xff0c;哈希碰撞&#xff0c;以及常见哈希表的区别&#xff0c;数组&#xff0c;set 和map。 什么时候想到用哈希法&#xff0c;当我们遇到了要快速判断一个元素是否出现集合里的时候&#xf…

sslh一键在一个端口上运行多个服务(KALI工具系列二十三)

目录 1、KALI LINUX 简介 2、sslh工具简介 3、信息收集 3.1 目标主机IP&#xff08;win&#xff09; 3.2 KALI的IP 4、操作示例 4.1 监听特定端口 4.2 配置SSH 4.3 配置apache 4.4 配置sshl 4.5 验证配置 5、总结 1、KALI LINUX 简介 Kali Linux 是一个功能强大、…

基于线性核函数的SVM数据分类算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于线性核函数的SVM数据分类算法matlab仿真&#xff0c;通过程序产生随机的二维数据&#xff0c;然后通过SVM对数据进行分类&#xff0c;SVM通过编程实现&#x…

[大模型]Phi-3-mini-4k-instruct langchain 接入

环境准备 在 autodl 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 。 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行演示。 创建工作…

HTML具体应用介绍要点和难点以及优缺点分析

HTML(HyperText Markup Language)是超文本标记语言,它是用于创建网页的标准标记语言。HTML 描述了网页的结构和内容,但它并不包含如何显示这些内容的样式(如字体、颜色、布局等)或如何处理用户输入(如表单提交)的信息。这些通常由 CSS(层叠样式表)和 JavaScript 来实…

Java Android 静态内部类 以及优雅实现单例模式/避免handler内存泄漏

前言 Java 中的静态内部类(Static Nested Class)是定义在另一个类里面的一个静态类。它和普通的内部类有些区别,主要是静态内部类不需要依赖于外部类的实例就可以被创建和访问。这种类的特性使得它非常适合用来作为辅助类,用于支持外部类的功能。 特点以及使用场景 静态内…

云计算时代的等保测评挑战和应对策略

概述 云计算作为一种新兴的计算模式&#xff0c;以其灵活性、可伸缩性和经济性&#xff0c;正逐渐成为企业和组织构建信息系统的首选。然而&#xff0c;云计算环境下的信息安全等级保护&#xff08;以下简称“等保”&#xff09;测评面临着前所未有的挑战。本文将从等保测评的…

RabbitMQ实践——配置Prometheus和Grafana报表

大纲 启用rabbitmq_prometheus插件安装启动Prometheus创建用户下载并解压修改配置启动 安装启动grafana安装启动配置数据源 在《RabbitMQ实践——在Ubuntu上安装并启用管理后台》中我们已经安装成功RabbitMQ及其管理后台。在此基础上&#xff0c;我们将打通它和Prometheus、Gra…

PHP地方门户分类信息网站源码讯客分类信息系统源码(含手机版)

源码介绍 1.上传程序到网站根目录,访问http://域名/install/index.php 进行安装,不要直接打开网址&#xff0c;先直接安装; 2.安装完成后 后台恢复数据即可 默认帐号密码都是admin http://域名/admin/ 3.不要删除任何文件&#xff0c;因为删除文件或者修改代码可能造成错误 运…

渗透测试练习题解析 6 (CTF web)

1、[HCTF 2018]admin 1 考点&#xff1a;二次注入 先注册一个账号看看&#xff0c;注册 admin 会提示该用户名已存在&#xff0c;那我们就换一个用户名 观察页面功能&#xff0c;存在一个修改密码&#xff0c;开始的思路是想看看能否通过该密码功能抓包然后修改用户名为 admin …

键盘、鼠标、轴体选购指南

起因 买了块27寸的屏幕msi&#xff0c;一旦入坑爬不起来了。 这不是要配个键盘么。 鼠标的左键也不够灵敏&#xff0c;不知道是电池不足还是使用时间太久&#xff0c;也萌生换的念头。有一个重要原因也是跟电脑和鼠标垫整体不搭。 搜集信息 原本的一个键盘是ikbc国产牌子&am…

Intellij IDEA开发Android项目打包生成APK

在 IntelliJ IDEA 左上方中选择 “Build” -> “Generate Signed Bundle / APK…”选择“APK”——“Next”——“Create New…”&#xff08;Password随便填123456即可&#xff09; “Next”——选择release&#xff08;APK生成后默认存放在本项目的release文件夹里&#x…

【产品经理】订单处理2

本次讲解订单初始化成功到ERP系统过程中的后续环节。 一、根据客服备注更新订单信息 初始化订单过程中&#xff0c;若订单中的客服备注信息对订单进行更新&#xff0c;包括可能改收货信息、改商品、加赠品、指定快递等。 注意&#xff1a;更新订单的过程中要注意订单当前状…

Python | Leetcode Python题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; class Solution:def evalRPN(self, tokens: List[str]) -> int:op_to_binary_fn {"": add,"-": sub,"*": mul,"/": lambda x, y: int(x / y), # 需要注意 python 中负数除法的表现与题目不一…

VUE3之响应系统

VUE3之响应系统 前言 最近在学习VUE3的新特性&#xff0c;记录一下学习成果。 副作用函数 什么是副作用函数&#xff1f; 会产生副作用的函数&#xff0c;或者说会直接或间接影响其他函数的执行结果。 举个简单的例子&#xff1a;一个函数改变了全局变量&#xff0c;这个函数…

电子制造业数字化整体解决方案

电子制造行业有特殊的着重点&#xff1a; 高精度要求&#xff1a;电子制造需要极高的精度和质量控制&#xff0c;因为电子组件和电路板的尺寸通常非常小&#xff0c;且对错误和缺陷非常敏感。 快速技术迭代&#xff1a;电子行业的技术迅速发展&#xff0c;产品生命周期短&…

passwall 自动切换节点

#! /bin/bashconf/etc/config/passwall # 获取所有节点 function getNodes(){f$1;retcat $f | grep "config nodes" | awk {print $3} | sed -r "s///g";echo $ret | tr " " " "; } # 移动旧的自动切换节点 function removeAutoSwitch…

第二节 单机版本redis部署

1. 部署环境 操作系统&#xff1a;centos7.XCPU: 2H内存&#xff1a;4GIP&#xff1a; 192.168.100.102部署版本&#xff1a; redis-7.0.15.tar.gz基础环境&#xff1a; gcc下载 2. 上传Redis安装包 [rootlocalhost opt]# ll 总用量 2932 drwxrwxr-x. 8 root root 4096 1…

刷题笔记2:用位运算找“只出现一次的一个数”

1. & 和 | 的基本操作 137. 只出现一次的数字 II - 力扣&#xff08;LeetCode&#xff09; 先对位运算的操作进行复习&#xff1a; 1、>> 右移操作符 移位规则&#xff1a;⾸先右移运算分两种&#xff1a; 1. 逻辑右移&#xff1a;左边⽤0填充&#xff0c;右边丢…

Python数据分析与建模库-02科学计算库Numpy01-05合集

1、该视频主要讲述了南派&#xff08;NumPy&#xff09;的核心操作和数据结构&#xff0c;以及如何使用NumPy库读取和处理数据。 2、该视频主要讲述了在编程中&#xff0c;如何对数组或矩阵中的元素进行判断和操作&#xff0c;以及在单排中如何进行类型转换。 3、该视频主要讲…