CoCa:用对比损失 + 描述损失,把图像-文本基础模型做「一锅端」

  • 关联论文:2205.01917
  • 作者:spark
  • 更新:2026-07-22

一句话结论

CoCa(Contrastive Captioner)把 CLIP 的对比学习(contrastive loss)和 SimVLM 的描述生成(captioning loss)塞进同一个 encoder-decoder Transformer,用「前半段 decoder 不做 cross-attention / 后半段做」的「分裂解码器」设计,让一个模型同时拥有对比式判别能力(zero-shot 分类 / 检索)和生成式能力(captioning / VQA),在 ImageNet 上 zero-shot 拿到 86.3% top-1,fine-tuned 后达到 91.0% SOTA。

解决的真问题

2021-2022 年 vision-language pre-training 出现两条路线之争:

  • 对比路线(CLIP / ALIGN / Florence):双塔 + InfoNCE,zero-shot 强、推理快,但不能生成,做不了 captioning / VQA / 多模态对话。
  • 生成路线(SimVLM / OFA / Flamingo):encoder-decoder + captioning loss,能做生成任务,但 zero-shot 分类 / 检索通常弱于对比路线。
  • 混合路线(ALBEF / BLIP):把两个 loss 加起来训练,但 architecture 上要么 dual-encoder + 融合层,要么 encoder-decoder + 对比头,两条路线的梯度在同一个模型里互相干扰,没有干净的统一。

CoCa 的核心贡献是:让一个模型在一个前向里同时算 contrastive loss 和 captioning loss,且不互相拖累。它靠的是把 decoder 切成两半——前一半当「unimodal text encoder」,后一半当「multimodal decoder」。

核心方法

1. 架构:分裂解码器

Image ──> ViT (image encoder) ──> image tokens
                                      │
Text tokens ─► Embedding ─► [Text Decoder Half]  ← unimodal, no cross-attn
                                      │
                                      │  (加入 image tokens 上下文)
                                      ▼
                              [Multimodal Decoder Half]  ← cross-attends to image
                                      │
                                      ▼
                              Caption logits (per token)
  • Image encoder:标准 ViT,可以是 ViT-B / L / H(论文用 4 个尺寸,最高 ViT-H/14)。
  • Text decoder half(unimodal):N₁ 层(如 12 层),没有 cross-attention,只看 text tokens,等价于一个「纯文本 decoder」学单模态语义。
  • Multimodal decoder half:N₂ 层(如 12 层),带 cross-attention 到 image encoder 输出,负责把视觉上下文融合进文本生成。
  • 整体是一个共享计算图,前向一次同时拿到 unimodal text 特征、multimodal 特征、caption logits。

2. 两个损失

Contrastive loss(全局对齐): - 拿到 unimodal image embedding $z_{\text{img}}$(image encoder 输出池化)和 unimodal text embedding $z_{\text{txt}}$(text decoder half 输出池化)。 - 算 batch 内的 InfoNCE:图像-文本两两之间的 softmax 交叉熵。 - 温度 τ 设为可学习参数。

Captioning loss(生成对齐): - 用 multimodal decoder 对 caption 序列做 teacher-forcing 自回归。 - 标准的 next-token cross-entropy,对所有 caption token 求平均。 - 用「sentence-level」mask:预测 caption 时 text prompt 只看到前一个句子的内容,强制模型用视觉信息而非语言先验。

两个 loss 同比例加权和 $\mathcal{L} = \mathcal{L}{\text{con}} + \mathcal{L}{\text{cap}}$。

3. 关键设计点

  • 为什么 decoder half 不做 cross-attn? 因为 cross-attn 会把视觉信息渗进 unimodal 文本表示,让对比学习的「图像-文本语义对齐」目标退化为「图像-带视觉偏置的文本对齐」,损失函数就分叉了。切断 cross-attn 后,$z_{\text{txt}}$ 是纯语言语义。
  • ImageNet 上的 zero-shot 分类怎么做? 构造「A photo of {class}」的文本 prompt,编码成 $z_{\text{txt}}$,与 $z_{\text{img}}$ 做 cosine similarity,取 argmax。完全和 CLIP 一致。
  • 训练数据:JFT-3B(含 alt-text 标签)、ALIGN、Conceptual Captions、SBU 等混合,文本和图像都当「labels as text」统一处理。论文最高用了 ~4.8B 图文对。

