1 MLLM
1.1 什么是 MLLM
多模态大语言模型(MultimodalLargeLanguageModel)是指能够处理和融合多种不同类型数据(如文本、图像、音频、视频等)的大型人工智能模型。这些模型通常基于深度学习技术,能够理解和生成多种模态的数据,从而在各种复杂的应用场景中表现出强大的能力。
常见 MLLM:国内 Qwen-VL、InterVL;国外GPT-4o、LLaVa……
多模态研究的重点:不同模态特征空间的对齐。
对齐是多模态学习中的一个关键步骤,它涉及到如何在不同的数据模态之间发现和建立对应关系。具体来说,不同模态的数据可能包含相互补充的信息,对齐就是将这些信息关联起来,使得可以从一个模态转移到另一个模态。这一过程中,特征空间的对齐是核心环节。
对齐是多模态融合的前提和基础。只有在对齐的基础上,才能有效地将不同模态的数据融合在一起,进行统一的分析和决策
实际应用案例:
- 图像描述生成:通过对齐图像和文本的特征空间,可以生成与图像内容相符的文本描述。
- 视频字幕生成:将视频中的声音和画面进行时间对齐和语义对齐,可以生成与视频内容同步的字幕。
- 跨模态检索:通过对齐不同模态的特征空间,可以实现跨模态的检索功能,如根据文本描述检索相关图像或视频。
常见的多模态架构:
1.2 Q-Former
参考 BLIP-2。BLIP-2 预训练主要分成2步:基于ViT,进行视觉和语言的表征学习;基于LLM模型,学习从图像生成文本。
1.2.1 视觉和语言表征学习
为了视觉和语言表征学习,设计了Q-Former,在视觉和语言模型之间架了一道桥,将时间特征和语言特征连接接。
为了进行表征学习,设计了3个任务:
1.图文匹配(ITM:Image-Text Matching)
这是一个分类任务,判断图像和文本描述是一对,是为1,否则为0。
分类需要正负样本,采样策略为在一个batch内寻找负样本,对于一个batch的每一个文本,根据计算的相似性权重,从当前batch选取一个(除自身外)作为负样本,相似性越高选取的概率越大
2.图文对比学习(ITC:Image-text Contrastive)
该部分和clip相同,图像和文本分别经过bert进行encoder,得到对应的特征,然后分别经过一个线性层,最后进行一致性loss计算
3.根据图像生成文本(ITG:Image-text Generation)
transfomer在decoder时,需要对token进行mask。text tokens解码是,输入【DEC】作为解码标记,然后逐token进行解码,还未解码的token先被mask住,此时的token可以看到query的信息(图文对比学习中的query embedding和图像交互得到的key和value值,Q-Former左半部分)和之前解码过的text token,但query看不到text tokens的信息。
即解码时文本可以看到图像信息和解码过的文本信息,但是图像看不到文本,解码时看着文本和图像一起进行解码,这样模型预测的文本可以从图像中学习到信息。
1.3 LLaVA
参考 Visual Instruction Tuning。
按照数据的不同,LLaVA会分开处理:
- 文本:因为是大语言模型,文本按正常方法,给大模型处理即可
- 图片:使用CLIP-ViT转化为向量,再通过一个线性层Projection转换到大模型的理解空间,然后输入到大模型
模型的组成:
- 视觉编码器(Vision Encoder):LLaVa 架构的视觉部分是预训练的 CLIP 视觉编码器,具体来说是 ViT-L/14 变体。该组件通过 Transformer 层处理输入图像 (Xv) 以提取特征 (Zv),使模型能够有效地理解视觉信息
- 大语言模型 (Vicuna):LLaVa 的语言能力依赖于 Vicuna,它是大型语言模型 (LLM) 的一种。Vicuna 根据输入语言指令 (Xq) 理解并生成语言响应 (Xa),补充视觉编码器的功能
- 线性投影(Projection):此组件充当视觉特征 (Zv) 和语言模型的嵌入空间之间的桥梁。它将视觉特征转换为视觉标记 (Hv),并将其与语言模型的词嵌入空间对齐,以促进多模态对话
1.3.1 LLaVA-1.5-HD
参考论文Improved Baselines with Visual Instruction Tuning
LLaVA-1.5 在 LLaVA 的基础上改进:
- 使用 CLIP-ViT-L-336px 视觉编码器替换原先的 CLIP-ViT-L/14
- 将原先的一层线性层替换为 MLP 层(两层线性层)
此外,为了支持更高的图像分辨率(可以提升模型的性能)且不影响 LLaVA-1.5 的推理效率,在 LLaVA-1.5 的基础上提出了 LLaVA-1.5-HD,它采用了创新的AnyRes策略,可以接受各种高分辨率的图像作为输入。具体步骤如下:
- 首先高分辨率图像被智能分割成多个小块(Patch),以便单独处理每个块。例如,CLIP-ViT-L/14型号的视觉编码器能够处理的最大分辨率为224x224像素。
- 同时,将高分辨率图像调整至视觉编码器能够处理的尺寸,并利用编码器对其进行编码。
将上面两步的结果拼接在一起作为视觉特征,输入到LLM。
1.3.2 LLaVA-NeXT
参考 LLaVA-NeXT
LLaVA-NeXT 是 LLaVA-1.5-HD的升级版,采用了动态的分辨率策略,预设了多种长宽比
与LLaVA-1.5相比,LLaVA-NeXT有以下几点改进:
-
将输入图像分辨率增加到4倍以上的像素。这使它能够掌握更多的视觉细节。它支持三种宽高比,高达672x672, 336x1344, 1344x336分辨率。
-
更好的视觉推理和OCR能力,改进的视觉指令调优数据混合。
-
为更多场景提供更好的可视化对话,涵盖不同的应用程序。更好的世界知识和逻辑推理能力。
-
使用SGLang进行高效部署和推理。
Q-Former与LLaVA对比
-
收敛速度:Q-Former的参数量较大(例如BLIP-2中的100M参数),导致其
在训练过程中收敛速度较慢。相比之下,MLP作为connector的模型(如
LLaVA-1.5)在相同设置下能够更快地收敛,并且取得更好的性能。 -
性能收益:在数据量和计算资源充足的情况下,Q-Former并没有展现出
明显的性能提升。即使通过增加数据量和计算资源,Q-Former的性能提升也并
不显著,无法超越简单的MLP方案。 -
baseline setting:LLaVA-1.5通过改进训l练数据,在较少的数据量和计
算资源下取得了优异的性能,成为了一个强有力的baseline。相比之下,BLIP2
的后续工作InstructBLIP在模型结构上的改进并未带来显著的性能提升,且无法
推广至多轮对话。 -
模型结构的简洁性:LLaVA系列采用了最简洁的模型结构,而后续从模型结构上
进行改进的工作并未取得明显的效果。这表明,在当前的技术和数据条件下,简
洁的模型结构可能更为有效。
2 MLLM: InterVL
参考:InterVL、InterVL2
书生·万象多模态大模型(InternVL 2.0)。关键评测指标比肩国际顶尖商用闭源模型,支持图像、视频、文本、语音、三维、医疗多种模态支持百种下游任务,性能媲美任务专用模型。
InterVL2的模型结构包括视觉(vision)模块和语言模型(LLM)模块。其中,视觉模块是一个微调过的ViT模型,而语言模型模块则是一个InternLM的模型。
2.1 架构设计
InterVL采用LLaVA式架构设计(ViT-MLP-LLM):
- 基座大模型:InternLM2.5
- 视觉编码器:InternViT
- 对齐模块:MLP
2.1.1 视觉编码器 InternViT
InternViT-6B-448px-V1.2
- 倒数第四层特征最有用,砍掉后三层,共45层
- 分辨率从224扩展到448
- 与LLM联合训练时,在captioning和OCR数据集上训练,获取高分辨率和OCR能力
2.1.2 Pixel shuffle
- Why:448 * 448的图,patch大小为14 * 14,得到32 * 32=1024个patch,即视觉插入1024个token。这些信息有较大余消耗较多的计算资源,对长的多模态上下文拓展不利。
- What:Pixelshuffle技术来自超分那边,是把不同通道的特征拿出来,拼到一个通道上,从(N,C×r²,H,W)转化为(N,C,H×r,W×r)。r是上采样因子。
- How:这里把采样因子设为0.5,就可以把(4096 * 0.5 * 0.5,32, 32)的图像特征转化为(4096,32 * 0.5,32 * 0.5),下采样到256个token了。
2.1.3 Dynamic High-Resolution
动态分辨率的设计,使得模型可以处理各种分辨率的情景。
2.1.4 Multitask output
- 利用VisionLLMv2的技术,初始化了一些任务特化embedding(图像生成、分割、检测),添加了一些任务路由token
- 训练下游任务特化embedding,生成路由token时,把任务embedding拼在路由embedding后面,送给LLM拿到hidden_state
- 把hidden_state送给路由到的解码器中,生成图像/bounding box/masks
2.2 训练
- 第一阶段:训练MLP,用高质量预训练数据(各种视觉任务)
- 第二阶段:视觉指令微调,ViT+MLP+LLM联合训练,用高质量视觉-文本指令任务
3 InternVL 部署微调实践
3.1 训练环境配置
新建虚拟环境并进入:
conda create --name xtuner-env python=3.10 -y
conda activate xtuner-env
"xtuner-env"为训练环境名,可以根据个人喜好设置,在本教程中后续提到训练环境均指"xtuner-env"环境。
安装与deepspeed集成的xtuner和相关包:
pip install xtuner==0.1.23 timm==1.0.9
pip install 'xtuner[deepspeed]'
pip install torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1 --index-url https://download.pytorch.org/whl/cu121
pip install transformers==4.39.0 peft==0.13.2
训练环境既为安装成功。
配置推理所需环境:
conda create -n lmdeploy python=3.10 -y
conda activate lmdeploy
pip install lmdeploy==0.6.1 gradio==4.44.1 timm==1.0.9
"lmdeploy"为推理使用环境名。
3.2 LMDeploy部署
3.2.1 LMDeploy基本用法介绍
我们主要通过pipeline.chat 接口来构造多轮对话管线,核心代码为:
## 1.导入相关依赖包
from lmdeploy import pipeline, TurbomindEngineConfig, GenerationConfig
from lmdeploy.vl import load_image
## 2.使用你的模型初始化推理管线
model_path = "your_model_path"
pipe = pipeline(model_path,
backend_config=TurbomindEngineConfig(session_len=8192))
## 3.读取图片(此处使用PIL读取也行)
image = load_image('your_image_path')
## 4.配置推理参数
gen_config = GenerationConfig(top_p=0.8, temperature=0.8)
## 5.利用 pipeline.chat 接口 进行对话,需传入生成参数
sess = pipe.chat(('describe this image', image), gen_config=gen_config)
print(sess.response.text)
## 6.之后的对话轮次需要传入之前的session,以告知模型历史上下文
sess = pipe.chat('What is the woman doing?', session=sess, gen_config=gen_config)
print(sess.response.text)
3.2.2 网页应用部署体验
我们可以使用UI界面先体验与InternVL对话:
拉取本教程的github仓库https://github.com/Control-derek/InternVL2-Tutorial.git:
git clone https://github.com/Control-derek/InternVL2-Tutorial.git
cd InternVL2-Tutorial
demo.py文件中,MODEL_PATH处传入InternVL2-2B的路径,如果使用的是InternStudio的开发机则无需修改,否则改为模型路径。
上述命令请在vscode下运行,因为vscode自带端口转发,可以把部署在服务器上的网页服务转发到本地。
启动后,CTRL+鼠标左键点进这个链接或者复制链接到浏览器。
会看到如下界面:
点击Start Chat即可开始聊天,下方食物快捷栏可以快速输入图片,输入示例可以快速输入文字。输入完毕后,按enter键即可发送。
3.3 XTuner微调实践
3.3.1 配置文件
cd /root/xtuner
conda activate xtuner-env # 或者是你自命名的训练环境
原始internvl的微调配置文件在路径./xtuner/configs/internvl/v2下,假设上面克隆的仓库在/root/InternVL2-Tutorial,复制配置文件到目标目录下:
cp /root/InternVL2-Tutorial/xtuner_config/internvl_v2_internlm2_2b_lora_finetune_food.py /root/xtuner/xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_lora_finetune_food.py
3.3.2 数据集下载
huggingface下载此数据集:FoodieQA。该数据集为了防止网络爬虫污染测评效果,需要向提交申请后下载使用。
由于原始数据集格式不符合微调需要格式,需要处理方可使用,在InternVL2-Tutorial下,运行:
python process_food.py
即可把数据处理为XTuner所需格式。注意查看input_path和output_path变量与自己下载路径的区别。
3.3.3 开始微调
运行命令,开始微调:
xtuner train /root/xtuner/xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_lora_finetune_food.py --deepspeed deepspeed_zero2 --work-dir ./work_dirs/
看到有日志输出,即为启动成功:
微调后,把模型checkpoint的格式转化为便于测试的格式:
python xtuner/configs/internvl/v1_5/convert_to_official.py xtuner/configs/internvl/v2/internvl_v2_internlm2_2b_lora_finetune_food.py ./work_dirs/internvl_v2_internlm2_2b_lora_finetune_food/iter_640.pth ./work_dirs/internvl_v2_internlm2_2b_lora_finetune_food/lr35_ep10/
如果修改了超参数,iter_xxx.pth需要修改为对应的想要转的checkpoint。
./work_dirs/internvl_v2_internlm2_2b_lora_finetune_food/lr35_ep10/
为转换后的模型checkpoint保存的路径。
3.3.4 使用微调后的模型
修改MODEL_PATH为刚刚转换后保存的模型路径:
cd /root/InternVL2-Tutorial
conda activate lmdeploy
python demo.py
微调前模型对锅包肉的识别:
微调后模型对锅包肉的识别: