Llama-Factory微调Qwen2.5-VL从数据集制作到部署记录

电脑环境配置:
1.ubuntu24
2.3090(24G)
3.Cuda==12.9

一、数据集制作

我的数据集主要是对图像内容进行描述
1.Label-studio制作数据集
这是最原始的从零开始制作数据集的方法,不建议这样做!
安装完label-studio后,输入指令启动

label-studio start

进入浏览器界面
在这里插入图片描述
创建项目:Create Project,引入图片后,选择图像描述数据集制作(Image Captioning)
在这里插入图片描述
2.利用Qwen2.5-VL半自动制作数据集
既然qwen本身具有较好的图像描述能力,那我们可以先使用qwen进行图像描述,在此基础上进行复核修改,这样做可以减少人力成本。
我这编写的脚本如下:

import torch
from modelscope import Qwen2_5_VLForConditionalGeneration, AutoTokenizer, AutoProcessor
from qwen_vl_utils import process_vision_info
import time
import os
from pathlib import Path
import jsondef process_single_image(model, processor, image_path, prompt):messages = [{"role": "user","content": [{"type": "image","image": image_path,},{"type": "text", "text": prompt},],}]# Preparation for inferencetext = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)image_inputs, video_inputs = process_vision_info(messages)inputs = processor(text=[text],images=image_inputs,videos=video_inputs,padding=True,return_tensors="pt",)inputs = inputs.to("cuda")time_start = time.time()# Inference: Generation of the outputgenerated_ids = model.generate(**inputs, max_new_tokens=256, do_sample=False)time_end = time.time()print(f"Inference time for {Path(image_path).name}: {time_end - time_start:.2f}s")generated_ids_trimmed = [out_ids[len(in_ids) :] for in_ids, out_ids in zip(inputs.input_ids, generated_ids)]output_text = processor.batch_decode(generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False)return output_text[0]def process_images_in_folder(model, processor, image_folder, prompt, output_file=None):# 支持的图像格式image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.tif'}# 获取文件夹中所有图像文件image_files = []for file in Path(image_folder).iterdir():if file.suffix.lower() in image_extensions:image_files.append(file)image_files.sort()if not image_files:print(f"No image files found in {image_folder}")returnprint(f"Found {len(image_files)} image files")# 存储结果results = []# 遍历处理每张图像for image_file in image_files:print(f"\nProcessing: {image_file.name}")try:result = process_single_image(model, processor, str(image_file), prompt)print(f"Result: {result}")# 保存结果results.append({'image': image_file.name,'path': str(image_file),'result': result})except Exception as e:print(f"Error processing {image_file.name}: {e}")results.append({'image': image_file.name,'path': str(image_file),'result': f"Error: {e}",'error': True})# 如果指定了输出文件,则保存为JSONL格式if output_file:with open(output_file, 'w', encoding='utf-8') as f:for item in results:# 构造JSONL格式的字典json_line = {"image": item['path'],"text": item['result']}# 写入一行JSONf.write(json.dumps(json_line, ensure_ascii=False) + '\n')print(f"\nResults saved to {output_file}")return resultsif __name__ == '__main__':# default: Load the model on the available device(s)model = Qwen2_5_VLForConditionalGeneration.from_pretrained("/home/ct/work/BigModel/Qwen2.5-VL/models/Qwen2.5-VL-7B-Instruct", torch_dtype="auto", device_map="auto")# The default range for the number of visual tokens per image in the model is 4-16384.# You can set min_pixels and max_pixels according to your needs, such as a token range of 256-1280, to balance performance and cost.min_pixels = 256*28*28max_pixels = 1280*28*28processor = AutoProcessor.from_pretrained("/home/ct/work/BigModel/Qwen2.5-VL/models/Qwen2.5-VL-7B-Instruct", min_pixels=min_pixels, max_pixels=max_pixels)# 设置图像文件夹路径和提示词image_folder = "/home/ct/work/Label_tools/PICS/Flame/"  prompt = "查看图像中红色矩形框中是否存在烟火,判定存在烟火需要看到明显的烟雾和火焰,注意区分灯光、太阳光和一些其他的影响。"output_file = "inference_results.jsonl"  # 结果输出文件# 处理文件夹中的所有图像results = process_images_in_folder(model, processor, image_folder, prompt, output_file)# 打印汇总信息print(f"\nProcessing completed. Total images processed: {len(results)}")