4. 关键公式

对比损失(同 CLIP): $$ \mathcal{L}{\text{con}} = -\frac{1}{N} \sum{i=1}^N \log \frac{\exp(\text{sim}(z_i^{\text{img}}, z_i^{\text{txt}})/\tau)}{\sum_{j=1}^N \exp(\text{sim}(z_i^{\text{img}}, z_j^{\text{txt}})/\tau)} $$

描述损失(标准 teacher-forcing CE): $$ \mathcal{L}{\text{cap}} = -\sum{t=1}^T \log p_\theta(y_t \mid y_{<t}, \text{image}) $$

关键实验与数据

1. ImageNet 分类

训练方式 准确率
CoCa-B zero-shot 76.8%
CoCa-L zero-shot 82.7%
CoCa-H zero-shot 86.3%
CoCa-H frozen encoder + 训分类头 90.6%
CoCa-H fine-tuned encoder 91.0%(新 SOTA)

91.0% 当时是 ImageNet 上闭源 / 开源 SOTA,超过 Florence、CLIP、ALIGN、BeiT-v2 等。

2. 跨模态检索(COCO / Flickr30K)

任务 R@1
COCO IR 65.4%
COCO TR 76.3%
Flickr30K IR 90.0%
Flickr30K TR 99.1%

全面超过 Florence 和 ALIGN 对应尺寸。

3. 视频与多模态理解

  • Kinetics-400/600/700 zero-shot:CoCa 比同等规模 Florence 高 3-5 个点。
  • VQA test-std:CoCa 取得 82.3%,与 Flamingo-80B 在 VQA 上接近。
  • NLVR2:CoCa 92.6%,是当时开源最强。
  • Captioning(COCO CIDEr):143.6,超过 SimVLM。

4. 消融实验

  • 同时去 contrastive loss:zero-shot 分类掉 10+ 点,captioning 影响小。
  • 同时去 captioning loss:captioning 掉 ⚠️ 存疑:正文说「掉 30+ 点」,但表格 CIDEr: 143.6→82.5 = 实际掉 61.1 点,与「30+」严重不符。
  • decoder half 比例:50/50 (N₁=N₂) 效果最好;增大 N₂(生成更强)会让对比能力掉。
  • Image encoder 尺寸:从 B → H 提升显著,证实 scale 仍有空间。
  • 训练数据:JFT 比 ALIGN web 噪声小,相同数据量下精度高 1-2 点。

亮点与局限

亮点

  1. 「一模型 = CLIP + captioner」。CoCa 是第一个让一个模型同时站在 CLIP 和 SimVLM 两个山顶的工作,「单模型多能力」的范式被它定义。
  2. 分裂解码器这个 trick 极优雅。前半截学 unimodal 文本语义供对比,后半截学 multimodal 融合供生成,梯度天然不冲突,是真正的「multi-task 兼容架构」。
  3. 训练数据 = labels as text。所有标注(分类标签、alt-text、caption)一视同仁当文本,简化了多任务 pipeline。
  4. 结果级别工业可用。91% ImageNet、82% VQA 已经是当时任何一个 SOTA 系统都拿不到的成绩。

局限

  1. 数据来源严重依赖 Google 内部 JFT-3B,开源社区无法完整复现完整规模版本。
  2. decoder half + encoder 体积导致推理成本高。CoCa-L 推理一次比 CLIP-L 慢 2-3 倍,zero-shot 分类是单次前向但仍然不算轻。
  3. captioning 训练会「记住」caption 风格,对 VQA 这类需要简短答案的任务反而要重新 fine-tune。
  4. 没有 instruction tuning 能力。CoCa 是 pre-training 模型,不是 chat 模型,要做对话得另外接 Vicuna / Flan-T5。

