首页
/ Hugging Face Transformers 中的 BLIP 模型:Bootstrapped 视觉-语言预训练架构、配置与 VQA 实战指南

Hugging Face Transformers 中的 BLIP 模型:Bootstrapped 视觉-语言预训练架构、配置与 VQA 实战指南

2026-09-06 18:48:45作者:郁楠烈Hubert

BLIP(Bootstrapped Language-Image Pretraining)是由 Salesforce 提出的视觉-语言预训练(VLP)框架,其核心目标是让同一套参数同时擅长理解类(如图文检索)与生成类(如图像描述、视觉问答)任务。本文以 Transformers 仓库中 BLIP 的官方文档为主体,结合 configuration_blip.pymodeling_blip.pyprocessing_blip.py 等源码,完整讲解三类任务模型、三个配置类的全部默认参数、预处理管线与底层实现原理。读完本文,你将能够独立完成 BLIP 的视觉问答、图像描述、图文检索的推理与训练,并能看懂、调整其双塔与融合层配置。

BLIP 的核心思想:用“标题生成器 + 噪声过滤器”驯服海量网页数据

大多数早期的预训练模型只能在“理解”或“生成”二者中擅长其一:CLIP 一类模型擅长图文对齐与检索,但不能生成自然语言;仅靠生成目标训练的模型又缺乏语义理解的对齐监督。BLIP 的设计动机正是打破这一瓶颈——它的全称即点明方法:Bootstrapping(自举式数据重标定)。

BLIP 使用一个 captioner(标题生成器)为网络图片生成合成标题,再用一个 filter(过滤器)剔除其中含噪、不相关的标题。通过这种方式,模型得以在训练过程中持续自我提升训练数据质量,从而更充分地利用参差不齐(messy)的网页图文数据。docs/source/en/model_doc/blip.md 将其概括为一种“同时面向理解与生成任务”的 VLP 框架。

据该文档记载,BLIP 论文于 2022-01-28 发布,该模型类型于 2022-12-21 由 ybelkada 贡献并入 Hugging Face Transformers。官方发布的 BLIP 检查点统一以 Salesforce/blip-* 命名,源码中各配置类与 Auto API 的 checkpoint 示例默认值均为 Salesforce/blip-vqa-base(见 configuration_blip.py),这是全库中最具代表性的 BLIP 权重标识。

快速上手:基于 Pipeline 的视觉问答(Visual Question Answering)

BLIP 最典型的落地场景是 VQA:输入一张图片 + 一个自然语言问题,输出答案。文档给出的第一种方式是 Pipeline 高层 API——无需手动管理预处理与模型实例:

from transformers import pipeline

# device=0 表示使用第一块 GPU;不传该参数则回退到 CPU
vqa_pipeline = pipeline(
    task="visual-question-answering",
    model="Salesforce/blip-vqa-base",
    device=0,
)

# 换成本地测试图即可复现;原文档示例使用远端 COCO 图片
answer = vqa_pipeline(
    question="What is in this image?",
    image="tests/fixtures/tests_samples/COCO/000000039769.png",  # 仓库自带测试样本
)
print(answer)

visual-question-answering 任务会在内部自动装配 BlipForQuestionAnswering 与其配套的 BlipProcessor(可在 src/transformers/models/auto 的 pipeline 注册表中确认映射)。仓库自带一张 COCO 样例图位于 tests/fixtures/tests_samples/COCO/000000039769.png,可用于离线快速验证推理流程。

进阶用法:AutoModel + AutoProcessor 手动串联

Pipeline 封装了全部细节,但当你需要精确控制预处理、batch、半精度推理时,更推荐文档展示的第二条路径——用 AutoModelForVisualQuestionAnsweringAutoProcessor 手工串联。Auto 注册表确认了 blip 架构到 BlipForQuestionAnswering 的映射(见 modeling_auto.pyMODEL_FOR_VISUAL_QUESTION_ANSWERING_MAPPING_NAMES 等常量)。

