两类多模态大模型
原生多模特模型和多个单模型拼接
原生多模态模型意味着这些模型是从一开始的设计阶段,就是用于处理多种模态(包括文本、图像、音频、视频等)的数据。
把不同的单个模型拼接起来使得模型具备多模态能力这种做法也比较好理解,比如之前社区开源的Qwen-VL[1],它就是 Qwen-7B + Openclip ViT-bigG(2.54B)的结构,前者作为LLM基础模型,后者作为视觉模型,因此Qwen-VL也支持图像、文本多模态输入。
在数据融合方面,来自不同模态的数据在模型内部被有效地融合,这样可以更好地理解数据间的关联和相互作用。而对于单个模型拼接,不同模态的处理通常是独立进行的,然后在某个阶段再把数据融合到一起。这种做法相对来说会使不同模态之间的信息融合不够紧密,协调性较差。
体现在模型能力上,原生多模态模型可以在整个模型中共享特征和学习策略,有助于捕获跨模态特征间的复杂关系。所以它们通常在执行跨模态任务时表现更好,例如图文匹配、视觉问答或多模态翻译。
但这是整体来说的,具体原生设计并训练的模型是否能产生一个在每个领域都具有强大能力的模型也是一个很难确定的问题。
Gemini
Gemini 模型专为多模态应用而设计。Gemini 模型接受包含文本和图片等提示,然后返回文本响应。Gemini 还支持函数调用,让开发者可以传递函数的说明,然后模型会返回与说明最匹配的函数和参数。然后,开发者可以在外部 API 和服务中调用该函数。
即将推出针对 Gemini 的微调。
Gemini Pro 和 Gemini Pro Vision 可在亚洲和美国区域使用。
Vertex AI Gemini API 专为开发者和企业设计,用于扩缩部署。它提供企业安全性、数据驻留、性能和技术支持等功能。如果您已经是 Google Cloud 客户或部署了大中型应用,那您就来对地方了。
优劣
Gemini 适用于各种多模态应用场景,包括但不限于:
使用场景 | 说明 |
---|---|
信息挖掘 | 将世界知识与从图片和视频中提取的信息融合。 |
对象识别 | 回答与对图片和视频中的对象进行精细识别相关的问题。 |
数字内容理解 | 回答问题并从信息图、图表、图形、表格和网页等各种内容中提取信息。 |
结构化内容生成 | 根据提供的提示说明,以 HTML 和 JSON 等格式生成响应。 |
字幕/说明 | 生成具有不同细节级别的图片和视频说明。我们建议您从以下图片/视频提示开始,从此处迭代操作以获取更具体的说明。 - 图片:“您能编写关于图片的说明吗?” - 视频:“您能编写这个视频所发生情况的说明吗?” |
推断结果 | 根据位置推荐其他可看到的内容,在图片或视频之后/之前/之间可能发生的情况,并实现创造性用途,例如根据视觉输入编写故事。 |
虽然强大,但 Gemini 存在局限性。它在图片、长视频和复杂的指令等方面难以确定精确的对象位置。不适用于医疗用途或聊天机器人。
限制 | 说明 |
---|---|
空间推理 | 难以对图片进行精确的对象/文本定位。它对理解旋转图片的准确率可能较低。 |
计数 | 只能提供对象数量的粗略近似值,尤其是对于模糊的对象。 |
理解较长的视频 | 可支持视频作为单独的模态(与仅处理单张图片不同)。但是,模型从一组非连续的图片帧中接收信息,而不是从连续视频本身(不接收音频)接收。Gemini 也不会提取超过视频 2 分钟之外的任何信息。如需提升包含密集内容的视频的性能,请缩短视频,以便模型捕获更多视频内容。 |
按照复杂的说明操作 | 难以处理需要多个推理步骤的任务。可以考虑分解说明或提供镜头较少的示例,以获得更好的指导。 |
幻觉 | 有时,推断内容可能超出图片/视频中的实际位置,或生成不正确的内容以进行广泛文本解析。降低温度或要求缩短说明有助于缓解这种情况。 |
医疗用途 | 不适合解读医学图片(例如 X 光片和 CT 扫描),或不适合提供医学建议。 |
多轮(多模态)聊天 | 未经训练,无法使用聊天机器人功能或以聊天语气回答问题,并且在多轮对话中表现不佳。 |
原理
- 多模态交叉编排
这个技术是在 Flamingo 中首先提出的,具体来说就是在文本序列中插入特殊的标记 来表示这个位置有一个图像/视频内容。直接输入到模型中的是包含这些特殊标记的文本序列,视觉信息则是通过交叉注意力机制来注入到模型中,并且通过mask来限制每段文本能感知到的视觉内容(一段文本对应一个图像/视频)。由于 Flamingo 没有开源代码,所以不知道官方的实现细节,但可以参考 OpenFlamingo 的代码。 Flamingo 补充材料中的图 7 非常能说明这个细节,可以仔细的研读。
根据技术报告中的图2(上面也引了),Gemini 没有简单的采用 Flamingo 的方式,应该是把其他模态内容的 token 序列直接和文本的 token 序列交叉合并在一起输入到模型中而不是通过交叉注意力机制注入进去,我认为这种形式才算得上原生多模态,不仅设计简洁优雅,而且可能效果更好。
- 多模态离散序列化
上面那段从 Gemini 技术报告中引用的内容提到 “the models ... can natively output images using discrete image tokens (Ramesh et al., 2021; Yu et al., 2022b). ”。这句话引用的两篇文章分别是 Google 自家的 Parti 和 OpenAI 的 DALL·E(临时吐槽一下,GPT4 都集成 DALL·E 3 了,Google 还搁这 DALL·E 1 呢),两个都是图像生成模型,都采用了 VQVAE 、 VQGAN 提出的离散图像序列化技术。最近受到广泛关注的 LVM 也使用了同样的技术,并且从 LVM 的实验来看,这种直接把离散视觉序列输入到大模型中学习出的效果还是挺好的,我个人也认同这种方式相比于用文本作为中介的方式能让模型更充分的感知视觉信息。
根据技术报告中另一段说明 “In addition, Gemini can directly ingest audio signals at 16kHz from Universal Speech Model (USM) (Zhang et al., 2023) features.”,音频模态是直接复用的 USM 这篇工作,其同样使用了和视觉中类似的 VQ(vector quantization) 技术,这个技术出自 NeurIPS 2022 的 BEST-RQ(RQ := random-projection quantizer ),BEST-RQ 文中也把自己的 RQ 和 VQVAE 的 VQ 做了比较。
可以看出这种离散序列化技术在 Gemini 的原生多模态架构中起了重要作用,可以把文本之外的模态内容在形式上和文本统一起来。根据 “Gemini models build on top of Transformer decoders (Vaswani et al., 2017)”,Gemini 就是和 GPT、Llama一样直接采用了 Decoder only 架构,因此统一的多模态 token 序列可以直接用自回归方式进行训练,LVM 在纯视觉数据上已经证明了可行性。
根据以上这两点关键技术,我个人很自然地就把 Gemini 理解为 Flamingo + LVM + USM,其实这个框架我在很久之前读 Flamingo 以及在 Gemini 发布的前几天读到 LVM 的时候就设想过,不过也仅仅是设想,真的很佩服能把设想真正实现的大神们。
所以原生多模态能力实现的关键就在于输入输出都统一为交叉编排的多模态 token 序列,那它到底什么样呢?有了 Flamingo + LVM 的铺垫,它可能是下面这样:
其中 BOS 和 EOS 标记整个序列起始结束,
本文到此为止,粗浅地梳理出 Gemini 原生多模态的可能实现,以后有时间可以再继续梳理和讨论更多的可能的细节,包括 Tokenizer 的实现、为什么是离散序列化、位置编码等。
Gemini团队组成
Gemini 将团队划分为约 10 个小组,分别负责预训练、数据、基础设施、模型微调、模型评估、代码库、多模态、强化学习、工具使用以及人工标注数据。
QWEN-VL
我们通过引入新的视觉接收器,包括与语言对齐的视觉编码器和位置感知适配器,增强了LLM 基础模型的视觉能力。
- 强大的性能:在四大类多模态任务的标准英文测评中(Zero-shot Caption/VQA/DocVQA/Grounding)上,均取得同等通用模型大小下最好效果;
- 多语言对话模型:天然支持多语言对话,端到端支持图片里中英双语的长文本识别;
- 多图交错对话:支持多图输入和比较,指定图片问答,多图文学创作等;
- 首个支持中文开放域定位的通用模型:通过中文开放域语言表达进行检测框标注;
- 细粒度识别和理解:相比于目前其它开源LVLM使用的224分辨率,Qwen-VL是首个开源的448分辨率的LVLM模型。更高分辨率可以提升细粒度的文字识别、文档问答和检测框标注。
Qwen-VL的整体网络架构由三个组件构成,模型参数的详细信息在表1中展示:
大型语言模型:Qwen-VL采用了一个大型语言模型作为其基础组件。该模型初始化自预训练权重Qwen-7B(Qwen, 2023)。
视觉编码器:Qwen-VL的视觉编码器采用了Vision Transformer(ViT)(Dosovitskiy等人,2021)架构,并使用Openclip的预训练权重ViT-bigG(Ilharco等人,2021)进行初始化。在训练和推理阶段,输入图像会被调整至特定分辨率。视觉编码器通过以步长为14的方式将图像分割成多个块,生成一组图像特征。
位置感知视觉-语言适配器:为了解决由于图像特征序列过长导致的效率问题,Qwen-VL引入了一个视觉-语言适配器来压缩图像特征。这个适配器包含一个随机初始化的单层交叉注意力模块。该模块使用一组可训练向量(嵌入)作为查询向量,并将视觉编码器生成的图像特征作为交叉注意力操作中的键向量。这种机制将视觉特征序列压缩到固定的长度256。关于查询数量的消融实验在附录E.2中有详细介绍。此外,考虑到精确图像理解中位置信息的重要性,2D绝对位置编码被融入到交叉注意力机制的查询-键对中,以减轻压缩过程中可能损失的位置细节。经过压缩得到的长度为256的图像特征序列随后被输入到大型语言模型中。
输入与输出
图像输入:图像通过视觉编码器和适配器处理后,产生固定长度的图像特征序列。为了区分图像特征输入和文本特征输入,在图像特征序列的开头和结尾分别添加两个特殊标记(),分别表示图像内容的起始和结束。
边界框输入与输出:为了提升模型对细粒度视觉理解和定位的能力,Qwen-VL在训练中涉及了区域描述、问题及检测数据。不同于涉及图像-文本描述或问题的传统任务,该任务要求模型精确地理解和生成指定格式的区域描述。对于任何给定的边界框,会应用一个归一化过程(范围在[0, 1000)内),然后将其转换为特定字符串格式:“(Xtopleft, Ytopleft),(Xbottomright, Ybottomright)”。这个字符串作为文本进行分词,并不需要额外的位置词汇表。为了区分检测字符串和常规文本字符串,在边界框字符串的开头和结尾添加了两个特殊标记()。此外,为了恰当关联边界框与其对应的描述性词语或句子,引入了另一组特殊标记(
和
),用以标记由边界框所指代的内容。
Flamingo
图文多模态领域典型任务如img-text retrieval、VQA、captioning、grounding等,目前的学术设定难度尚可。但是,一旦知识范围扩展,到了open-ended scenario,任务难度立刻剧增。但是DeepMind的Flamingo模型在这些挑战场景中使用同一个模型便做到了。
在机器学习和深度学习的领域中,"open-ended scenario"通常指的是一个具有高度复杂性和不确定性的场景,这种场景下的问题没有固定的结束点,可能会有多种可能的解决方案和路径。
在open-ended scenario中,系统或模型需要能够处理未知的、新颖的或动态变化的情况,而不仅仅是根据预先定义的规则或者有限的训练数据集来做决定。这要求系统具备一定程度的创新能力、适应性和泛化能力。实际应用示例
- 自然语言处理(NLP):在开放式对话系统中,用户可以自由地输入任何形式的问题或评论,系统必须能够理解和生成合理的回答,而不是仅仅从预定义的回复中选择。
- 游戏AI:在某些策略游戏或模拟环境中,AI可能需要面对无法预测的玩家行为和持续变化的游戏状态,它必须实时地制定和调整策略。
- 机器人:在真实世界的机器人任务中,如搜救任务或家庭服务机器人,机器人可能会遇到各种预料之外的障碍和情况,它需要能够自主学习和适应环境。
解决Open-Ended Scenario的方法
在处理open-ended scenario时,研究人员和工程师会采取各种方法来提高模型的鲁棒性和灵活性:
- 强化学习:通过让模型在模拟环境中尝试和错误来学习最优策略。
- 迁移学习:使用在一个任务上训练好的模型来解决另一个相似的任务,从而快速适应新场景。
- 元学习:训练模型学习如何学习,以便它能够在面对新任务时快速适应。
- 多任务学习:同时训练模型在多个任务上工作,以提高其泛化能力。
- 生成对抗网络(GANs):在某些情况下,使用GANs生成新的训练样本来增强模型的泛化能力。
open-ended scenario是AI研究中的一个重要领域,因为它更接近人类的认知和解决问题的能力,同时对于开发真正智能的系统也是一个关键的挑战。
作者团队目前已经开源了OpenFlamingo-9B模型权重,虽然还未经过全面优化,但基于社会的反馈,它已经展现出惊人的替力,并为领域的发展提供了深入挖掘的基础
该模型在COCO目标检测任务和知识问答任务中,也展现现强大的few-shot能力:
COCO(CIDEr)
0-shot | 4-shot | 8-shot | 16-shot | 32-shot | |
---|---|---|---|---|---|
OpenFlamingo-9B* | 65.5 | 74.3 | 79.3 | 81.8 | 84.5 |
DeepMind Flamingo-9B | 79.4 | 93.1 | 99.0 | 102.2 | 106.3 |
VQAv2 (VQA accuracy)
0-shot | 4-shot | 8-shot | 16-shot | 32-shot | |
---|---|---|---|---|---|
OpenFlamingo-9B | 43.5 | 44.0 | 47.5 | 48.9 | 50.3 |
DeepMind Flamingo-9B | 51.8 | 56.3 | 58.0 | 59.4 | 60.4 |
Yi-VL
- **Yi Visual Language (Yi-VL **系列的开源多模态版本 **)模型是易语大语言模型(LLM) **,可实现内容理解、识别和图像的多轮对话。
- Yi-VL表现出卓越的性能 **,在最新的基准测试中, **在所有现有的开源模型中 包括英文版MMMU和 中文CMMMU(基于截至2024年1月的数据),
- Yi-VL-34B是 **全球首个 **开源的34B视觉语言模型。
结构
Yi-VL采用 LLaVA架构,由三个主要组件组成:
- Vision Transformer (ViT):使用 CLIP ViT-H/14 模型初始化并用于图像编码。
- 投影模块:它旨在将图像特征与文本特征空间对齐,由具有层归一化的两层多层感知器 (MLP) 组成。
- 大型语言模型(LLM):使用 Yi-34B-Chat Yi-34B-Chat 或 Yi-6B-Chat进行初始化,在理解和生成英文和中文方面表现出非凡的熟练程度。
gpt4-vision-preview
基于GPT4的vision版本
Vary-toy
Vary-toy在消费级显卡可训练、8G显存的老显卡可运行,依旧支持中英文!我们希望Vary-toy能当好一个结构简单、能力全面、性能可比的baseline的角色,因此这个“小”VLM几乎涵盖了目前LVLM主流研究中的所有能力:Document OCR、Visual Grounding、Image Caption、VQA…… 技术报告在这里:Small Language Model Meets with Reinforced Vision Vocabulary
我们基于它设计了两个优秀的模型,一个是Vary-document(专门用于文档/pdf处理),另一个是用于图表分析的Vary-plot。你可以在这里看到他们精彩的表演Vary-family。
微调方法
大模型微调
qwen-vl 微调
我们提供了finetune.py这个脚本供用户实现在自己的数据上进行微调的功能,以接入下游任务。此外,我们还提供了shell脚本减少用户的工作量。这个脚本支持 DeepSpeed 和 FSDP 。我们提供的shell脚本使用了DeepSpeed,因此建议您确保已经安装DeepSpeed。
首先,你需要准备你的训练数据。你需要将所有样本放到一个列表中并存入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:
对于带图像输入的内容可表示为 Picture id: \n{your prompt},其中id表示对话中的第几张图片。"img_path"可以是本地的图片或网络地址。
对话中的检测框可以表示为
准备好数据后,你可以使用我们提供的shell脚本实现微调。注意,你需要在脚本中指定你的数据的路径。
微调脚本能够帮你实现:
-
全参数微调
-
LoRA
-
Q-LoRA
全参数微调
默认下全参数微调在训练过程中更新LLM所有参数。我们的实验中,在微调阶段不更新ViT的参数会取得更好的表现。你可以运行这个脚本开始训练:
# 分布式训练。由于显存限制将导致单卡训练失败,我们不提供单卡训练脚本。 sh finetune/finetune_ds.sh
尤其注意,你需要在脚本中指定正确的模型名称或路径、数据路径、以及模型输出的文件夹路径。如果你想修改deepspeed配置,可以删除掉--deepspeed这个输入或者自行根据需求修改DeepSpeed配置json文件。此外,我们支持混合精度训练,因此你可以设置--bf16 True或者--fp16 True。经验上,如果你的机器支持bf16,我们建议使用bf16,这样可以和我们的预训练和对齐训练保持一致,这也是为什么我们把默认配置设为它的原因。
LoRA
运行LoRA的方法类似全参数微调。但在开始前,请确保已经安装peft代码库。另外,记住要设置正确的模型、数据和输出路径。我们建议你为模型路径使用绝对路径。这是因为LoRA仅存储adapter部分参数,而adapter配置json文件记录了预训练模型的路径,用于读取预训练模型权重。同样,你可以设置bf16或者fp16。
# 单卡训练 sh finetune/finetune_lora_single_gpu.sh # 分布式训练 sh finetune/finetune_lora_ds.sh
与全参数微调不同,LoRA (论文) 只更新adapter层的参数而无需更新原有语言模型的参数。这种方法允许用户用更低的显存开销来训练模型,也意味着更小的计算开销。
注意,如果你使用预训练模型进行LoRA微调,而非chat模型,模型的embedding和输出层的参数将被设为可训练的参数。这是因为预训练模型没有学习过ChatML格式中的特殊token,因此需要将这部分参数设为可训练才能让模型学会理解和预测这些token。这也意味着,假如你的训练引入新的特殊token,你需要通过代码中的modules_to_save将这些参数设为可训练的参数。如果你想节省显存占用,可以考虑使用chat模型进行LoRA微调,显存占用将大幅度降低。下文的显存占用和训练速度的记录将详细介绍这部分细节。Q-LoRA
如果你依然遇到显存不足的问题,可以考虑使用Q-LoRA (论文)。该方法使用4比特量化模型以及paged attention等技术实现更小的显存开销。运行Q-LoRA你只需运行如下脚本:
# 单卡训练 sh finetune/finetune_qlora_single_gpu.sh # 分布式训练 sh finetune/finetune_qlora_ds.sh
我们建议你使用我们提供的Int4量化模型进行训练,即Qwen-VL-Chat-Int4。请不要使用非量化模型!与全参数微调以及LoRA不同,Q-LoRA仅支持fp16。此外,上述LoRA关于特殊token的问题在Q-LoRA依然存在。并且,Int4模型的参数无法被设为可训练的参数。所幸的是,我们只提供了Chat模型的Int4模型,因此你不用担心这个问题。但是,如果你执意要在Q-LoRA中引入新的特殊token,很抱歉,我们无法保证你能成功训练。
与全参数微调不同,LoRA和Q-LoRA的训练只需存储adapter部分的参数。假如你需要使用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()
如果你觉得这样一步到位的方式让你很不安心或者影响你接入下游应用,你可以选择先合并并存储模型(LoRA支持合并,Q-LoRA不支持),再用常规方式读取你的新模型,示例如下:
```python
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)
注意:分布式训练需要根据你的需求和机器指定正确的分布式训练超参数。此外,你需要根据你的数据、显存情况和训练速度预期,使用--model_max_length设定你的数据长度。
显存占用及训练速度
下面记录Qwen_VL模型在单GPU使用LoRA(LoRA (Base)指的是embedding和输出层参与训练,而LoRA (Chat)则不优化这部分参数)和QLoRA时处理不同长度输入的显存占用和训练速度的情况。本次评测运行于单张A100-SXM4-80G GPU,使用CUDA 11.8和Pytorch 2.0。我们统一使用batch size为1,gradient accumulation为8的训练配置,每个样本包含一张图,分别记录输入长度分别为384、512、1024和2048的显存占用(GB)和训练速度(s/iter)。具体数值如下所示:
Method | Sequence Length | |||
---|---|---|---|---|
384 | 512 | 1024 | 2048 | |
LoRA (Base) | 37.1G / 2.3s/it | 37.3G / 2.4s/it | 38.7G / 3.6s/it | 38.7G / 6.1s/it |
LoRA (Chat) | 23.3G / 2.2s/it | 23.6G / 2.3s/it | 25.1G / 3.5s/it | 27.3G / 5.9s/it |
Q-LoRA | 17.0G / 4.2s/it | 17.2G / 4.5s/it | 18.2G / 5.5s/it | 19.3G / 7.9s/it |
swift 微调
零一万物开源Yi-VL多模态大模型,魔搭社区推理&微调最佳实践来啦!
参考文献
像 Gemini 这样的原生多模态模型,和多个单模型拼接相比有什么区别?有哪些优势? - 知乎
原生多模态通用大模型——从 Gemini 说起
https://makersuite.google.com/app/prompts/new_freeform
https://ai.google.dev/tutorials/
GitHub - QwenLM/Qwen-VL: The official repo of Qwen-VL (通义千问-VL) chat & pretrained large vision language model proposed by Alibaba Cloud.
通义千问
解读 Gemini 技术报告(Gemini: A Family of Highly Capable Multimodal Models)
大语言模型之五 谷歌Gemini_谷歌通过对比五个大型自然语言处理模型-CSDN博客
https://arxiv.org/pdf/2312.11805.pdf
https://arxiv.org/pdf/2204.14198v1.pdf
多模态LLM系列调研 - 1 | LLaVA、MiniGPT-4、Flamingo
https://zhuanlan.zhihu.com/p/617864689
https://zhuanlan.zhihu.com/p/507622221
https://github.com/Ucas-HaoranWei/Vary-family
评论区