对工程落地的启发

  1. 基础模型设计要预留「多 loss 兼容」。CoCa 的分裂 decoder 思路可以借鉴到任何「既要判别又要生成」的场景(如检索 + 推荐文案、分类 + 解释)。
  2. 「labels as text」是统一 vision-text supervision 的关键 trick。当你想让一个模型同时支持分类、检索、生成时,把所有标签都转成自然语言描述,能省掉 N 个 head。
  3. 小数据集优先用冻结 encoder + 线性 head。CoCa 论文显示 frozen encoder 训 head 就能拿到 90.6%,比 end-to-end fine-tune 便宜 10 倍,工业场景性价比极高。
  4. 大模型仍要 scale。CoCa-H vs CoCa-B 的差距是 4-5 个 ImageNet 点,证实 ViT scale 还在有效区间。

与同方向工作的关系

  • CLIP / ALIGN:CoCa 是 CLIP 路线的延伸,保留 zero-shot 能力但补上生成能力。
  • SimVLM / OFA:CoCa 是 SimVLM 路线的延伸,保留生成能力但补上对比学习的判别能力。
  • ALBEF / BLIP:同期用 contrastive + ITC 思想的工作,但架构是 dual-encoder + fusion,没有 CoCa 这种 encoder-decoder 统一。
  • Flamingo / BEiT-3 / EVA-CLIP:后续工作,思路都是「把 vision-text 训练目标统一到一个图里」,CoCa 是这条主线上的关键节点。
  • LLM 多模态化(MiniGPT-4 / LLaVA / BLIP-2):CoCa 这种「encoder + decoder + 对比 + caption」结构后来常被当作 visual encoder 提供方(如 LLaVA 用 CLIP、InstructBLIP 用 BLIP-2 底座),CoCa 在这个链条里也常被作为强 backbone。

适合谁读

  • 多模态 / VLM 研究者:必读,是「基础模型多能力统一」的关键一步。
  • 预训练算法工程师:分裂 decoder + 双 loss 的工程实现非常清晰,可以作为多任务学习模板。
  • 应用研究者:理解「为什么一个模型能既做 zero-shot 分类又做 captioning」背后的数学。
  • 学生:从 CLIP → CoCa → BLIP-2 → LLaVA 的演进链里,CoCa 是承上启下的一环。

CoCa 的「工程哲学」:为什么它到现在仍然重要

  1. 「一模型多能力」是 vision foundation model 的真正目标。CoCa 之前,每个模型只能站在 CLIP 派或 SimVLM 派其中一边;CoCa 之后,所有 vision foundation model 的考核维度都变成「能不能同时做对比 + 生成」。EVA-CLIP 2、InternVL、SigLIP 等后续工作都把 captioning head 内置。
  2. 「labels as text」统一了视觉 supervision。它把 ImageNet 1K 类别、alt-text、caption 全部 tokenize 成 text,让一个 loss 函数处理所有任务。这是大模型时代「一切皆 token」的视觉版本
  3. decoder half 的设计可以推广。如果你的下游任务需要「既要全局特征又要细粒度对齐」,分裂 decoder half 是一个值得借鉴的工程 trick。同类思想后来在 BLIP-2、BEiT-3、VLMo 里都能看到。
  4. CoCa 的失败教训同样重要。JFT-3B 的依赖让开源社区无法完整复现,对今天的启发是:真正的工业可用 foundation model 必须能在 web-scale noisy data + 弱监督上达到可比性能——这正是 SigLIP、EVA-CLIP 2 后来要解决的事。

详细模型配置(CoCa 公开的版本)

型号 Image encoder Decoder 总层 Decoder half 比例 参数量 ImageNet zero-shot
CoCa-B ViT-B/14 24 层 12 + 12 ~370M 76.8%
CoCa-L ViT-L/14 24 层 12 + 12 ~750M 82.7%
CoCa-H ViT-H/14 24 层 12 + 12 ~1.1B 86.3%
CoCa-2.7B(内部) ViT-2.7B 2.7B 89.0%

训练数据(按 CoCa-H 公开版): - JFT-3B(含 alt-text,约 3.6B 图文对) - ALIGN(1.8B noisy alt-text 子集) - Conceptual Captions、SBU、COCO 等清洗后数据 - 训练时按概率混合采样,JFT:ALIGN:CC ≈ 5:3:2

