LLaMA-Factory微调qwen2-VL(无sudo)

写这个的目的是自己前几个月微调的qwen2相对来说比较轻松但是这次实验室的机子由于重装了环境全没了,因此在conda上面踩了很多网上的坑,还有qwen2-VL-instruction的批量处理数据在网上也几乎找不到正确的写法,写这篇是为了记录一下微调的步骤和方法。

实验机器:A6000 40G显存(实际估计二十左右)

实验环境:linux

一、首先安装anconda

linux安装Anaconda及pytorch配置环境 无root权限_linux没有root怎么配置anaconda-CSDN博客这个文章第五点顺手做点别的什么都是可以安心食用的。

有个需要注意的点是source ~/. bashrc发现仍未安装到路径中,那就手动添加。

二、conda虚拟环境配置

首先去到github中搜LLaMA-Factory,git clone到文件夹中即可。

接着网上搜LLaMA-Factory配置会看到其中大部分文档会教你先安装torch,但是CUDA版本相对较高就会导致和LLaMA-Factory的版本不兼容,比如实验室的版本就是CUDA 12.1,安装的pytorch版本就会过高,但是CUDA是可以向下兼容一些版本的。

在2024.12(提及日期指的是现阶段的包版本号,以后可能会出现变化)

1
conda create --name LLaMA python=3.10

这是先创建一个conda的虚拟环境。

1
2
conda activate LLaMA;
pip install -r requirements.txt

通过pip项目里面的requirements.txt我们可以直接安装对应的可以和LLaMA-Factory兼容的pytorch的版本。

在这里我们需要观察会不会出现一些红色的报错如果出现一些红色的报错那有可能出现了一些问题。之后就算全部重新安装好了也有可能会出现一些问题。可以多创建几个环境,跑到不报错就行。

三、运行LLaMA-Factory

1
2
cd LLaMA-Factory
python src/webui.py

如果可以成功运行就可以出现对应的webui页面。

如果出现 llamafactory-cli:未找到命令这样的情况

1
2
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

这种情况在conda环境容易发生

还有不能运行大概率是包没装对。

四、模型的安装

由于没有管理员权限无法安装git中的lfs这个包,这个包是git专门用来下载那些巨大无比的文件。没有他我们是能换modelspace这个国内的大模型社区进行下载。

我个人推荐命令行下载。

在modelspace中有三四个方法可以下载。

模型的下载 · 文档中心

1
pip install modelspace

如果下载,modelspace这个模块进行import发现不行就说明处理问题。可以单独重新conda一个虚拟环境来modelspace。

modelspace环境进行下载

1
modelscope download --model 'Qwen/Qwen2-7b' --local_dir 'path/to/dir'

命令行稳定性相对来说比用代码下载好,用文档里面的代码进行模型的下载会经常出现一些报错。

关于模型的下载我个人是在LLaMA-Factory的文件夹之外创建了model文件夹,存放大模型的位置是/model/hub/xxx(你的大模型)

五、关于数据集的格式

进入~/LLaMA-Factory/data我们可以看到很多的数据集格式。

模仿这些数据集格式来构造自己的数据集格式即可。

简单的文字的格式很简单,我讲一下有图片的格式。

首先创建一个数据集文件夹data,里面在创建一个文件夹images,然后data下的另外一个文件是json文件的数据集格式。

有些模型是不支持图片这些,不过多模态的大模型大多数是可以使用的。

1
2
3
4
5
{//我用的是最基础的
"instruction"://描述
"input":images/xxx.jpg
"output"://想要的结果
}

这样子数据集就是可以的了

六、微调

对于不同的模型,微调的参数自然是不同的。

对于可视化微调和代码微调其实我觉得没什么区别,我个人更喜欢可视化微调。

对于微调的参数我是看的网上的文章进行参数的调整。使用PAI+LLaMA Factory 微调 Qwen2-VL 模型,搭建文旅领域知识问答机器人-阿里云开发者社区

这里面都是有微调的方法不多赘述了。

七、微调后模型的整合

四个模块

我们看到Export是模型为微调后进行整合。

export

