Qwen-VL模型微调及遇到的一些小问题

2024-08-28 18:36
文章标签 问题 模型 遇到 微调 qwen vl

本文主要是介绍Qwen-VL模型微调及遇到的一些小问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        Qwen-VL 是阿里云研发的大规模视觉语言模型(Large Vision Language Model, LVLM)。Qwen-VL 可以以图像、文本、检测框作为输入,并以文本和检测框作为输出。相比较前文提到的llava-llama3的模型,它相对更成熟一些,功能更强大一些。

        比较有特点的功能:

  • 多图交错对话:支持多图输入和比较,指定图片问答,多图文学创作等;
  • 首个支持中文开放域定位的通用模型:通过中文开放域语言表达进行检测框标注;
  • 细粒度识别和理解:相比于目前其它开源LVLM使用的224分辨率,Qwen-VL是首个开源的448分辨率的LVLM模型。更高分辨率可以提升细粒度的文字识别、文档问答和检测框标注。

 

1、模型原理

2、模型结构

3、模型使用

4、模型微调

 

1、模型原理

        整体上来说,Qwen-VL采用了类似于flamingo的多模态结构,通过输入图像和可学习的Qurey序列和图像特征进行注意力计算,进行特征查询和压缩,压缩后再和text同步输入到llm中进行输出。 

 

上图为Flamingo的基本结构,它提出了visual resampler、cross-attention adapter等模块做图文对齐,通过感知器重采样器模块将视觉编码器连接到冻结的语言模型,并将来自视觉编码器的可变数量的图像或视频特征作为输入,产生固定数量的视觉输出。 

Qwen-VL的整体结构如下,它参考了Flamingo的visual resampler模块做视觉输出,利用该输出与大模型进行结合。

Qwen-VL模型网络包括视觉编码器(Vision Encoder)、视觉语言适配器(VL Adapter)、语言模型(LLM)三部分,其中编码器1.9B、视觉语言适配器0.08B、语言模型7.7B,共计9.6B。

从图中可以看出具体的训练过程分为三步:

预训练:只优化视觉编码器和视觉语言适配器,冻结语言模型。使用大规模图像-文本配对数据,输入图像分辨率为224x224。
多任务预训练:引入更高分辨率(448x448)的多任务视觉语言数据,如VQA、文本VQA、指称理解等,进行多任务联合预训练。
监督微调:冻结视觉编码器,优化语言模型和适配器。使用对话交互数据进行提示调优,得到最终的带交互能力的Qwen-VL-Chat模型。

2、模型结构

ModuleList语言模型部分:包含32个QwenBlock,每个QwenBlock中包含1个QwenAttention和QwenMLP
ViT视觉编码器部分:包含TransformerBlock和Resampler部分: TransformerBlock包含48个VisualAttentionBlock,每个VisualAttentionBlock包含1个1664维输入的VisualAttention和1个Sequential的mlp, Resampler包含1个MultiheadAttention

下面简单从代码中对应查看一下

a. VIT视觉编码部分:

 可以查看visual.py文件

这里定义了VisionTransformer类用来提取图像特征,整体上就是一个ViT先进行特征提取,然后通过Resampler进行压缩适配。

我们可以看到,这里在117行定义了Query,使用Query和VIT的图像特征做attention计算,来进行特征压缩。

b. 语言模型部分:

可以查看modeling_qwen.py

通过多个QWenBlock叠加完成modellist的搭建。

3、模型使用

模型使用可以参考官方文档,使用HuggingFace或ModelScope都可以,建议使用ModelScope下载模

型比较快,或者下载模型后加载使用也行。

from modelscope import (snapshot_download, AutoModelForCausalLM, AutoTokenizer, GenerationConfig
)
import torch
model_id = 'qwen/Qwen-VL-Chat'
revision = 'v1.0.0'model_dir = snapshot_download(model_id, revision=revision)
torch.manual_seed(1234)tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
if not hasattr(tokenizer, 'model_dir'):tokenizer.model_dir = model_dir
# 打开bf16精度,A100、H100、RTX3060、RTX3070等显卡建议启用以节省显存
# model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", trust_remote_code=True, bf16=True).eval()
# 打开fp16精度,V100、P100、T4等显卡建议启用以节省显存
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", trust_remote_code=True, fp16=True).eval()
# 使用CPU进行推理,需要约32GB内存
# model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="cpu", trust_remote_code=True).eval()
# 默认gpu进行推理,需要约24GB显存
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", trust_remote_code=True).eval()# 指定生成超参数(transformers 4.32.0及以上无需执行此操作)
# model.generation_config = GenerationConfig.from_pretrained(model_dir, trust_remote_code=True)# 第一轮对话
# Either a local path or an url between <img></img> tags.
image_path = 'https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg'
response, history = model.chat(tokenizer, query=f'<img>{image_path}</img>这是什么', history=None)
print(response)
# 图中是一名年轻女子在沙滩上和她的狗玩耍,狗的品种是拉布拉多。她们坐在沙滩上,狗的前腿抬起来,与人互动。# 第二轮对话
response, history = model.chat(tokenizer, '输出击掌的检测框', history=history)
print(response)
# <ref>"击掌"</ref><box>(211,412),(577,891)</box>
image = tokenizer.draw_bbox_on_latest_picture(response, history)
if image:image.save('output_chat.jpg')
else:print("no box")