配置运行后,将会生成推理结果的JSONL文件。主要包含图像路径和对应描述。其他任务主要修改以下提示词就可以。
接下来就是对这图像查看与qwen2.5-vl描述的是否一致就行。

二、LLama-Factory微调

1.配置LLama-Factory环境
因为我是一边测试一边记录,为了安全起见,建议使用anaconda建立LLama-Factory虚拟环境。
(1)克隆LLama-Factory项目

git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory

(2)创建虚拟环境

# 使用 conda(推荐)
conda create -n llama-factory python=3.10
conda activate llama-factory# 或使用 venv
python -m venv venv
source venv/bin/activate

(3)安装依赖

pip install -r requirements.txt

在这里插入图片描述
2.转化标签数据格式
目前我们的数据格式大概是:

{"image": "/path/to/image.jpg", "text": "图像描述语句"}

而LLama-Factory对于多模态大模型的建议数据格式为:

{"images": ["/home/ct/work/Label_tools/PICS/Smoke/Smoke001.png"], "conversations": [{"content": "<image>\n请分析图像中红色矩形框内是否存在吸烟行为,并说明理由。", "from": "user"}, {"content": "红色矩形框中的人在吸烟。", "from": "assistant"}]}

转换脚本如下:

import json# 读取原始文件
input_file = "/home/ct/work/LLaMA-Factory/inference_results_Smoke.jsonl"
output_file = "/home/ct/work/LLaMA-Factory/smoke_dataset.jsonl"with open(input_file, 'r', encoding='utf-8') as infile:lines = infile.readlines()# 转换格式
converted_lines = []
for line in lines:data = json.loads(line.strip())# 构建新的数据结构new_data = {"images": [data["image"]],"conversations": [{"content": "<image>\n请分析图像中红色矩形框内是否存在吸烟行为,并说明理由。","from": "user"},{"content": data["text"],"from": "assistant"}]}converted_lines.append(json.dumps(new_data, ensure_ascii=False) + '\n')# 写入新文件
with open(output_file, 'w', encoding='utf-8') as outfile:outfile.writelines(converted_lines)print(f"转换完成!已保存到 {output_file}")

3.启动微调
(1)下载模型
huggingface由于是外网,下载困难,建议去魔塔社区下载,下载后置于LLama-factory根目录下,新建models文件夹。
在这里插入图片描述
(2)构建dataset_info.json
在LLama-factory的根目录下新建该文件,并写入:

{"smoke_dataset": {"file_name": "smoke_dataset.jsonl","formatting": "sharegpt","columns": {"messages": "conversations","images": "images"},"tags": {"role_tag": "from","content_tag": "content","user_tag": "user","assistant_tag": "assistant"}}
}

注意smoke_dataset和smoke_dataset.jsonl两者需要对应。
(3)启动微调

cd /home/ct/work/LLaMA-Factory
python src/train.py \--stage sft \--do_train \--model_name_or_path /home/ct/work/LLaMA-Factory/models/Qwen2.5-VL-7B-Instruct \--dataset smoke_dataset \--dataset_dir . \--template qwen2_vl \--finetuning_type lora \--lora_target all \--output_dir saves/Qwen2.5-VL-7B-Instruct-lora \--per_device_train_batch_size 1 \--gradient_accumulation_steps 8 \--lr_scheduler_type cosine \--logging_steps 10 \--save_steps 100 \--learning_rate 5e-5 \--num_train_epochs 3.0 \--plot_loss \--fp16

在这里插入图片描述
生成的权重文件在LLama-Factory根目录下的Saves文件夹下。
内存占用大概22G.
在这里插入图片描述

三、模型合并

在模型微调训练后,会在saves文件夹下生成一系列的微调权重文件,我使用的lora微调。大小在100~300m之间。需要与原始权重文件合并。
在这里插入图片描述

可以采用llama-factory和pytorch+transform等多种方法进行合并,我这的脚本如下:

# merge_lora_weights.py
import os
import torch
from transformers import AutoModelForVision2Seq, AutoTokenizer, AutoProcessor
from peft import PeftModeldef merge_lora_weights():# 配置路径base_model_path = "models/Qwen2.5-VL-7B-Instruct"  # 原始模型路径lora_weights_path = "saves/Qwen2.5-VL-7B-Instruct-lora/checkpoint-3520"  # LoRA权重路径output_path = "./merged_qwen2.5-vl-finetuned"  # 合并后模型保存路径print("Loading base model...")base_model = AutoModelForVision2Seq.from_pretrained(base_model_path,torch_dtype=torch.float16,low_cpu_mem_usage=True,trust_remote_code=True)print("Loading LoRA adapter...")lora_model = PeftModel.from_pretrained(base_model, lora_weights_path)print("Merging weights...")merged_model = lora_model.merge_and_unload()print("Saving merged model...")# 创建输出目录os.makedirs(output_path, exist_ok=True)# 保存模型merged_model.save_pretrained(output_path, safe_serialization=True, max_shard_size="5GB")# 保存tokenizer和processortokenizer = AutoTokenizer.from_pretrained(base_model_path, trust_remote_code=True)tokenizer.save_pretrained(output_path)# 保存processor(对VL模型很重要)processor = AutoProcessor.from_pretrained(base_model_path, trust_remote_code=True)processor.save_pretrained(output_path)print(f"Merged model saved to {output_path}")if __name__ == "__main__":merge_lora_weights()

合并后模型权重大小:
在这里插入图片描述
接下来就是测试了。

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

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

相关文章

【蓝桥杯真题67】C++数位和为偶数的数 第十五届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解

C++数位和为偶数的数 第十五届蓝桥杯青少年创意编程大赛C++选拔赛真题 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】 1、C++专栏 电子学会C++一级历年真题解析 电子学会C++二级历年真题解析

【计算机网络 | 第11篇】宽带接入技术及其发展历程

文章目录宽带接入技术详解数字传输系统技术演进早期电话网的传输技术演变数字传输系统技术演进&#xff1a;从碎片到统一宽带接入技术 ADSLADSL的基本原理与非对称特性DMT调制技术&#xff1a;多子信道并行传输ADSL接入网组成电话分离器的设计原理与优势ADSL的升级&#xff1a;…

(论文速读)SCSegamba:用于结构裂纹分割的轻量级结构感知视觉曼巴

论文题目&#xff1a;SCSegamba: Lightweight Structure-Aware Vision Mamba for Crack Segmentation in Structures&#xff08;用于结构裂纹分割的轻量级结构感知视觉曼巴&#xff09;会议&#xff1a;CVPR2025摘要&#xff1a;不同场景下的结构裂缝像素级分割仍然是一个相当…

《苏超风云》亮相时尚大赏,成短剧行业发展新风向

当男频短剧凭借《一品布衣》五天横扫10亿播放的数据宣告逆袭&#xff0c;短剧市场格局正经历深刻洗牌。风口之下&#xff0c;头条视听、中皋文旅、国内时尚视觉与短视频创作领域的头部厂牌“大湾视频”携手下场&#xff0c;打造精品男频短剧《苏超风云》&#xff0c;剑指2025年…

HTML5新年元旦网站源码

新年主题网站开发概述 本项目基于HTML5、CSS3与JavaScript技术栈&#xff0c;打造了一个功能丰富、交互体验流畅的新年主题网站&#xff0c;涵盖文化展示、互动娱乐与社交分享三大核心模块&#xff0c;通过现代化前端技术实现沉浸式节日氛围营造。 1.1、核心功能架构 网站采…

CentOS 7 下iscsi存储服务配置验证

一、环境说明 centos7服务器*2服务器ip&#xff1a;服务端10.10.10.186 客户端10.10.10.184服务端存储卷sda1提前关闭防火墙&#xff0c;或开放默认 iSCSI 使用 3260 端口 二、服务端&#xff08;Target&#xff09;配置 安装 iSCSI target 服务 yum install -y targetcli syst…

立即数、栈、汇编与C函数的调用

一、立即数在 ARM 架构中&#xff0c;立即数是指在指令中直接编码的常量值&#xff0c;而不是通过寄存器或内存引用的值立即数的特点编码限制&#xff1a;ARM指令是固定长度的&#xff08;32位&#xff09;&#xff0c;因此立即数不能占用太多位数。典型的算术和逻辑指令通常只…

贪心算法与动态规划:数学原理、实现与优化

贪心算法与动态规划&#xff1a;数学原理、实现与优化 引言&#xff1a;算法选择的本质 在计算机科学领域&#xff0c;算法选择的本质是对问题特征的数学建模与求解策略的匹配。贪心算法与动态规划作为两种经典的优化算法&#xff0c;分别在不同问题域展现出独特优势。本文将从…

Leetcode 刷题记录 21 —— 技巧

Leetcode 刷题记录 21 —— 技巧 本系列为笔者的 Leetcode 刷题记录&#xff0c;顺序为 Hot 100 题官方顺序&#xff0c;根据标签命名&#xff0c;记录笔者总结的做题思路&#xff0c;附部分代码解释和疑问解答&#xff0c;01~07为C语言&#xff0c;08及以后为Java语言&#xf…

