LLaVA 是一个由威斯康星大学麦迪逊分校、微软研究院和哥伦比亚大学的研究人员开发的大型语言和视觉助手。它是一个端到端训练的大型多模态模型,结合了视觉编码器和语言模型,用于通用的视觉和语言理解。
微软研究院、威斯康星大学的研究人员在LLaVA基础之上,继续开源了LLaVA-1.5版本。与前一代相比,LLaVA-1.5引入了跨模态连接器和特定格式的学术视觉问答数据集,全面提升了多模态理解和生成能力。
LLaVA-1.5在多模态理解和生成能力上实现了开源模型中的最高水平,可媲美GPT-4V效果。该模型由视觉模型、大语言模型和视觉语言连接器组成,其中视觉模型使用CLIPViT-L/336px提取图像特征,大语言模型使用Vicunav1.5理解文本内容。训练流程分为预训练和调优两个阶段,数据集覆盖视觉问答、语言对话等典型应用,使用约65万条多模态指令数据进行视觉指令调优。
为了评估LLaVA-1.5的性能,研究人员在MMEMM、BenchMM、SQA、POPE等11个知名数据平台中对视觉问答、自然语言处理、图像生成等进行了测试。结果显示,LLaVA-1.5皆实现了开源模型中的最高水平,可媲美GPT-4V效果。
接下来,本篇博客将为你详细介绍LLaVA的架构。我将从LLaVA的核心设计理念出发,逐步解析其如何通过结合视觉编码器和语言模型,实现对视觉和语言信息的深度理解和处理。通过本篇博客,你将获得对LLaVA架构的全面认识,理解它是如何在多模态人工智能领域中占据领先地位的。
github代码:https://github.com/haotian-liu/LLaVA
clip权重:openai/clip-vit-large-patch14-336 · HF Mirror
其他人写的教程:第一节 LLaVA模型安装、预测、训练详细教程-CSDN博客
其他人写的教程:多模态大模型 LLaVA 微调教程-大语言模型8 - vanilla阿草 - 博客园
其他人写的报错信息总结:https://zhuanlan.zhihu.com/p/656307174
对于图像Xv及其相关联的Caption Xc,作者创建了一组问题Xq,其意图是指示助手描述图像内容。我们提示GPT-4编制此类问题列表。因此,将一个图像-文本对扩展为
Human:Xq Xv Assistant:Xc
尽管构建成本低廉,但这种简单的扩展版本在指令和响应方面缺乏多样性和深入的推理。
作者利用纯语言GPT-4或ChatGPT作为教师模型(两者都只接受文本作为输入)来创建涉及可视内容的指令遵循数据。具体地说,为了将图像编码成其视觉特征以提示纯文本GPT,作者使用了两种类型的符号表示:(i)字幕(Caption)通常从各种角度描述视觉场景;(ii)边界框通常定位场景中的对象,并且每个框编码对象概念及其空间位置。如下图所示。
作者使用COCO图像,生成三种类型的指令跟随数据。对于每种类型,作者首先手动设计一些示例。它们是在数据收集过程中唯一的人工注释,相当于few-shot。
简单来说,按照数据的不同,LLaVA会分开处理:
模型的组成:
在这个阶段中,保持视觉编码器和LLM权值不变,只训练线性层projection。这样,图像特征可以与预训练的大语言模型的词嵌入空间对齐。
在这个阶段中,始终保持视觉编码器权值不变,并不断更新投影层和大语言模型的预训练权值。
数据集:
LLaVA-1.5 在 LLaVA 的基础上做了以下改动:
此外,为了支持更高的图像分辨率(可以提升模型的性能)且不影响 LLaVA-1.5 的推理效率,在 LLaVA-1.5 的基础上提出了 LLaVA-1.5-HD,它采用了创新的AnyRes策略,可以接受各种高分辨率的图像作为输入。具体步骤如下:
这个过程可以看做特征金字塔,如下图所示
conda create -n llava python=3.10 -y
conda activate llava
pip install --upgrade pip # enable PEP 660 support
pip install -e .
我们可以遵循官方的指示,安装环境。我这里直接使用CogVideoX的环境,可以直接使用。
权重方面,大家需要下载llava的权重,有1、1.5、1.6三个版本,每个版本又分7b等多个版本,我这里使用1.5-7b:
liuhaotian/llava-v1.5-7b at main
大模型权重:lmsys/vicuna-7b-v1.5 · HF Mirror
除此之外,还需要下载openai的clip模型,这是llava的视觉编码器部分,然后把config.json里面的相应位置做更改:
openai/clip-vit-large-patch14-336 · HF Mirror
输入:
What are the things I should be cautious about when I visit here?
我这里是直接按照官方文档里面的方法,自建了一个inference.py,代码如下:
需要注意的是,官方文档还有模型导入的代码,这部分不需要加进inference.py,如果加了模型会导两次!我就是在这里被坑惨了。
from llava.model.builder import load_pretrained_model
from llava.mm_utils import get_model_name_from_path
from llava.eval.run_llava import eval_model
model_path = "llava-v1.5-7b"
prompt = "What are the things I should be cautious about when I visit here?"
image_file = "datasets/view.jpg"
args = type('Args', (), {
"model_path": model_path,
"model_base": None,
"model_name": get_model_name_from_path(model_path),
"query": prompt,
"conv_mode": None,
"image_file": image_file,
"sep": ",",
"temperature": 0,
"top_p": None,
"num_beams": 1,
"max_new_tokens": 512
})()
eval_model(args)
文件位置如下图所示:
运行即可打印结果。
When visiting this location, which features a pier extending over a large body of water, there are a few things to be cautious about. First, be mindful of the weather conditions, as the pier may be affected by strong winds or storms, which could make it unsafe to walk on. Second, be aware of the water depth and any potential hazards, such as submerged rocks or debris, that could pose a risk to your safety. Additionally, be cautious of the presence of wildlife in the area, as there might be birds or other animals that could pose a threat or disturbance. Finally, be respectful of the environment and other visitors, and follow any posted rules or guidelines to ensure a safe and enjoyable experience for everyone.
具体来说,模型会直接调用run_llava.py里面的eval_model,接下来,我们一步步来看里面的代码。
run_llava.py里面的函数
具体来说,这部分负责处理提示词,主要操作就是将
qs = args.query # 提示词
image_token_se = DEFAULT_IM_START_TOKEN + DEFAULT_IMAGE_TOKEN + DEFAULT_IM_END_TOKEN # ''
if IMAGE_PLACEHOLDER in qs:
if model.config.mm_use_im_start_end:
qs = re.sub(IMAGE_PLACEHOLDER, image_token_se, qs)
else:
qs = re.sub(IMAGE_PLACEHOLDER, DEFAULT_IMAGE_TOKEN, qs)
else:
if model.config.mm_use_im_start_end:
qs = image_token_se + "\n" + qs
else:
qs = DEFAULT_IMAGE_TOKEN + "\n" + qs # 提示词
这部分是将system、user、assistant的信息拼接起来
conv = conv_templates[args.conv_mode].copy() # system
conv.append_message(conv.roles[0], qs) # user
conv.append_message(conv.roles[1], None) # assistant
prompt = conv.get_prompt() # 完整提示词
"A chat between a curious human and an artificial intelligence assistant. The assistant gives helpful, detailed, and polite answers to the human's questions. USER:
What are the things I should be cautious about when I visit here? ASSISTANT:"
处理图片
image_files = image_parser(args) # 地址
images = load_i