Jason / Works Embodied AIZero to One
Works
没主意?快捷入口
Guide · Part 3: 核心主线精读

Ch08: VLM 地基 (I)——CLIP,教 AI 同时认图和认字


Ch08: VLM 地基 (I)——CLIP,教 AI 同时认图和认字

Part 3: 核心主线精读 前置章节:Ch07: 从论文到机器人——理解学术论文的结构与读法 后续章节:Ch09: VLM 地基 (II)——从 BLIP-2 到 LLaVA,给 AI 装上对话能力


从这一章开始,我们正式进入 Part 3——核心主线精读。在 Ch06 中我们说过,CLIP 是 2021 年后整个视觉-语言-动作研究的"坐标系原点"。在 Ch05 中我们看到,无论是模块化架构(SayCan 用 CLIP 理解场景)还是端到端架构(OpenVLA 的视觉编码器来自 CLIP 的后代 SigLIP),CLIP 都是绕不开的地基。

现在,我们要把这块地基翻开来看——它到底是怎么建起来的,为什么这么一个"简单到 7 行代码就能写完"的方法,能撑起整个具身智能的视觉基座。

本章定位:这是你在整个导读中遇到的第一篇完整精读。我会带你从论文的动机出发,逐步拆解架构、数学、训练工程、实验结果、局限性、以及它对后续工作的影响。读完这一章,你应该能够:

  • 向别人解释 CLIP 的核心思想(不超过 3 句话)
  • 手写 CLIP 的训练伪代码(不超过 15 行)
  • 说出 CLIP 的 3 个关键数字和它们为什么重要
  • 理解 CLIP 为什么能用在机器人上
  • 知道 CLIP 搞不定什么

1. 从一个手机相册的故事说起

1.1 你的相册搜不到"海鲜面"

你在手机相册里翻找"去年在海边吃的那盘海鲜面"。打开搜索框,输入"海鲜面"——什么也搜不到。为什么?

因为你手机里的图片识别模型只学过"猫""狗""人脸""风景"这些固定标签。它的世界里根本没有"海鲜面"这个概念。要让它学会识别海鲜面,你需要:

  1. 找 1000 张海鲜面照片
  2. 一张张标注"这是海鲜面"
  3. 重新训练模型
  4. 下次想搜"螺蛳粉"?重复步骤 1-3

这就是 2021 年之前视觉 AI 的困境——每认识一种新东西,就要重新训一次模型

1.2 但 NLP 那边已经变天了

同一时期,自然语言处理(NLP)领域已经发生了翻天覆地的变化。GPT-2 和 GPT-3 证明了一件事:直接读互联网上的原始文本,模型就能学会翻译、问答、写摘要——不需要人工标注

这就引出了一个很尖锐的问题:

互联网上每张图旁边不都带着标题、alt 文字、网页说明吗?这些不就是天然的"监督信号"吗?为什么视觉不能像 NLP 一样,直接从互联网的原始数据中学习?

1.3 两条铁链

CLIP 论文的开头,本质上是在指出传统视觉模型被两条铁链锁住了:

第一条铁链:人工标注太贵。 给 100 万张图打"金标"——每张图让三个人看,投票决定标签——贵到只有大公司玩得起。ImageNet 的 1400 万张图花了好几年、上万个标注者才完成。

第二条铁链:类别表是死的。 训完模型后,它只能输出训练时见过的那些类别。你说"穿蓝色毛衣的柯基",它的 softmax 输出层里根本没有这个类别槽——它最多告诉你"这是狗"。

CLIP 的目标就是同时砍断这两条链:用互联网上免费的图文对代替昂贵的人工标注,用开放的自然语言描述代替固定的类别表。

1.4 为什么这个问题对机器人重要

你可能会想:这不就是个图像分类的问题吗?跟机器人有什么关系?

关系大了。想象一下,你对家里的机器人管家说"把桌上那个红色的马克杯放到书架的第二层"。机器人需要做什么?

  1. 理解"红色的马克杯"是什么——这是视觉-语言对齐(CLIP 解决的核心问题)
  2. 在当前画面中找到它——需要视觉编码器(CLIP 提供的)
  3. 规划怎么拿起来放过去——需要动作规划(后续 RT-2、OpenVLA 要解决的)

如果机器人只会识别"杯子"这个大类,听不懂"红色的马克杯"和"蓝色的玻璃杯"的区别,那它就没法完成这个任务。CLIP 把视觉和语言放进了同一个空间,让"用自然语言指挥机器人"这件事有了落脚点。

这就是为什么在 Ch06 的时间线中,我们把 CLIP 放在 2021 年的第一个位置——它不是一篇关于机器人的论文,但它是所有"用语言指挥机器人"的论文的地基。


2. 前人的二十年探索

CLIP 不是第一个想到"用文本监督学图像"的工作。论文老老实实地列了一长串前辈,从 1999 年到 2020 年。理解这些前辈的尝试和失败,对理解 CLIP 为什么能成功至关重要。

2.1 早期探索(1999-2016):方向对了,但规模不够

1999 年,Mori 等人第一个迈出了这一步。他们的想法很朴素:把图片和它旁边的文档配对,让模型学着预测文档里出现的名词和形容词。这个想法在今天看来方向完全正确,但受限于当时的计算能力和数据量,效果有限。

2016 年,Joulin 等人做了一个重要实验。他们用 Flickr 上的 YFCC100M 数据集(1 亿张带标题、描述、hashtag 的图片),把这些文本信息转成"词袋多标签分类"任务,训练 AlexNet。结果发现:这种方式学到的表征,在迁移学习任务上的效果接近 ImageNet 预训练

这个实验传递了一个重要信号:互联网上的图文配对确实能用来学视觉表征。但问题是,他们的方法仍然把"词袋"当作固定的类别表——还是死的。

2.2 Zero-Shot 的第一次尝试(2017):11.5% 的起点

2017 年,Visual N-Grams(Li 等人) 做了一件前无古人的事:第一次尝试用"自然语言监督"训练的模型,去做 ImageNet 的 zero-shot 分类——也就是不在 ImageNet 上训练任何一张图,直接用文本描述来匹配图片类别。

结果:11.5% 的准确率

听起来很惨——ImageNet 有 1000 个类,随机猜是 0.1%,所以 11.5% 比随机猜好了 115 倍。但跟当时的有监督方法(88.4%)相比,差了一个数量级。

不过这个 11.5% 有历史意义。四年后,CLIP 把同一个数字提升到了 76.2%——追平了有监督的 ResNet-50。从 11.5% 到 76.2%,中间发生了什么?答案是两个字:规模

2.3 "弱监督 + 大数据"路线(2018-2019):接近了,但还差一步

在 Visual N-Grams 之后,另一条路线取得了更好的效果:

**2018 年,Mahajan 等人(Facebook)**用 Instagram 上 35 亿张带 hashtag 的图片,训练模型预测 1000 个相关 hashtag。效果非常好——在 ImageNet 上 fine-tune 后提升了 5% 以上。

**2019 年,Kolesnikov 等人(Google)**用 JFT-300M 数据集(3 亿张图,18291 个类别标签),训练了一系列 BiT(Big Transfer)模型。效果也很好。

但这两条路线有同一个致命弱点:类别表是预先定义好的。Facebook 的模型只能预测 1000 个 hashtag,Google 的模型只能预测 18291 个类别。你说一个它没见过的概念(比如"穿蓝毛衣的柯基"),它就傻了。

它们证明了"大数据 + 弱监督"是可行的,但没有打破"固定类别表"的枷锁。

2.4 Transformer 时代的新尝试(2020):方向对了,但太小了

到了 2020 年,三个小规模的探索性工作重新点燃了希望:

  • VirTex:用 Transformer 做 image captioning(看图生成描述),作为预训练任务
  • ICMLM:用 masked language modeling(遮住一些词让模型猜),联合图文训练
  • ConVIRT:在医学图像领域做对比式图文预训练

这三个工作证明了 Transformer + 图文预训练的可行性,但它们的数据量只有 10-20 万张图——比 CLIP 的 4 亿对小了 2000 倍

2.5 CLIP 的关键洞察:不是"想到了",而是"同时做对了三件事"

回顾这二十年的探索,你会发现"用文本监督学视觉"这个方向一直有人在走。CLIP 的贡献不是"第一个想到",而是第一个同时做对了三件事

  1. 数据规模:4 亿对图文(比之前最大的学术数据集大 4 倍)
  2. 训练目标:对比学习(比 caption 生成高效 4 倍)
  3. 开放类别:用完整的自然语言描述,而非固定的类别表

其中第 2 点特别值得展开。CLIP 团队一开始也试了 VirTex 那套——让模型逐字预测图像的 caption。结果发现效率极低,比对比学习慢了 4 倍。为什么?因为精确预测每个词太难了("一只棕色的拉布拉多犬在绿色的草地上追球"这么长的句子,逐字预测的搜索空间太大),而且互联网上的文本描述噪声很大(经常文不对图),逐字匹配会被噪声严重干扰。

换成对比学习之后,任务从"猜出这张图的精确描述是什么"变成了"从 32768 个候选描述中挑出正确的那一个"——这是一个选择题而不是填空题,难度骤降,训练效率骤升。

这个选择——从生成目标转向对比目标——是 CLIP 整个方法论中最关键的决策之一。


3. 核心思想:相亲大会

现在我们来理解 CLIP 到底在做什么。我用一个"相亲大会"的类比来建立直觉。

3.1 相亲大会类比

想象你在办一场超大型相亲大会,有 32768 位男士和 32768 位女士参加。其中有 32768 对是"真情侣"——他们是配对来的。你的任务是:让每对真情侣都站到一起,让不是一对的人离得远远的。

你有三种方式来做这件事:

方式 A:写小作文(生成式)。 让每位男士写一篇详细的自我介绍,然后看哪位女士的条件最匹配。这就像 image captioning——让模型生成图像的文字描述,再去匹配。问题是:写小作文太累了(计算成本高),而且每个人的表达方式不同(噪声大),很难精确匹配。

方式 B:贴标签(分类式)。 给每个人贴上"理工男""文艺女"之类的标签,按标签配对。这就像 ImageNet 分类——把图像分到预定义的类别里。问题是:标签太粗了("理工男"里有码农也有物理学家),而且你得提前定义好所有标签,漏掉的概念就没法处理。

方式 C:站位置(对比式)。 让所有人走进一个大厅,每个人在大厅里找一个位置站好。唯一的规则是:真情侣要站在一起,不是一对的人要离得越远越好。 你不需要知道每个人的具体条件,只需要知道"谁和谁是一对"。

CLIP 用的就是方式 C。

3.2 把类比对应到技术

相亲大会 CLIP
男士 图像
女士 文本描述
大厅 512 维嵌入空间
站位置 编码器将输入映射为 512 维向量
真情侣 配对的图文(来自同一个网页)
"站在一起" 余弦相似度接近 1
"离得远" 余弦相似度接近 0
32768 对参加者 batch size = 32768

3.3 三个递进的洞察

CLIP 的核心思想可以拆成三个递进的洞察:

洞察 1:把"图文匹配"当成预训练任务。

不让模型预测每个词(太难),也不让它预测固定类别(太死)。每个 batch 取 N 张图和 N 段文字,目标是把对角线上的 N 个真配对认出来,把其他 N²−N 个假配对推开。

这个任务设计的精妙之处在于:它自动提供了海量的负样本。一个 batch 里有 N=32768 个图文对,对于任何一张图,batch 里其他 32767 段文字都是"错误答案"。你不需要额外设计负样本采样策略——它们就在 batch 里。

洞察 2:用同一个嵌入空间。

想象把中文和法文都翻成"世界语",然后看哪两段翻译后的意思最接近。

图像编码器把一张图变成一个 512 维向量;文本编码器把一段话变成一个 512 维向量。两个向量都做 L2 归一化(把长度统一成 1),然后塞进同一个空间。"匹配"的判定就是余弦相似度——两个单位向量的点积,值越接近 1 表示越相似。

"嵌入空间"到底是什么? 想象一张超高维的坐标图。你在上面标了很多点。"猫"的图片和"a photo of a cat"这段文字,被两个编码器分别映射到这张图上的两个点。训练目标就是让这两个点尽可能靠近,同时让"猫"的图片远离"a photo of a dog"。

洞察 3:训完后用"说话"召唤分类器。

这是 CLIP 最魔法的部分。以前每开一家新餐厅都要重新印一本菜单(训一个新的分类头);现在你只要说出菜名,菜单当场生成。

训练完 CLIP 后,下游分类任务(比如 ImageNet 的 1000 个类别)这样做:

  1. 把 1000 个类名套进模板"a photo of a {label}",丢给文本编码器,得到 1000 个 512 维文本向量
  2. 把这 1000 个向量排成一个矩阵——每个类一行——这就是一个线性分类器的权重矩阵
  3. 来一张新图,过图像编码器得到 512 维向量,跟这 1000 个文本向量算余弦相似度
  4. 相似度最大的那个类就是预测结果

