微信搜索superit|邀请体验:大数据, 数据管理、OLAP分析与可视化平台 | 赞助作者:赞助作者

Qwen-VL多模态大模型的微调与部署

架构 aide_941 1℃ 0评论

1. Qwen-VL简介

Qwen-VL 是阿里云研发的大规模视觉语言模型(Large Vision Language Model, LVLM)。Qwen-VL 可以以图像、文本、检测框作为输入,并以文本和检测框作为输出。

Qwen-VL-Chat = 大语言模型(Qwen-7B) + 视觉图片特征编码器(Openclip ViT-bigG) + 位置感知视觉语言适配器(可训练Adapter)+ 1.5B的图文数据 + 多轮训练 + 对齐机制(Chat)

Qwen-VL 系列模型的特点包括:

  • 多语言对话模型:天然支持英文、中文等多语言对话,端到端支持图片里中英双语的长文本识别;
  • 多图交错对话:支持多图输入和比较,指定图片问答,多图文学创作等;
  • 开放域目标定位:通过中文开放域语言表达进行检测框标注;
  • 细粒度识别和理解:448分辨率可以提升细粒度的文字识别、文档问答和检测框标注。

2. 硬件配置及部署要求

  • 微调训练的显存占用及速度如下(BS=1),可根据显存大小调整Sequence Length参数
Method Speed (512 Sequence Length) Mermory (512 Sequence Length)
LoRA (Base) 2.4s/it 37.3GB
LoRA (Chat) 2.3s/it 23.6GB
Q-LoRA 4.5s/it 17.2GB
  • 推理阶段的显存占用及速度如下
Quantization Speed (2048 tokens) Mermory (2048 tokens)
BF16 28.87 22.60GB
Int4 37.79 11.82GB
  1. A100、H100、RTX3060、RTX3070等显卡建议启用bf16精度以节省显存
  2. V100、P100、T4等显卡建议启用fp16精度以节省显存
  3. 使用CPU进行推理,需要约32GB内存,默认GPU进行推理,需要约24GB显存
  4. 软件环境配置
$ curl -O https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh   // 从官网下载安装脚本
$ bash Anaconda3-2019.03-Linux-x86_64.sh           // 阅读协议确认安装,安装完成后再输入yes以便不需要手动将Anaconda添加到PATH
$ conda create -n qwen_vl python=3.10            // 安装虚拟环境, python 3.10及以上版本
$ conda activate qwen_vl                         // 激活虚拟环境
$ conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=11.8 -c pytorch -c nvidia // pytorch 2.0及以上版本, 建议使用CUDA 11.4及以上

3. 快速使用及模型下载地址

利用 ModelScope 和 Transformers 快速使用 Qwen-VL 和 Qwen-VL-Chat。

  1. 安装相关的依赖库
pip3 install -r requirements.txt
pip3 install -r requirements_openai_api.txt
pip3 install -r requirements_web_demo.txt
pip3 install deepspeed
pip3 install peft
pip3 install optimum
pip3 install auto-gptq
pip3 install modelscope -U

2. 各模型文件的下载

建议先从 ModelScope 下载模型及代码至本地,再从本地加载模型:

import os
os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"

from modelscope import snapshot_download
from transformers import AutoModelForCausalLM, AutoTokenizer

# 其中版本v1.1.0支持INT4、INT8的在线量化,其余版本不支持
model_id = 'qwen/Qwen-VL-Chat'

revision = 'v1.0.0' 

# 下载模型到指定目录
local_dir = "/root/autodl-tmp/Qwen-VL-Chat"

snapshot_download(repo_id=model_id, revision=revision, local_dir=local_dir)

也可手动下载,下载地址如下:

3. Qwen-VL-chat 推理使用

第一种通过网页端Web UI使用:

# 启动命令,局域网访问
python web_demo_mm.py --server-name 0.0.0.0

第二种通过代码使用:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig
import torch
torch.manual_seed(1234)

# 请注意:根据显存选择配置,分词器默认行为已更改为默认关闭特殊token攻击防护。
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-VL-Chat", trust_remote_code=True)

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-VL-Chat", device_map="auto", trust_remote_code=True, bf16=True, fp16=Flase).eval()

# 第一轮对话
query = tokenizer.from_list_format([
    {'image': 'https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg'}, # Either a local path or an url
    {'text': '这是什么?'},
])
response, history = model.chat(tokenizer, query=query, history=None)
print(response)
# 图中是一名女子在沙滩上和狗玩耍,旁边是一只拉布拉多犬,它们处于沙滩上。