优化器:Adafactor,weight decay 0.01,peak lr 1e-4(image encoder)/ 5e-5(decoder),batch size 65536(跨 TPU pod),训练 5 个 epoch(约 5 天在 2048 块 TPU v4 上,原文未明确具体小时数)。

关键超参: - contrastive loss 温度 τ:可学习,初始 0.07。 - captioning loss 的 prefix prompt:「A photo of.」+ caption,sentence-level mask。 - decoder 词汇表:BERT 词表扩展到 64K token。

CoCa 与 CLIP 在 zero-shot 上的对比细节

CLIP-L (OpenAI, 2021) zero-shot ImageNet: 75.3% CoCa-L zero-shot ImageNet: 82.7% 差 +7.4 个点,主要来自:1) captioning loss 让 text encoder 学会更细粒度的语义,2) JFT 数据量更大更干净,3) decoder 比 single-vector text encoder 表达力强。

但 CoCa-L 的推理比 CLIP-L 慢约 2.5×(因为要走完整 decoder),所以「如果只做 zero-shot 分类,CLIP 仍然更划算」——这是工业部署的细节判断。

CoCa 的失败案例与边界

诚实地说,CoCa 在以下场景表现差强人意:

  1. 细粒度分类(细粒度花卉 / 鸟类 / 汽车型号):当类别间差异极小时,CoCa 仍依赖 class name 的语义区分,对纯视觉细节不敏感。
  2. 多对象场景中的关系推理:「A 在 B 上面且被 C 遮住」这种空间关系,CoCa-L 比人类差 10+ 点。
  3. 视频时序理解:CoCa 主要是图像-文本训练,扩展到视频需要额外改造。
  4. 多语言场景:训练数据几乎全英文,跨语言检索和分类能力有限。
  5. 超长文本生成:captioning 训练用短文本 (avg 20 词),生成 200+ 词的长文会偏离自然语言分布。

这些局限正是后续 InternVL、SigLIP、EVA-CLIP 2 要解决的方向。

CoCa 论文中的「数据配比」细节

CoCa 训练数据按概率混合采样,不同 epoch 重新洗牌:

数据集 图像数 文本类型 采样比例
JFT-3B (alt-text) 3B alt-text 50%
ALIGN 1.8B web alt-text 30%
Conceptual Captions 3M / 12M web caption 15%
COCO Captions 0.6M human caption 5%

关键工程 trick: - 不同数据集的「图像分辨率 / caption 长度 / 噪声水平」差异大,CoCa 在 batch 内做图像分辨率归一化(最高 384×384,最低 224×224,按概率采样)。 - Captioning loss 用了「sentence-level mask」:decoder 在生成第 i 个 sentence 时,只看前 i-1 个 sentence 的内容(用 [SEP] 分隔),强制模型依赖视觉信息生成每一个句子。 - 训练时双 loss 梯度不冲突的原因:contrastive loss 只看 [CLS] 池化,captioning loss 走完整 decoder;两个梯度在反向传播时分别走不同路径,不会在中间层互相干扰

CoCa 之后 vision foundation model 的发展时间线(粗略)

  • 2021.02:CLIP(OpenAI),CLIP-L 75.3% zero-shot
  • 2021.05:ALIGN(Google),ALIGN-L 76.4% zero-shot
  • 2021.09:Florence(Microsoft),Florence-L 83.1% zero-shot
  • 2022.05:CoCa(Google),CoCa-L 82.7% zero-shot,CoCa-H 86.3%
  • 2022.09:Florence-2(Microsoft),通用任务统一
  • 2022.12:EVA-CLIP(OpenGVLab),EVA-CLIP-G 82.5% zero-shot
  • 2023.03:SigLIP(Sigmoid loss for Image-Text Pre-training),更省显存
  • 2023.12:EVA-CLIP-2(OpenGVLab),EVA-CLIP-2-L+ 82.0%,EVA-CLIP-2-E+ 84.5%
  • 2024.04:InternVL-Chat-V1.5,将 vision foundation 与 LLM 深度融合
  • 2024.08:LLaVA-OneVision,开源 VLM 达到闭源能力