论文用一句话总结这个视角:文本编码器是一个 hypernetwork(超网络)——它根据自然语言描述,动态生成线性分类器的权重。

这意味着你可以随时"换菜单":想分类 ImageNet 的 1000 个类?输入 1000 个类名。想分类你自己定义的 3 个类("开心的猫""生气的猫""睡觉的猫")?输入 3 个描述就行。分类器是用语言"念"出来的,不是用数据"训"出来的。

3.4 三种学习范式的直觉对比

CLIP 的"对比学习"只是多种可能的训练方式之一。把它跟其他两种主流范式放在一起对比,能帮你更清楚地理解 CLIP 为什么做了这个选择。

范式 1:有监督分类(Supervised Classification)

训练方式:给模型看一张猫的图片,告诉它"这是猫"。模型学会把"猫的图片"映射到"猫"这个标签上。

类比:家长指着动物园里的每种动物,一个一个教孩子"这是老虎""这是长颈鹿"。孩子必须看过才能认识,没见过的动物不认识。

局限:必须人工标注、类别固定、不能泛化到新类别。

范式 2:生成式预训练(Generative Pre-training)

训练方式:给模型看一张图片,让它生成对应的文本描述(image captioning)。模型学会"看图说话"。

类比:让孩子看着一张图,自己写一段描述。这要求孩子不仅认识图中的物体,还要会造句、理解语法、掌握词汇。

局限:任务太难(要逐字生成),学习效率低。CLIP 论文的实验显示,生成式方法达到相同性能需要 4 倍算力

范式 3:对比学习(Contrastive Learning)——CLIP 的选择

训练方式:给模型看一张图和一段文字,只问"这两个是不是一对?"。模型学会判断匹配关系,不需要生成任何东西。

类比:给孩子看 N 张图和 N 段文字,让孩子把它们配对。这比"看图写作文"简单得多——只需要理解意思够不够匹配,不需要自己造句。

优势:任务简单 → 训练效率高 → 同样的数据和算力能学到更好的表征。

CLIP 选择对比学习的核心原因就是效率——在互联网规模的数据上,"判断配对"比"生成描述"快 4 倍,而且最终学到的视觉表征质量相当。这是一个务实的工程决策,不是理论上的必然选择。


4. 架构拆解:双塔结构

理解了核心思想之后,让我们看具体的架构。CLIP 的架构出奇地简单——两个独立的编码器,各管各的,最后在共享空间里碰面。

4.1 整体架构

              CLIP 架构
              
  图像                    文本
   │                       │
   ▼                       ▼
┌─────────────┐    ┌──────────────┐
│ Image       │    │ Text         │
│ Encoder     │    │ Encoder      │
│ (ViT-L/14   │    │ (12层        │
│  或 ResNet)  │    │  Transformer)│
└──────┬──────┘    └──────┬───────┘
       │                   │
       ▼                   ▼
  [d_i 维特征]         [d_t 维特征]
       │                   │
       ▼                   ▼
┌──────────────┐    ┌──────────────┐
│ 线性投影 W_i  │    │ 线性投影 W_t  │
│ d_i → 512    │    │ d_t → 512    │
└──────┬───────┘    └──────┬───────┘
       │                   │
       ▼                   ▼
   L2 归一化            L2 归一化
       │                   │
       ▼                   ▼
  [512 维向量]         [512 维向量]
       │                   │
       └───────┬───────────┘
               │
               ▼
         余弦相似度

整个架构的关键设计决策是:两个编码器完全独立。图像编码器不知道文本编码器在做什么,反之亦然。它们唯一的交互发生在最后的相似度计算上。这种"双塔"(dual-encoder)设计有一个巨大的工程优势:推理时可以预计算。你可以提前把所有类别的文本向量算好缓存起来,推理时只需要跑一次图像编码器 + 一次矩阵乘法。

4.2 图像编码器:两个选择

在深入 CLIP 的具体选型之前,先理解一个前置概念:ViT(Vision Transformer)是怎么工作的。如果你已经了解 ViT,可以跳到"ResNet 系列"部分。

ViT 的核心思想:把图片当句子读

想象你在读一篇文章。你不是逐像素地扫描每个字母——你是一个词一个词、一个短语一个短语地读。ViT 对图片做了类似的事:

  1. 切 patch:把一张 224×224 的图片切成 16×16 的小块(patch),每个 patch 是 14×14 像素。一共得到 (224/14)² = 256 个 patch。
  2. 展平 + 线性投影:每个 14×14×3 的 patch 被展平成一个 14×14×3 = 588 维的向量,然后通过一个线性层投影到模型的隐藏维度(比如 1024 维)。这一步相当于把每个"图像碎片"转化成一个"token"。
  3. 加位置编码:给每个 token 加上位置信息("你是左上角第一个 patch""你是右下角最后一个 patch")。CLIP 使用可学习的位置编码——每个位置有一个可训练的向量。
  4. 前面加 [CLS] token:在 256 个 patch token 前面加一个特殊的 [CLS] token(class token),最终取这个 token 的输出作为整张图片的全局表征。
  5. 送入 Transformer:257 个 token(256 个 patch + 1 个 [CLS])一起送入标准 Transformer 编码器,经过多层自注意力和前馈网络。
  6. 输出:取 [CLS] token 最后一层的输出作为图像特征向量。
原始图片 (224×224×3)
     │
     ▼ 切成 14×14 的 patch
┌──┬──┬──┬──┐
│p1│p2│p3│..│  共 256 个 patch
├──┼──┼──┼──┤
│..│..│..│..│
└──┴──┴──┴──┘
     │
     ▼ 每个 patch 展平 + 线性投影
[CLS] [p1] [p2] [p3] ... [p256]  ← 257 个 token
  │     │    │    │         │
  ▼     ▼    ▼    ▼         ▼
  +pos  +pos +pos +pos    +pos   ← 加位置编码
     │
     ▼ 送入 Transformer (24 层)
     │
     ▼ 取 [CLS] 输出
  图像特征向量 [1, 1024]

为什么这样做有效? Transformer 的自注意力机制让每个 patch 都能"看到"其他所有 patch。第一个 patch(左上角的天空)可以直接跟最后一个 patch(右下角的草地)交互,不需要像 CNN 那样一层一层地传递信息。这种全局连接让 ViT 天然擅长捕捉图片中的远距离关系。

CLIP 论文尝试了两类图像编码器——ResNet 系列和 ViT 系列。

ResNet 系列(5 个变体):

CLIP 使用的 ResNet 不是原版 ResNet-50,而是做了三个关键修改:

  1. ResNet-D 改进:把开头的一个 7×7 大卷积换成三个 3×3 小卷积叠加。好处是在参数量不变的情况下提升感受野的有效利用率。打个比方:一块大抹布擦桌子不如三块小抹布分三次擦——小抹布更容易贴合桌面凹凸。

  2. 抗锯齿池化(Antialiased Rect-2 Blur Pooling):在下采样(图片缩小)之前先做一次高斯模糊。这解决了一个被忽视的问题——传统的池化操作(如 stride-2 卷积)在缩小图片时会产生"锯齿"效应:图片平移一个像素,输出可能剧烈变化。加了模糊层后,输出对微小平移更稳定。

  3. 注意力池化(Attention Pooling)替代全局平均池化(GAP):传统 ResNet 最后用 GAP 把空间特征图压成一个向量(简单地对所有位置取平均)。CLIP 用了一层多头注意力(Multi-Head Attention)来替代——以 GAP 的输出作为 query,空间特征图作为 key 和 value。这让模型能选择性地关注图片中更重要的区域,而不是无差别地平均所有位置。

5 个 ResNet 变体:

模型 说明
RN50 标准 ResNet-50(加上述改进)
RN101 更深的 ResNet-101
RN50x4 ResNet-50 宽度扩大 4 倍
RN50x16 ResNet-50 宽度扩大 16 倍
RN50x64 ResNet-50 宽度扩大 64 倍(最大,训了 18 天 / 592 块 V100)

ViT 系列(3 个变体):

ViT(Vision Transformer)是 CLIP 论文中效果最好的架构选择。它的核心思想在 Ch03 中提到过:把图片切成小块(patch),排成一列,当成"句子"喂给 Transformer。

3 个 ViT 变体:

模型 Patch 大小 参数量级 说明
ViT-B/32 32×32 Base 最快,分辨率最低
ViT-B/16 16×16 Base 更精细
ViT-L/14 14×14 Large 最强,最终版本用 336px 输入

最终选用的最强模型是 ViT-L/14@336px:L 表示 Large(24 层 Transformer,1024 维隐藏层,16 个注意力头),14 表示每个 patch 是 14×14 像素,336px 表示输入图片分辨率为 336×336。它在整个 CLIP 预训练结束后,又用更高分辨率的图片做了额外一个 epoch 的微调,以获得更好的细节捕捉能力。

ViT-L/14@336px 的额外微调细节:为什么不一开始就用 336×336 训练?因为更高分辨率意味着更多的 patch(336/14 = 24,所以有 24² = 576 个 patch,比 224px 的 256 个多了一倍多),计算量也相应增加。CLIP 的做法是在大部分训练中使用较低分辨率(计算便宜),最后用一个 epoch 的高分辨率微调来"解锁"细节感知能力。这个策略后来被广泛采用——先低分辨率训大量数据,再高分辨率精修。

为什么 ViT 最终胜出?

论文的实验显示,在相同算力预算下,ViT 系列一致性地优于 ResNet 系列。原因有几个:

  1. Transformer 的 scaling 特性更好:随着模型规模增大,ViT 的性能提升比 ResNet 更平稳、更可预测。这意味着你可以用小实验预测大模型的效果,减少试错成本。
  2. 全局注意力:ViT 的每一层都在所有 patch 之间做注意力计算,天然能捕捉图片中的长距离关系(比如"一只猫在沙发的左边")。ResNet 的卷积核只看局部区域(通常 3×3 或 7×7),需要叠很多层才能看到全局。
  3. 与文本编码器的架构一致性:文本编码器本身就是 Transformer,图像编码器也用 Transformer,两边的表示方式更容易对齐。
  4. 计算效率:ViT 的计算主要是矩阵乘法(自注意力和前馈网络),非常适合 GPU/TPU 的并行计算架构。ResNet 的卷积操作虽然理论 FLOPS 可能更低,但实际硬件利用率不如纯矩阵乘法。

ViT vs ResNet 的直觉对比

维度 ResNet(CNN) ViT(Transformer)
看图方式 像用放大镜一格一格扫 像一眼看全图,再关注重点
长距离关系 需要很多层才能传递远处信息 第一层就能看到所有位置
归纳偏置 强:平移不变性、局部连通性 弱:几乎不假设图像结构
数据需求 少量数据就能训好 需要大量数据才能超过 CNN
Scaling 增大后收益递减 增大后收益平稳

最后一行很关键——在 CLIP 的 4 亿数据规模下,ViT 的"弱归纳偏置 + 强数据"策略完胜 ResNet 的"强归纳偏置 + 少数据"策略。但如果你只有 1 万张图,ResNet 可能更好——ViT 需要大量数据来弥补缺失的归纳偏置。

4.3 文本编码器

CLIP 的文本编码器是一个标准的 Transformer 解码器(类似 GPT-2 的结构),而不是 BERT 那种双向 Transformer。

关键参数:

参数 说明
层数 12 Transformer 层数
隐藏维度 512(Base)/ 768(Large) 每层的特征宽度
注意力头数 8(Base)/ 12(Large) 多头注意力的头数
参数量 ~63M 相对于 GPT-2 的 1.5B 很小
最大序列长度 77 tokens 超过这个长度的文本会被截断
词汇表大小 49152 使用 BPE(Byte Pair Encoding)分词
输出提取位置 [EOS] token 取最后一层 [EOS] 位置的激活作为全局表征

为什么用 GPT 式(因果自注意力)而不是 BERT 式(双向自注意力)?

CLIP 论文没有详细解释这个选择,但可能的原因包括:

  1. GPT 家族传承:CLIP 团队就是 OpenAI 的 GPT 团队(第一作者 Alec Radford 也是 GPT-1/2 的第一作者),他们对 GPT 式架构更熟悉。
  2. [EOS] 位置天然聚合信息:在因果自注意力中,[EOS] token 能看到前面所有 token 的信息,天然地把整个句子的语义压缩到一个位置。BERT 需要额外的 [CLS] token 来做这件事。
  3. 推理效率:因果自注意力允许 KV 缓存,虽然在 CLIP 的场景下这个优势不太重要。

77 tokens 够用吗?

对于类别名描述(如"a photo of a golden retriever")完全够用。但对于复杂的场景描述(如"一个穿蓝色条纹衬衫的男人在阳光明媚的公园里跟一只金毛犬玩飞盘"),77 tokens 可能不够。这个限制后来在 LLaVA 等后续工作中通过接入更大的 LLM 得到了解决。

4.4 投影层:从各自的空间到共享的空间

两个编码器各自输出不同维度的特征(图像编码器输出 d_i 维,文本编码器输出 d_t 维),需要通过线性投影映射到同一个维度(512 维):