# 第二轮对话
response, history = model.chat(tokenizer, '框出图中击掌的位置', history=history)
print(response)
# <ref>击掌</ref><box>(536,509),(588,602)</box>

4. 自定义数据微调

提供了finetune.py这个脚本供用户实现在自己的数据上进行微调的功能,以接入下游任务。此外还提供了shell脚本减少用户的工作量。这个脚本支持 DeepSpeed 和 FSDP 。

4.1 训练数据准备

需要将所有样本数据放到一个列表中并存入JSON文件中。每个样本对应一个字典,包含id和conversation,其中后者为一个列表。示例如下所示:

[
  {
    "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": "第一张图片是重庆的城市天际线,第二张图片是北京的天际线。"
      }
    ]
  }
]

对数据格式的解释:

  • 为针对多样的VL任务,增加了一下的特殊tokens: <img> </img> <ref> </ref> <box> </box>.
  • 对于带图像输入的内容可表示为 Picture id: <img>img_path</img>\n{your prompt},其中id表示对话中的第几张图片。”img_path”可以是本地的图片或网络地址。
  • 对话中的检测框可以表示为<box>(x1,y1),(x2,y2)</box>,其中 (x1, y1) 和(x2, y2)分别对应左上角和右下角的坐标,并且被归一化到[0, 1000)的范围内. 检测框对应的文本描述也可以通过<ref>text_caption</ref>表示。

4.2 对模型进行LoRA微调

微调脚本能够帮你实现:

  • 全参数微调,不支持单卡训练,且需确认机器是否支持bf16 sh finetune/finetune_ds.sh
  • LoRA
  • Q-LoRA

1. LoRA微调

使用官方项目里提供的微调脚本进行LoRA微调测试,模型采用HuggingFace下载的那个全精度模型,数据采用上面的示例数据,建议模型路径使用绝对路径,如果你想节省显存占用,可以考虑使用chat模型进行LoRA微调,显存占用将大幅度降低。

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

#!/bin/bash

export CUDA_DEVICE_MAX_CONNECTIONS=1
DIR=</span><span class="nb">pwd</span><span class="sb">

MODEL="/root/autodl-tmp/Qwen-VL-Chat"
DATA="/root/autodl-tmp/data.json"

export CUDA_VISIBLE_DEVICES=0

python3 finetune.py \
    --model_name_or_path $MODEL \
    --data_path $DATA \
    --bf16 True \
    --fix_vit True \
    --output_dir output_qwen \
    --num_train_epochs 5 \
    --per_device_train_batch_size 1 \
    --per_device_eval_batch_size 1 \
    --gradient_accumulation_steps 8 \
    --evaluation_strategy "no" \
    --save_strategy "steps" \
    --save_steps 1000 \
    --save_total_limit 10 \
    --learning_rate 1e-5 \
    --weight_decay 0.1 \
    --adam_beta2 0.95 \
    --warmup_ratio 0.01 \
    --lr_scheduler_type "cosine" \
    --logging_steps 1 \
    --report_to "none" \
    --model_max_length 600 \
    --lazy_preprocess True \
    --gradient_checkpointing \
    --use_lora

注意事项:

  • 需要修改脚本中的MODEL、DATA参数,将其换成实际的模型和数据地址
  • 需要修改脚本里的model_max_length参数,默认是2048,这需要27.3GB的显存

2. Q-LoRA微调,仅支持fp16

如果你依然遇到显存不足的问题,可以考虑使用Q-LoRA (论文)。该方法使用4比特量化模型以及paged attention等技术实现更小的显存开销。运行Q-LoRA你只需运行如下脚本:

# 单卡训练
sh finetune/finetune_qlora_single_gpu.sh
# 分布式训练
sh finetune/finetune_qlora_ds.sh

3. 模型合并及推理

与全参数微调不同,LoRA和Q-LoRA的训练只需存储adapter部分的参数。因此需要先合并并存储模型(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)

引用及参考

[1] Qwen-VL预训练大语言视觉模型

[2] 可以成功Lora微调的Qwen-VL模型

[3] Qwen-VL模型微调

[4] Qwen-VL多模态大模型的部署与微调

[5] 1张图片+3090显卡微调

[6] 中文视觉语言模型+本地部署

转载请注明:SuperIT » Qwen-VL多模态大模型的微调与部署

喜欢 (0)or分享 (0)

您必须 登录 才能发表评论!