import torch
from PIL import Image

from transformers import AutoModelForVisualQuestionAnswering, AutoProcessor

processor = AutoProcessor.from_pretrained("Salesforce/blip-vqa-base")
model = AutoModelForVisualQuestionAnswering.from_pretrained(
    "Salesforce/blip-vqa-base",
    device_map="auto",          # 自动分配 GPU / CPU
    torch_dtype=torch.float16,  # 半精度加速(需 GPU 支持)
)

# 读取仓库内置 COCO 样例图片
image = Image.open("tests/fixtures/tests_samples/COCO/000000039769.png")
question = "What is in this image?"

# 注意:图片与文本必须由同一个 processor 处理,processor 会自动完成 resize/rescale/normalize 与 tokenize
inputs = processor(images=image, text=question, return_tensors="pt").to(model.device, torch.float16)

# BLIP 为 encoder-decoder 结构,最终答案通过自回归生成得到
output = model.generate(**inputs)
print(processor.batch_decode(output, skip_special_tokens=True)[0])

要点拆解:

  • processor(...) 一次性把图片变成 pixel_values、把问题变成 input_ids/attention_mask,并统一移动到模型所在设备、转为 fp16;
  • 由于输出是文本而非 logits 取 argmax,VQA 必须走 generate()
  • processor.batch_decode(output, skip_special_tokens=True) 负责去掉 BOS/SEP/PAD 等特殊 token 后还原答案字符串。

三个下游模型类:按任务选择正确的入口

文档特别强调:BlipModel 属于早期综合入口,后续版本将弃用,应按任务在三个专用模型中选择(官方提示见 docs/source/en/model_doc/blip.mdmodeling_blip.py):

模型类 适用任务 结构组成
BlipForConditionalGeneration 图像描述(captioning)、以文本为前缀的条件生成 视觉编码器 BlipVisionModel + 文本解码器 BlipTextLMHeadModel
BlipForQuestionAnswering 视觉问答(VQA) 视觉编码器 + 文本编码器(带交叉注意力融合图像)+ 文本解码器
BlipForImageTextRetrieval 图文检索 / ITM 匹配打分 视觉编码器 + 文本编码器 + 投影层 + ITM 分类头
BlipModel(已弃用) 通用对比学习入口(近似 CLIP) 双塔编码器 + 投影 + logit scale

BlipForConditionalGeneration:图像描述与条件文本生成

该类在 modeling_blip.py 中实现,main_input_name = "pixel_values",结构为 BlipVisionModel + BlipTextLMHeadModel。其 forward 先将图片编码为 image_embeds,再以 encoder_hidden_states=image_embeds 送入文本解码器做交叉注意力(源码 L830-L846)。

该类的 generate 覆盖了父类实现(源码 L857-L932),行为要点如下:

  • 不传 input_ids 时,解码器从 [BOS]bos_token_id=30522)开始生成纯图像描述;
  • input_ids 时,它会作为文本 prompt,让解码器“续写”——这正是文档所述“以文本前缀引导生成”的能力;
  • 生成阶段 eos_token_id 被设为 sep_token_id(102),pad_token_id 为 0。
from PIL import Image
from transformers import AutoProcessor, BlipForConditionalGeneration

processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")

image = Image.open("tests/fixtures/tests_samples/COCO/000000039769.png")
# 不传 text:纯图像描述
inputs = processor(images=image, return_tensors="pt")
print(processor.decode(model.generate(**inputs)[0], skip_special_tokens=True))

# 传 text 作为前缀:条件生成(prompt-guided captioning)
inputs = processor(images=image, text="A picture of", return_tensors="pt")
print(processor.decode(model.generate(**inputs)[0], skip_special_tokens=True))

BlipForQuestionAnswering:视觉问答

该类结构为“视觉编码器 + 文本编码器 + 文本解码器”(源码 L942-L955),与 captioning 的关键差异在于引入了一个文本编码器:它先让问题 token 与图像特征做交叉注意力(question_embeds),融合后的表示再作为解码器的 encoder_hidden_states 输出答案(源码 L1033-L1055)。