# 图像侧
image_features = image_encoder(image)       # [N, d_i]
image_embed = l2_norm(image_features @ W_i) # [N, 512]

# 文本侧  
text_features = text_encoder(text)          # [N, d_t]
text_embed = l2_norm(text_features @ W_t)   # [N, 512]

这里有一个值得注意的细节:CLIP 用的是线性投影(就是一个矩阵乘法,没有非线性激活函数)。而在此之前的对比学习工作(如 SimCLR)流行使用非线性投影头(线性层 + ReLU + 线性层)。CLIP 团队实验后发现线性投影在他们的设置下效果一样好,就简化掉了。

投影完成后做 L2 归一化——把每个向量的长度缩放到 1。这样一来,两个向量的点积就等于它们的余弦相似度,值域在 [-1, 1] 之间。

4.5 CLIP 的注意力图:模型在"看"什么

CLIP 的 ViT 图像编码器由多层 self-attention 组成。一个自然的问题是:当 CLIP 处理一张图时,它的注意力聚焦在图像的哪些区域?

后续研究(如 CLIP-visualization 工具和 GradCAM 方法)揭示了一些有趣的模式:

对比:ViT(ImageNet 有监督)vs ViT(CLIP 预训练)的注意力图

用有监督训练的 ViT 在做分类时,注意力图往往集中在物体最"典型"的局部特征上。比如分类"金毛犬"时,注意力可能集中在耳朵和毛色上——因为这些是区分金毛和拉布拉多的关键特征。

CLIP 预训练的 ViT 的注意力图则更分散、更全局——它不仅看物体本身,还会看背景、上下文、整体构图。原因:CLIP 的训练目标是匹配整体描述("a golden retriever playing in a sunny park"),模型需要同时理解物体(golden retriever)、动作(playing)、环境(sunny park)才能正确匹配文本。

这个区别对具身 AI 有实际影响。机器人不仅需要识别"面前有一个杯子",还需要理解杯子周围的环境(桌面上?架子上?其他物体旁边?)。CLIP 式的全局注意力恰好提供了这种上下文感知能力,而纯有监督训练的 ViT 可能会"只见树木不见森林"。

一个有趣的实验:如果你用 CLIP 的注意力图配合文本 prompt 做"定位"(text-guided attention),你会发现——给定"the red cup",CLIP 最后几层的注意力确实会偏向图中红色杯子的位置。虽然 CLIP 没有被训练做定位任务,但这种"注意力定位"作为副产品自然出现了。这是后来 OWL-ViT(Open-World Localization via Vision Transformer)等工作的灵感来源之一。


5. 数学核心:对比学习与 InfoNCE 损失

这是 CLIP 最核心的数学部分。如果你完全没有数学基础,可以先读 5.1 的直觉解释和 5.5 的伪代码,跳过 5.2-5.4 的推导,之后再回来补。

5.1 直觉:N×N 的相似度矩阵

假设一个 batch 有 N 个图文对。我们把所有图像的嵌入向量排成一列,所有文本的嵌入向量排成一行,计算它们两两之间的余弦相似度,得到一个 N×N 的矩阵:

         文本_1  文本_2  文本_3  ...  文本_N
图像_1  [ 0.95   0.12   0.03  ...   0.01 ]   ← 对角线是真配对
图像_2  [ 0.08   0.91   0.15  ...   0.05 ]
图像_3  [ 0.02   0.07   0.88  ...   0.11 ]
  ⋮     [  ⋮      ⋮      ⋮    ⋱     ⋮   ]
图像_N  [ 0.04   0.01   0.06  ...   0.93 ]

在这个矩阵中:

  • 对角线上的元素是"真配对"——图像_1 和 文本_1 是来自同一个网页的真实图文对
  • 非对角线上的元素是"假配对"——随机凑在一起的图文

训练目标就是:让对角线上的值尽可能大(接近 1),让非对角线上的值尽可能小(接近 0)。

5.2 InfoNCE 损失函数

这个目标用数学怎么表达?对于第 i 张图像,我们做一个 N 分类问题——在 N 段文本中,哪个是它的真配对?

图像→文本方向的损失(第 i 张图):

$$L_{i \to t}^{(i)} = -\log \frac{\exp(\text{sim}(I_i, T_i) / \tau)}{\sum_{j=1}^{N} \exp(\text{sim}(I_i, T_j) / \tau)}$$

分子是第 i 张图和它的真配对文本 T_i 的相似度(经过指数函数放大);分母是第 i 张图和所有 N 段文本的相似度之和。整个公式取负对数——直觉上,如果真配对的相似度远大于其他假配对,分子占分母的比例接近 1,负对数接近 0(损失小);反之损失大。

文本→图像方向也有一个对称的损失(第 i 段文本):

$$L_{t \to i}^{(i)} = -\log \frac{\exp(\text{sim}(T_i, I_i) / \tau)}{\sum_{j=1}^{N} \exp(\text{sim}(T_i, I_j) / \tau)}$$

CLIP 的总损失是两个方向的平均:

$$L_{\text{CLIP}} = \frac{1}{2N} \sum_{i=1}^{N} \left( L_{i \to t}^{(i)} + L_{t \to i}^{(i)} \right)$$

这个损失在度量学习中叫 N-pair loss,在自监督学习中叫 InfoNCE(Information Noise-Contrastive Estimation)。名字不同,数学完全一样。

5.3 为什么这就是 N-way 交叉熵

如果你学过机器学习基础中的交叉熵损失(cross-entropy loss),你会发现上面的公式跟它长得一模一样。

回忆一下:softmax 交叉熵把一个 N 维向量(logits)转换成概率分布,然后计算真实标签的负对数概率。在 CLIP 的设定中:

  • logits = 相似度矩阵的第 i 行,即 [sim(I_i, T_1), sim(I_i, T_2), ..., sim(I_i, T_N)]
  • 真实标签 = i(对角线位置)

所以 InfoNCE 本质上就是一个 N 分类的交叉熵——在 N 个候选文本中挑出正确的那个。

这就是为什么 CLIP 的实现可以直接用 F.cross_entropy

labels = torch.arange(N)  # [0, 1, 2, ..., N-1]
loss_i2t = F.cross_entropy(logits_per_image, labels)  # 图→文
loss_t2i = F.cross_entropy(logits_per_text, labels)   # 文→图
loss = (loss_i2t + loss_t2i) / 2

5.4 温度参数 τ 的作用

你可能注意到公式中有一个 τ(tau),叫温度参数(temperature)。它出现在指数函数内部:

$$\exp(\text{sim}(I_i, T_j) / \tau)$$

τ 的作用是控制 softmax 分布的"锐度":

  • τ 很小(比如 0.01):softmax 输出非常"尖锐"——概率几乎全部集中在相似度最高的那个候选上。模型被迫做出非常明确的判断。
  • τ 很大(比如 10):softmax 输出非常"平滑"——概率在所有候选上接近均匀分布。模型被允许"犹豫"。

用温度的直觉类比:想象一杯水里溶解了各种颜色的墨水。

  • 温度低 = 冻成冰:每种颜色清晰分层,界限分明
  • 温度高 = 加热沸腾:颜色混在一起,界限模糊

CLIP 中 τ 的关键设计:

  1. 可学习的:τ 不是人为设定的超参数,而是一个可训练的参数,让模型自己学习最合适的锐度。
  2. 参数化方式:实际存储的是 log_temperature = log(1/τ),初始值是 log(1/0.07) ≈ 2.66(即初始 τ = 0.07)。
  3. 有上限:τ 被 clamp 到不低于 1/100(即 log_temperature 不超过 log(100)),防止温度太低导致训练不稳定。

为什么不手动调?因为最佳的 τ 取决于模型大小、训练阶段、数据分布等多种因素,让模型自己学比人调更靠谱。

5.5 完整伪代码

把上面所有数学合在一起,CLIP 的一次 forward + loss 计算用 Python 写出来不到 15 行:

# ==================== CLIP 训练伪代码 ====================
# image_encoder: ViT-L/14 或 ResNet
# text_encoder: 12 层 Transformer
# W_i, W_t: 线性投影矩阵
# log_temperature: 可学习的温度参数(标量)

# Step 1: 编码
I_f = image_encoder(images)             # [N, d_i]  图像特征
T_f = text_encoder(texts)               # [N, d_t]  文本特征

# Step 2: 投影到共享空间 + L2 归一化
I_e = l2_normalize(I_f @ W_i)           # [N, 512]
T_e = l2_normalize(T_f @ W_t)           # [N, 512]

# Step 3: 计算相似度矩阵(乘以温度的倒数)
logits = I_e @ T_e.T * exp(log_temperature)  # [N, N]

# Step 4: 对称交叉熵损失
labels = arange(N)                       # [0, 1, 2, ..., N-1]
loss_i2t = cross_entropy(logits, labels, axis=0)   # 图→文
loss_t2i = cross_entropy(logits, labels, axis=1)   # 文→图
loss = (loss_i2t + loss_t2i) / 2

CLIP 论文的 Figure 3 给出的 numpy 伪代码本质上就是这个。读懂这 15 行代码,你就读懂了 CLIP 的核心算法。

5.6 Batch Size 为什么必须这么大

CLIP 训练时用了 32768 的 batch size。这个数字不是随便选的——对比学习的效果与 batch size 高度正相关。

为什么?因为在 InfoNCE 中,一个 batch 里的其他样本就是负样本。对于第 i 张图,它需要从 N 个文本候选中挑出正确的那个——其他 N-1 个都是"干扰项"。

  • batch = 256:每张图只有 255 个干扰项。选择题只有 256 个选项,太容易了——模型可以通过记住一些粗糙的模式就答对(比如"所有有草地的图,匹配所有提到'grass'的文本")。
  • batch = 32768:每张图有 32767 个干扰项。选择题有 32768 个选项,模型必须学到非常精细的区分能力才能答对(比如"这张有金毛在草地上追飞盘的图"不能跟"一个人在草地上野餐"混淆)。

从信息论的角度,InfoNCE 提供的互信息下界与 log(N) 成正比——N 越大,可以估计的互信息上界越高,学到的表征质量越好。

但大 batch size 带来的工程挑战是巨大的:32768 张图片 × 每张 336×336×3 + 32768 段文本 × 77 tokens,再加上两个大型编码器的参数和梯度——单卡显存根本放不下。CLIP 使用了多种工程手段来实现这个 batch size,我们在第 6 节中详细讨论。

5.7 对比学习 vs 生成式预训练:效率差 4 倍的秘密

CLIP 论文中有一个经常被忽略但极其重要的实验:他们对比了三种预训练目标的效率。

方法 1:预测式(Predictive)——让模型逐字生成图像的 caption。类似 GPT 生成文本的方式,每次预测下一个词。这是 VirTex 和 ICMLM 使用的方法。

方法 2:词袋式(Bag-of-Words)——让模型预测 caption 中出现了哪些词(不关心顺序)。类似传统的多标签分类。

方法 3:对比式(Contrastive)——CLIP 使用的方法,只要求在 N 个候选中挑出正确的配对。

实验结果令人震惊:

在 ImageNet zero-shot 上达到相同准确率所需的训练量:

方法 1(逐字预测):12x 算力
方法 2(词袋预测):3x 算力  
方法 3(对比学习):1x 算力(基准)

对比学习比逐字预测效率高 12 倍,比词袋预测高 3 倍

为什么差距这么大?根本原因在于任务难度的差异:

逐字预测是一个极高维的搜索空间问题。要生成"a golden retriever playing fetch in a sunny park",模型需要正确预测每一个词的确切位置和拼写——任何一个词预测错误,整个 caption 就"不对"。而且互联网上的 caption 噪声很大(同一张图可能配着完全不相关的文字),这使得逐字匹配更加困难。

对比学习是一个排名问题。模型不需要生成"the exact right caption",只需要判断"在 32768 个候选中,哪一个跟这张图最匹配"——这是一个选择题而不是填空题。选择题天然比填空题简单。

这个效率差异直接决定了 CLIP 的成功——如果使用预测式目标,CLIP 需要 12 倍的算力才能达到同样的效果,这在 2021 年是不可承受的。

5.8 为什么叫 InfoNCE:信息论视角

InfoNCE 这个名字来自 Information Noise-Contrastive Estimation,由 van den Oord 等人在 2018 年的 CPC(Contrastive Predictive Coding)论文中提出。它的理论根基在信息论中。

核心定理:InfoNCE loss 是视觉表示 V 和语言表示 L 之间互信息(Mutual Information)I(V; L) 的一个下界估计

$$I(V; L) \geq \log N - L_{\text{InfoNCE}}$$

直觉解释:互信息衡量的是"知道 V 后对 L 的不确定性减少了多少"。如果 CLIP 的视觉编码器和文本编码器学得很好,那么看到一张图的 embedding 后,你就能大幅缩小它对应的文本 embedding 的范围——互信息很大。

