使用 BLIP-2 实现图像到文本的零镜头生成
本指南介绍了 Salesforce Research 的 BLIP-2,它支持一套最先进的视觉语言模型,这些模型现已在 Transformer 中🤗提供。我们将向您展示如何将其用于图像标题、提示图像标题、视觉问答和基于聊天的提示。
引言
近年来,计算机视觉和自然语言处理取得了快速发展。尽管如此,许多现实世界的问题本质上是多模态的——它们涉及几种不同形式的数据,例如图像和文本。
视觉语言模型面临着组合模态的挑战,以便它们可以为广泛的应用程序打开大门。视觉语言模型可以处理的一些图像到文本任务包括图像标题、图像文本检索和视觉问答。
图像字幕可以帮助视障人士,创建有用的产品描述,识别文本以外的不适当内容等等。图像文本检索可以应用于多模式搜索,也可以应用于自动驾驶等应用。
视觉问答可以帮助教育,启用多模式聊天机器人,并协助各种特定领域的信息检索应用程序。
现代计算机视觉和自然语言模型变得更加强大;然而,与它们的前辈相比,它们的规模也显着增长。虽然预训练单一模态模型既耗费资源又昂贵,但端到端视觉和语言预训练的成本变得越来越令人望而却步。
BLIP-2通过引入一种新的视觉语言预训练范式来应对这一挑战,该范式可以利用预训练视觉编码器和LLM的任意组合,而无需端到端地预训练整个架构。这使得在多个视觉语言任务上实现最先进的结果,同时显着减少可训练参数的数量和预训练成本。此外,这种方法为多模态ChatGPT类模型铺平了道路。
BLIP-2 的引擎盖下有什么?
BLIP-2通过在现成的冻结预训练图像编码器和冻结的大语言模型之间添加轻量级查询转换器(Q-Former)来弥合视觉和语言模型之间的模态差距。Q-Forformer 是 BLIP-2 中唯一可训练的部分;图像编码器和语言模型都保持冻结状态。
BLIP-2框架概述
Q-Former 是一个转换器模型,由两个共享相同自我注意层的子模块组成:
- 与冻结图像编码器相互作用以进行视觉特征提取的图像转换器
- 可用作文本编码器和文本解码器的文本转换器
Q-Former架构
图像转换器从图像编码器中提取固定数量的输出特征,与输入图像分辨率无关,并接收可学习的查询嵌入作为输入。查询还可以通过相同的自我注意层与文本进行交互。
Q-Forform分两个阶段进行预训练。在第一阶段,图像编码器被冻结,Q-Forformer被训练有三个损失:
-
图像-文本对比损失:计算每个查询输出和文本输出的 CLS 令牌之间的成对相似性,并选择最高的一个。查询嵌入和文本不会“看到”彼此。
-
基于图像的文本生成:查询可以相互关注,但不能关注文本标记,文本具有因果掩码,可以关注所有查询。
-
图文匹配损失:查询和文本可以看到其他,获取一个logit来指示文本是否与图片匹配。为了获得反面示例,使用硬负挖掘。
在第二个预训练阶段,查询嵌入现在具有与文本相关的视觉信息,因为它已经通过信息瓶颈。这些嵌入现在用作 LLM 输入的视觉前缀。这个预训练阶段实际上涉及使用因果LM损失的图像-地面文本生成任务。
作为视觉编码器,BLIP-2使用ViT,对于LLM,论文作者使用OPT和Flan T5模型。您可以在Hugging Face Hub上找到OPT和Flan T5的预训练检查点。但是,如前所述,引入的预训练方法允许将任何视觉骨干与任何LLM相结合。
将 BLIP-2 与Hugging Face变换器一起使用
使用 Hugging Face 变换器,您可以轻松下载并在图像上运行预先训练的 BLIP-2 模型。如果您想按照此博客文章中的示例进行操作,请确保使用具有高 RAM 的 GPU 环境。
让我们从安装变换器开始。由于此模型最近已添加到变换器中,因此我们需要从源头安装变换器:
pip install git+https://github.com/huggingface/transformers.git
接下来,我们需要一个输入图像。每周《纽约客》都会在读者中举办一场卡通字幕比赛,所以让我们用其中一部漫画来测试BLIP-2。
import requests
from PIL import Image
url = 'https://media.newyorker.com/cartoons/63dc6847be24a6a76d90eb99/master/w_1160,c_limit/230213_a26611_838.jpg'
image = Image.open(requests.get(url, stream=True).raw).convert('RGB')
display(image.resize((596, 437)))
《纽约客》动画片
我们有一个输入图像。现在我们需要一个预先训练的 BLIP-2 模型和相应的预处理器来准备输入。您可以在Hugging Face Hub上找到所有可用的预训练检查点的列表。在这里,我们将加载一个 BLIP-2 检查点,该检查点利用 Meta AI 预先训练的 OPT 模型,该模型具有 27 亿个参数。
from transformers import AutoProcessor, Blip2ForConditionalGeneration
import torch
processor = AutoProcessor.from_pretrained("Salesforce/blip2-opt-2.7b")
model = Blip2ForConditionalGeneration.from_pretrained("Salesforce/blip2-opt-2.7b", torch_dtype=torch.float16)
请注意,BLIP-2 是一种罕见的情况,您无法使用 Auto API 加载模型(例如 AutoModelForXXX),并且您需要显式使用
让我们使用 GPU 来加快文本生成速度:
device = "cuda" if torch.cuda.is_available() else "cpu"
model.to(device)
图片说明
让我们看看 BLIP-2 是否可以以零镜头的方式为《纽约客》漫画配字幕。要为图像添加标题,我们不必向模型提供任何文本提示,只需提供预处理的输入图像。在没有任何文本提示的情况下,模型将开始从 BOS(序列开头)令牌生成文本,从而创建标题。
inputs = processor(image, return_tensors="pt").to(device, torch.float16)
generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)0].strip()
print(generated_text)
"two cartoon monsters sitting around a campfire"
对于一个没有接受过纽约客风格卡通训练的模型来说,这是一个令人印象深刻的准确描述!
提示图片说明
我们可以通过提供文本提示来扩展图像标题,模型将在给定图像的情况下继续该提示。
prompt = "this is a cartoon of"
inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)
generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)0].strip()
print(generated_text)
"two monsters sitting around a campfire"
prompt = "they look like they are"
inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)
generated_ids = model.generate(**inputs, max_new_tokens=20)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)0].strip()
print(generated_text)
"having a good time"
视觉问答
对于视觉问答,提示必须遵循特定格式:“问题:{} 答案:”
prompt = "Question: What is a dinosaur holding? Answer:"
inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)
generated_ids = model.generate(**inputs, max_new_tokens=10)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)0].strip()
print(generated_text)
"A torch"
基于聊天的提示
最后,我们可以通过连接每个生成的对话响应来创建类似 ChatGPT 的接口。我们用一些文本提示模型(比如“恐龙拿着什么?”),模型为它生成一个答案“火炬”),我们可以将其连接到对话中。然后我们再做一次,建立上下文。但是,请确保上下文不超过 512 个标记,因为这是 BLIP-2(OPT 和 T5)使用的语言模型的上下文长度。
context =
("What is a dinosaur holding?", "a torch"),
("Where are they?", "In the woods.")
]
question = "What for?"
template = "Question: {} Answer: {}."
prompt = " ".join(template.format(contexti]0], contexti]1]) for i in range(len(context))]) + " Question: " + question + " Answer:"
print(prompt)
Question: What is a dinosaur holding? Answer: a torch. Question: Where are they? Answer: In the woods.. Question: What for? Answer:
inputs = processor(image, text=prompt, return_tensors="pt").to(device, torch.float16)
generated_ids = model.generate(**inputs, max_new_tokens=10)
generated_text = processor.batch_decode(generated_ids, skip_special_tokens=True)0].strip()
print(generated_text)
To light a fire.
结论
BLIP-2 是一种零镜头视觉语言模型,可用于具有图像、图像和文本提示的多个图像到文本任务。这是一种有效且高效的方法,可以应用于许多场景中的图像理解,尤其是在示例稀缺的情况下。
该模型通过在预先训练的模型之间添加转换器来弥合视觉和自然语言模态之间的差距。新的预训练范式使该模型能够跟上两种单独模式的进步。
本文正在参加 人工智能创作者扶持计划 ”