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

news2024/12/27 21:48:53

        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 AutoPeftModelForCausalLM

model = AutoPeftModelForCausalLM.from_pretrained(
    path_to_adapter, # path to the output directory
    device_map="auto",
    trust_remote_code=True
).eval()

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

from peft import AutoPeftModelForCausalLM

model = AutoPeftModelForCausalLM.from_pretrained(
    path_to_adapter, # path to the output directory
    device_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修改为如下,才能正确初始化这个类。

最后就是正常训练了。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式篇(DesignPattern - 行为型模式)(持续更新迭代)(图片待加载)

目录 一、模版方法模式&#xff08;制作豆浆问题&#xff09; 1. 豆浆制作问题 2. 模板方法模式 2.1. 基本介绍 2.2. 代码实现 2.3. 钩子方法 2.4. 应用案例 应用一&#xff1a;Android中View的draw 应用二&#xff1a;Spring 框架应用的源码分析 2.5. 注意事项和细节…

手持机定制方案_安卓手机主板定制_MTK联发科智能终端方案开发

手持机定制方案搭载了8核CPU&#xff0c;主频高达2.0GHz&#xff0c;并运行Android12.0操作系统。无论是多媒体播放、游戏娱乐还是多任务处理&#xff0c;均能带来极为流畅的体验。高达8GB的RAM确保应用程序和游戏可以顺畅运行&#xff0c;而256GB的内部存储空间以及支持扩展至…

Python酷库之旅-第三方库Pandas(106)

目录 一、用法精讲 461、pandas.DataFrame.lt方法 461-1、语法 461-2、参数 461-3、功能 461-4、返回值 461-5、说明 461-6、用法 461-6-1、数据准备 461-6-2、代码示例 461-6-3、结果输出 462、pandas.DataFrame.gt方法 462-1、语法 462-2、参数 462-3、功能 …

【系统架构设计师-2017年】综合知识-答案及详解

文章目录 【第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题】【第3…

【html+css 绚丽Loading】000022 三元循环轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

【Git 学习笔记_22】Git 实用冷门操作技巧(上)

文章目录 第十一章 Git 操作技巧与诀窍简介11.1 活用 git stash11.2 保存并应用 stash 第十一章 Git 操作技巧与诀窍 本章相关主题&#xff1a; 活用 git stash&#xff08;上&#xff09; ✔️保存并应用 stash&#xff08;上&#xff09; ✔️用 git bisect 进行调试使用 g…

并发性服务器

同一时刻能处理多个客户端 多进程&#xff1a; int init_tcp_ser(const char *ip,unsigned short port) {int sockfd socket(AF_INET,SOCK_STREAM,0);if(-1 sockfd){perror("fail socket");return -1;}struct sockaddr_in ser;ser.sin_family AF_INET;ser.sin_por…

【Python 千题 —— 基础篇】简易购物车

Python 千题持续更新中 …… 脑图地址 👉:⭐https://twilight-fanyi.gitee.io/mind-map/Python千题.html⭐ 题目描述 题目描述 设计一个在线购物车系统,该系统能够管理用户的购物行为。用户可以将商品添加到购物车中、移除购物车中的商品、查看购物车中的商品列表,并计算…

nerfstudio半离线配置踩坑记录

安装torch2.1.2 with cuda11.8 由于清华镜像源&#xff08;包括阿里源和豆瓣源&#xff09;都没有torch2.1.2cu118的包&#xff0c;因此只能从pytorch官网下载。 服务器上直接通过下面pip的方式安装会由于网络原因中断&#xff0c;无奈只能在本地先把torch的包下载下来再上传到…

8.Linux_Makefile

Makefile 1、基本知识 语法&#xff1a; 目标:依赖 //依赖可以是0个或多个&#xff0c;依赖之间用空格分隔命令 //命令前面必须有tab键 目标&#xff1a;最终要生成的文件依赖&#xff1a;生成目标所需要的文件命令&#xff1a;怎么样通过依赖来生成目标的 make访问mak…

pve首页查看功耗拓展脚本

作者&#xff1a;TP唉 https://www.bilibili.com/read/cv26924314/?jump_opus1 出处&#xff1a;bilibili 如图所示想要这全方位信息很难吗&#xff1f;不&#xff0c;很简单只需要在shell里粘贴两串代码轻松搞定&#xff01; 命令1&#xff1a;(curl -Lf -o /tmp/temp.sh ht…

CleanClip: macOS 上最干净的剪贴板管理工具

在日常工作中,我们经常需要复制粘贴各种内容。但是 macOS 自带的剪贴板功能非常有限,只能保存最后一次复制的内容。这就是为什么我们需要一个强大的剪贴板管理工具 - CleanClip。 CleanClip 是什么? CleanClip 是一款专为 Mac 用户设计的剪贴板管理工具&#xff0c;它可能是 …

day13JS-MoseEvent事件

1. MouseEvent的类别 mousedown &#xff1a;按下键mouseup &#xff1a;释放键click &#xff1a;左键单击dblclick &#xff1a;左键双击contextmenu &#xff1a;右键菜单mousemove &#xff1a;鼠标移动mouseover : 鼠标经过 。 可以做事件委托&#xff0c;子元素可以冒泡…

FUNCTION_ALV 下拉框的实现

下拉框可以用drdn_field或者使用DRDN_HNDL&#xff0c;这个文章主要是下拉框的基本使用&#xff0c;核心就是在fieldcat内表里面设置好下拉框的字段或者组的编号 文章目录 drdn_field使用DRDN_HNDL复制状态完整代码核心代码运行结果 drdn_field 使用DRDN_HNDL 复制状态 完整代码…

AcWing852.spfa判断负环

cnt数组表示&#xff1a;cnt【j】表示边j #include<iostream> #include<cstring> #include<algorithm> #include<queue> #define N 2010 #define M 10010 using namespace std; int n,m; int h[N],w[M],e[M],ne[M],idx; int dis[N],cnt[N]; bool st[N…

ps笔刷设置使用介绍

形状动态 建议开启&#xff0c;作用是笔刷会有粗细变换 传递 不透明度抖动 . 选择钢笔压力&#xff0c;作用就是压感&#xff0c;压力值&#xff0c;有粗细深浅轻重变化 调到这画的时候就不会特别浅 流量抖动 选择钢笔压力&#xff0c;开了就有虚边 方便画过渡。 一般画…

JavaWeb实战教程:如何一步步构建房产信息管理系统?MySQL助力数据管理

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

Unable to delete file: .....(路径) signing-config.json无法删除

运行了一个去年很久之前的项目,在打包的时候弹出这个错误,提示要删除这个json文件,尝试了很多次无法删除,最后想到可能是文件权限的问题 Execution failed for task :app:clean. > Unable to delete file: D:\xxxxxx\xxxxxx\app\build\intermediates\signing_config\debug\…

基于Python、Django的企业门户网站设计

一、框架设计 1.1 创建项目和应用 企业门户网站的结构如下图所示。 因此,在文件夹下创建hengDaProject项目。在该项目下添加homeApp、aboutApp、newsApp、productsApp、serviceApp、scienceApp、contactApp应用。该操作参见:https://blog.csdn.net/qq_42148307/article/det…

【归纳总结】常见排序算法及其实现:直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快排、归并排序

思维导图&#xff1a; 目录 思维导图&#xff1a; 一、插入排序 1.直接插入排序&#xff1a; a:基本思想&#xff1a; b:基本步骤&#xff1a; c:复杂度分析 d:Java代码实现&#xff1a; 2.希尔排序&#xff08;缩小增量排序&#xff09; a:基本思想&#xff1a; c…