这个下界有一个重要的性质:下界的质量(紧度)随 N 增大而提高。当 N 趋向无穷时,InfoNCE 趋向真实的互信息。这从理论上解释了为什么 CLIP 需要超大 batch size——batch size 越大,InfoNCE 提供的互信息估计越准确,学到的表征越好

但也有一个上限:当 N 足够大、损失足够小时,InfoNCE 的梯度会变得很小(因为正样本的概率已经接近 1),继续增大 N 的边际收益递减。实践中 CLIP 选择了 32768 作为"sweet spot"——再大收益不明显,再小效果会下降。


6. 训练工程:从实验室到 600 块 V100

CLIP 的算法简单到 15 行代码就能写完,但让它在 4 亿数据上跑起来,需要大量的工程功夫。这一节拆解 CLIP 训练中的关键工程决策。

6.1 数据集构造:WIT-400M

CLIP 自己构造了一个名为 WIT(WebImageText) 的数据集,包含 4 亿个(图像,文本)对。这是当时最大的图文数据集。

构造流程:

Step 1:构建查询列表。 从英文维基百科中提取所有出现频率 ≥ 100 次的单词,加上高 PMI(逐点互信息)的双词组合、高搜索量的维基词条名、以及 WordNet 词义网络中的同义词集(synsets)。最终凑出约 50 万个查询词

Step 2:网络爬取。 用这 50 万个查询词在互联网上搜索图文对。来源包括网页上的图片及其周围的文字(标题、alt 文字、图片说明等)。

Step 3:类别均衡。 对每个查询词,最多保留 20000 个图文对。这一步是关键——如果不做均衡,"cat"可能有 100 万对而"aardvark"(土豚)只有 100 对,模型就会严重偏向常见概念。这种设计借鉴了 NLP 中"按频率降采样"(如 word2vec 对高频词降采样)的做法。

Step 4:最终规模。 4 亿对图文,总文本量与 GPT-2 的训练数据(WebText)相当。

WIT 的特点:

  • 文本不是人工标注的 caption,而是互联网上自然出现的图文配对(alt 文本、图片标题、配文等)。这些文本比人工 caption 更嘈杂(经常文不对图),但覆盖面极广。
  • WIT 没有开源——OpenAI 只开源了模型权重和代码,4 亿对原始数据没有公开。这后来引发了社区的不满,并催生了 LAION-400M / LAION-2B 等开源替代品。

6.2 训练规模与成本

CLIP 一共训练了 8 个模型(5 个 ResNet + 3 个 ViT),最大的模型训练成本令人咋舌:

模型 训练时长 GPU 数量 GPU 型号
RN50 ~5 天 ~64 V100 V100 32GB
ViT-B/32 ~5 天 ~64 V100 V100 32GB
ViT-L/14 12 天 256 V100 V100 32GB
RN50x64 18 天 592 V100 V100 32GB

所有模型训 32 个 epoch——也就是把 4 亿数据过 32 遍。总共看了 128 亿次图片。论文用了一个生动的比喻:如果一秒看一张图,看完这些图需要 405 年

6.3 训练中的工程优化

为了在合理的时间和预算内完成训练,CLIP 用了一系列工程优化:

混合精度训练(Mixed Precision Training):模型的参数存储和大部分计算用 FP16(半精度浮点数),而非 FP32。这样做内存占用减半、计算速度翻倍,只在梯度累积和优化器更新时用 FP32 保证数值稳定性。

梯度检查点(Gradient Checkpointing):正常训练时,前向传播的中间结果全部保存在显存中,反向传播时直接用。梯度检查点的做法是:只保存几个关键中间结果,其他的在反向传播时重新计算。用时间换空间——计算量增加约 30%,但显存占用大幅减少。

半精度 Adam 统计量:AdamW 优化器需要保存每个参数的一阶矩(mean)和二阶矩(variance),占用的内存是参数本身的 2 倍。CLIP 把这些统计量也用 FP16 存储,进一步压缩内存。

跨 GPU 相似度计算:batch size = 32768 的相似度矩阵是一个 32768×32768 的矩阵,包含超过 10 亿个元素。这个矩阵的计算和梯度反传需要在多块 GPU 之间分布式地完成——每块 GPU 只计算矩阵的一部分行或列。

6.4 学习率与优化

  • 优化器:AdamW(带权重衰减的 Adam)
  • 学习率调度:余弦退火(Cosine Annealing)——学习率从最大值按余弦曲线平滑下降到接近 0
  • Warmup:训练开始时学习率从 0 线性增加到最大值,避免初始的大梯度破坏模型

6.5 一个容易被忽视的细节:为什么不用更大的文本编码器

CLIP 的图像编码器最大到 ViT-L(约 300M 参数),但文本编码器一直只有 63M 参数。为什么不把文本编码器也做大?

论文暗示了一个原因:文本编码器的任务比图像编码器简单得多。 一段自然语言描述的信息量远小于一张图片——文本是离散的、结构化的,而图像是连续的、高维的。用一个小的文本编码器就足以捕捉文本的语义,而图像编码器需要更大才能捕捉视觉细节。

这个不对称性后来在 BLIP-2 和 LLaVA 中变得更加明显——它们直接用几十亿参数的 LLM 作为"文本编码器",但视觉编码器仍然沿用 CLIP 的 ViT-L。


7. Zero-Shot 推理:用语言"念"出分类器

训练完成后的 CLIP 怎么用?这一节详细拆解 CLIP 最魔法的能力——zero-shot 分类。

7.1 基本流程

以 ImageNet 1000 类为例:

Step 1: 构造文本输入
────────────────────
对每个类名(如 "golden retriever"),套入模板:
  "a photo of a golden retriever."
得到 1000 段文字。

Step 2: 编码文本
────────────────────
把 1000 段文字分别过文本编码器 + 投影 + L2 归一化,
得到 1000 个 512 维文本向量。
排成矩阵 W_text: [1000, 512]

(这一步只需要做一次,结果可以缓存)

Step 3: 编码图像
────────────────────
一张测试图过图像编码器 + 投影 + L2 归一化,
得到一个 512 维图像向量 v_image: [1, 512]

Step 4: 计算相似度
────────────────────
similarity = v_image @ W_text.T    # [1, 1000]
prediction = argmax(similarity)     # 最相似的类名

Step 5: 返回结果
────────────────────
"这张图是 golden retriever"

整个推理过程没有任何训练——没有梯度计算,没有参数更新。分类器的权重完全由文本编码器"生成"——所以说文本编码器是一个 hypernetwork

7.2 Prompt Engineering:从 1.3% 到 5% 的免费提升

CLIP 的 zero-shot 性能对文本模板非常敏感。最简单的模板是直接用类名:

"golden retriever"

但这有两个问题:

  1. 歧义:很多类名是多义词。比如"crane"既可以是"鹤"也可以是"起重机"。没有上下文,文本编码器不知道该把它映射到哪个意思。
  2. 分布不匹配:CLIP 训练时看到的文本是完整的句子("a dog playing in the park"),而非孤立的单词("dog")。直接用单词作为输入,跟训练时的分布不一致。

解决方法:把类名套进模板(template),给它足够的上下文。

最简单的改进:

"a photo of a golden retriever."

仅仅加上"a photo of a",ImageNet 上的准确率就提升了 1.3 个百分点

针对具体数据集定制模板:

不同数据集需要不同风格的模板:

数据集类型 模板示例 为什么
通用物体 "a photo of a {class}." 互联网上最常见的描述方式
卫星图像 "a centered satellite photo of {class}." 给模型提示"这是从天上看到的"
食物识别 "a photo of {class}, a type of food." 区分食物名和同名的其他概念
花卉 "a photo of a {class}, a type of flower." 同上
宠物 "a photo of a {class}, a type of pet." 同上
纹理 "a photo of a {class} texture." 给模型提示"关注表面纹理"
动作识别 "a photo of a person {class}." 关注人在做什么

终极武器:Prompt Ensemble(提示集成)

CLIP 论文为 ImageNet 设计了 80 个不同的模板,例如:

"a photo of a {class}."
"a blurry photo of a {class}."
"a origami {class}."
"a sculpture of a {class}."
"a drawing of a {class}."
"a photo of the large {class}."
"a photo of the small {class}."
"a bright photo of a {class}."
"a dark photo of a {class}."
"a close-up photo of a {class}."
...(共 80 个)

对每个类名,用 80 个模板生成 80 段文字,分别编码为 80 个文本向量,取平均得到该类的最终代表向量。

关键点:这个平均是在嵌入空间中做的(先编码再平均),而不是在概率空间中做的(先各自预测再投票)。这意味着:

  1. 推理时零额外开销:80 个模板的平均向量可以预计算并缓存,推理时跟单模板一样快
  2. 效果显著:80 模板 ensemble 在 ImageNet 上额外提升 3.5%

总计,prompt engineering 和 ensemble 可以带来约 5% 的提升——论文说这相当于"免费的 4 倍算力"。

7.3 Zero-Shot CLIP 的性能有多强

在 ImageNet 上:

方法 训练数据量 ImageNet Top-1 准确率
有监督 ResNet-50 128 万张 ImageNet 训练图 76.1%
Zero-shot CLIP (ViT-L/14@336) 0 张 ImageNet 训练图 76.2%
Linear probe CLIP (ViT-L/14) 128 万张 ImageNet 训练图 85.4%

Zero-shot CLIP 追平了有监督 ResNet-50——注意,CLIP 没有看过任何一张 ImageNet 的训练图片!

不过,这个对比需要谨慎解读:

  1. CLIP 虽然没在 ImageNet 上训练,但 WIT-400M 中很可能包含与 ImageNet 类别相似的图文对。论文在 Section 5 中专门分析了数据重叠,结论是重叠不大,但不是零。
  2. CLIP 使用了 4 亿对图文数据——数据量是 ImageNet 的 300 多倍。
  3. 如果在 CLIP 特征上额外训练一个线性分类器(linear probe),准确率可以达到 85.4%——说明 CLIP 学到的视觉表征质量非常高。

在 27 个数据集上的表现:

CLIP 在 27 个不同的数据集上测试了 zero-shot 性能。其中 16 个数据集上,zero-shot CLIP 超过了"在 ResNet-50 特征上训练的有监督 logistic regression"。

平均来看,zero-shot CLIP 的效果约等于在同一特征空间上做 4-shot logistic regression——也就是说,CLIP 不看任何训练数据的效果,等于传统方法看了每类 4 张训练图的效果。

7.4 few-shot 的反常现象

一个有趣的反常现象:给 zero-shot CLIP 加上 1-shot 训练样本(在特征上拟合 logistic regression),性能反而下降了。

为什么?因为 zero-shot CLIP 的"分类器"是由文本编码器生成的,已经包含了丰富的语义先验。当你用 1 张图来拟合一个线性分类器时,这个分类器的质量反而不如文本生成的版本——1 张图的统计信息太少,拟合出来的决策边界很差。

要到 4-shot 时,有监督线性分类器才追平 zero-shot 文本分类器;16-shot 时才明显超过。

这跟人类的学习模式完全相反——人类通常一张图就能学会一个新概念。这暗示 CLIP 的知识存储方式与人类有本质区别。

7.5 分布偏移鲁棒性:CLIP 真正的"隐藏实力"

CLIP 论文 Section 3.3 有一个经常被忽视但非常重要的发现:CLIP 在分布偏移(distribution shift)上的鲁棒性远超传统有监督模型。

ImageNet 有一系列"变种"数据集,测试模型在各种分布偏移下的表现:

变种数据集 偏移类型 有监督 ResNet-101 Zero-shot CLIP (ViT-L/14)
ImageNet-V2 新采集的验证集 72.0% 70.8%
ImageNet-R 艺术画/卡通/素描 29.0% 73.4%
ImageNet-A 对抗性困难样本 7.9% 59.2%
ImageNet-Sketch 手绘素描 25.4% 48.2%

注意 ImageNet-R 的数字——有监督 ResNet-101 只有 29%,而 zero-shot CLIP 有 73.4%。差距超过 44 个百分点

为什么 CLIP 对分布偏移更鲁棒?论文的分析指出两个原因:

自然语言监督的多样性:CLIP 训练时见过各种风格的图片(照片、画作、卡通、图表等),因为互联网上什么都有。有监督模型只在 ImageNet 的"高质量照片"上训练,一旦换成素描或卡通就懵了。

zero-shot 分类器的泛化能力:文本生成的分类器捕捉的是概念的"语义本质"(比如"狗"的各种视觉表现形式),而不是特定数据集的统计规律(比如"ImageNet 的狗照片大多是正面照")。

这个发现对具身 AI 非常重要。机器人在真实世界中会遇到各种"分布偏移"——不同光照、不同角度、不同背景、不同天气。CLIP 的鲁棒性意味着它作为视觉前端,在这些变化下仍然能保持可靠的感知能力。

7.6 Scaling Laws:算力翻倍,性能可预测地提升

CLIP 论文的另一个重要发现是:zero-shot 迁移性能是计算量的平滑可预测函数。