forward 有一个必须遵守的约束(源码 L1017-L1022):必须传入 decoder_input_idslabels 之一。训练时传 labels(源码注释说明 labels 已被右移,符合 #23153 的约定),推理时调用 generate()。VQA 训练片段(从模型 docstring 提取):

# 训练:question 作为编码器输入,answer 作为解码器监督
inputs = processor(images=image, text="How many cats are in the picture?", return_tensors="pt")
labels = processor(text="2", return_tensors="pt").input_ids
inputs["labels"] = labels

outputs = model(**inputs)
loss = outputs.loss
loss.backward()

# 推理
inputs = processor(images=image, text="How many cats are in the picture?", return_tensors="pt")
print(processor.decode(model.generate(**inputs)[0], skip_special_tokens=True))

BlipForImageTextRetrieval:图文检索与 ITM 打分

该类对应理解型任务(源码 L1165-L1182),在视觉编码器与文本编码器之上增加:

  • vision_proj / text_proj:将两侧特征投影到 image_text_hidden_size=256 的共享空间;
  • itm_headLinear(text_hidden_size, 2) 的图像-文本匹配分类头。

forward 通过 use_itm_head 开关支持两种打分模式(源码 L1248-L1270):

  • use_itm_head=True(默认):对“图文是否匹配”做二分类,取 [CLS] 位置的 logits;
  • use_itm_head=False:对 vision_proj/text_proj 投影后的 [CLS] 特征做 L2 归一化后点积,得到余弦相似度作为检索分数。
from PIL import Image
from transformers import AutoProcessor, BlipForImageTextRetrieval

processor = AutoProcessor.from_pretrained("Salesforce/blip-itm-base-coco")
model = BlipForImageTextRetrieval.from_pretrained("Salesforce/blip-itm-base-coco")

image = Image.open("tests/fixtures/tests_samples/COCO/000000039769.png")
inputs = processor(images=image, text="an image of a cat", return_tensors="pt")

# ITM 二分类 logits:判断该文本是否与该图匹配
outputs = model(**inputs)
print(outputs.itm_score)

已弃用的 BlipModel 与特征提取接口

BlipModel源码 L509)是类 CLIP 的双塔对比学习封装:文本塔 BlipTextModel 与视觉塔 BlipVisionModel 分别输出特征,经 text_projection/visual_projection 投影到 projection_dim=512 并 L2 归一化,相似度乘以可学习的 logit_scale(初始值 2.6592,见配置)得到 logits_per_image/logits_per_text源码 L730-L758)。训练目标是对称的 image_text_contrastive_loss(该函数与 contrastive_loss 均直接拷贝自 CLIP 实现,源码 L44-L53)。

即使该类即将弃用,其三个特征接口仍值得理解,因为它们的逻辑被下游模型复用:

  • get_text_features:纯文本编码,pooler_output 经过 text_projection
  • get_image_features:纯图像编码,pooler_output 经过 visual_projection
  • get_multimodal_features:先视觉编码得到 image_embeds,再将其作为 encoder_hidden_states 喂给文本编码器做交叉注意力,返回融合了图文信息的“多模态特征”。

配置类深度解析:BlipConfig / BlipTextConfig / BlipVisionConfig

BLIP 是一个复合架构,因此配置被拆成三个类,位于 configuration_blip.pyBlipConfig 通过 sub_configs = {"text_config": BlipTextConfig, "vision_config": BlipVisionConfig}源码 L145)把两个子配置聚合为一个整体——这正是 AutoModel/AutoProcessor 加载时能看到统一 config.json 的原因。

