InternVL 多模态模型部署微调实践
友情链接
该文档参考InternVL垂直领域场景微调实践而写成,感谢社区同学法律人的文档。
写在前面(什么是InternVL)
InternVL 是一种用于多模态任务的深度学习模型,旨在处理和理解多种类型的数据输入,如图像和文本。它结合了视觉和语言模型,能够执行复杂的跨模态任务,比如图文匹配、图像描述生成等。通过整合视觉特征和语言信息,InternVL 可以在多模态领域取得更好的表现
InternVL 模型总览
对于InternVL这个模型来说,它vision模块就是一个微调过的ViT,llm模块是一个InternLM的模型。对于视觉模块来说,它的特殊之处在Dynamic High Resolution。
Dynamic High Resolution
InternVL独特的预处理模块:动态高分辨率,是为了让ViT模型能够尽可能获取到更细节的图像信息,提高视觉特征的表达能力。对于输入的图片,首先resize成448的倍数,然后按照预定义的尺寸比例从图片上crop对应的区域。细节如图所示。
Pixel Shuffle
Pixel Shuffle在超分任务中是一个常见的操作,PyTorch中有官方实现,即nn.PixelShuffle(upscale_factor) 该类的作用就是将一个tensor中的元素值进行重排列,假设tensor维度为[B, C, H, W], PixelShuffle操作不仅可以改变tensor的通道数,也会改变特征图的大小。
InternVL 部署微调实践
我们选定的任务是让InternVL-2B生成文生图提示词,这个任务需要VLM对图片有格式化的描述并输出。
让我们来一起完成一个用VLM模型进行冷笑话生成,让你的模型说出很逗的冷笑话吧。在这里,我们微调InterenVL使用xtuner。部署InternVL使用lmdeploy。
准备InternVL模型
我们使用InternVL2-2B模型。该模型已在share文件夹下挂载好,现在让我们把移动出来。
cd /root
mkdir -p model# cp 模型cp -r /root/share/new_models/OpenGVLab/InternVL2-2B /root/model/
准备环境
这里我们来手动配置下xtuner。
- 配置虚拟环境
conda create --name xtuner python=3.10 -y# 激活虚拟环境(注意:后续的所有操作都需要在这个虚拟环境中进行)
conda activate xtuner# 安装一些必要的库
conda install pytorch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 pytorch-cuda=12.1 -c pytorch -c nvidia -y
# 安装其他依赖
apt install libaio-dev
pip install transformers==4.39.3
pip install streamlit==1.36.0
- 安装xtuner
# 创建一个目录,用来存放源代码
mkdir -p /root/InternLM/codecd /root/InternLM/codegit clone -b v0.1.23 https://github.com/InternLM/XTuner
进入XTuner目录
cd /root/InternLM/code/XTuner
pip install -e '.[deepspeed]'
- 安装LMDeploy
pip install lmdeploy==0.5.3
- 安装验证
xtuner version##命令xtuner help
确认一下你的版本号和我们一致哦~
准备微调数据集
我们这里使用huggingface上的zhongshsh/CLoT-Oogiri-GO据集,特别鸣谢~。
@misc{zhong2023clot,title={Let's Think Outside the Box: Exploring Leap-of-Thought in Large Language Models with Creative Humor Generation},author={Zhong, Shanshan and Huang, Zhongzhan and Gao, Shanghua and Wen, Weushao and Lin, Liang and Zitnik, Marinka and Zhou, Pan},journal={arXiv preprint arXiv:2312.02439},year={2023}
}
数据集我们从官网下载下来并进行去重,只保留中文数据等操作。并制作成XTuner需要的形式。并已在share里,我们一起从share里挪出数据集。
## 首先让我们安装一下需要的包
pip install datasets matplotlib Pillow timm## 让我们把数据集挪出来
cp -r /root/share/new_models/datasets/CLoT_cn_2000 /root/InternLM/datasets/
让我们打开数据集的一张图看看,我们选择jsonl里的第一条数据对应的图片。首先我们先把这张图片挪动到InternLM文件夹下面。
cp InternLM/datasets/CLoT_cn_2000/ex_images/007aPnLRgy1hb39z0im50j30ci0el0wm.jpg InternLM/
哈哈,是两只猫在掐架。那我给到的冷笑话回复是什么呢?
InternVL 推理部署攻略
我们用LMDeploy来推理这张图片~看看它能不能成功解释出梗图呢?
使用pipeline进行推理
之后我们使用lmdeploy自带的pipeline工具进行开箱即用的推理流程,首先我们新建一个文件。
touch /root/InternLM/code/test_lmdeploy.py
cd /root/InternLM/code/
然后把以下代码拷贝进test_lmdeploy.py中。
from lmdeploy import pipeline
from lmdeploy.vl import load_imagepipe = pipeline('/root/model/InternVL2-2B')image = load_image('/root/InternLM/007aPnLRgy1hb39z0im50j30ci0el0wm.jpg')
response = pipe(('请你根据这张图片,讲一个脑洞大开的梗', image))
print(response.text)
运行执行推理结果。
python3 test_lmdeploy.py
推理后
推理出来有什么文字是纯随机的,并不一定和展示结果完全一致哦~
推理后我们发现直接使用2b模型不能很好的讲出梗,现在我们要对这个2b模型进行微调。
InternVL 微调攻略
准备数据集
数据集格式为:
# 为了高效训练,请确保数据格式为:
{"id": "000000033471","image": ["coco/train2017/000000033471.jpg"], # 如果是纯文本,则该字段为 None 或者不存在"conversations": [{"from": "human","value": "<image>\nWhat are the colors of the bus in the image?"},{"from": "gpt","value": "The bus in the image is white and red."}]}
这里我们也为大家准备好了可以直接进行微调的数据集。数据集就是咱们刚才复制进InternLM/datasets的数据。
配置微调参数
让我们一起修改XTuner下 InternVL的config,文件在:
/root/InternLM/code/XTuner/xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_qlora_finetune.py
- 需要修改的部分
最基础修改一下模型地址和数据地址即可。
- 总体config文件(复制即可)
# Copyright (c) OpenMMLab. All rights reserved.
from mmengine.hooks import (CheckpointHook, DistSamplerSeedHook, IterTimerHook,LoggerHook, ParamSchedulerHook)
from mmengine.optim import AmpOptimWrapper, CosineAnnealingLR, LinearLR
from peft import LoraConfig
from torch.optim import AdamW
from transformers import AutoTokenizerfrom xtuner.dataset import InternVL_V1_5_Dataset
from xtuner.dataset.collate_fns import default_collate_fn
from xtuner.dataset.samplers import LengthGroupedSampler
from xtuner.engine.hooks import DatasetInfoHook
from xtuner.engine.runner import TrainLoop
from xtuner.model import InternVL_V1_5
from xtuner.utils import PROMPT_TEMPLATE#######################################################################
# PART 1 Settings #
#######################################################################
# Model
path = '/root/model/InternVL2-2B'# Data
data_root = '/root/InternLM/datasets/CLoT_cn_2000/'
data_path = data_root + 'ex_cn.json'
image_folder = data_root
prompt_template = PROMPT_TEMPLATE.internlm2_chat
max_length = 6656# Scheduler & Optimizer
batch_size = 4 # per_device
accumulative_counts = 4
dataloader_num_workers = 4
max_epochs = 6
optim_type = AdamW
# official 1024 -> 4e-5
lr = 2e-5
betas = (0.9, 0.999)
weight_decay = 0.05
max_norm = 1 # grad clip
warmup_ratio = 0.03# Save
save_steps = 1000
save_total_limit = 1 # Maximum checkpoints to keep (-1 means unlimited)#######################################################################
# PART 2 Model & Tokenizer & Image Processor #
#######################################################################
model = dict(type=InternVL_V1_5,model_path=path,freeze_llm=True,freeze_visual_encoder=True,quantization_llm=True, # or Falsequantization_vit=False, # or True and uncomment visual_encoder_lora# comment the following lines if you don't want to use Lora in llmllm_lora=dict(type=LoraConfig,r=128,lora_alpha=256,lora_dropout=0.05,target_modules=None,task_type='CAUSAL_LM'),# uncomment the following lines if you don't want to use Lora in visual encoder # noqa# visual_encoder_lora=dict(# type=LoraConfig, r=64, lora_alpha=16, lora_dropout=0.05,# target_modules=['attn.qkv', 'attn.proj', 'mlp.fc1', 'mlp.fc2'])
)#######################################################################
# PART 3 Dataset & Dataloader #
#######################################################################
llava_dataset = dict(type=InternVL_V1_5_Dataset,model_path=path,data_paths=data_path,image_folders=image_folder,template=prompt_template,max_length=max_length)train_dataloader = dict(batch_size=batch_size,num_workers=dataloader_num_workers,dataset=llava_dataset,sampler=dict(type=LengthGroupedSampler,length_property='modality_length',per_device_batch_size=batch_size * accumulative_counts),collate_fn=dict(type=default_collate_fn))#######################################################################
# PART 4 Scheduler & Optimizer #
#######################################################################
# optimizer
optim_wrapper = dict(type=AmpOptimWrapper,optimizer=dict(type=optim_type, lr=lr, betas=betas, weight_decay=weight_decay),clip_grad=dict(max_norm=max_norm, error_if_nonfinite=False),accumulative_counts=accumulative_counts,loss_scale='dynamic',dtype='float16')# learning policy
# More information: https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/param_scheduler.md # noqa: E501
param_scheduler = [dict(type=LinearLR,start_factor=1e-5,by_epoch=True,begin=0,end=warmup_ratio * max_epochs,convert_to_iter_based=True),dict(type=CosineAnnealingLR,eta_min=0.0,by_epoch=True,begin=warmup_ratio * max_epochs,end=max_epochs,convert_to_iter_based=True)
]# train, val, test setting
train_cfg = dict(type=TrainLoop, max_epochs=max_epochs)#######################################################################
# PART 5 Runtime #
#######################################################################
# Log the dialogue periodically during the training process, optional
tokenizer = dict(type=AutoTokenizer.from_pretrained,pretrained_model_name_or_path=path,trust_remote_code=True)custom_hooks = [dict(type=DatasetInfoHook, tokenizer=tokenizer),
]# configure default hooks
default_hooks = dict(# record the time of every iteration.timer=dict(type=IterTimerHook),# print log every 10 iterations.logger=dict(type=LoggerHook, log_metric_by_epoch=False, interval=10),# enable the parameter scheduler.param_scheduler=dict(type=ParamSchedulerHook),# save checkpoint per `save_steps`.checkpoint=dict(type=CheckpointHook,save_optimizer=False,by_epoch=False,interval=save_steps,max_keep_ckpts=save_total_limit),# set sampler seed in distributed evrionment.sampler_seed=dict(type=DistSamplerSeedHook),
)# configure environment
env_cfg = dict(# whether to enable cudnn benchmarkcudnn_benchmark=False,# set multi process parametersmp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),# set distributed parametersdist_cfg=dict(backend='nccl'),
)# set visualizer
visualizer = None# set log level
log_level = 'INFO'# load from which checkpoint
load_from = None# whether to resume training from the loaded checkpoint
resume = False# Defaults to use random seed and disable `deterministic`
randomness = dict(seed=None, deterministic=False)# set log processor
log_processor = dict(by_epoch=False)
开始训练
这里使用之前搞好的configs进行训练。咱们要调整一下batch size,并且使用qlora。要不半卡不够用的 QAQ。
cd XTunerNPROC_PER_NODE=1 xtuner train /root/InternLM/code/XTuner/xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_qlora_finetune.py --work-dir /root/InternLM/work_dir/internvl_ft_run_8_filter --deepspeed deepspeed_zero1
合并权重&&模型转换
用官方脚本进行权重合并
如果这里你执行的epoch不是6,是小一些的数字。你可能会发现internvl_ft_run_8_filter下没有iter_3000.pth, 那你需要把iter_3000.pth切换成你internvl_ft_run_8_filter目录下的pth即可。
cd XTuner
# transfer weights
python3 xtuner/configs/internvl/v1_5/convert_to_official.py xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_qlora_finetune.py /root/InternLM/work_dir/internvl_ft_run_8_filter/iter_3000.pth /root/InternLM/InternVL2-2B/
最后我们的模型在:/root/InternLM/InternVL2-2B/,文件格式:
.
|-- added_tokens.json
|-- config.json
|-- configuration_intern_vit.py
|-- configuration_internlm2.py
|-- configuration_internvl_chat.py
|-- conversation.py
|-- generation_config.json
|-- model.safetensors
|-- modeling_intern_vit.py
|-- modeling_internlm2.py
|-- modeling_internvl_chat.py
|-- special_tokens_map.json
|-- tokenization_internlm2.py
|-- tokenizer.model
`-- tokenizer_config.json
微调后效果对比
现在我们微调好啦,让我们再来试试这张图片吧!
我们把下面的代码替换进test_lmdeploy.py中,然后跑一下效果。
from lmdeploy import pipeline
from lmdeploy.vl import load_imagepipe = pipeline('/root/InternLM/InternVL2-2B')image = load_image('/root/InternLM/007aPnLRgy1hb39z0im50j30ci0el0wm.jpg')
response = pipe(('请你根据这张图片,讲一个脑洞大开的梗', image))
print(response.text)
cd /root/InternLM/codepython3 test_lmdeploy.py
效果还不错吧~哈哈哈。
附上一些其他有意思的例子,全都不是训练集里的(:
相关文章:

InternVL 多模态模型部署微调实践
友情链接 该文档参考InternVL垂直领域场景微调实践而写成,感谢社区同学法律人的文档。 写在前面(什么是InternVL) InternVL 是一种用于多模态任务的深度学习模型,旨在处理和理解多种类型的数据输入,如图像和文本。它…...

Ruby Dir 类和方法
Ruby Dir 类和方法 Ruby 中的 Dir 类提供了用于处理目录的各种方法。这些方法允许您列出目录内容、更改当前工作目录、创建和删除目录等。本文将详细介绍 Dir 类的常用方法,并通过示例展示如何使用它们。 目录 Dir 类的简介常用方法 Dir.chdirDir.childrenDir.de…...

C++STL~~deque
文章目录 deque的概念deque的使用deque的练习总结 deque的概念 deque(双端队列):是一种序列容器、是一种双开口的"连续"空间的数据结构,双开口的含义是:可以在头尾两端进行插入和删除操作,且时间复杂度为O(1)ÿ…...

SpringCloud的学习,Consul服务注册与发现、分布式配置,以及 服务调用和负载均衡
介绍 Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。 提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,…...

闯关leetcode——26. Remove Duplicates from Sorted Array
大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ 内容 Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appear…...

基于A2C与超启发式的航天器星载自主任务规划算法-笔记
1. Actor-Critic 模块 主要文件:AC.py, PolicyNet.py, ValueNet.py作用:该模块实现了 A2C(Advantage Actor-Critic)强化学习算法。其中,ActorCritic 类是核心,它同时管理策略网络(Actor&#x…...

[机器学习]决策树
1 决策树简介 2 信息熵 3 ID3决策树 3.1 决策树构建流程 3.2 决策树案例 4 C4.5决策树 5 CART决策树(分类&回归) 6 泰坦尼克号生存预测案例 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import …...

CentOS7更换阿里云yum更新源
目前CentOS内置的更新安装源经常报错无法更新,或者速度不够理想,这个时候更换国内的镜像源就是一个不错的选择。 备份内置更新源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载阿里云repo源(需要系统…...

算法参数对拥塞控制的影响
来看看参数对公平收敛的影响。仅假象一下就知道应该是个加权公平,但事实如何,还是要具体看一下。 首先看 aimd,标准的 reno 算法是每 round 之后 cwnd 加 1,但如果有些流加 1,有些流加 2,会如何࿱…...

Go websocket
Go 中的 gorilla/websocket 是一个常用且高效的 WebSocket 实现库,可以帮助你轻松地在 Web 应用中实现实时通信。学习 gorilla/websocket 的基本用法包括建立 WebSocket 连接、发送和接收消息、处理错误、以及在实际场景中的使用。以下是关于 gorilla/websocket 的学…...

C# 委托与事件 观察者模式
委托与事件是一种观察者模式。 什么是委托与事件 在c#中,委托类似于代理,也跟其它语言的函数指针、回调函数等相似,但委托是类型安全和可靠的。声明自定义委托时,加上delegate关键字,委托定义类似于接口。 事件是特殊…...

K8S - 用service account 登陆kubectl
刚安装好k8s时 我就可以用kubectl 在master server里管理k8s的资源。 这时我们是感觉不到 k8s的用户和权限管理存在的, 但是其实用户的配置都在kubeclt 的配置文件中 /etc/kubernetes/admin.conf 中 我们可以用下命令来查看当前正在用的帐号 rootk8s-master:~/.d…...

Redis 持久化机制详解
引言 Redis 是一款基于内存的高性能键值存储系统,为了在数据丢失时能快速恢复,Redis 提供了多种持久化机制。这些持久化机制可以将内存中的数据存储到磁盘上,确保即使系统重启或宕机后也能恢复数据。Redis 支持两种主要的持久化方式…...

小阿轩yx-案例:Zabbix监控kubernetes云原生环境
小阿轩yx-案例:Zabbix监控kubernetes云原生环境 前言 传统监控的本质 就是收集、分析和使用信息来观察一段时间内监控对象的运行进度,并且进行相应的决策管理的过程,监控侧重于观察特定指标。 随着云原生时代的到来 我们对监控的功能提出…...

量化交易的个人见解
程序化交易在国内兴起有些年数了,个人以为,程序化交易与量化投资的关系,在于两者侧重点有差别。程序化交易侧重于下单的动作是机器自动执行的,量化投资则侧重于投资分析的过程是通过一个量化模型来实现的,所以量化投资…...

Java集合(一)
目录 Java集合(一) 集合介绍 单列集合分类 Collection接口 创建Collection实现类对象 常用方法 迭代器 基本使用 迭代器的执行过程 迭代器底层原理 集合中的并发修改异常及原因分析 List接口 ArrayList类 介绍 常用方法 遍历集合 Array…...

车载软件架构 --- SOA设计与应用(下)
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

网络原理 IP协议与以太网协议
博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 目录 1.网络层 IP协议 1.IP协议格式 2.地址管理 2.1 IP地址 2.2 解决IP地址不够用的问题 2.3NAT网络地址转换 2.4网段划分 3.路由选择…...

k8s的安装
k8s的安装 1.创建主机,设置ip,hostname,关闭firewalld,selinux,NetworkManager 编号主机名称ip1k8s-master192.168.118.662k8s-node01192.168.118.773k8s-node02192.168.118.88 2.设置主机之间的ssh免密 [rootk8s-master ~]# ssh-keygen [rootk8s-ma…...

Qt中样式表常用的属性名称定义
Qt中,用好样式表,不但可以做出意想不到的酷炫效果,有时候也能减轻开发量,可能由于你不了解某些样式使用,想破脑袋通过代码实现的效果,反倒不如别人用样式,一两句样式脚本就搞定。 Qt中ÿ…...

React源码学习(一):如何学习React源码
本系列源码学习,是基于 v16.13.1,v17.x与v16.x区别并不太大! 一、如何正确的学习React源码? 找到Github,转到React仓库,fork / clone源码:React 查看Readme,在Documentation中有Cont…...

云计算服务的底层,虚拟化技术的实现原理
虚拟化技术: 一、 从cpu说起, intel和amd等cpu制造商 为了提高其cpu对 虚拟化程序的运算速度, 给cpu硬件里面 增加了指令集 VMLAUNCH, VMRESUME, VMEXIT, VMXOFF 这些指令集称为硬件辅助虚拟化技术的指令集。 ---------------------…...

大数据Flink(一百一十六):Flink SQL的时间属性
文章目录 Flink SQL的时间属性 一、Flink 三种时间属性简介 二、Flink 三种时间属性的应用场景 三、SQL 指定时间属性的两种方式 四、SQL 处理时间DDL定义 五、SQL 事件时间DDL定义 Flink SQL的时…...

Ansible自动化部署kubernetes集群
机器环境介绍 1.1. 机器信息介绍 IP hostname application CPU Memory 192.168.204.129 k8s-master01 etcd,kube-apiserver,kube-controller-manager,kube-scheduler,kubelet,kube-proxy,containerd 2C 4G 192.168.204.130 k8s-w…...

网络通信流程
目录 ♫IP地址 ♫子网掩码 ♫MAC地址 ♫相关设备 ♫ARP寻址 ♫网络通信流程 ♫IP地址 我们已经知道 IP 地址由网络号主机号组成,根据 IP 地址的不同可以有5钟划分网络号和主机号的方案: 其中,各类地址的表示范围是: 分类范围适用…...

数据结构一:绪论
(一)数据结构的基本概念 1.相关名词 【1】数据 1.信息的载体,描述客观事物 2.能被输入到计算机中 3.能被计算机程序识别和处理的符号的集合。 【2】数据元素 1.数据的一个“个体” 2.数据的基本单位 3.有时候也被称为元素、结点、顶点…...

使用OpenFeign在不同微服务之间传递用户信息时失败
文章目录 起因原因解决方法: 起因 从pay-service中实现下单时,会调用到user-service中的扣减余额。 因此这里需要在不同微服务之间传递用户信息。 但是user-service中始终从始至终拿不到user的信息。 原因 在pay-service中,不仅要Enable O…...

js中【Worker】相关知识点详细解读
什么是 JavaScript 中的 Worker? JavaScript 中的 Worker 是一个可以在后台线程中运行代码的 API,这样可以避免主线程(通常是 UI 线程)被阻塞。使用 Worker 时,JavaScript 可以在多线程环境中工作,解决了单…...

使用Apify加载Twitter消息以进行微调的完整指南
# 使用Apify加载Twitter消息以进行微调的完整指南## 引言在自然语言处理领域,微调模型以适应特定任务是提升模型性能的常见方法。本文将介绍如何使用Apify从Twitter导出聊天信息,以便进一步进行微调。## 主要内容### 使用Apify导出推文首先,我…...

【C++算法】滑动窗口
长度最小的子数组 题目链接: 209. 长度最小的子数组 - 力扣(LeetCode)https://leetcode.cn/problems/minimum-size-subarray-sum/description/ 算法原理 代码步骤: 设置left0,right0设置sum0,len0遍历l…...