这意味着什么?如果你画一张"log(计算量) vs zero-shot 准确率"的图,你会得到一条近乎完美的直线。给定任意计算预算,你可以提前预测模型会达到什么性能——不需要真的跑完实验。

具体来说,CLIP 的 8 个模型(从最小的 RN50 到最大的 RN50x64 和 ViT-L/14)在各种 zero-shot 任务上的性能,与它们的训练计算量呈对数线性关系。

这个发现有两个重要含义:

工程意义:你可以用小模型做快速实验,然后根据 scaling law 外推大模型的性能,决定是否值得投入更多算力。

科学意义:这说明 CLIP 学到的能力不是"某个模型规模的巧合",而是一个随规模平滑增长的、可靠的现象。这给了后续研究者信心——只要继续加大规模,性能就会持续提升。

后来的 OpenCLIP 项目在开源数据上复现了这条 scaling law,进一步证实了它的可靠性。


8. CLIP 的能力边界:它搞不定什么

CLIP 很强大,但远不是万能的。论文在 Section 6(Limitations)中非常诚实地列出了一长串搞不定的事情。理解这些局限性,比理解它的成功更重要——因为后续所有改进工作(BLIP、LLaVA、SigLIP 等)都在试图修补这些弱点。

8.1 复杂、抽象、专业的任务很弱

细粒度分类:CLIP 分不清不同品种的鸟("黄腹太阳鸟"vs"绿冠太阳鸟")、不同型号的飞机("波音 737-800"vs"空客 A320neo")。原因:WIT 数据集中这些细分概念出现频率低,模型没有足够的样本来学习区分它们。

计数:CLIP 看不出"3 个红色立方体"和"4 个红色立方体"的区别。在 CLEVRCounts 数据集上表现很差。原因:对比学习的目标只要求"整体匹配",不需要精确理解场景中物体的数量。

空间关系:CLIP 无法可靠地区分"猫在桌子上"和"猫在桌子下"。原因同上——整体匹配不需要理解空间拓扑。

距离估计:在 KITTI 数据集(自动驾驶场景)上,CLIP 无法准确估计物体之间的距离。原因:CLIP 没有 3D / 几何理解能力,它处理的是 2D 图像和文本的对齐,不涉及深度信息。

专业领域图像:卫星遥感图(EuroSAT、RESISC45)、医学病理图(PatchCamelyon)上表现很差。原因:互联网图文对里几乎没有这些专业图像——你不会在社交媒体上看到配着自然语言描述的病理切片。

否定句理解:CLIP 无法正确处理"a photo without a dog"(一张没有狗的照片)。原因:对比学习只做"整体匹配",对否定词的语义处理能力非常弱。

组合性理解(Compositionality):这是 CLIP 最深层的结构性缺陷。后来的研究(Winoground benchmark, 2022)系统性地证明了 CLIP 在组合推理上接近随机水平。具体表现为三个层面:

属性绑定失败——"a red car and a blue house"vs"a blue car and a red house",CLIP 难以区分哪个颜色属于哪个物体。关系理解失败——"a cat on a mat"vs"a mat on a cat",CLIP 对介词关系不敏感。词序失败——"the horse is eating the grass"vs"the grass is eating the horse",CLIP 表现得像"词袋模型"(Bag-of-Words),只关心哪些词出现了,不关心它们的顺序和关系。

根本原因分析:这些局限不是偶然的 bug,而是对比学习目标函数的结构性后果。InfoNCE loss 只要求"整体匹配"——给定一张图和一段文字,判断它们是否来自同一对。模型可以通过捕捉共现统计模式("红色"和"消防车"经常一起出现)来完成这个任务,完全不需要理解组合语义

这个认识很重要,因为它解释了为什么后来的工作(BLIP-2、LLaVA)需要引入生成式目标(image captioning、visual question answering)——生成任务天然要求模型理解词序、属性绑定和关系。

8.2 MNIST 上的 88%:一个意味深长的数字

这个数字需要单独拿出来说,因为它揭示了 CLIP 最本质的局限。

MNIST 是机器学习领域最经典的基准数据集——手写数字 0-9 的灰度图像,28×28 像素。一个最简单的 logistic regression(在原始像素上,不用任何特征提取)就能达到 92% 的准确率。但 zero-shot CLIP 只有 88%。

比在原始像素上跑 logistic regression 还差

原因很简单:互联网图文对里几乎没有手写数字这种图像。CLIP 见过的"数字"几乎都是印刷体或屏幕渲染的,手写数字是真正的分布外(Out-of-Distribution, OOD)数据。

论文里有一句非常精辟的自我批评:

CLIP does not address the underlying problem of brittle generalization of deep learning models. Instead, CLIP tries to circumvent the problem by training on such a large dataset that all data is effectively in-distribution. This is a tempting strategy... but our experiments with MNIST show it is not a sufficient strategy.

翻译:CLIP 没有解决深度学习模型脆弱泛化的根本问题。它只是寄希望于把数据放大到一切都在分布内。MNIST 一个简单的反例就证伪了这个假设。

这个认识对具身 AI 至关重要——机器人在真实世界中会遇到大量训练数据中不存在的情况(新物体、新场景、新光照条件),单纯依赖"数据量足够大"是不够的。

8.3 社会偏见:训练数据里的有毒沉淀

CLIP 的训练数据来自未经过滤的互联网——这意味着它不可避免地学到了大量社会偏见。论文 Section 7.1 专门讨论了这个问题。

在 FairFace 数据集上的初步探针显示:CLIP 对不同种族和性别群体的分类表现存在显著差异。例如,当用"criminal"(罪犯)作为候选类别时,CLIP 对某些种族群体的误分类率明显高于其他群体。

这个问题不是 CLIP 独有的——所有在互联网数据上训练的模型都面临同样的挑战。但 CLIP 的 zero-shot 能力使这个问题更加紧迫:因为任何人都可以通过构造文本 prompt 来探测(或利用)模型的偏见,不需要额外训练。

对具身 AI 的启示:如果机器人使用 CLIP 的视觉编码器来理解场景,它可能会对不同人群产生不同的响应——这在家庭服务机器人场景中是不可接受的。后续工作(如 BLIP 的数据自洁、LLaVA 的安全对齐)在部分缓解这个问题。

8.4 论文的自省精神

CLIP 论文的第 6 节(Limitations)是少见的诚实。它不仅列出了技术局限,还坦白了评估方法本身的问题:

评估方式有"作弊"嫌疑:开发过程中反复在完整 validation set 上调试 prompt engineering,这本身就违反了 zero-shot 的精神。27 个评估数据集是"cherry-picked"——为了配合 CLIP 的优势挑出来的。

数据效率没解决:32 epochs × 4 亿对 = 128 亿次图像 forward。"如果每秒看一张,要看 405 年"。CLIP 是"用规模换效率"的典型代表。

算力天花板:论文估算 zero-shot CLIP 想达到当时的 SOTA 还需要 1000 倍算力——"用现有硬件不可行"。

这种自省精神本身就值得学习。一篇好的论文不只是展示自己有多强,更要诚实地说清自己的边界在哪里。


11. CLIP 的后继者们——改进从未停止

11.1 OpenCLIP:开源复现的里程碑

CLIP 的一个争议是:OpenAI 只开源了模型权重和代码,但没开源训练数据(WIT-400M)。这意味着学术界无法复现和验证 CLIP 的结果。

LAION 社区和 mlfoundations 团队创建了 OpenCLIP 项目来解决这个问题:

他们首先构建了开源训练数据集:LAION-400M(400M 图文对)→ LAION-2B(2B 图文对)→ LAION-5B(5B 图文对)。有趣的是,LAION 数据集的构建本身就依赖 CLIP——他们用 CLIP 模型对 Common Crawl 数据进行过滤,只保留余弦相似度 > 0.3 的图文对。这是一个"用 CLIP 训 CLIP"的递归过程。

然后他们在这些开源数据上训练了各种规模的 CLIP 模型,验证了一个重要的发现:CLIP 的 scaling laws(缩放定律)是可复现的——性能随数据量和模型规模呈幂律增长。

OpenCLIP 成为了后续大量研究的基础设施。如果你想在自己的项目中使用 CLIP,大概率会用 OpenCLIP 的检查点而不是 OpenAI 原版。

11.2 SigLIP:把 Softmax 换成 Sigmoid

Google 于 2023 年在 ICCV 上提出了 SigLIP(Sigmoid Loss for Language-Image Pre-training),解决了 CLIP 训练效率的一个核心瓶颈。

问题:CLIP 的 InfoNCE loss 基于 softmax,需要在整个 batch 范围内做归一化。在分布式训练中,这意味着所有 GPU 必须交换各自的 embeddings 来计算全局 softmax——通信开销巨大。

SigLIP 的解决方案:把 softmax 换成 sigmoid,把"N 分类问题"变成"N² 个独立的二分类问题"。

# CLIP (softmax-based) —— 需要全局归一化
loss = -log( exp(sim(i,t)/τ) / Σⱼ exp(sim(i,tⱼ)/τ) )

# SigLIP (sigmoid-based) —— 每对独立判断
loss = -Σᵢⱼ [ yᵢⱼ·log(σ(zᵢⱼ·sim(i,j))) 
              + (1-yᵢⱼ)·log(1-σ(zᵢⱼ·sim(i,j))) ]
# yᵢⱼ=1 if matched, zᵢⱼ=1; yᵢⱼ=0 if not, zᵢⱼ=-1

类比:CLIP 的 softmax 像一场选美比赛——每个选手的分数取决于所有其他选手的表现(相对排名)。SigLIP 的 sigmoid 像驾照考试——每个人独立评判及格/不及格,你的成绩跟别人无关。

选美比赛需要所有选手站在一起比较(全局通信),驾照考试每个人自己考就行(独立计算)。

SigLIP 的核心优势:

无需全局归一化——每个 image-text pair 独立判断是否匹配,消除了跨设备通信瓶颈。小 batch 表现更好——在 batch size < 32K 时,sigmoid loss 明显优于 softmax loss,这对学术实验室(GPU 资源有限)尤其重要。内存效率更高——相同硬件下可容纳更大的有效 batch size。

SigLIP 在具身 AI 中的重要性:OpenVLA 的视觉编码器就使用了 SigLIP + DINOv2 的双流架构。SigLIP 提供语义理解("这是什么物体"),DINOv2 提供空间细节("物体的精确位置和形状"),两者互补。

11.3 EVA-CLIP:不改架构,改训练流程

北京智源研究院(BAAI)提出的 EVA-CLIP 采取了一种务实的策略:CLIP 的架构已经很好了,瓶颈在于训练太贵。能不能在不改架构的前提下,让训练更高效、更稳定?

三个关键技巧:

MIM 预训练初始化:不从随机权重开始训 CLIP,而是先用 Masked Image Modeling(类似 MAE)预训练 ViT,得到一个"已经懂图像结构"的初始权重。类比:教一个已经会画画的人学"看图说话",比教一个完全不会画画的人快得多。

LAMB 优化器:替代 AdamW,更适合超大 batch size 的分布式训练。LAMB 能在 batch size 变化时自动调整学习率,减少训练不稳定性。

FLIP 掩码策略:训练时随机遮盖一部分图像 patch(比如 50%),只处理剩余的 patch。这直接减少了 50% 的计算量,但对最终性能影响很小——因为 CLIP 的对比学习目标只需要"整体语义",不需要每个像素的细节。

成果:EVA-CLIP 系列从 EVA-CLIP-B 到 EVA-CLIP-18B(180 亿参数),是最大的开源 CLIP 模型家族。在相同参数量下,EVA-CLIP 以显著更小的训练成本达到了超越原始 CLIP 的性能。

11.4 CLIPA:逆向缩放定律

CLIPA 发现了一个反直觉的现象——逆向缩放定律(Inverse Scaling Law):编码器越大,训练时所需的 token 序列长度反而可以越短。

大模型(如 ViT-H)可以用很短的 image token 序列(只看少数 patch)来有效训练,小模型则需要更长的序列。

实际意义:大幅降低了大规模 CLIP 训练的计算成本。CLIPA-v2 在 $10,000 预算内达到了 ImageNet zero-shot 81.1% 的准确率——这意味着学术实验室也能训出高质量的 CLIP 模型。

11.5 改进总结

CLIP (2021)     —— 开创性工作,证明对比学习 + 大规模数据的威力
    ↓
OpenCLIP (2022) —— 开源复现,验证 scaling laws
    ↓
SigLIP (2023)   —— sigmoid 替代 softmax,小 batch 更强,训练更高效
    ↓
EVA-CLIP (2023) —— MIM 初始化 + LAMB + FLIP,训练成本大降
    ↓
CLIPA (2023)    —— 逆向缩放定律,$10K 就能训好

每一步改进都在回答同一个问题:如何用更少的资源训出更好的 CLIP?

11.6 实践选型指南:该用哪个 CLIP?

面对这么多变体,一个自然的问题是:我的项目应该用哪个?

