【多模态】swift框架使用qwen2-vl

前言

前几篇里面学习了常见的一些多模态模型的典型架构和源代码,上一篇里面测试使用了minicpm-v系列模型,在尝试RLHF的时候发现swift特别好用特别全,记录一下对swift的一些使用,欢迎批评指正~

前一篇里面写了minicpm-v的使用方法,这里主要记录qwen2-vl的使用。

1.swift安装

  • python可以安装3.10版本
  • 就在这几天swift更新了3.0版本,本文使用的是swift的2.6.0版本/2.5.0版本,据群里面说swift的3.0是大更新可能差别挺大的
  • 安装方法(同时在这里安装flash-attention和vllm)
bash 复制代码
conda create -n swift pyhton==3.10
pip install torch torchvision
pip install flash-attn vllm qwen_vl_utils optimum transformers==4.46.1
pip install 'ms-swift[llm]' -U

2.模型微调

2.1 SFT

一定要注意,使用qwen2-vl需要指定MAX_PIXELS,脚本里面是MAX_PIXELS,py里面是max_pixels,602112=7682828,这个值越大模型看图片看得越清楚,显存开销越大,如果不指定,默认是非常大的可能直接爆显存了

bash 复制代码
NPROC_PER_NODE=1 CUDA_VISIBLE_DEVICES=0 MAX_PIXELS=602112 swift sft \
--model_type qwen2-vl-7b-instruct \
--model_id_or_path 模型路径 \
--dataset data.jsonl \
--sft_ype lora \
--use_flash_attn true \ # 提速
--batch_size 2 \
--lora_target_modules DEFAULT \
--output_dir qwen_lora \
--max_steps 3000 \
--save_total_limit 2 \
--logging_steps 10 \
--gradient_checkpointing false # true的话训练变慢

swift和minivpm-v不一样,使用jsonl格式的数据,类似这样,<image>表示这个位置有一张图,图在后面的images里面指定:

bash 复制代码
#jsonl格式的数据
{"query": "<image>55555", "response": "66666", "images": ["image_path"]}
{"query": "eeeee<image>eeeee<image>eeeee", "response": "fffff", "history": [], "images": ["image_path1", "image_path2"]}
{"query": "EEEEE", "response": "FFFFF", "history": [["query1", "response2"], ["query2", "response2"]], "images": []}
  • 注意swift里面如果要微调的目标模块使用正则表达式,就要使用target_regex来指定,例如qwen2-vl的指定--target_regex "^(model)(?!.(lm_head|output|emb|wte|shared|mlp|norm))." \
  • 或者--target_regex "model...*layers.\d+.self_attn.(q_proj|k_proj|v_proj|o_proj)"类似这样的,可以具体看文档和模型结构

2.2 merge lora

在SFT之后合并文件,输出的结果会在运行完之后显示,默认在lora结果存储路径里面有一个-merge的文件夹

bash 复制代码
#!/bin/bash
CUDA_VISIBLE_DEVICES=0 swift export \
    --ckpt_dir lora结果存储路径 \
    --merge_lora true

2.3 RLHF

支持CPO/DPO/SimPO等,具体参考官方文档

bash 复制代码
#!/bin/bash
source activate vllm
 
CUDA_VISIBLE_DEVICES=0 \
swift rlhf \
    --rlhf_type cpo \
    --model_type  minicpm-v-v2_6-chat \ # 模型类型,可以在官方文档支持的模型里面找,或者报错了在报错信息里面找哈哈哈
    --model_id_or_path 模型存储路径/ \
    --beta 0.1 \
    --rpo_alpha 0.1 \
    --sft_type  lora \
    --dataset dataset_dpo.jsonl \
    --lora_target_modules  DEFAULT  \
    --max_steps 500 \
    --save_steps 250 \
    --batch_size  2  \
    --learning_rate  5e-5  \
    --gradient_checkpointing false \
    --warmup_ratio  0.03  \
    --save_total_limit  2 \
    --output_dir output \
    --logging_steps 10

注意RHLF的数据集格式:

bash 复制代码
{"system": "123", "query": "11111", "response": "22222", "rejected_response": "33333", "images": ["image_path"], "history": [["query1", "response1"], ["query2", "response2"]]}
{"system": "123", "query": "aaaaa", "response": "bbbbb", "rejected_response": "ccccc", "images": ["image_path"], "history": [["query1", "response1"], ["query2", "response2"]]}
{"system": "123", "query": "AAAAA", "response": "BBBBB", "rejected_response": "CCCCC", "images": ["image_path"], "history": [["query1", "response1"], ["query2", "response2"]]}

3. 模型量化和推理

3.1 qwen2-vl量化

  • qwen2-vl的int4的模型qlora微调后不支持merge并且推理很慢,官方推荐先lora在merge再量化
  • 原始模型微调后,不支持autoawq量化,支持gptq量化,同样需要指定最大像素,否则爆显存
  • gptq量化时load_dataset_config为true使用训练时候的数据集来进行量化
  • gptq量化后准确率损失不大
bash 复制代码
CUDA_VISIBLE_DEVICES=0 MAX_PIXELS=1003520 swift export \
    --ckpt_dir '训练好的模型路径' \
    --merge_lora true --quant_bits 4 \
    --load_dataset_config true --quant_method gptq

3.2 模型推理

python 复制代码
-----flash-attn用于swift推理
kwargs = {}
# kwargs['use_flash_attn'] = True  # use flash_attn
model_id_or_path = None
model, tokenizer = get_model_tokenizer(model_type, model_id_or_path=model_id_or_path,
                                       model_kwargs={'device_map': 'auto'}, **kwargs)
                                       
----flash-attn用于qwen2-vl
model_name = "。。。。。。"
model = Qwen2VLForConditionalGeneration.from_pretrained(model_name, torch_dtype="auto", device_map="auto",attn_implementation="flash_attention_2")
model.eval()


-----minicpm-v的推理也flash-attention-2加速
model = AutoModel.from_pretrained('。。。。。。', trust_remote_code=True,attn_implementation='flash_attention_2')

3.3 CLI推理

数据集格式和训练集一样

bash 复制代码
{"query": "<image>55555", "response": "66666", "images": ["image_path"]}
{"query": "eeeee<image>eeeee<image>eeeee", "response": "fffff", "history": [], "images": ["image_path1", "image_path2"]}
{"query": "EEEEE", "response": "FFFFF", "history": [["query1", "response2"], ["query2", "response2"]], "images": []}

推理脚本,里面的val_dataset是待推理的数据集,result_dir是输出的结果保存的地址,输出的是一个jsonl文件

bash 复制代码
CUDA_VISIBLE_DEVICES=0 MAX_PIXELS=602112 swift infer --ckpt_dir 模型地址 --use_flash_attn true --val_dataset data_need_infer.jsonl --save_result true --result_dir result_output
相关推荐
德林恩宝几秒前
从深度图到 3D 网格与点云:完整实现
人工智能·计算机视觉·3d
程序边界20 分钟前
ChatGPT 4:解锁AI文案、绘画与视频创作新纪元
人工智能·chatgpt·音视频
有颜有货1 小时前
数字产业化和产业数字化到底是什么?
大数据·人工智能·产业数字化·数字产业化
ai-guoyang1 小时前
tensorflow gpu版安装(直接anaconda虚拟环境中配置cuda,无需主机安装cuda、cudnn)
深度学习·tensorflow·cuda·anaconda
ai_xiaogui1 小时前
【AIStarter】告别复杂转换 - MinerU整合包实现PDF到Markdown的无缝转变
人工智能·ai作画·pdf·语音识别·ai写作·ai软件
正在走向自律2 小时前
探秘 AI Agent 之 Coze 智能体:从简介到搭建全攻略(4/30)
人工智能·coze·扣子·ai ggent
lyw_YTU_Sussex2 小时前
深度学习day4|用pytorch实现猴痘病识别
人工智能·pytorch·深度学习
SunkingYang2 小时前
做T和做T+0有什么区别
大数据·人工智能·区块链·股票·关系·做t·t+0
香港科大商学院内地办事处2 小时前
港科夜闻 | 香港科大与荷兰代尔夫特理工大学(TU Delft)建立合作伙伴关系,推动艺术科技教育与研究...
大数据·人工智能·科技