4、模型微调

a.准备数据

数据格式为:

[{"id": "identity_0","conversations": [{"from": "user","value": "你好"},{"from": "assistant","value": "我是Qwen-VL,一个支持视觉输入的大模型。"}]},{"id": "identity_1","conversations": [{"from": "user","value": "Picture 1: <img>https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg</img>\n图中的狗是什么品种?"},{"from": "assistant","value": "图中是一只拉布拉多犬。"},{"from": "user","value": "框出图中的格子衬衫"},{"from": "assistant","value": "<ref>格子衬衫</ref><box>(588,499),(725,789)</box>"}]},{ "id": "identity_2","conversations": [{"from": "user","value": "Picture 1: <img>assets/mm_tutorial/Chongqing.jpeg</img>\nPicture 2: <img>assets/mm_tutorial/Beijing.jpeg</img>\n图中都是哪"},{"from": "assistant","value": "第一张图片是重庆的城市天际线,第二张图片是北京的天际线。"}]}
]

其中几个特殊token,<img> </img> 代表图片地址;<ref> </ref>代表检测框标题; <box> </box>代表检测框位置(其中 (x1, y1) 和(x2, y2)分别对应左上角和右下角的坐标,并且被归一化到[0, 1000)的范围内)

b. 微调

我这里使用的lora进行的微调,需要修改.\finetune\finetune_lora_single_gpu.sh文件中的DATA地址为对应的数据集json地址。

# 单卡训练
sh finetune/finetune_lora_single_gpu.sh
# 分布式训练
sh finetune/finetune_lora_ds.sh

与全参数微调不同,LoRA和Q-LoRA的训练只需存储adapter部分的参数。假如你需要使用LoRA训练后的模型,你需要使用如下方法。你可以用如下代码读取模型:

from peft import AutoPeftModelForCausalLMmodel = AutoPeftModelForCausalLM.from_pretrained(path_to_adapter, # path to the output directorydevice_map="auto",trust_remote_code=True
).eval()

如果你觉得这样一步到位的方式让你很不安心或者影响你接入下游应用,你可以选择先合并并存储模型(LoRA支持合并,Q-LoRA不支持),再用常规方式读取你的新模型,示例如下:

from peft import AutoPeftModelForCausalLMmodel = AutoPeftModelForCausalLM.from_pretrained(path_to_adapter, # path to the output directorydevice_map="auto",trust_remote_code=True
).eval()merged_model = model.merge_and_unload()
# max_shard_size and safe serialization are not necessary. 
# They respectively work for sharding checkpoint and save the model to safetensors
merged_model.save_pretrained(new_model_directory, max_shard_size="2048MB", safe_serialization=True)

c. 微调过程的一些问题

提示不支持bf16,这是由于V100硬件不支持bf16编码,需要将fintune.sh中的参数--bf16改为False

第二个问题,这个错误提示表示,一个需要梯度的变量的视图正在使用原地操作。这意味着您正在尝试在一个变量上进行某些操作,而这个变量是不能更改的。在inplace前先clone()就可以解决这个问题

第三个问题,是训练开始时会提示没有IMAGE_ST这个属性,这个时候需要把下载下来的模型文件中的tokenization_qwen.py修改为如下,才能正确初始化这个类。

最后就是正常训练了。

 

这篇关于Qwen-VL模型微调及遇到的一些小问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

idea npm install很慢问题及解决(nodejs)

《ideanpminstall很慢问题及解决(nodejs)》npm安装速度慢可通过配置国内镜像源(如淘宝)、清理缓存及切换工具解决,建议设置全局镜像(npmconfigsetregistryht... 目录idea npm install很慢(nodejs)配置国内镜像源清理缓存总结idea npm in

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

idea突然报错Malformed \uxxxx encoding问题及解决

《idea突然报错Malformeduxxxxencoding问题及解决》Maven项目在切换Git分支时报错,提示project元素为描述符根元素,解决方法:删除Maven仓库中的resolv... 目www.chinasem.cn录问题解决方式总结问题idea 上的 maven China编程项目突然报错,是

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

前端导出Excel文件出现乱码或文件损坏问题的解决办法

《前端导出Excel文件出现乱码或文件损坏问题的解决办法》在现代网页应用程序中,前端有时需要与后端进行数据交互,包括下载文件,:本文主要介绍前端导出Excel文件出现乱码或文件损坏问题的解决办法,... 目录1. 检查后端返回的数据格式2. 前端正确处理二进制数据方案 1:直接下载(推荐)方案 2:手动构造

Python绘制TSP、VRP问题求解结果图全过程

《Python绘制TSP、VRP问题求解结果图全过程》本文介绍用Python绘制TSP和VRP问题的静态与动态结果图,静态图展示路径,动态图通过matplotlib.animation模块实现动画效果... 目录一、静态图二、动态图总结【代码】python绘制TSP、VRP问题求解结果图(包含静态图与动态图

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access