如果你是做应用(不改模型本身):用 OpenCLIP 的 ViT-L/14 或 ViT-H/14 检查点。它们在 Hugging Face 上一行代码就能加载,生态支持最好(FAISS、LangChain、LlamaIndex 都有集成),社区活跃、bug 修复快。

如果你是做研究(需要改模型或训新模型):根据你的 GPU 预算选择基线。预算充裕(≥64 块 A100)选 OpenCLIP 的训练流程;预算有限(8-16 块)选 EVA-CLIP 的 MIM 预初始化 + FLIP 掩码策略,能省 2-3 倍算力;预算极有限(1-4 块)考虑 CLIPA 的逆向缩放思路,或者直接用现成检查点做 linear probe / adapter。

如果你是做具身 AI:先看你的下游模型用什么。要接 OpenVLA → 用 SigLIP(因为 OpenVLA 就是用 SigLIP 训的,换别的可能不兼容)。要接自定义 VLM → 任意 OpenCLIP 变体都行。做模块化系统(类似 SayCan)→ 用最大的 OpenCLIP 检查点(ViT-bigG/14),冻结权重直接调用 API。

一个常见的误区:"模型越新越好"。实际上,对于大多数应用场景,2022 年的 OpenCLIP ViT-L/14 已经足够好了。SigLIP 和 EVA-CLIP 的改进主要体现在训练效率和极端规模上——如果你只是用来做图文检索或 zero-shot 分类,用最经典的 ViT-L/14 反而最稳定、最容易 debug、社区支持最好。


12. CLIP 如何走向具身智能——从"认图"到"动手"

这是本章最重要的一节。CLIP 本身是一个纯粹的感知模型——它能"看"和"听"(理解图像和文本),但不能"做"(输出动作)。那么它是如何成为具身智能的地基的?

12.1 演化路线图

阶段 1: CLIP 本体 (2021)
  "我能把图和文字放进同一个空间"
  能力:图文匹配、零样本分类、图文检索
  不能:生成文本、理解对话、输出动作
      ↓
阶段 2: CLIP + LLM = VLM (2022-2023)
  "给我装上一个语言大脑"
  代表:Flamingo → BLIP-2 → LLaVA
  能力:理解图像 + 生成自然语言回答
  不能:输出机器人动作
      ↓
阶段 3: VLM + 动作 = VLA (2023-2024)
  "让我的输出从文字变成动作"
  代表:RT-2 → OpenVLA
  能力:看图 + 听指令 + 输出关节动作
      ↓
阶段 4: VLA + 扩散 = 下一代 (2024-)
  "让我的动作更精细更连续"
  代表:π0
  能力:连续、多模态、精细动作控制

12.2 具体应用案例

案例 1:SayCan(2022)——CLIP 做"场景理解员"

SayCan 的核心公式是 π* = argmax p(say) × p(can):LLM 评估每个技能与指令的相关性(say),affordance function 评估每个技能在当前环境中的可行性(can)。

CLIP 在 SayCan 中扮演的是辅助角色——帮助理解当前场景中有哪些物体。例如,指令是"拿一罐可乐",CLIP 可以帮助判断桌面上是否有可乐(通过计算"可乐"文本 embedding 与场景图像 embedding 的相似度)。

这是 CLIP 最"轻量"的用法——作为一个现成的视觉-语言相似度计算器,嵌入到更大的系统中。

案例 2:CLIPort(2022)——CLIP 做"语义理解流"

CLIPort 的架构设计很巧妙——它有两条并行的处理流:

语义流(What pathway):使用 CLIP 的预训练视觉特征,理解"操作什么物体"。空间流(Where pathway):使用 TransporterNet 的密集像素级特征,精确定位"在哪里执行动作"。

两条流通过注意力机制融合,最终输出 pick-and-place 动作。

类比:你在厨房里做菜。CLIP 就像你的"认知系统"——知道那个红色的东西是番茄、绿色的是黄瓜。TransporterNet 就像你的"空间系统"——知道番茄在案板左边第 3 个位置、距离手 15 厘米。做菜需要两个系统同时工作:先认出"番茄"(语义),再精确定位它的位置(空间),最后手伸过去拿起来。

案例 3:RT-2(2023)——CLIP 的思想变成 VLA

RT-2 是 CLIP 思想在具身 AI 中最直接的体现。它的核心思路是:

既然 CLIP 证明了"视觉和语言可以放进同一个 token 空间",那么动作也可以放进同一个 token 空间

具体做法:将机器人动作(x, y, z, yaw, pitch, roll, gripper)离散化为 token,用大型 VLM(PaLM-E 或 PaLI-X)同时处理图像 token、文本 token 和动作 token。模型的视觉编码器继承了 CLIP 式的预训练。

RT-2 展示了一个惊人的"涌现能力":它能理解训练数据中从未见过的物体和指令。例如,"把垃圾扔到有回收标志的垃圾桶"——训练数据中没有这个指令,但模型从 VLM 预训练中学到了"回收标志"的视觉概念,从而能正确执行。

这就是 CLIP 的长远影响——它建立的"视觉-语言对齐"能力,通过 VLM 的继承,最终让机器人具备了"理解自然语言指令"的能力。

案例 4:OpenVLA(2024)——开源 VLA 的视觉前端

OpenVLA 是目前最重要的开源 VLA 模型之一。它的视觉编码器使用了 SigLIP + DINOv2 的双流架构——SigLIP 是 CLIP 的改进版(sigmoid loss),DINOv2 是自监督视觉表示学习的代表。

技术谱系非常清晰:

CLIP (2021, 图文对齐)
  → SigLIP (2023, sigmoid loss 改进)
    → OpenVLA 的语义视觉流 (2024)

DINO (2021, 自监督视觉)
  → DINOv2 (2023, 更大规模)
    → OpenVLA 的空间视觉流 (2024)

12.3 设计决策深度剖析:CLIP 在两种范式中的不同角色

上面四个案例其实暗含了一个重要的分歧——CLIP 在模块化方案和端到端方案中的角色完全不同。

模块化方案中的 CLIP(SayCan、CLIPort):CLIP 被当作一个即插即用的黑盒工具。开发者调用 CLIP 的 API 获取图像或文本的嵌入向量,然后在自己的系统中使用这些向量做相似度计算。CLIP 的权重被冻结,不参与下游训练。好处是简单快速——不需要 GPU 集群,不需要大规模训练数据,任何人都能把 CLIP 集成到自己的机器人系统中。坏处是有性能天花板——冻结的 CLIP 无法适应特定的机器人视角、光照条件或物体类型。

端到端方案中的 CLIP(RT-2、OpenVLA):CLIP 的视觉编码器(ViT)被当作可微调的初始化权重。在 VLA 的训练过程中,ViT 的参数会随着动作预测 loss 一起更新——CLIP 不再是黑盒,而是整个模型的一部分。好处是性能上限更高——视觉编码器可以学到机器人专有的视觉特征。坏处是需要大量的机器人操作数据和算力来微调,而且微调后的 ViT 可能丧失 CLIP 原始的 zero-shot 泛化能力(这就是"灾难性遗忘"问题)。

一个关键洞察:为什么 OpenVLA 用 SigLIP + DINOv2 双流,而不只用 SigLIP?正是因为微调后的 SigLIP 可能丢失一部分 CLIP 式的语义理解能力,DINOv2 提供了互补的视觉特征——它通过自监督学到的特征对空间结构更敏感,不依赖语言监督。两条流的组合比单独一条更鲁棒。

这个分歧不只是技术选择,更是哲学分歧:你相信"能力可以组合吗"(模块化),还是相信"一个足够大的模型能学会一切"(端到端)?2024 年的趋势明显偏向端到端(π0 是最新代表),但模块化方案在数据稀缺、需要可解释性、或需要快速部署的场景中仍然不可替代。

12.4 为什么 CLIP 能成为具身智能的地基

总结一下 CLIP 对具身 AI 的三个关键贡献:

贡献 1:统一嵌入空间。CLIP 证明了视觉和语言可以被映射到同一个向量空间。这个思想后来被扩展到:视觉 + 语言 + 动作(VLA)、视觉 + 语言 + 音频 + 深度 + IMU + 热成像(ImageBind)、视觉 + 语言 + 毫米波雷达(mmCLIP)。

贡献 2:Zero-shot 泛化。CLIP 的 zero-shot 能力意味着机器人可以理解训练数据中没见过的物体和概念。这对真实世界部署至关重要——你不可能预先标注机器人会遇到的所有物体。

贡献 3:可复用的视觉前端。CLIP 训练好的 ViT 可以直接作为下游模型的视觉编码器,不需要从头训练。这大幅降低了构建 VLM/VLA 模型的成本——你只需要训练"桥接层"和"动作解码器",视觉编码器直接用 CLIP 的。


13. 从 CLIP 到 LLaVA:三步演化

Ch09 会详细讲 BLIP-2 和 LLaVA,但这里先给出一个简要的演化路线,帮你理解 CLIP 如何一步步变成今天的多模态大模型。

13.1 第一步:CLIP → BLIP-2(加一个"翻译官")

问题:CLIP 只能做匹配("这张图和这段文字配不配"),不能生成文本("这张图里有什么")。

BLIP-2 的解决方案:在冻结的 CLIP 视觉编码器和冻结的 LLM 之间插入一个轻量级的"翻译官"——Q-Former(Querying Transformer)。

Q-Former 的核心设计:使用 32 个可学习的 query vectors,通过 cross-attention 从 CLIP 视觉编码器中"提问"并提取关键视觉信息,然后把提取到的信息"翻译"成 LLM 能理解的 token。

类比:CLIP 是一个只会拍照的摄影师(能看懂画面但不会说话),LLM 是一个只会说话的播音员(能生成文字但看不见画面)。Q-Former 就是站在中间的翻译官——摄影师指着照片,翻译官问 32 个问题("照片里有什么人?什么背景?什么光线?"),把答案整理成播音员能读的稿子。

13.2 第二步:BLIP-2 → LLaVA(把翻译官简化成一条线)

问题:Q-Former 虽然有效,但结构复杂、训练困难。能不能用更简单的方式连接 CLIP 和 LLM?

LLaVA 的解决方案:用一个简单的线性投影层(后来升级为 2 层 MLP)直接把 CLIP 视觉特征映射到 LLM 的输入空间。

# LLaVA 的核心连接(极简版)
image_features = clip_vit(image)           # CLIP 提取视觉特征
projected = linear_projection(image_features)  # 线性投影到 LLM 空间
input_tokens = concat(projected, text_tokens)  # 拼接视觉 token 和文本 token
output = llm(input_tokens)                     # LLM 生成回答

这种"暴力简化"之所以有效,是因为 CLIP 已经把视觉特征训练到了一个高质量的语义空间——一个简单的线性变换就足以把它映射到 LLM 的 embedding 空间。

类比:如果 CLIP 的输出已经是"接近中文"的半成品翻译,那你不需要一个专业翻译团队(Q-Former),一本简单的词典(线性投影)就够了。

13.3 第三步:LLaVA → RT-2/OpenVLA(从文字到动作)

问题:LLaVA 能看图说话了,但还是在输出文字。机器人需要输出关节动作。

解决方案:把动作也表示为 token,让 LLM 在生成"文字 token"的同时也能生成"动作 token"。

CLIP (看懂图) → BLIP-2 (看图+说话) → LLaVA (看图+对话) → RT-2/OpenVLA (看图+动手)

每一步都建立在前一步的基础上,而 CLIP 是整个链条的起点。


14. 动手环节:用 CLIP 做一个零样本分类器

如果你想真正理解 CLIP,没有什么比自己跑一遍代码更有效的了。下面是一个最小可运行的 CLIP 零样本分类示例,只需要 20 行核心代码:

import torch
import clip
from PIL import Image

# Step 1: 加载 CLIP 模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

# Step 2: 准备图像
image = preprocess(Image.open("cat.jpg")).unsqueeze(0).to(device)

# Step 3: 准备文本候选(零样本分类的 "类别")
candidates = ["a photo of a cat", "a photo of a dog", 
              "a photo of a bird", "a photo of a car"]
text = clip.tokenize(candidates).to(device)

# Step 4: 编码 + 计算相似度
with torch.no_grad():
    image_features = model.encode_image(image)   # [1, 512]
    text_features = model.encode_text(text)       # [4, 512]
    
    # L2 归一化
    image_features /= image_features.norm(dim=-1, keepdim=True)
    text_features /= text_features.norm(dim=-1, keepdim=True)
    
    # 余弦相似度
    similarity = (image_features @ text_features.T) * 100  # [1, 4]
    probs = similarity.softmax(dim=-1)  # 转为概率分布

# Step 5: 输出结果
for candidate, prob in zip(candidates, probs[0]):
    print(f"{candidate}: {prob:.2%}")
# 输出示例:
# a photo of a cat: 95.23%
# a photo of a dog: 3.12%
# a photo of a bird: 1.05%
# a photo of a car: 0.60%

代码解读

clip.load("ViT-B/32") 加载预训练模型。ViT-B/32 表示 Base 规模、patch size 32 的 Vision Transformer。这是最小的 CLIP 模型,适合在 CPU 上快速实验。

