Li J, Li D, Xiong C, et al. Blip: Bootstrapping language-image pre-training for unified vision-language understanding and generation[C]//International Conference on Machine Learning. PMLR, 2022: 12888-12900.
BLIP 是 Salesforce 在 2022 年的工作,文章发表在 ICML-2022。BLIP 统一了视觉语言任务的理解与生成能力,还通过引入 Captioner-Filter 机制减少了监督文本的噪声。BLIP 在多种视觉语言任务上都获得了 SOTA 的结果,具有很强的迁移能力,性能甚至超越了 CLIP。
本文不再按照论文解读的方式逐段记录,只专注于介绍 BLIP 技术本身。本文参考 《BLIP》-用更干净更多样的数据进行多模态预训练,性能超越CLIP!代码已开源!,更多参考资料如下:
- 全文翻译:多模态超详细解读 (六):BLIP:统一理解和生成的自举多模态模型;
- 文章总结:[BLIP/BLIP2/InstructBLIP] 图文多模态理解与生成、一文读懂BLIP和BLIP-2多模态预训练;
- 视频讲解:CLIP 论文逐段精读【论文精读】;
目录
- 一. 背景
- 二. BLIP 原理
- 1. MED 架构
- 2. 预训练方法
- 3. CapFilt 机制
- 三. 实验
- 1. 实验结果
- 2. 对比实验
- 四. 总结
- 五. 复现
一. 背景
自从 CLIP 横空出世,各种 视觉语言预训练 (Vision-Language Pre-training, VLP) 模型逐渐涌现,显著提高了各种视觉语言任务的性能。然而,现有的 VLP 方法主要存在以下两个问题:
- 模型角度:大多数方法都是基于 编码器模型 (encoder-based model) 或 编码器 - 解码器模型 (encoder-decoder models),前者难以完成文本生成任务,后者无法完成图像文本检索任务,这两项任务无法兼顾;
- 数据角度:以 CLIP 为代表的方法都是从互联网上收集海量图像 - 文本对作为样本进行预训练,这些带噪声的文本作为监督信号显然不是最优解;
为了让 VLP 同时兼具图文多模态的理解和生成能力,即既能够根据图像生成描述,又能够根据图像回答问题。于是,Salesforce 的研究者们提出了 BLIP,通过引入一种全新的多模态混合架构 MED,可以分别作为单模态编码器(包括图像编码器和文本编码器)、图像引导文本编码器和图像引导文本解码器来进行操作,从而完成图文多模态的理解和生成任务。
为了去除 VLP 文本监督信号的杂音,Salesforce 的研究者们在预训练完成的 MED 基础上引入了 CapFilt,它包括 Captioner 和 Filter 两个模块:Captioner 用于生成文本标注,Filter 用于去除文本噪声。这两个模块都是在预训练的 MED 模型上初始化,然后在 COCO 数据集上进行微调。通过引入 Captioner 和 Filter,提高了数据的质量和数量,从而提高了 BLIP 在视觉语言任务上的性能。
COCO 数据集:全称 Common Objects in Context,是一个广泛使用的图像理解数据集,包含超过 33 万张带有标注的图像,用于训练和评估视觉语言模型。COCO 数据集的图像涵盖了各种各样的场景和对象,标注包括物体检测、分割和自然语言描述等多种任务,常用于物体检测、实例分割和图像描述等任务。
BLIP 这种全新的 VLP 框架可以灵活地在视觉理解和生成任务上完成迁移,并且通过引入 Captioner-Filter 机制减少了监督文本的噪声。训练完成的 BLIP 模型在图像文本检索、图像字幕、VQA 等视觉语言任务上都获得了 SOTA 的结果,以 zero-shot 方式直接迁移到视频语言任务时也表现出很强的泛化能力,性能超越了 CLIP。
二. BLIP 原理
BLIP 全称是 Bootstrapping Language-Image Pre-training,是一种 统一视觉语言理解与生成的预训练模型。这里的 Bootstrapping 指的是利用 Captioner-Filter 机制来生成文本标注:Captioner 生成标注,Filter 去除标注中的噪声,从而得到更准确的标注,提高数据的质量和数量。Captioner-Filter 机制可以看作是一种 Bootstrapping 的过程,因为它利用已有数据进行采样以生成更多的数据,并且不断地通过过滤来提高数据的质量。
Bootstrapping:一种统计估计方法,通过对观测数据进行再抽样,进而对总体的分布特性进行统计推断,更好地理解存在于其中的偏差、方差和特征。Bootstrapping 翻译为中文一般称为 “自助法” 或 “自举法”,在数据集较小、难以有效划分训练 / 测试集时很有用,将多次随机抽样作为训练集,将初始数据作为测试集。示例见 【机器学习】Bootstrap详解。
Bootstrapping 在机器学习领域较为常见,被广泛应用于集成学习方法中,如随机森林中的每个决策树都是在一个被 Bootstrapping 抽样得到的训练集上训练的 1。由于是有放回地抽样,同样的样本可能在一个训练集中出现多次,而其他样本可能根本不出现。这种方法有助于引入随机性,增加模型的多样性,从而提高整体模型的泛化能力。
1. MED 架构
BLIP 采用了基于 编码器 - 解码器的多模态混合结构 (Multimodal mixture of Encoder-Decoder, MED),包括两个单模态编码器、一个以图像为基础的文本编码器和一个以图像为基础的文本解码器:
- 单模态编码器 lmage Encoder:基于 transformer 的 ViT 的架构,将输入图像分割为多个的 patch 并将它们编码为一系列 Image Embedding,并使用
[CLS]
token 来表示全局的图像特征。lmage Encoder 用来提取图像特征做对比学习,相当于 CLIP 中的 Image Encoder; - 单模态编码器 Text Encoder:基于 BERT 的架构,将
[CLS]
token 加到输入文本的开头以总结句子。Text Encoder 用来提取文本特征做对比学习,相当于 CLIP 中的 Text Encoder; - 以图像为基础的编码器 Image-grounded text encoder:在 Text Encoder 的 self-attention 层和前馈网络之间添加一个 交叉注意 (cross-attention, CA) 层用来注入视觉信息,还将
[Encode]
token 加到输入文本的开头以标识特定任务。Image-grounded text encoder 用来提取文本特征并将其和图像特征对齐,相当于 CLIP 中更精细化的 Text - Image 对齐; - 以图像为基础的解码器 Image-grounded text decoder:将 Image-grounded text encoder 的 self-attention 层换成 causal self-attention 层,还将
[Decode]
token 和[EOS]
token 加到输入文本的开头和结尾以标识序列的开始和结束。Image-grounded text decoder 用来生成符合图像和文本特征的文本描述,这是 CLIP 中所没有的;注意,Image-grounded text decoder 生成的文本描述不同于输入的图像 - 文本对中的文本,图像 - 文本对中的文本是互联网上找到的图片的上下文,拥有大量的噪音;而 Image-grounded text decoder 生成的文本描述是针对图像特征和文本特征的特定描述,更加精炼。这里其实就已经是 Captioner 的雏形了,下文的 Captioner 也是基于训练完成的 Image-grounded text decoder 再进行的优化和微调。
通过上文 lmage Encoder、Text Encoder、Image-grounded text encoder、Image-grounded text decoder 的描述不难发现,四个模块之间共用了一些参数,如下图所示,相同颜色表示共用参数:
2. 预训练方法
如上图所示,预训练 MED 过程中联合优化了 3 个目标,包括 2 个理解任务的目标函数和 1 个生成任务的目标函数:
-
图文对比损失 (Image-Text Contrastive Loss, ITC):ITC 用于训练 lmage Encoder 和 Text Encoder,通过对比学习对齐图像和文本的特征空间。具体方法是最大化正样本图像 - 文本对的相似度且最小化负样本图像 - 文本对的相似度,从映射的角度讲就是将语义相关的图像 - 文本对映射到空间中的相邻点且语义不相关的图像 - 文本对映射到不相邻的点。这里还使用了 ALBEF 中的动量编码器,目的是产生一些伪标签以辅助模型的训练;
-
图文匹配损失 (Image-Text Matching Loss, ITM):ITM 用于训练 Image-grounded text encoder,通过学习图像 - 文本对的联合表征实现视觉和语言之间的细粒度对齐。具体方法是通过一个二分类任务,预测图像文本对是正样本还是负样本。这里还使用了 ALBEF 中的 hard negative mining 技术以更好地捕捉负样本信息;
ITM 与 ITC 并不一样,ITC 虽然也对齐了图像和文本的特征空间,但并没有显式地区分正负样本,主要是用于评价图像和文本的匹配情况,给出任意输入图像 - 文本对的相似度。而 ITM 则是通过计算样本的损失达到区分正负样本的目的,激励正样本的图像和文本使其更加匹配。
-
语言建模损失 (Language Modeling Loss, LM):LM 用于训练 Image-grounded text decoder,实现生成图像的文本描述任务。具体方法是通过优化交叉熵损失函数,训练模型以自回归的方式最大化文本的概率。这里还使用了 0.1 的标签平滑计算损失;
3. CapFilt 机制
COCO 数据集的高质量人工注释图像 - 文本对 { ( I h , T h ) } \{(I_h, T_h)\} {(Ih,Th)} 数量有限,因此 CLIP、BLIP 等 VLP 都是从网络中收集大量图像 - 文本对 { ( I w , T w ) } \{(I_w, T_w)\} {(Iw,Tw)} 作为训练集。但这些网络图像 - 文本对的文本来自图像上下文,难以精准地描述图像内容,存在大量噪声。
于是,文中提出了 字幕和过滤 (Captioning and Filtering, CapFilt) 机制:
上图给出了 CapFilt 的图示,包含字幕器和过滤器两个模块:
- 字幕器 Captioner:一个视觉文本解码器,基于Image-grounded text decoder,用于生成给定图像的字幕,使用 LM 损失函数在 COCO 数据集上进行微调。给定网络图片 I w I_w Iw,Captioner 生成字幕 T w T_w Tw。
- 过滤器 Filter:一个视觉文本编码器,基于 Image-grounded text encoder,用于去除文本噪声,使用 ITC 和 ITM 损失函数在 COCO 数据集上进行微调。Filter 通过比对文本和图像的匹配情况,删除原始 Web 文本
T
w
T_w
Tw 和合成文本
T
s
T_s
Ts 中的噪声;
Captioner 和 Filter 都是在预训练完成后的 MED 模型上初始化的,并各自在人工注释的图像 - 文本对数据集 COCO 上进行 微调 (finetune)。最后,将过滤后的图像 - 文本对与人工注释对相结合,形成一个新的数据集(这也是 Bootstrapping 的由来),最后再用它来训练一遍模型。
介绍到这里可以大致捋一下 BLIP 的训练思路:先使用含有噪声的网络数据训练一遍 BLIP,再在 COCO 数据集上进行微调以训练 Captioner 和 Filter,然后使用 Filter 从原始网络文本和合成文本中删除嘈杂的字幕,得到干净的数据。最后再使用干净的数据训练一遍得到高性能的 BLIP。
三. 实验
1. 实验结果
2. 对比实验
四. 总结
BLIP 是一个全新的 VLP 框架,统一了视觉语言任务的理解与生成功能,并且通过嵌入 Captioner 和 Filter 去除网络资源中的文本噪声,提高了模型在下游视觉语言任务上的性能。
作者在文末表明,BLIP 存在一些潜在的优化方向可以进一步提高性能:
- 多轮数据集的 Bootstrapping;
- 为每幅图像生成多个合成字幕,进一步扩大预训练语料库;
- 训练多个不同的 Captioner 和 Filter 进行集成;
五. 复现
Salesforce 开源了 预训练的代码 和 训练好的模型,可以直接拿来做下游任务。网页版的 Demo 也可以在线完成 Image Captioning、VQA、Image-Text Matching 等任务。
一开始在 Colab notebook 里运行 demo.ipynb
,第一步配置环境就出现 ERROR: Failed building wheel for tokenizers
。当时没有找到解决办法,于是下载到本地运行。后来在 Issues 中找到答案 2:升高版本 transformers==4.25.1
。
在本地运行 demo.ipynb
以简单复现:
- 平台:本地 VS Code
- 显卡:GTX 1650
- 镜像:PyTorch 1.10.1、Python 3.8.1、Cuda 11.7
- 源码:https://github.com/salesforce/BLIP
实验记录:
-
一开始选错了 python 内核,导致无法加载安装在默认环境的包;
-
在安装 pytorch 时,注意不能直接
pip install pytorch
,因为这是默认 CPU 版本的 pytorch。安装 GPU 版本的方法是pip install torch==XX +cuXX
,这里需要注意 项目要求的版本和本地 CUDA 的兼容性。例如 BLIP 要求的 pytorch 版本是 1.10,去 Pytorch 官网 查找满足要求的 Windows 版本;我本地的 CUDA 是 11.7 的,选择不高于 11.7 的即可。torchvision 和 torchaudio 同理。因为我使用的 交大的源,所以还需要比对源上是否有对应版本,否则找不到对应的版本。最终找到符合要求的版本是:pip install torch==1.10.1+cu102 torchvision==0.11.2+cu102 torchaudio==0.10.1 -f https://mirror.sjtu.edu.cn/pytorch-wheels/torch_stable.html
; -
调用模型参数时,遇到
RuntimeError: PytorchstreamReader failed reading zip archive:failed finding central directoryOutput is truncated.
报错。后来发现参数文件model_base_capfilt_large.pth
下载异常,近 2G 的参数文件只下载了 33M。重新下载参数文件后,将 URL 加载改为本地路径加载即可:# model_url = 'https://storage.googleapis.com/sfr-vision-language-research/BLIP/models/model_base_capfilt_large.pth' # model = blip_decoder(pretrained=model_url, image_size=image_size, vit='base') model_path = r"C:\Users\Jackson1125\.cache\torch\hub\checkpoints\model_base_capfilt_large.pth" model = blip_decoder(pretrained=model_path, image_size=image_size, vit='base')
-
图文匹配时,遇到
RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same
报错。原因是模型在 CPU 上但数据在 GPU 上 3,一开始将模型移到 GPU 上:# model = model.to(device='cpu') model = model.to(device=device)
但是又遇到
RuntimeError: CUDA out of memory. Tried to allocate 16.00 MiB (GPU 0; 4.00 GiB total capacity; 3.39 GiB already allocated; 0 bytes free; 3.45 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation.
,显存太小不够存放模型。因此将模型移到 CPU 上即可:# image = load_demo_image(image_size=image_size,device=device) image = load_demo_image(image_size=image_size,device='cpu')
实验结果:
Image Captioning 实验结果如下:
VQA 实验结果如下(question = ‘where is the woman sitting?’):
(不知道为什么,这里生成的回答永远是 “a black and white photo of a woman in”,哪怕我换了其他图片也还是这样。目前还没有找到解决办法,网页版的 Demo 就没有问题…)
Image-Text Matching 实验结果如下:
Bootstrapping算法(附python代码) ↩︎
Demo Google Colab not working ↩︎
RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same ↩︎