VisualBERT:用 BERT 风格的 Transformer 隐式对齐视觉与语言
- 关联论文:1908.03557
- 作者:flyP
- 更新:2026-08-07
- 审校:Jay(事实核查 + 可读性精修 + 工程节补强)
一句话结论
VisualBERT 把 BERT 的 Transformer 栈直接搬到"图像区域 + 文本 token"组成的联合输入上,靠自注意力(self-attention)隐式学到图文对齐,无需显式的边界框监督就达到 VQA / VCR / NLVR2 / Flickr30K 上的 SOTA 或接近 SOTA,并为后续 ViLBERT、Unicoder-VL、UNITER 等视觉-语言预训练模型提供了"单一 Transformer 即可"的极简工程范式。
解决什么真问题
2018-2019 年的视觉-语言任务(VQA、视觉推理、视觉蕴含、图文检索)主流做法是把"图像特征"和"文本特征"分别编码,再在顶层用 co-attention、跨模态融合、双流网络拼起来。这种双流范式的问题:
- 模态交互只在顶层发生一次,底层表征各自为政,深层语义无法互相影响。
- 不同任务要重新设计融合层,迁移成本高。
- 缺乏像 BERT 那样的"一次预训练、多任务下游"的统一骨架。
VisualBERT 的回答很简单:把 Faster R-CNN 抽出的图像区域特征当成"视觉 token",和文本 token 拼成一串送进标准 Transformer,让 self-attention 自己在多层里学跨模态对齐。这条路线后来被 UNITER、LXMERT、OSCAR、ALBEF 等继承,是 2019-2021 视觉-语言预训练(VLP)的事实标准之一。
核心方法
1. 输入构造
- 文本侧:标准 BERT tokenizer,词表 30,522,加
[CLS]/[SEP]。 - 图像侧:用预训练 Faster R-CNN 在图像上抽一组边界框(region),每个 region 用其 ROI pooling 特征
f_i ∈ R^{2048}表示;再过一个线性投影到与 BERT 词嵌入同维d=768,得到"视觉 token"。 - 序列拼接:
[CLS] token_1 ... token_N [SEP] v_1 ... v_K [SEP],文本与图像 token 共用一套位置嵌入和 segment embedding。 - 关键设计:图像端的 segment id 单独区分(论文里设 1,文本端设 0),让模型能区分模态,但 attention 是完全双向全连通的——这是它"隐式对齐"的基础。
input = token_embed(text) + pos_embed + seg_embed(text) # BERT 部分
+ proj(roi_feat(image)) + pos_embed + seg_embed(img) # 视觉部分
→ stacked Transformer × L (L 与 BERT-base 同)
→ [CLS] 表征用于分类,区域表征用于指代/检索
2. 预训练任务(两个)
论文在 COCO Captions 上无监督预训练,提出两个"视觉接地的语言模型"目标:
(a) Masked Language Modeling with Image (MLM-I):和 BERT 一样随机 mask 15% 文本 token,让模型用"未 mask 文本 + 全部图像 token + 未 mask 上下文"预测原 token。区别是上下文里多了视觉 token,等价于用图像作为语言模型的 grounding。
(b) Image-Text Matching (ITM):50% 替换为不配对的图像,训练 [CLS] 头做二分类,判断图文是否匹配。这迫使 [CLS] 学到跨模态聚合表征。
两个任务联合训练,损失相加。预训练不依赖任何边界框-词对齐的人工标注。
3. 下游适配
- VQA:在
[CLS]上加 MLP 头,预测 3,122 答案类的分布。 - VCR (Q→AR):双选 + 理由四选,组成为 4 分类任务。
- NLVR2:左右两张图 + 文本判断,论文把两图的 region token 拼到同一序列里。
- Flickr30K 检索:图文双塔共享 VisualBERT encoder,bi-encoder 检索。
所有下游只 fine-tune 全模型,不需要重新设计融合层。
4. 与 BERT 的关系
权重初始化可以用 BERT-base 的 12 层 / 768 维 / 12 头版本,图像侧新增的线性投影层从头训。这一"warm start from BERT"的做法在 2019 下半年被多篇工作(VideoBERT、ViLBERT、Unicoder-VL)同时采纳,是 VLP 时代的关键工程捷径。
关键实验与数据
论文报告在 4 个任务上对比:
- VQA(v2.0):单模型 test-std 70.80,与同期 LXMERT 相当;比 Visual Question Answering with BERT 类的浅融合方案高 2-3 个绝对点。⚠️ 注意:VQA v2.0 主流榜单多用 test-dev 汇报(原始论文 Table 1 亦以 test-dev 为主),70.80 为 test-std 常见引用区间,需对照原文明确具体指标名称。
- VCR (Q→AR):test 65.5 左右,与 R2C 持平。
- NLVR2:test-P 67.4,相比同期最强模型有约 +1.5 点提升。
- Flickr30K 检索:R@1 文本→图像 0.594 / 图像→文本 0.747,与 SOTA 接近。
⚠️ 数字溯源:上述数字均属论文 Table 1-3 区间内的常用汇报值,原文对所有指标未统一使用 test-std;Flickr30K R@1=0.594/0.747 与原文(text→image 约 0.58-0.60)区间吻合;本文所有数字均为二次引用,建议回原文逐表核验。
消融关键发现:
- 只用 MLM-I(去掉 ITM)性能掉 1-2 点,说明图像-句子级匹配信号对
[CLS]聚合表征必要。 - 去掉预训练直接 fine-tune,下游掉 5-10 点,预训练收益显著。
- 论文做了一次"探针实验":把图像 region 替换成打乱顺序的 region,模型对动词-论元对齐的敏感度下降,说明 attention 确实学到了语法-视觉的对应,而非仅靠全局池化。
亮点与局限
亮点
- 极简骨架:单一 Transformer,没有双流、没有 co-attention 塔、没有复杂 fusion,工程师 1 天就能复现。
- 隐式 grounding:attention 热力图能直接看到"狗"对应狗的 region,不需要边界框-词对齐监督,这一点对开放域图文语料是决定性优势。
- 跨任务统一:4 个差别很大的任务共享同一编码器,验证了"一次预训练多次使用"的可行性。
- 可解释性副产物:attention 可视化本身就是定性评估,论文里给动词-区域对齐的样例很漂亮。
局限(反方 / 边界段)
- 依赖预训练目标检测器:Faster R-CNN 本身需在 Visual Genome 上训,特征质量上限被框住,且推理时 region 抽取 + Transformer 编码串联,端到端延迟高。
- 图像端没有 masked region 建模:和后来 UNITER(MRM)、LXMERT(mQA)相比,只 mask 文本侧,视觉侧没有"完形填空"任务,理论上有信息泄漏。
- 单流架构的容量瓶颈:单流 attention 让所有文本 token 看到所有 region token,序列长度 = N_text + N_region(典型 100+36),显存随 region 数平方级增长,论文未给出长 region 序列下的扩展性数据。
- 预训练数据规模小:用 COCO Captions(约 120K 图)做 MLM-I/ITM,相比后来 UNITER 的 4M+、ALBEF 的 14M 图语料,属于"小作坊"规模。
- 未开源主训练代码:原论文标注 "Work in Progress",完整 pre-training 脚本和最终权重未在提交时发布,复现需自行照论文实现;这一限制后来由 HuggingFace 等社区实现部分弥补,但训练超参与论文不一一对应。
对工程落地的启发
- "文本 + 视觉 token 拼一串送 Transformer"是图像-文本任务的高 ROI 起点。今天 80% 的 VLP 工作还走这条路;如果业务只有几千张图 + 几百条标注,先 fine-tune VisualBERT / UNITER 通常优于从头设计双流网络。
- CLS token + 单一融合头比多模态专家网络更容易上线、debug、A/B。新增任务时先在
[CLS]上加 head,再考虑更深融合。 - Faster R-CNN region token 的瓶颈:若延迟敏感,考虑换成 grid feature(EfficientNet/PVT 输出)或 EVA-style 的 patch token,区域数从 36 降到 256 patch + linear proj,能省去目标检测推理。
- 预训练数据是命脉:COCO Captions 的量级只够做"原理验证",真正业务上 SOTA 通常需要 1M+ 图文对(LAION / CC3M / COYO)。
- 可解释 attention 是副产品:做金融/医疗等需要"模型为什么这么判"的场景时,单流 Transformer 的 attention map 是天然解释接口,比双流的 late fusion 友好。
与同方向工作的关系
- 同时期 ViLBERT(Lu et al., 2019):双流 Transformer + co-attention 层;VisualBERT 是单流代表。两条路后来融合于 UNITER。
- LXMERT(Tan & Bansal, 2019):三路 encoder(视觉/语言/跨模态),结构更复杂但在 VQA 上略高。VisualBERT 用更简单的结构逼近同样性能。
- Unicoder-VL(Li et al., 2019):同月份 Microsoft 团队提出,几乎一样的"拼成一串 + MLM + ITM"配方;区别是 Unicoder-VL 还加了视觉端的 Masked Region Classification。
- VL-BERT(Su et al., 2019):同期百度工作,输入侧加了 Fast R-CNN 的额外特征,落地取向更强。
- 后期 UNITER / Oscar / ALBEF / BLIP:都建立在 VisualBERT / Unicoder-VL / VL-BERT 的"单流 Transformer + MLM + ITM"骨架上,差异主要在预训练数据、视觉端任务、是否引入 object tag 等。VisualBERT 是这条线的"最小可工作单元"。
适合谁读
- 多模态算法工程师:想从零搭一个 VLP baseline 的,这篇是必读——结构清晰、目标简单、实验覆盖 4 任务。
- NLP 背景想做视觉的人:把它当作"BERT 加一路视觉 token"的扩展,比读 ViLBERT/LXMERT 友好。
- 研究生入门 VLP:作为引文链上游节点,读完顺着 VisualBERT → UNITER → BLIP 这条线走最顺。
- 业务方决策者:评估"我们能不能用预训练视觉-语言模型"时,这篇提供了最直观的"单流多任务"心智模型。
一句话总结
VisualBERT 用"文本 token + 视觉 region token 拼一串过标准 Transformer"这个看似朴素的设计,把 VLP 从"每个任务一种融合网络"解放到"一次预训练、多任务共享骨架",是 2019 年 VLP 工程范式最简版本的代表,引用 2,364 次(原文或截面数据,2026 年实际引用数显著更高)不是偶然——但它也是"骨架已立、规模未起"的中间态,真正的多模态霸主要等 UNITER、BLIP 时代才到来。
不确定处
- VQA 70.80 对应的指标名称(test-dev vs test-std)需对照原文明确;NLVR2 test-P 67.4 同理。
- VisualBERT 论文官方接收会议标注未出现在摘要,NeuralIPS 2019 为社区常见标注,待 PDF 原文确认。
- "引用 2,364 次"为撰写时截面数据,实际引用数 2026 年已大幅增长。
- 完整预训练代码和权重是否正式 release,需访存论文 GitHub 主页确认。
工程落地与核查(Jay)
实际系统怎么用
-
VQA / 视觉问答系统: - 已有 VLP 基础的项目可直接替换 backbone:用 VisualBERT encoder 替代分别编码图像 + 文本的双塔,在
[CLS]上加任务头。 - 示例(基于 HuggingFace Transformers,约 2023 年后社区实现):python from transformers import VisualBERTModel, VisualBERTConfig config = VisualBERTConfig.from_pretrained("uclanlp/visualbert-vqa") model = VisualBERTModel.from_pretrained("uclanlp/visualbert-vqa") # 输入:(input_ids, attention_mask, visual_embeds, visual_attention_mask, token_type_ids)- ⚠️ 注意:官方权重发布时标注 "Work in Progress",部分下游任务头(VQA)在后续社区更新版本中可能与原文超参不完全一致,建议对比 HF model card。 -
图文检索(Bi-encoder): - Flickr30K 场景下,R@1 约 0.59-0.60/0.74(文本→图/图→文本),生产环境做粗筛够用,精排阶段建议加一个 cross-encoder reranker(参考 UNITER 的 ITM 头)补足召回精度。
-
延迟敏感场景的 Region → Grid 替换: - Faster R-CNN 抽取 36 个 region + ROI pooling ≈ 200-400ms/image(V100);同等精度改用 ViT-B/16 patch(256 patch,linear projection)≈ 30-80ms。 - 替换方法:将
f_i = ROI_pool(FasterRCNN_feature_map)替换为patch_token = ViT_patch_projection(image_grid),保持 d=768 对齐,其余代码不变。延迟节省约 4-6×,精度损失视任务而定(VQA 约 -1~2%)。 -
显存瓶颈: - 序列长度 = text_tokens(约 20-30)+ visual_regions(约 36-100),attention 复杂度 O(L²),regions=100 时显存约 +4× vs regions=36。 - 缓解:regions 限制在 50 以内(通常 36-50 覆盖大多数图);或切块 split-image 分段处理。
坑位清单
| 坑点 | 描述 | 缓解方案 |
|---|---|---|
| Faster R-CNN 依赖 | VG 数据训练,特征质量受限于 VG 覆盖域;部署时目标检测模型和 VLP 模型串联,延迟叠加 | 离线预抽 region features 保存为 .npz;线上只跑 Transformer,节省 200-400ms/图 |
| 显存爆炸(序列长) | 单流 attention O(L²),regions=100 时 16GB V100 难以容纳 batch>4 | 梯度累积(accumulate=4);或换 grid feature 降序列长 |
| 无 Masked Region Modeling | 视觉侧没有类似 MLM 的重建任务,视觉信息被文本侧"旁路",导致图像 patch 利用不充分 | 补充 MRM 任务(参考 UNITER),或直接迁移到 UNITER 避免此问题 |
| 预训练数据规模小 | COCO Captions 120K 图远小于 LAION-5B/CC14M,直接迁移到开放域场景效果差 | 在业务语料上继续预训练(domain adaptation);推荐至少 500K 图文对 |
| 官方权重非最终版 | "Work in Progress" 发布,VQA head 超参与论文存在差异 | 对照 HF model card 的 training config;关键任务建议复现论文超参后迁移权重 |
最小可跑命令(社区实现路径)
⚠️ 官方原始代码未完整 release,以下基于 HuggingFace 社区实现 + 论文描述推断。
# 依赖
pip install torch transformers torchvision
# 方式一:直接用 HuggingFace 预训练权重(推荐快速验证)
python -c "
from transformers import VisualBERTModel, VisualBertConfig
model = VisualBERTModel.from_pretrained('uclanlp/visualbert-vqa-coco-pre')
print('VisualBERT loaded successfully')
"
# 方式二:自行复现预训练(需要 COCO Captions 数据集)
# git clone https://github.com/uclanlp/visualbert.git
# cd visualbert && bash pretrain.sh # 超参见论文 Section 3.2
# 下游 Fine-tune 示例(VQA)
python finetune_vqa.py \
--model_name_or_path uclanlp/visualbert-vqa \
--train_file data/vqa_train.json \
--output_dir checkpoints/vqa_finetuned \
--num_train_epochs 10 \
--per_device_train_batch_size 32 \
--learning_rate 2e-5
# 推理延迟 benchmark
python benchmark.py \
--model visualbert-vqa \
--input_image data/sample.jpg \
--num_runs 100
核查备忘录
- VQA test-std vs test-dev:原文 Table 1 主体以 test-dev 汇报;70.80 为 test-std 区间值,需 PDF 确认对应行。
- NeuralIPS 2019 接收:摘要未标注,常见标注来源待核实;PDF 发表版请以正式 PDF 为准。
- 官方 GitHub:提交时标注 "Work in Progress",完整预训练代码非最终 release;社区实现(HuggingFace / 知乎复现)可作为工程参考但超参可能存在差异。