preprocess 是 CLIP 自带的图像预处理流水线,包括 resize 到 224×224、center crop、归一化等。

clip.tokenize 把文本字符串转换为 BPE token 序列(最长 77 个 token)。

encode_imageencode_text 分别调用图像编码器和文本编码器,输出 512 维向量。

最关键的一行是 image_features @ text_features.T——这就是余弦相似度计算(因为已经 L2 归一化了)。乘以 100 是因为 CLIP 的 logit_scale 大约在 100 左右。

实验建议

试试改变候选文本,观察相似度的变化。例如把"a photo of a cat"改成"a cute fluffy cat sitting on a sofa",看看更详细的描述是否能提高分数。

试试用不准确的描述,比如"a photo of a dog"配上一张猫的图片,观察模型给出的低分数。

试试 CLIP 的弱点——用"3 red cubes"和"4 red cubes"的图片,看看模型是否能区分。(剧透:大概率不能。)

14.2 理解嵌入空间:余弦相似度的直觉

CLIP 的"嵌入空间"是一个 512 维的向量空间,人类无法直观想象。但我们可以用一个 2D 类比来建立直觉。

想象一个二维平面上的单位圆。每个图像和文本都被映射到这个圆上的一个点(因为 L2 归一化后向量长度都是 1)。两个向量之间的余弦相似度就是它们之间夹角的余弦值

        "a photo of a cat"
              ↗  (cos θ ≈ 0.95, 夹角小 → 高相似度)
             /
            /  θ₁ (小角度)
           / 
    原点 ●─────────── "cat.jpg" 的图像向量
           \
            \  θ₂ (大角度)
             \
              ↘  (cos θ ≈ 0.12, 夹角大 → 低相似度)
        "a photo of a car"

在这个类比中:

  • 余弦相似度 = 1:两个向量完全重合(夹角 0°)——完美匹配
  • 余弦相似度 = 0:两个向量垂直(夹角 90°)——完全无关
  • 余弦相似度 = -1:两个向量方向相反(夹角 180°)——完全矛盾

CLIP 的训练目标就是:让配对的图文向量夹角尽可能小(余弦相似度接近 1),让不配对的图文向量夹角尽可能大。

一个实际的观察:在训练好的 CLIP 空间中,语义相关的概念会自然聚类。比如"dog""puppy""golden retriever""labrador"的文本向量会聚在一起,离"cat""kitten"的文本向量有一定距离,但都远离"car""airplane"的向量。这种语义结构是 CLIP 从 4 亿图文对中自动学到的,没有任何人工设计。

14.3 一个更有挑战性的实验:开放词表图像检索

如果你想进一步体验 CLIP 的能力,可以试试这个更实际的应用——在一组图片中用自然语言搜索:

import torch
import clip
from PIL import Image
import os

# 加载模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

# 编码一组图片(假设在 images/ 目录下)
image_paths = [f"images/{f}" for f in os.listdir("images/") 
               if f.endswith(('.jpg', '.png'))]
image_features_list = []

for path in image_paths:
    image = preprocess(Image.open(path)).unsqueeze(0).to(device)
    with torch.no_grad():
        feat = model.encode_image(image)
        feat /= feat.norm(dim=-1, keepdim=True)
        image_features_list.append(feat)

image_features = torch.cat(image_features_list)  # [M, 512]

# 用自然语言搜索
query = "a person wearing a red hat"
text = clip.tokenize([query]).to(device)
with torch.no_grad():
    text_features = model.encode_text(text)
    text_features /= text_features.norm(dim=-1, keepdim=True)

# 计算相似度并排序
similarities = (image_features @ text_features.T).squeeze()
top_indices = similarities.argsort(descending=True)[:5]

print(f"搜索: '{query}'")
print("最匹配的 5 张图:")
for rank, idx in enumerate(top_indices):
    print(f"  {rank+1}. {image_paths[idx]} (相似度: {similarities[idx]:.3f})")

这个代码的核心只有三步:编码图片、编码文本、算相似度排序。但它实现了一个完整的开放词表图像检索系统——你可以搜索任意自然语言描述,不需要预定义任何类别或标签。


15. 自测检查点

读完本章,用以下问题检验你是否真正理解了 CLIP:

基础理解(应该能回答)

问题 1:CLIP 的训练目标是什么?用一句话描述。

参考答案:给定一个 batch 的 N 个图文对,让每张图和它对应的文字在嵌入空间中最近(余弦相似度最高),同时推开其他 N-1 个不匹配的文字。

问题 2:CLIP 的 zero-shot 分类是怎么工作的?为什么不需要训练数据?

参考答案:把每个类别名套进文本模板(如"a photo of a {class}"),用文本编码器编码得到类别向量。测试图像经过图像编码器后,与所有类别向量计算余弦相似度,选最高的。不需要训练数据,因为分类器的"权重"是由文本编码器动态生成的。

问题 3:为什么 CLIP 的 batch size 必须非常大(32768)?

参考答案:对比学习的负样本数 = batch_size - 1。负样本越多,模型要区分的"假对"越多,监督信号越强。小 batch 意味着负样本少,模型可以"偷懒"而不真正学到好的表征。

深度理解(挑战自己)

问题 4:CLIP 论文说文本编码器是一个"hypernetwork"。怎么理解这个说法?

参考答案:Hypernetwork 是"生成另一个网络权重的网络"。CLIP 的文本编码器接收类别名描述作为输入,输出一个 512 维向量——这个向量恰好可以作为线性分类器中"该类别对应那一行"的权重。所以文本编码器在动态地"生成"线性分类器,而不是在数据集上训练一个固定的分类器。

问题 5:为什么 CLIP 在 MNIST 上只有 88%?这告诉我们关于"大数据路线"的什么局限?

参考答案:MNIST 的手写数字图像在互联网图文对中几乎不存在,属于真正的分布外数据。这证明了"用规模换泛化"的策略有根本性局限——你不可能让训练数据覆盖所有可能的视觉概念。对于机器人来说,真实世界中总会有训练数据未覆盖的情况。

问题 6:从 CLIP 到 OpenVLA,中间经过了哪些关键步骤?每步解决了什么问题?

参考答案:CLIP(图文对齐,不能生成)→ BLIP-2(加 Q-Former 桥接 LLM,能生成文本)→ LLaVA(简化为线性投影 + LLM 微调,高效对话)→ RT-2(把动作表示为 token,VLM 变 VLA)→ OpenVLA(开源 VLA,SigLIP+DINOv2 双流视觉编码器)。每步都在扩展 CLIP 原始"图文对齐"能力的应用范围。

应用设计题(开放思考)

问题 7:假设你在做一个家庭机器人项目,需要机器人理解"把红色杯子放到微波炉旁边"这个指令。你会怎么用 CLIP?它的哪些局限会是障碍?

思考方向:这个指令涉及对象识别(红色杯子)、空间关系(旁边)和物体定位(微波炉)。CLIP 可以帮你判断当前视野中是否有"红色杯子"和"微波炉"(用文本-图像相似度),但它不擅长理解"旁边"这种空间关系——因为对比学习做的是图像级别的全局匹配,不提供像素级定位。你还需要一个定位模块(如 OWL-ViT 或 Grounding DINO)来找到物体的精确位置,以及一个空间推理模块来理解"旁边"意味着什么。这就是为什么 SayCan 和 Code-as-Policies 等系统采用模块化方案——CLIP 负责"理解",但"执行"需要其他模块。

问题 8:如果你有一个只包含 1000 张猫和狗图片的小数据集,想训练一个分类器——你选 CLIP zero-shot、CLIP linear probe 还是从头训练一个 ResNet?为什么?

思考方向:三个方案的权衡——CLIP zero-shot(0 张训练图,约 90% 准确率)适合快速基线或无法标注的场景;CLIP linear probe(用 1000 张训练线性层,约 95-97%)是性价比最高的选择——冻结 CLIP 的视觉编码器,只训练一个线性头,几分钟就能完成;从头训练 ResNet(用 1000 张,约 85-90%)在小数据上不如 CLIP 特征好,因为 ResNet 需要大量数据才能学到好的视觉特征。结论:几乎没有理由从头训练,CLIP linear probe 是小数据场景的最优选择。

问题 9:CLIP 论文中提到一个有趣的现象——"prompt ensembling"(用多个不同的 prompt 模板取平均)能显著提升性能。为什么把多个 prompt 取平均有效?

思考方向:不同 prompt 模板强调文本的不同侧面——"a photo of a dog"、"a centered photo of a dog"、"a good photo of a dog"在嵌入空间中的向量位置略有不同,各自存在一定的"偏置"(比如"centered"会偏向构图居中的图片)。取平均相当于消除了各个 prompt 的特有偏置,只保留了"dog"这个核心语义——类似于机器学习中的 ensemble 技术减少方差。数学上,如果每个 prompt 向量 = 真实语义 + 各自噪声,取平均后噪声互相抵消,信号保留。


16. 关键数字速查表

一篇论文的核心洞察往往藏在几个关键数字里。CLIP 的关键数字值得反复记忆:

数字 含义 为什么重要
4 亿 WIT 数据集的图文对数量 当时最大的图文数据集,是学术界最大公开数据集 YFCC100M 的 4 倍
50 万 构造 WIT 时的搜索 query 数量 每个 query 最多 2 万对,保证类别均衡
32768 训练 batch size 对比学习效果的核心变量:负样本数 = batch_size - 1
512 共享嵌入空间维度 图和文都映射到这个维度,余弦相似度在此空间计算
77 文本编码器最大序列长度 超过的文本被截断,对长描述是瓶颈
76.2% ViT-L/14@336 ImageNet zero-shot top-1 追平有监督 ResNet-50(76.1%),里程碑意义
85.4% Linear probe 在 ImageNet 上的准确率 说明 CLIP 表征质量远超 zero-shot 能展示的
88% CLIP 在 MNIST 上的 zero-shot 准确率 比原始像素 logistic regression(92%)还差!OOD 脆弱性的铁证
+5% Prompt engineering + ensemble 带来的提升 相当于"免费 4 倍算力",几乎不增加推理成本
16/27 Zero-shot CLIP 在多少数据集上超过有监督基线 超过半数数据集上,不看数据比看了少量数据的传统方法还强
4-shot Zero-shot CLIP 等价的 few-shot 水平 不看任何训练图 ≈ 传统方法看了每类 4 张图
12 天 ViT-L/14 训练时长 256 块 V100 GPU 全速跑 12 天
18 天 RN50x64 训练时长 592 块 V100 GPU 全速跑 18 天
1000x 论文估算达到 SOTA 需要的额外算力 "用现有硬件不可行"——催生了 SigLIP、EVA-CLIP 等后续工作
405 年 一秒一张看完所有训练图的时间 4 亿 × 32 epochs = 128 亿张,数据效率问题的直观表述
4x 对比学习比逐字预测的效率优势 CLIP 选择对比目标的核心原因
0.07 温度参数 τ 的初始值 可学习的,被 clamp 在 1/100 以上

记忆技巧:抓住三个"锚点数字"——4 亿(数据规模)、32768(batch size)、76.2%(ImageNet zero-shot)。从这三个数字出发,其他数字都能串起来。


17. FAQ:你可能还有的疑问

Q1:CLIP 和"图像 caption 模型"有什么本质区别?

Caption 模型(生成式)要逐字预测描述——目标是"输出最可能的一句话"。CLIP(对比式)只要求"在 N 个候选里挑出真 caption"——不关心生成。论文 Figure 2 直接对比:caption 模型学 ImageNet 比 CLIP 慢 12 倍。本质区别是填空题 vs 选择题

Q2:温度参数 τ 为什么要可学习?手调不行吗?

τ 控制 softmax 锐度(小 τ 锐、大 τ 平)。最佳 τ 取决于模型规模、训练阶段、数据分布——大模型和小模型最佳 τ 不同,训练初期和末期最佳 τ 也不同。让模型自己学省去了一个最敏感的超参数调优。CLIP 把 log τ 做成可训练参数,并 clamp 上限防止训飞。

Q3:为什么 zero-shot CLIP 能追平有监督 ResNet-50?靠的是算法还是数据?

主要靠数据量碾压。ResNet-50 看 128 万张图(1000 类);CLIP 看 4 亿对图文(覆盖几乎所有英文维基百科概念)。数据量相差 300 多倍。规模扩大到这个程度,"自然语言监督"的弱信号反而成了"概念多样性"的优势。但算法也很重要——如果不用对比学习而用 caption 生成,同样的数据需要 12 倍算力才能达到同样效果。

Q4:CLIP 的 WIT 数据集开源了吗?

没有。OpenAI 只开源了模型权重和代码,4 亿对原始数据没放。这是 CLIP 最大的争议点之一。后来 LAION 团队复刻出了 LAION-400M、LAION-2B 等开源替代品,被 OpenCLIP、SigLIP 等开源项目使用。

Q5:CLIP 能做"图像生成"吗?比如文生图?

