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种简单的…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