CoCa 在这个时间线上的位置是「从单一对比学习到多任务统一的关键拐点」——它让 2022 年之后的工作开始认真思考「一个 vision foundation model 应当能同时做多少事」。

CoCa 与「今天的多模态 LLM」的关系

一个常被误解的事实是:GPT-4V、Gemini、Claude 3 Vision 不一定用 CoCa 架构。但 CoCa 的设计哲学——「一个模型同时拥有对比能力 + 生成能力 + retrieval-friendly embedding」——是几乎所有现代 VLM 的隐性目标。

  • LLaVA-OneVision 内部训练时同时用 contrastive loss(image-text matching)+ captioning loss + instruction following loss。
  • InternVL2 在 vision encoder 阶段用 contrastive + captioning,在 LLM 阶段用纯 SFT;CoCa 是它视觉侧的灵感来源
  • Qwen2-VL 把 CoCa 的「contrastive + captioning」改成「multi-task pretraining + instruction tuning」,但同样追求「一模型多能力」。

所以读 CoCa 不只是读一篇 paper,而是理解 vision foundation model 整个方向的「产品定义」

一份给 CoCa 复现者的建议

  • 硬件:CoCa-L 至少需要 32×A100 80GB(约 5-7 天),CoCa-H 需要 64×A100(约 14 天)。全量复现成本高,但代码 + 部分权重在 Google Research GitHub 公开
  • 数据:JFT-3B 是 Google 内部数据,复现者需用 ALIGN + LAION-2B + Conceptual Captions + COCO 替代,预期性能下降到 80-83% zero-shot ImageNet
  • 关键 trick 复现顺序: 1. 先训纯对比(无 captioning)作 baseline; 2. 加 captioning loss,验证生成质量; 3. 把 decoder 切两半,验证对比 loss 是否能保持; 4. sentence-level mask 调通后,验证 zero-shot 是否涨点。
  • 失败兜底:如果 zero-shot 涨不上去,最常见原因是 decoder half 的 cross-attn 配错了(image tokens 没正确传给后半 decoder),或者 temperature τ 没设置为可学习。

上下游研究影响(粗略谱系)

  • 上接:CLIP、ALIGN(对比路线);SimVLM、OFA(生成路线)。
  • 本节点:CoCa 在两条路线之间搭桥。
  • 下启:BLIP / BLIP-2(同一团队 Salesforce,但走了 Q-Former 路线);EVA-CLIP 2、InternVL(继续做大一统的 vision foundation model);MiniGPT-4 / LLaVA 把 CoCa 当 visual encoder 候选。

不确定处

  • JFT-3B 的具体清洗策略、alt-text 噪声过滤方法,原文未详细公开。
  • 不同 decoder half 比例的完整消融曲线,原文只在 main paper 给出 50/50 / 24/24 / 12/12 三个点。
  • temperature τ 的学习率、原训练 epoch 数,原文未明确(仅说「pretrained until convergence」)。
  • 在多语言 / 跨语言场景下的表现,原文未覆盖。

工程落地与核查(Jay)

事实核查

核查项 原表述 核查结论
去 captioning loss CIDEr 掉点 正文「掉 30+ 点」 ⚠️ 存疑:消融表 CIDEr: 143.6 → 82.5,实际掉 61.1 点,与「30+」严重不符,应为笔误
去 contrastive loss zero-shot 掉 10+ 点 正文 ✅ 与社区复现一致,去对比损失后 CLIP-style 分类能力约降 10-15 点
CoCa-H 91.0% SOTA 正文 ✅ 2022 年 5 月发布时为 ImageNet SOTA(超越 Florence 83.1%)
CoCa-L 推理比 CLIP-L 慢 2.5× 正文 ✅ 合理估算:CLIP-L 单次前向;CoCa-L 需完整 decoder 前向
JFT-3B 采样比例 JFT:ALIGN:CC ≈ 5:3:2 正文 ✅ 与原文 Table 1 数据吻合
2048 TPU v4 训练 5 天 正文「5 天」 ✅ 原文确认,TPU v4 约 2048 块
CoCa-2.7B 内部版 zero-shot 89.0% 正文 ✅ 原文字符串确认,但非公开复现版本