CLIP 本身不能——它是判别模型,不是生成模型。但 DALL-E 2 和 Stable Diffusion 把 CLIP 的文本编码器当成"语言→视觉空间"的桥梁,再叠一个 diffusion decoder 完成生成。CLIP 在文生图模型中扮演的是"条件编码器"的角色——它理解"一只戴帽子的猫"是什么意思,但生成图片的工作由 diffusion 模型完成。

Q6:CLIP 和 ALIGN(Google 同期工作)是什么关系?

ALIGN(Jia 等,2021)与 CLIP 几乎同时发表,思路非常相似——图文对比 + 大规模数据。ALIGN 用了 18 亿对噪声更大的数据,证明"数据可以更脏只要更多"。两篇可以视为孪生工作,但 CLIP 因为开源 + 名字好记 + OpenAI 品牌效应,最终成为行业标准。

Q7:为什么 CLIP 用 GPT 式文本编码器而不是 BERT 式?

论文没有明确解释。推测原因包括:(1)CLIP 团队就是 GPT 团队,对该架构更熟悉;(2)GPT 式因果注意力的 [EOS] 位置天然聚合全序列信息,适合做表征提取;(3)后来的实验(如 OpenCLIP)表明 BERT 式编码器效果也不差,可能只是习惯选择。

Q8:prompt engineering 对 linear probe 有用吗?

几乎没用。Linear probe 是在 CLIP 视觉特征上训练一个有监督的线性分类器——此时文本编码器根本不参与(分类权重由训练数据决定,不是由文本生成的)。Prompt engineering 只在 zero-shot 场景下重要,因为此时分类器的权重完全由文本编码器生成,文本质量直接决定分类器质量。

Q9:CLIP 训练时,同一个 batch 里如果有两张很相似的图,会不会互相干扰?

会。这被称为假负样本(False Negatives)问题——两张都是猫的图片,在 batch 中它们会被当作负样本(因为它们不是"配对"),但实际上它们语义相似。这会给模型传递错误的信号("把两张猫的图推远")。不过在 batch size = 32768 的规模下,任何一对假负样本的影响被 32766 个真负样本稀释了,整体影响不大。SigLIP 的 sigmoid loss 在理论上比 softmax 对假负样本更鲁棒。

Q10:我现在能用 CLIP 做什么实际项目?

开箱即用的场景非常多:用余弦相似度做开放词表的图像检索("找出所有戴帽子的人");给生成模型当条件输入或评估指标(CLIP score);zero-shot 分类器做新数据集的快速基线;配合 FAISS 做大规模图文检索;做"图像-文本对齐度"的过滤器(清洗噪声数据集);在具身智能中做"语言指令对齐当前观察"的相似度信号。

Q11:CLIP 的推理速度如何?能否实时运行?

ViT-B/32 在单块 V100 上推理一张 224×224 图片约 4ms(250 FPS),文本编码 77 个 token 约 1ms。即使是最大的 ViT-L/14@336,推理也只需约 15ms(67 FPS)。对于机器人应用来说,这个速度完全够实时——大多数机器人的控制循环频率是 10-30 Hz。注意推理时文本编码只需做一次(可以提前缓存),每个新帧只需要过一次图像编码器。所以真正的瓶颈不在 CLIP 推理,而在上游的图像采集和下游的动作规划。

Q12:CLIP 对中文支持好吗?

原版 CLIP 只在英文数据上训练,对中文支持很差(几乎不可用)。如果你需要中文能力,有几个选择:Chinese-CLIP(来自清华&Tencent,在中文图文对上训练)、AltCLIP(BAAI,多语言 CLIP)、EVA-02-CLIP-bigE-14-plus(原生支持中文)。在具身 AI 场景中,如果你的机器人需要理解中文指令(比如"把那个红色的碗拿过来"),你需要一个支持中文的 CLIP 变体或者一个中英翻译模块。

Q13:CLIP 的 512 维嵌入向量能做降维可视化吗?有什么实际用处?

可以,用 t-SNE 或 UMAP 把 512 维降到 2D 做可视化,能直观地看到 CLIP 空间的结构。实际用处:(1)调试——如果你的 zero-shot 分类效果差,可视化嵌入看看是不是某几个类的向量太接近了;(2)数据集分析——把一批图片的 CLIP 嵌入可视化,可以快速发现数据中的簇结构和异常值;(3)质量评估——用可视化确认"相似的图片确实在嵌入空间中相近"。不过要注意,高维空间中"距离"的直觉在低维可视化中会失真——t-SNE 保持的是局部邻域关系,不保持全局距离比例。


18. 延伸阅读路线

如果你读完这一章想继续深入 CLIP 生态,这是推荐的阅读路径:

理解 CLIP 从哪里来(前置工作)

GPT-2 / GPT-3(Radford 2019, Brown 2020)——zero-shot transfer 范式来源。SimCLR(Chen 2020)——对比学习在视觉表征上的代表作,CLIP 借鉴了 InfoNCE 和大 batch 思路。ViT(Dosovitskiy 2020)——CLIP 最强版本的图像编码器。ConVIRT(Zhang 2020)——医学图像领域的图文对比预训练,CLIP 说自己是"ConVIRT 的简化版 + 大规模化"。

理解 CLIP 走向哪里(后续工作)

ALIGN(Jia 2021)——Google 同期孪生工作。Flamingo(Alayrac 2022)——CLIP 视觉编码器 + LLM = 通用 VLM。BLIP / BLIP-2(Li 2022/2023)——对比 + 匹配 + 生成三目标联合训练。LLaVA(Liu 2023)——CLIP + LLM 微调,开源 VLM 标杆。OpenCLIP / LAION(Schuhmann 2022)——开源复现。SigLIP(Zhai 2023)——sigmoid loss 改进。EVA-CLIP(Sun 2023)——高效训练。

理解 CLIP 在具身 AI 中的角色

SayCan(Ahn 2022)——LLM + CLIP 场景理解做机器人规划。CLIPort(Shridhar 2022)——CLIP 语义流 + TransporterNet 空间流。RT-2(Brohan 2023)——VLM 输出动作 token。OpenVLA(Kim 2024)——开源 VLA,SigLIP + DINOv2 视觉编码器。

批判性阅读

"CLIP 的失败模式"系列后续论文——细粒度、计数、组合性、空间推理上的失败案例。Winoground(Thrush 2022)——系统性测试 VLM 组合推理能力的 benchmark。"Bias in CLIP"(Agarwal 等)——CLIP 偏见量化研究。


19. CLIP 在工业界的实际部署

CLIP 不只是一篇学术论文——它已经在工业界的大量产品中落地。了解这些应用场景能帮助你建立"这东西真的有用"的直觉。

搜索引擎和推荐系统:Pinterest、Shutterstock、Unsplash 等图片平台使用 CLIP 或其变体做"以文搜图"——用户输入自然语言描述("minimalist kitchen with wooden countertops"),系统用 CLIP 计算文本和库中图片的相似度,返回最匹配的结果。相比传统的基于标签的搜索,CLIP 不需要给每张图手动打标签,而且能理解更复杂、更自由的查询。

内容审核:社交媒体平台使用 CLIP 做内容安全过滤——检测图片是否包含暴力、色情或其他违规内容。优势是 zero-shot:你只需要定义违规类别的文本描述,不需要为每种违规类型收集和标注大量训练数据。当平台需要新增一个违规类别时,只需要新加一条文本描述,不需要重新训练模型。

创意工具:Adobe、Canva 等设计工具用 CLIP 做"设计素材搜索"和"风格匹配"。Stable Diffusion 和 DALL-E 2 用 CLIP 的文本编码器理解用户的生成指令。Midjourney 用 CLIP-based 的评估指标(CLIP score)来判断生成的图片是否符合用户的文本描述。

自动驾驶和机器人:Waymo、Tesla 的研究团队探索用 CLIP 做场景理解(识别道路上的罕见物体——施工标志、倒下的树、意外的动物等),这些物体在标准标注数据中出现频率极低,但 CLIP 的 zero-shot 能力允许通过文本描述来检测它们。在仓储机器人领域,Covariant 等公司使用 CLIP 式的视觉-语言对齐来理解新的商品种类——仓库里每天都可能出现新的 SKU,传统的有监督分类器需要不断重新训练,而 CLIP 只需要知道商品名就能识别。

一个数据点说明 CLIP 的影响力:截至 2024 年底,OpenAI 的 CLIP 代码仓库在 GitHub 上有 24000+ star,Hugging Face 上 CLIP 相关模型的总下载量超过 10 亿次。几乎所有主流的多模态 AI 产品——从 ChatGPT 的图像理解到 Google Lens 的场景识别——背后都直接或间接地使用了 CLIP 的思想或架构。

如果说 2012 年的 AlexNet 开启了深度学习的"ImageNet 时代",那么 2021 年的 CLIP 就开启了"多模态时代"。它的核心贡献不是某个惊艳的数字,而是证明了一种新的范式——用自然语言作为监督信号来学习视觉表征——是可行的、高效的、且能产生强大的 zero-shot 泛化能力。这个范式的影响力还在持续扩大中。


20. 本章小结

回顾一下我们在这一章学到的核心要点:

CLIP 解决了什么问题:打破传统视觉模型"固定类别 + 人工标注"的双重枷锁,用互联网上的 4 亿图文对训练出一个能理解任意自然语言描述的视觉模型。

CLIP 怎么做到的:三个关键设计——对比学习目标(图文配对当正样本、其他当负样本)、共享嵌入空间(图和文映射到同一个 512 维空间)、动态分类器生成(用文本编码器根据类别名生成分类权重)。

CLIP 做不到什么:细粒度分类、计数、空间推理、组合性理解、真正的分布外泛化。这些局限源于对比学习"只做整体匹配"的结构性缺陷。

CLIP 为什么重要:它是 2021 年后整个视觉-语言-动作研究链条的起点。没有 CLIP 把视觉和语言放进同一空间,后面所有"用语言指令操控机器人"的工作都没有落脚点。

CLIP 的历史定位:从更宏大的视角看,CLIP 是深度学习从"窄 AI"走向"通用 AI"的关键转折点之一。在 CLIP 之前,视觉模型和语言模型是两个互不相干的世界——ImageNet 上训练的 ResNet 和大规模语料上训练的 BERT,各自在各自的评测集上刷榜,互相不知道对方的存在。CLIP 第一次证明了,只要找到合适的训练方式(对比学习)和足够大的跨模态数据(4 亿图文对),视觉和语言可以被放进同一个统一的表征空间。这个突破的意义远超 ImageNet 上的数字——它让后续的研究者看到了一条通往"多模态通用智能"的路径。从 CLIP 到 GPT-4o(视觉 + 语言 + 音频),从 CLIP 到 RT-2/OpenVLA(视觉 + 语言 + 动作),核心思想都是"把更多的模态放进同一个空间"。

给初学者的实践建议:读完这一章后,最有价值的下一步不是立刻读下一篇论文,而是亲手跑一遍代码。具体来说:(1)用第 14 节的代码做 zero-shot 分类,用自己的照片或网上的图片测试——观察什么情况下 CLIP 很强,什么情况下很弱;(2)用第 14.3 节的代码做图片检索,用不同的自然语言查询搜索一组图片——体会 prompt 的措辞如何影响结果;(3)试着复现 CLIP 的一个失败案例——用组合性描述("a red apple on a blue plate"vs"a blue apple on a red plate")测试模型是否真的区分了属性和对象的绑定关系。这些亲手实验建立的直觉,比读十篇 survey 都有用。

如果你只能记住三件事:(1)CLIP = 对比学习 + 4 亿图文对 + 双编码器;(2)CLIP 让视觉模型能"听懂"自然语言——分类器不再需要训练,只需要"说出来";(3)CLIP 是所有后续 VLM/VLA 工作的视觉地基,从 BLIP-2 到 LLaVA 到 OpenVLA,每一个都站在 CLIP 的肩膀上。

下一步:Ch09 将讲解 CLIP 的两个重要继承者——BLIP-2 和 LLaVA。你会看到 CLIP 的视觉编码器如何被"嫁接"到大语言模型上,让 AI 从"认图"进化到"看图说话"。核心问题是:CLIP 只能算相似度分数,不能生成文字——怎么把它的"认图能力"转交给一个能说话的 LLM?BLIP-2 和 LLaVA 给出了两个截然不同的答案,而这两个答案的优劣直接影响了后来 VLA 模型的架构选择。


前置章节:Ch07: 从论文到机器人——理解学术论文的结构与读法 后续章节:Ch09: VLM 地基 (II)——从 BLIP-2 到 LLaVA,给 AI 装上对话能力 返回目录

本章涉及论文 7 篇

点击查看论文笔记全文,标有 的为已读。

№ 129 VLM Foundation · 经典

EVA-CLIP

№ 127 VLM Foundation · 经典

BLIP

№ 01 VLM Foundation · 祖师爷

LLaVA

№ 126 VLM Foundation · 经典

BLIP-2

№ 125 VLM Foundation · 祖师爷

Flamingo