Llama-Factory微調Qwen2.5-VL從數據集制作到部署記錄

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;設…