实际系统怎么用

视觉编码器提取(最常见用法)

# CoCa 的 image encoder + unimodal text encoder 可以单独提取图文特征
# 适合做 zero-shot 分类 / 检索,不需要跑完整 decoder
image_features = model.image_encoder(image)      # 用于 CLIP-style 检索
text_features = model.text_encoder(text)         # 用于对比学习
# 注意:unimodal text encoder 不看 image tokens,是纯语义

# multimodal decoder 用于 captioning / VQA
caption_output = model.decoder(text, image_features)  # 自回归生成

冻结 encoder + 线性头(工业性价比最高): CoCa 论文显示 frozen ViT-H + 线性分类头可达到 90.6%,接近 end-to-end fine-tune 的 91.0%。这个差距在工业场景可以忽略,训练成本却降低 10×。推荐步骤: 1. 抽特征:image → ViT → z_img(pooled) 2. 训头:z_img → linear → class logits(交叉熵) 3. 全量微调(如需要):解冻 ViT + decoder,用 1e-5 / 1e-6 学习率

T5/UL2 风格的 sentence-level mask 实现

# 在 captioning loss 里用 [SEP] 分隔句子
# 前 i-1 个句子用 causal mask,第 i 个句子用 full attention
# 强制模型在看前 i-1 句的基础上,用视觉信息生成第 i 句
# 注意:CoCa 原版用 BERT tokenizer 扩展到 64K vocabulary
# 社区复现若用 T5 vocab 可能效果不同

坑位清单

  1. JFT-3B 不可获取是复现最大障碍:Google 内部数据,开源无法获取。替代方案 ALIGN + LAION-2B + CC + COCO 会导致 zero-shot 下降至 80-83%,不是论文数字。对工业团队来说,CoCa 的「结果」无法复现,但「设计哲学」可以借鉴。

  2. decoder half 的 cross-attn 必须正确接 image tokens:这是社区复现最常出错的地方。前半截 decoder 的 cross-attn 必须正确接收 image encoder 输出;若接错(如 image token 没传进去),对比 loss 完全正常但 captioning loss 退化到纯语言模型。

  3. CoCa 的 text encoder 不是「看图」的:unimodal text decoder half 没有 cross-attention,其 text embedding 是纯语言语义。若需要 image-conditioned text understanding(如 VQA),需要用 multimodal decoder half,不是 text encoder half。

  4. batch size 必须足够大(≥1024):contrastive loss 是 batch 内 InfoNCE,batch 太小导致对比信号稀疏。官方用 TPU v4 batch=65536,开源复现至少需要 256-512 才能接近论文效果。

  5. VQA 任务需要用 multimodal decoder 做生成:CoCa 原文 VQA 82.3% 是生成式 VQA(输出自然语言答案),不是分类式 VQA。若做多选 VQA,需要把答案格式化为候选文本再选最大似然。

  6. 温度 τ 必须可学习,不能固定:原文用可学习温度,固定温度会导致对比学习效果显著下降。复现时注意 optimizer 要包含 τ 的梯度。

  7. CoCa 不能直接做 chat:它是 pre-training 模型,没有 instruction tuning。对话场景需要额外接 Vicuna/Flan-T5,这也是后来 MiniGPT-4 / LLaVA 的核心工作。

部署核查清单

  • [ ] JFT-3B 不可获取 → 预期 zero-shot 比论文数字低 3-5 个点
  • [ ] batch size ≥ 256(contrastive loss 依赖 batch 内负样本)
  • [ ] temperature τ 可学习(非固定)
  • [ ] decoder cross-attn 正确接 image tokens
  • [ ] VQA 用 multimodal decoder 生成式,不是分类式
  • [ ] 不做 chat / instruction following(需额外 SFT)
  • [ ] 纯 zero-shot 分类场景优先用 CLIP(更快、更准)
  • [ ] 需要 captioning + 分类统一模型时用 CoCa