llama-factory 系列教程 (六),linux shell 脚本自动实现批量大模型的训练、部署与评估
背景
最近在做大模型微调训练的评估,每次都要手动训练大模型,手动评估。
发现这样太浪费时间了,于是就尝试着使用linux shell 脚本,利用 for 循环自动实现大模型的训练、部署与评估。
实验:在不同的文本分类数据集尺寸上微调大模型
在这次实验中,我们分别使用了100、500、1000和2000条数据对大模型进行了微调。我们的目标是评估不同大小的数据集对大模型表现的影响。
项目开源地址:https://github.com/JieShenAI/csdn/blob/main/24/07/few_shot_sft/readme.md
实验方法
为了高效地完成微调任务,我们使用了Linux shell脚本 自动化运行。具体步骤如下:
- 数据准备:将不同大小的数据集准备好。
- 批量微调:利用Linux shell脚本批量化地微调大模型,自动保存微调后的模型权重。
- 自动评估:微调完成后,脚本会自动调用评估程序,对模型在测试集上的表现进行评估。
这种方法极大地提高了工作效率。若不使用自动化脚本,我们需要手动逐个训练模型,然后手动运行评估程序,这不仅耗时,而且容易出错。
优势
- 时间节省:利用自动化脚本,我们可以在夜间让计算机自行完成微调和评估工作,第二天早上起床后即可查看结果。
- 减少人工干预:整个过程无需过多人工干预,减少了人工的时间与精力。
通过这种方式,我们能够得出不同大小数据集对大模型表现的影响,为进一步的研究提供了宝贵的数据支持。
项目文件介绍
build_llm_data.ipynb
从训练集中随机筛选并转换为Alpaca样式的数据集格式
在大模型的微调过程中,从训练集中随机抽取不同规模的数据样本,以便进行模型的测试和优化。本文从训练集中随机筛选100、500、1000和2000条数据,并将这些数据转换为Alpaca样式的微调数据集格式,最后将筛选后的数据保存在data文件夹下。
本文在文本分类数据集上进行模型训练。
下述是转化为大模型微调的数据集样例:[{"instruction": "You are a document classifier. When given the text, you classify the text into one of the following categories:\n\n\"Human Necessities\"\n\"Performing Operations; Transporting\"\n\"Chemistry; Metallurgy\"\n\"Textiles; Paper\"\n\"Fixed Constructions\"\n\"Mechanical Engineering; Lightning; Heating; Weapons; Blasting\"\n\"Physics\"\n\"Electricity\"\n\"General tagging of new or cross-sectional technology\"\n\"Unknown\"\n\nYour output should only contain one of the categories and no explanation or any other text.","input": "Classify the document:\nan image sensor device may include a dual - gated charge storage region within a substrate . the dual - gated charge storage region includes first and second diodes within a common charge generating region . this charge generating region is configured to receive light incident on a surface of the image sensor device . the first and second diodes include respective first conductivity type regions responsive to first and second gate signals , respectively . these first and second gate signals are active during non - overlapping time intervals .","output": "Electricity"},... ]
train.sh
在开始训练之前,需要在LLaMA-Factory/data/dataset_info.json
文件中注册data
目录下的数据集。接下来,从 LLaMA-Factory 的可视化界面获取 LoRA 微调的命令行。train.sh
脚本实现了批量化训练,并在训练完成后保存 LoRA 的权重。# 对所有切分后的数据集进行训练 cd LLaMA-Factory data_files=(llm_train_100 llm_train_500 llm_train_1000 llm_train_2000) echo ${data_files[@]}for data_file in ${data_files[@]}; doecho ${data_file}llamafactory-cli train \--stage sft \--do_train True \--model_name_or_path ZhipuAI/glm-4-9b-chat \--preprocessing_num_workers 16 \--finetuning_type lora \--template glm4 \--flash_attn auto \--dataset_dir data \--dataset ${data_file} \--cutoff_len 1024 \--learning_rate 5e-05 \--num_train_epochs 3.0 \--max_samples 100000 \--per_device_train_batch_size 2 \--gradient_accumulation_steps 4 \--lr_scheduler_type cosine \--max_grad_norm 1.0 \--logging_steps 5 \--save_steps 100 \--warmup_steps 0 \--optim adamw_torch \--packing False \--report_to none \--output_dir saves/GLM-4-9B-Chat/lora/240731-${data_file} \--fp16 True \--plot_loss True \--ddp_timeout 180000000 \--include_num_input_tokens_seen True \--lora_rank 8 \--lora_alpha 16 \--lora_dropout 0 \--lora_target all done# nohup bash train.sh > train.log 2>&1 &
eval.sh
在训练完成后,使用 VLLM 部署训练完成的 LoRA 模型,并将其部署成 API 接口,便于通过infer_eval.py
进行评估。eval.sh
脚本实现了对训练模型的批量部署与评估,自动化地逐个部署和推理。在评估完成一个大模型后,脚本会杀死正在部署的进程,开始部署下一个大模型,并进行新的评估。# conda activate llm cd LLaMA-Factory# kw_arr=(llm_train_100 llm_train_500 llm_train_1000 llm_train_2000) kw_arr=(llm_train_100 llm_train_500 llm_train_1000)for kw in "${kw_arr[@]}"; doecho $kwCUDA_VISIBLE_DEVICES=0 API_PORT=8000 llamafactory-cli api \--model_name_or_path /home/jie/.cache/modelscope/hub/ZhipuAI/glm-4-9b-chat \--adapter_name_or_path ./saves/GLM-4-9B-Chat/lora/240731-${kw} \--template glm4 \--finetuning_type lora \--infer_backend vllm \--vllm_enforce_eager &# 模型预测推理脚本,便于后续评估python ../infer_eval.py ${kw} > ../logs/${kw}.log 2>&1# 杀掉服务进程pkill -f llamafactoryecho "Stopped llamafactory" done# nohup bash eval.sh > eval.log 2>&1 &
infer_eval.py
利用在线部署的大模型,结合 LangChain 工具,在测试集上逐个进行评估。import os import json import random import logging import argparse import pickle import evaluate from tqdm import tqdm from datasets import load_dataset from dataclasses import dataclass, field from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, SystemMessage from langchain_core.output_parsers import StrOutputParseros.environ['HTTP_PROXY'] = 'http://127.0.0.1:7890' os.environ['HTTPS_PROXY'] = 'http://127.0.0.1:7890'logging.basicConfig(format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",datefmt="%m/%d/%Y %H:%M:%S",handlers=[logging.FileHandler('../eval.log')],level=logging.INFO )@dataclass class EvalData:name : strin_cnt : int = 0not_in_cnt : int = 0preds : list = field(default_factory=list)labels : list = field(default_factory=list)not_in_texts : list = field(default_factory=list)eval : dict = field(default_factory=dict)def save_obj(obj, name): """ 将对象保存到文件 :param obj: 要保存的对象 :param name: 文件的名称(包括路径) """ with open(name, 'wb') as f: pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)def load_obj(name): """ 从文件加载对象 :param name: 文件的名称(包括路径) :return: 反序列化后的对象 """ with open(name, 'rb') as f: return pickle.load(f)LABELS_DICT = {0: "Human Necessities",1: "Performing Operations; Transporting",2: "Chemistry; Metallurgy",3: "Textiles; Paper",4: "Fixed Constructions",5: "Mechanical Engineering; Lightning; Heating; Weapons; Blasting",6: "Physics",7: "Electricity",8: "General tagging of new or cross-sectional technology", }LABELS_NAME = [LABELS_DICT[i]for i in range(9) ]LABELS_2_IDS = {v : kfor k, v in LABELS_DICT.items() }def compute_metrics(pred, label):res = {}accuracy = evaluate.load("accuracy")res.update(accuracy.compute(predictions=pred, references=label))precision = evaluate.load("precision")res.update(precision.compute(predictions=pred, references=label,average="macro"))recall = evaluate.load("recall")res.update(recall.compute(predictions=pred, references=label,average="macro"))f1 = evaluate.load("f1")res.update(f1.compute(predictions=pred, references=label,average="macro"))return resdef eval(kw):eval_data = EvalData(name=kw)model = ChatOpenAI(api_key="0",base_url="http://localhost:8000/v1",temperature=0)valid_dataset = load_dataset("json",data_files="../data/llm_valid.json")["train"]# labels = valid_dataset["output"][:50]labels = valid_dataset["output"]eval_data.labels = labelsparser = StrOutputParser()preds = []cnt = 0for item in tqdm(valid_dataset):cnt += 1messages = [SystemMessage(content=item['instruction']),HumanMessage(content=item['input']),]chain = model | parserpred = chain.invoke(messages).strip()preds.append(pred)# if cnt == 50:# breakeval_data.preds = predsnot_in_texts = []in_cnt = 0not_in_cnt = 0for pred in preds:if pred in LABELS_NAME:in_cnt += 1else:not_in_cnt += 1not_in_texts.append(pred)eval_data.in_cnt = in_cnteval_data.not_in_cnt = not_in_cnteval_data.not_in_texts = not_in_textspred_num = [LABELS_2_IDS[pred] if pred in LABELS_NAME else random.choice(range(9))for pred in preds]label_num = [LABELS_2_IDS[label]for label in labels]eval_data.eval = compute_metrics(pred=pred_num, label=label_num)logging.info(f"in_cnt: {in_cnt}, not_in_cnt: {not_in_cnt}")logging.info(f"eval: {eval_data.eval}")# 推理结果保存save_obj(eval_data,f"../objs/{kw}.pkl")if __name__ == "__main__":parser = argparse.ArgumentParser(description="输入大模型名,开始推理")parser.add_argument("kw", help="目前部署的大模型名字")args = parser.parse_args()logging.info(args.kw)eval(args.kw)
see_result.ipynb
导入保存到objs文件夹中的预测结果,并进行结果的渲染
最后结果如下图所示,数据集量越大效果越好:
各位读者在看完,训练脚本 train.sh
, 部署和推理脚本 eval.sh
,应该已经明白本项目大致流程。
一言以蔽之,就是在shell脚本中,使用 for 循环实现训练、部署、评估流程。
若大家想复现本文实验,本项目已经在Github开源,项目开源地址:https://github.com/JieShenAI/csdn/blob/main/24/07/few_shot_sft/readme.md
本文主要是为大家展示,使用linux shell 脚本,自动化处理的流程,故在项目的具体细节没有过多的解释。
应该与Bert文本分类进行对比,就可以明显看出大模型的few-shot能力,有读者感兴趣可以实现一下。
相关文章:
llama-factory 系列教程 (六),linux shell 脚本自动实现批量大模型的训练、部署与评估
背景 最近在做大模型微调训练的评估,每次都要手动训练大模型,手动评估。 发现这样太浪费时间了,于是就尝试着使用linux shell 脚本,利用 for 循环自动实现大模型的训练、部署与评估。 实验:在不同的文本分类数据集尺…...
python安全脚本编写之流量泛洪
多线程与流量泛洪 并发操作 如果一个单核的cpu,是并不存在严格意义的并发,只是因为处理时间极短,所以感觉上是并发操作的。 针对多核CPU,4核CPU,严格意义上的并发处理是4个 线程和进程 每一个应用程序,至少…...
一文看懂Java反射、注解、UML图和Lambda表达式
反射 定义: 反射是 java 开发语言的特征之一,它允许 java 程序对自身进行检查(自审),并能直接操作程序内部属性,即就是将类中的各种成分映射成一个 java 对象,利用反射技术可以对一个类进行解剖,将各个组成部分映射成…...
【漏洞复现】搜狗输入法简单绕过Windows锁屏机制
免责申明 本公众号的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息…...
JAVA Spring学习Day1
Maven Maven配置: Maven是Java项目的构建工具,使用pom.xml配置文件管理项目依赖、插件和构建目标。Spring Boot项目搭建: Spring Boot是基于Spring框架的快速开发框架,通过约定大于配置的理念简化了Spring应用的搭建和开发。 …...
linux常见面试题(三)
18 什么事SQL注入 由于程序员的水平及经验参差不齐,大部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断。 应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据…...
【JS】ES6新类型Map与Set
一、Map Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为键或值。 描述 Map 对象是键值对的集合。Map 中的一个键只能出现一次;它在 Map 的集合中是独一无二的。 Map 对象按键值对迭代——…...
FETCH FIRST ROW ONLY和 DISTINCT ON和 LIMIT 1的用法
以下是 PostgreSQL 中函数 FETCH FIRST ROW ONLY、DISTINCT ON 和 LIMIT 1 的用法、含义、例子以及适用版本的信息总结: FETCH FIRST ROW ONLY 用法和含义 FETCH FIRST ROW ONLY 用于限制查询结果集,只返回第一行。它可以和 ORDER BY 子句一起使用&am…...
前端小白安装node、vue、Express、Electron及(Electron桌面端exe应用开发)
一、node.js (一)、下载 下载地址 Node.js — 在任何地方运行 JavaScript (nodejs.org) 参考文章:Node.js安装及环境配置超详细教程【Windows系统】_windows 安装nodejs-CSDN博客 (二)、安装 安装路径可以更换&a…...
solidity多态【很重要】
多态是面向对象编程(OOP)的一个核心概念,允许不同类的对象被视为同一类型的实例,并根据实际类型来响应相同的方法调用。 这意味着同一个接口可以用来引用属于不同类的对象,而这些对象可以有自己的方法实现,…...
Jangow-1.0.1靶机漏洞复现(未完成)
首先,这个靶机只能使用VirtualBox打开,靶机下载地址为 https://download.vulnhub.com/jangow/jangow-01-1.0.1.ova 虚拟机软件下载地址为 Download_Old_Builds – Oracle VM VirtualBox 开启靶机后访问ip进入如下页面,点击site进入到一个…...
软件测试--python基础
一、python基础 (1)第一个python (2)python解释器 (3)基础语法 ①字面量 什么是字面量 常用的值类型 字符串 ②注释 ③变量 什么是变量 变量的特征 变量的目的是存储运行过程的数据 存储的目的是为了:重复使用 ④数据类型 type()语句 变量有类型吗?…...
GPIO子系统
1. GPIO子系统视频概述 1.1 GPIO子系统的作用 芯片内部有很多引脚,这些引脚可以接到GPIO模块,也可以接到I2C等模块。 通过Pinctrl子系统来选择引脚的功能(mux function)、配置引脚: 当一个引脚被复用为GPIO功能时,我们可以去设…...
学会这个Python库,接口测试so easy
前言 我们在做接口测试时,大多数返回的都是json属性,我们需要通过接口返回的json提取出来对应的值,然后进行做断言或者提取想要的值供下一个接口进行使用。 但是如果返回的json数据嵌套了很多层,通过查找需要的词,就…...
Stable Diffusion4.8.7(Ai绘画)软件安装教程
软件下载 [名称]:Stable Diffusion4.8.7(Ai绘画) [大小]:16.52GB [语言]:简体中文 [安装环境]:Win11/Win10/Win8/Win7 [硬件要求]:CPU2.0GHz ,内存4G(或更高&#x…...
操作系统错误处理
错误处理 1、通过函数的返回值表示执行错误: // 返回合法值表示成功 返回非法值表示失败 // 计算大小、查找 long file_size(const char* path) {FILE* fp fopen(path,"r");if(NULL fp)return -1; // 返回非法值fseek(fp,SEEK_END,0);long size …...
【靶场实操】sql-labs通关详解----第一节:基础注入方式(Less-1~Less-10)
目录 一、注入方式简要概括 1.1 SQL常见注入方式 1.2 爆破函数 二、靶场实操 2.1 Less-1 2.1.1 判断类型 2.1.2 联合注入查询 2.2 Less-2 2.2.1 判断类型 2.2.2 注入攻击 2.2.3 字符型与数字型漏洞对比 2.3 Less-3 2.3.1 判断 2.3.2 注入 2.4 Less-4 2.4.1 判断…...
力扣676.实现一个魔法字典
力扣676.实现一个魔法字典 字典树 dfs class Trie{public:Trie* next[26];bool is_end false;};class MagicDictionary {public:Trie* root new Trie();void add(string& word){Trie* p root;for(char c:word){if(p->next[c-a] NULL) p->next[c-a] new Trie…...
ctfshow-web入门-sql注入(web171-web175)
目录 1、web171 2、web172 3、web173 4、web174 5、web175 1、web171 单引号测一下,报错 -- 闭合后回显正常 也可以用 # ,不过需要 URL 编码 成功闭合之后,先判断下字段数: 1 order by 3-- 3 的时候正常 4 的时候报错&am…...
视频怎么添加音乐?分享5种视频添加音乐方法
在如今火爆的短视频时代,为视频添加合适的背景音乐,无疑是让其脱颖而出的关键一步。无论是打造个人Vlog、纪录片,还是创意短片,音乐都能赋予视频独特的情感与氛围。那么怎么给视频添加上背景音乐呢?给大家分享5种简单的…...
黑马JavaWeb后端案例开发(包含所有知识点!!!)
目录 1.准备工作 环境搭建 开发规范 REST(REpresentation State Transfer),表述性状态转换,它是一种软件架构风格 注意事项 统一响应结果 2.部门管理功能 查询部门 删除部门 新增部门 RequestMapping 3.员工管理功能 分页查询 批…...
FPGA开发——蜂鸣器实现音乐播放器的设计
一、概述 我们在进行蜂鸣器的学习的时候,总会在想既然蜂鸣器能够发出声音,那么它能够播放音乐吗,今天这篇我们文章我们就一起来学习怎样使用使用蜂鸣器来播放音乐,也就是怎样成为一个音乐播放器。 1、蜂鸣器的类型 在设计的时候…...
InnoDB存储引擎(1)
InnoDB存储引擎的优点 InnoDB在设计时考虑到了处理大数据量时的性能,支持事务,回滚和崩溃修复的能力,通过多版本并发控制来减少锁定(降低了锁的争用),同时还支持外键的约束;通过缓冲池在内存中缓存数据来提高查询的性能ÿ…...
VMWare虚拟机共享主机的网络访问外网
1.主机中启动客户端并连接外网 2.设置虚拟网络类型为NAT 3.启动虚拟并通过主机访问外网...
LeetCode Easy|【415. 字符串相加】
力扣题目链接 题目本身难度不大,但是后续的一些补充内容还是值得搞清楚的 主要的逻辑如下: 其实本题的目的就是让我们来模拟我们的竖式加法。所以很直观的一个想法就是使用双指针:分别指向两个 num 的末尾。随后就会产生一些问题:…...
RAG 革命:NVIDIA 工作站如何成为企业 AI 的秘密武器
在深圳的一家科技初创公司,首席技术官李梅正在向她的团队展示一个令人兴奋的新项目。“看这个,” 她指着屏幕上的实时演示说,“我们刚刚用公司的技术文档训练了一个 AI 助手,它现在可以回答任何关于我们产品的问题,而且…...
九大原则,轻松构建个人高效SOP
1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!) 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景,目标,愿景 C - Complication 冲突 讲卡点,讲冲突 Q - Question 疑问-问题 这些冲…...
Airtest的demo实现多设备并行
Airtest的demo实现多设备并行 它实现是的获取adb连接上的所有设备,然后在每一台设备上跑给定的测试用例,跑完之后生成单机的测试报告,最后再汇总这些单机测试报告的结果,形成汇总(聚合)报告: 同…...
社区养老服务小程序的设计
管理员账户功能包括:系统首页,个人中心,用户管理,服务人员管理,服务产品管理,服务预约管理,服务状态管理,服务退订管理,活动管理,视频管理 微信端账号功能包…...
Interceptor拦截器开发
因为1登录后的接口都需要token验证代码,会出现重复代码;2当前的接口不防刷,会被恶意攻击 所以在controller层增加请求拦截,如果你的token不合法,就不让你做后续的处理了 拦截器的作用是什么 作用: 1、对controller层代码的访问进行拦截,合法的请求,那此层代码就处理,反…...
做制作网站找啥工作/郑州网站推广方案
我有一个权限为4750的进程.我的Linux系统中存在两个用户. root用户和appz用户.该进程继承了以“appz”用户身份运行的进程管理器的权限.我有两个基本的例程:void do_root (void){int status;status seteuid (euid);if (status < 0) {exit (status);}}/* undo ro…...
淘宝上做网站可信吗/惠州百度seo
投资是一门艺术,并不仅仅是简单的买进卖出,这些只是结果,而我们最重要学习的地方在于如何达成这一结果,总而达到盈利的最终目的,在整个市场大多数人不懂技术的时候,只能一直靠自己不停的研究,虚…...
163企业邮箱怎么申请/惠州市seo广告优化营销工具
开头 中国互联网发展的这些年,如今90后程序员是中国程序员的主力军,互联网的热潮也让一批批00后蠢蠢欲动,尝试涌入互联网圈。 当程序员容易,当一个优秀的程序员需要不断学习,从初级程序员到高级程序员,从…...
专门做玉的网站/seo的概念是什么
微服务技术栈选型,看了这个别的可以不用看了 摘要: 本文由PPmoney架构师敖小剑分享:微服务的核心技术,目前可选的开源微服务框架,以及为微服务提供支撑的基础设施。 前言 大家好,我是敖小剑,…...
如何做美食的视频网站/南京市网站seo整站优化
2019独角兽企业重金招聘Python工程师标准>>> 周五,耶,OSC 明天终于要上班啦!明天终于还是要上班啦!系不系很开森呢?duang ~ duang ~ duang~ 上班第一天,红包在哪里? 开源中国首席撸管…...
甘肃住房建设厅网站/免费个人网站建站申请
不是所有的记录打开后都可以进行修改的。1.当项目处于完成和终止的状态是不能修改的。2.暂时不考虑其他状态是否应该禁止修改。3.其他视图改变了项目状态时,是否可以修改需要重新设置。4.如果项目已经被修改,而且状态改变为只读时,需要提示是…...