BlipVisionConfig(视觉塔,model_type="blip_vision_model"

参数 默认值 说明
hidden_size 768 Transformer 隐藏维度
intermediate_size 3072 FFN 中间层维度
projection_dim 512 对比学习投影输出维度
num_hidden_layers 12 编码器层数
num_attention_heads 12 注意力头数
image_size 384 输入图像边长(预训练分辨率)
patch_size 16 Patch 尺寸,patch 数 = (384/16)² = 576
hidden_act "gelu" FFN 激活函数
layer_norm_eps 1e-5 LayerNorm epsilon
attention_dropout 0.0 注意力 dropout
initializer_range 1e-10 权重初始化范围

以上默认值对应 configuration_blip.py L97-L107

BlipTextConfig(文本塔/解码器,model_type="blip_text_model"

参数 默认值 说明
vocab_size 30524 词表大小
hidden_size 768 隐藏维度
encoder_hidden_size 768 交叉注意力的 key/value 维度(被强制同步为视觉塔 hidden_size)
intermediate_size 3072 FFN 中间层维度
projection_dim 768 文本侧投影维度
num_hidden_layers 12 Transformer 层数
num_attention_heads 8 注意力头数
max_position_embeddings 512 文本最大序列长度
hidden_dropout_prob 0.0 隐藏层 dropout
attention_probs_dropout_prob 0.0 注意力 dropout
bos_token_id 30522 生成起始符
eos_token_id 2 结束符
pad_token_id 0 填充符
sep_token_id 102 分隔符(生成阶段的 eos 实际使用它)
is_decoder True 是否以解码器模式运行
use_cache True 生成时使用 KV cache
tie_word_embeddings True 输入输出词嵌入权重共享
label_smoothing 0.0 训练损失标签平滑系数,取值范围 [0,1]

对应 configuration_blip.py L52-L72。值得注意 tie_word_embeddings=True 与解码器头部实现是配套的:BlipForConditionalGeneration/BlipForQuestionAnswering 通过 _tied_weights_keys 显式声明了 text_decoder.cls.predictions.decoder.weight 与 word embedding 之间的权重共享关系(见 modeling_blip.py L772-L775)。

BlipConfig(聚合配置,model_type="blip"

参数 默认值 说明
projection_dim 512 图文投影统一维度
logit_scale_init_value 2.6592 对比学习温度参数初值
image_text_hidden_size 256 图文融合层(retrieval 的 proj 层)隐藏维度
label_smoothing 0.0 解码器 LM loss 标签平滑系数
initializer_factor 1.0 初始化缩放因子
initializer_range 0.02 初始化范围

BlipConfig__post_init__源码 L157-L172)负责收尾:两个子配置若传 dict 会被实例化为对应类;若为空则使用默认值;同时强制 text_config.encoder_hidden_size = vision_config.hidden_size,从配置层保证交叉注意力的维度一致性。使用时可像源码 docstring 演示的那样分别构造再合并:

from transformers import BlipConfig, BlipTextConfig, BlipVisionConfig

config = BlipConfig(text_config=BlipTextConfig(), vision_config=BlipVisionConfig())
# 等价于 BlipConfig(),二者都会被自动实例化并完成维度同步

预处理与 Processor:图片与文本的标准化入口

BLIP 的多模态输入需要在同一入口统一处理,仓库提供了三个类(image_processing_blip.pyimage_processing_pil_blip.pyprocessing_blip.py):

  • BlipImageProcessor:基于 TorchvisionBackend 的图像处理器,类属性即默认预处理策略——BICUBIC 重采样、size={"height": 384, "width": 384}default_to_square=Truedo_convert_rgb=True,均值/方差采用 OpenAI CLIP 的 OPENAI_CLIP_MEAN/OPENAI_CLIP_STDimage_processing_blip.py L21-L31),完整流程为 Resize → Rescale → Normalize → Convert RGB;
  • BlipImageProcessorPil:同配置的纯 PIL 后端版本,为不依赖 torchvision 的环境提供等价功能(其 preprocess 同样被 docs/source/en/model_doc/blip.md 的 autodoc 覆盖);
  • BlipProcessorProcessorMixin 的组合处理器,构造时接收 image_processortokenizer,并强制 tokenizer.return_token_type_ids = False(BLIP 不使用 token type ids,见 processing_blip.py L42-L48)。

AutoProcessor 就是根据 checkpoint 的 preprocessor_config.json 自动选择这三个类中合适组合的便捷入口,因此上文所有示例都推荐用 AutoProcessor.from_pretrained

源码级架构剖析:从 Patch 到融合表示

视觉塔:ViT 式 Patch Embedding + 可插值位置编码

BlipVisionEmbeddingsmodeling_blip.py L172-L243)用卷积核/步长均为 patch_sizenn.Conv2d(3, 768, 16, 16) 切 patch,前置一个可学习的 class token,并采用可学习位置编码。它实现了一个对实战很有价值的机制——interpolate_pos_encoding:当输入图片分辨率不是训练时的 384×384 时,位置编码会沿空间维度做 bicubic 插值(对齐 DINO/DINOv2 的做法),从而支持任意分辨率输入。这在文档介绍的高分辨率推理场景中尤为重要。