Android Studio Meerkat | 2024.3.1 Gradle Tasks不展示

把这两个开关打开&#xff0c;然后刷新gradle文件

Java中方法重写与重载的区别

目录 1. 方法重载 (Overload) 什么是方法重载&#xff1f; 重载的特点&#xff1a; 重载的示例&#xff1a; 重载的调用&#xff1a; 2. 方法重写 (Override) 什么是方法重写&#xff1f; 重写的特点&#xff1a; 重写的示例&#xff1a; 重写的调用&#xff1a; 3.…

微信小程序发送订阅消息-一次订阅,一直发送消息。

实现思路长期订阅要求太高&#xff0c;需要政府、公共交通等单位才有资格&#xff0c;所以只能使用一次性订阅。 就像是买奶茶&#xff0c;下单以后&#xff0c;会弹出让用户订阅消息那种。以买奶茶为例:用户第一次下单成功&#xff0c;点击了订阅消息。&#xff08;一般都有三…

408 Request Timeout:请求超时,服务器等待客户端发送请求的时间过长。

408 Request Timeout 是 HTTP 状态码之一&#xff0c;表示客户端在发送请求时&#xff0c;服务器等待的时间过长&#xff0c;最终放弃了处理该请求。此问题通常与网络延迟、客户端配置、服务器设置或者应用程序的性能有关。1. 常见原因1.1 客户端问题网络连接延迟或不稳定&…

MongoDB面试集锦

该书的使用的MongoDB版本是 4.2.01、什么是NoSQL数据库&#xff1f;NoSQL和RDBMS有什么区别&#xff1f;在那些情况下使用和不使用NoSQL数据库&#xff1f;NoSQL是非关系型数据库&#xff0c;NoSQLNot Only SQL 。关系型数据库采用的是结构化的数据&#xff0c;NoSQL采用的是键…

直击JVM面试题

JVM组成 JVM JVM 就是 Java 程序的运行环境&#xff0c;它通过 类加载、字节码执行、内存管理、GC、线程调度 等机制&#xff0c;让 Java 实现了 跨平台、自动内存管理和高效执行。 它是一个抽象的计算机&#xff0c;能执行以 字节码&#xff08;.class 文件&#xff09; 为单…

地球系统模式(CESM)实践技术应用及进阶

目前通用地球系统模式&#xff08;Community Earth System Model&#xff0c;CESM&#xff09;在研究地球的过去、现在和未来的气候状况中具有越来越普遍的应用。CESM由美国NCAR于2010年07月推出以来&#xff0c;一直受到气候学界的密切关注。近年升级的CESM2.0在大气、陆地、海…

StarRocks导入数据-使用 Broker Load 进行异步导入

目录 一、背景 二、实操 三、查看导入进度 一、背景 将hive库数据表导入starrocks. 二、实操 LOAD LABEL user_behavior (DATA INFILE("hdfs://<hdfs_ip>:<hdfs_port>/user/amber/user_behavior_ten_million_rows.parquet")INTO TABLE user_behavior…

c语言,识别到黑色就自动开枪,4399单击游戏狙击战场,源码分享,豆包ai出品

不好用&#xff0c;识别速度慢&#xff0c;有时候识别不准确#include <windows.h> #include <stdio.h> #include <math.h> HDC hdcScreen; void leftClick(); void RGBtoHSV(int r, int g, int b, int* h, int* s, int* v); int fuzzyFindColor(int x1, int…

电动汽车充电标准之 — SAE J1772“电动汽车传导充电连接器”简介

SAE J1772&#xff08;通常读作 "J seventeen seventy-two"&#xff09;是由美国汽车工程师学会&#xff08;SAE&#xff09;制定的&#xff0c;针对电动汽车传导充电连接器的北美标准。它规范了电动汽车&#xff08;EV&#xff09;与充电设备&#xff08;EVSE&#…

ZooKeeper Multi-op+乐观锁实战优化:提升分布式Worker节点状态一致性

系列文章目录 第一章 ZooKeeper入门概述:Znode,Watcher,ZAB . 第二章 技术解析&#xff1a;基于 ZooKeeper 实现高可用的主-从协调系统&#xff08;通过例子深入理解Zookeeper如何进行协调分布式系统&#xff09; 第三章 基于 ZooKeeper 的主从模式任务调度系统&#xff1a;设…