首先model path仍是原来的模型,在微调完后,在LLaMA-Factory/save这个文件中可以看到微调的文件,然后点击checkpoint path会有对应的日志文件。然后就是export dir中填入导入的文件夹。我个人仍是导入到model/hub里面。

八、批量处理代码

网上的qwen2-VL-Instruct处理批量文件资料比较少,因此自己根据网上的代码进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import json
from PIL import Image
import torch
from transformers import Qwen2VLForConditionalGeneration, AutoProcessor
from tqdm import tqdm

# 设置随机种子(可选)
torch.manual_seed(1234)

# 强制使用 cuda:0(如果有可用的GPU)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(f"使用设备: {device}")

# 加载模型,确保它在指定的设备上
model = Qwen2VLForConditionalGeneration.from_pretrained(
"/home/lijiawei/model/hub/qwen/qwen2-VLtune", # 替换为你的模型路径或名称
torch_dtype=torch.float32, # 使用半精度以节省内存
device_map={"": device}, # 将整个模型加载到指定设备
trust_remote_code=True # 如果模型需要自定义代码
).eval() # 不需要再调用 .to(device) 因为 device_map 已经指定

# 加载处理器,用于预处理输入数据
processor = AutoProcessor.from_pretrained("/home/lijiawei/model/hub/qwen/qwen2-VLtune") # 替换为你的处理器路径或名称

# 定义输入文件夹路径和输出JSON文件路径
input_folder = "/home/lijiawei/extracted_images" # 替换为你的图片文件夹路径
output_json = "/home/lijiawei/model/processed_results.json" # 替换为你希望保存结果的JSON文件路径

# 支持的图片扩展名
supported_extensions = ('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff')

# 获取所有图片文件路径
image_paths = [
os.path.join(input_folder, img)
for img in os.listdir(input_folder)
if img.lower().endswith(supported_extensions)
]

print(f"找到 {len(image_paths)} 张图片。")

# 初始化结果列表
results = []

# 定义处理单张图片的函数
def process_single_image(image_path):
try:
# 打开图片
image = Image.open(image_path).convert("RGB")

# 构建对话结构,包含用户角色、图像和文本提示
messages = [
{
"role": "user",
"content": [
{
"type": "image",
"image": image_path, # 如果使用本地路径,确保模型支持
},
{"type": "text", "text": "Please describe the pedestrian in the image"},
],
}
]
text = processor.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)

# 预处理输入数据,将文本和图像转换为模型可接受的格式
inputs = processor(
text=[text],
images=[image],
padding=True,
return_tensors="pt"
)

# 将输入数据移至指定设备
inputs = {k: v.to(device) for k, v in inputs.items()}

# 使用 `torch.no_grad()` 进行推理,节省内存
with torch.no_grad():
generated_ids = model.generate(**inputs, max_new_tokens=1024)

# 提取生成的新token(去除输入部分)
generated_ids_trimmed = [
generated_ids[i][len(inputs['input_ids'][i]):]
for i in range(len(generated_ids))
]

# 解码生成的token为可读文本
output_text = processor.batch_decode(
generated_ids_trimmed, skip_special_tokens=True, clean_up_tokenization_spaces=False
)

# 获取描述文本
description = output_text[0] if output_text else "No description generated."

# 清理缓存以释放内存
del inputs, generated_ids, generated_ids_trimmed, output_text
torch.cuda.empty_cache()

return {
"image_path": image_path,
"description": description
}

except Exception as e:
print(f"Error processing {image_path}: {e}")
return {
"image_path": image_path,
"description": "Processing Failed"
}

# 遍历每张图片并生成描述
for image_path in tqdm(image_paths, desc="Processing Images"):
result = process_single_image(image_path)
results.append(result)

# 将结果保存为JSON文件
with open(output_json, 'w', encoding='utf-8') as f:
json.dump(results, f, ensure_ascii=False, indent=4)

print(f"批量图片处理完成,结果已保存到 {output_json}")


LLaMA-Factory微调qwen2-VL(无sudo)
https://ljw030710.github.io/2024/12/13/LLaMA-Factory微调qwen2-VL-无sudo/
Author
iolzyy
Posted on
December 13, 2024
Licensed under