BlipVisionModel.forward源码 L473-L498)返回 BaseModelOutputWithPoolinglast_hidden_state 经过 post_layernormpooler_output[CLS] 位置再做一次 LayerNorm。

文本塔:可复用的 decoder 结构

BlipTextModel/BlipTextLMHeadModel 被拆分在独立的 modeling_blip_text.py 中,其中注意力层同时支持自注意力与针对图像特征的交叉注意力(encoder_hidden_states 参数)。BlipTextLMHeadModel 在文本塔之上叠加 LM Head,作为 captioning 与 VQA 的共享解码器组件被两个上游模型类复用——这是理解 BLIP 各模型参数重叠关系的钥匙。

权重转换、回归测试与生态集成

  • 权重转换脚本convert_blip_original_pytorch_to_hf.py(192 行)内含 rename_key 函数,负责把 Salesforce 官方 PyTorch checkpoint 的 key 名映射为 HF 命名规范,供从官方仓库移植自定义检查点使用。
  • 回归测试tests/models/blip 目录下四个测试文件覆盖模型前向(test_modeling_blip.pytest_modeling_blip_text.py)、图像预处理(test_image_processing_blip.py)与 Processor 文本-图像联合处理(test_processing_blip.py)。阅读这些测试可以快速确认处理器默认参数的边界行为与各模型类的输入输出张量形状。
  • Auto 体系接入:BLIP 家族注册在多张 Auto 映射表中——MODEL_MAPPING(blip→BlipModel)、MODEL_FOR_CAUSAL_LM_MAPPING(blip→BlipForConditionalGeneration)以及 VQA、Retrieval 映射(见 modeling_auto.py)。这也解释了为何同一个 blip 架构能通过 AutoModelForVisualQuestionAnswering 等多种 Auto 类按需加载,同时也为后续扩展(如 BLIP-2)共用架构名埋下伏笔。

模型取舍与常见问题小结

  1. 该选哪个类? 描述/条件生成用 BlipForConditionalGeneration,VQA 用 BlipForQuestionAnswering,打分/检索用 BlipForImageTextRetrieval;不要在新代码中使用将被弃用的 BlipModel
  2. 分辨率限制与扩展:默认 image_size=384patch_size=16。对更高分辨率图片,可在配置中调大 image_size 或利用位置编码插值机制直接传入大图。
  3. 文本超长怎么办:文本侧 max_position_embeddings=512,超出会在 BlipTextEmbeddings 中直接抛错(modeling_blip.py L267-L271),预处理时应按需截断。
  4. 继续深入:上文涉及的官方模型文档原文位于 docs/source/en/model_doc/blip.md;本文所引配置、模型与处理器实现分别在 src/transformers/models/blip/ 下的 configuration_blip.pymodeling_blip.pymodeling_blip_text.pyprocessing_blip.py 与两个 image_processing* 文件中,可作为进一步阅读与二次开发的起点。
登录后查看全文
热门项目推荐
相关项目推荐