当前位置: 首页 > news >正文

(第三期)书生大模型实战营——InternVL(冷笑话大师)部署微调实践

任务

  • follow 教学文档和视频使用QLoRA进行微调模型,复现微调效果,并能成功讲出梗图.
  • 尝试使用LoRA,或调整xtuner的config,如LoRA rank,学习率。看模型Loss会如何变化,并记录调整后效果

InternVL

InternVL 是一种用于多模态任务的深度学习模型,旨在处理和理解多种类型的数据输入,如图像和文本。它结合了视觉和语言模型,能够执行复杂的跨模态任务,比如图文匹配、图像描述生成等。通过整合视觉特征和语言信息,InternVL 可以在多模态领域取得更好的表现。

InternVL 模型总览

在这里插入图片描述
对于InternVL这个模型来说,它vision模块就是一个微调过的ViT,llm模块是一个InternLM的模型。对于视觉模块来说,它的特殊之处在Dynamic High Resolution。

Dynamic High Resolution

动态高分辨率,为了让ViT模型能够尽可能获取到更细节的图像信息,提高视觉特征的表达能力。对于输入的图片,首先resize成448的倍数,然后按照预定义的尺寸比例从图片上crop对应的区域。细节如图所示。
在这里插入图片描述

Pixel Shuffle

Pixel Shuffle在超分任务中是一个常见的操作,PyTorch中有官方实现,即nn.PixelShuffle(upscale_factor) 该类的作用就是将一个tensor中的元素值进行重排列,假设tensor维度为[B, C, H, W], PixelShuffle操作不仅可以改变tensor的通道数,也会改变特征图的大小。

InternVL 部署微调实践

准备InternVL模型

cd /root
mkdir -p modelcp -r /root/share/new_models/OpenGVLab/InternVL2-2B /root/model/

准备环境

  • 配置虚拟环境
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数据集
在这里插入图片描述
数据集我们从官网下载下来并进行去重,只保留中文数据等操作。并制作成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/007aPnLRgy1go3ja52bvaj30ci0el7d7.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

# 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 = 1
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。

NPROC_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

在这里插入图片描述

合并权重&&模型转换

用官方脚本进行权重合并

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

微调后效果对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关文章:

  • BUG——imx6u开发_结构体导致的死机问题(未解决)
  • Redis 有序集合【实现排行榜】
  • 【ARM+Codesys 客户案例 】基于RK3568/A40i/STM32+CODESYS开发的控制器在自动输送分拣系统上的应用,支持定制
  • 大数据开发工程师面试整理-性能优化
  • 细数目标管理的坑:避免陷阱,实现高效执行
  • Oracle-OraclePartition
  • Unity | 游戏开发中的优化思维
  • 使用微软Detours库进行DLL注入
  • 【JAVA】阿里巴巴 EasyExcel:高效的Excel处理解决方案
  • 【java】RuoYi-Vue前后端分离版本-登陆请求流程解析
  • OpenAI推出GPT-4o微调功能
  • Nuitka 打包 exe 软件步骤
  • JSON, YAML, XML, CSV交互可视化
  • 设计模式六大原则(一)--单一职责原则
  • 一站式NVR模组解决方案:基于海思 3520D芯片的完整源码与系统集成
  • Docker容器管理
  • exports和module.exports
  • httpie使用详解
  • Java的Interrupt与线程中断
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • React as a UI Runtime(五、列表)
  • SwizzleMethod 黑魔法
  • Swoft 源码剖析 - 代码自动更新机制
  • Twitter赢在开放,三年创造奇迹
  • 二维平面内的碰撞检测【一】
  • 复杂数据处理
  • 那些被忽略的 JavaScript 数组方法细节
  • 小程序01:wepy框架整合iview webapp UI
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 第二十章:异步和文件I/O.(二十三)
  • 回归生活:清理微信公众号
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #includecmath
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #数据结构 笔记三
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (1) caustics\
  • (4) PIVOT 和 UPIVOT 的使用
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (编译到47%失败)to be deleted
  • (二)fiber的基本认识
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (附源码)ssm高校志愿者服务系统 毕业设计 011648
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (十五)Flask覆写wsgi_app函数实现自定义中间件
  • (五)MySQL的备份及恢复
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)基于IDEA的JAVA基础1
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)winform之ListView
  • (转)机器学习的数学基础(1)--Dirichlet分布