CLIP(Contrastive Language-Image Pre-training)是 OpenAI 提出的图文对比学习模型,训练了 4 亿个图文对,学习将图像和文本映射到同一个向量空间。CLIP 的视觉编码器(ViT)是几乎所有现代 VLM 的视觉塔起点,包括 Qwen-VL 系列。
CLIP 使用两个独立编码器,训练目标是让配对的图文在向量空间中距离最近:
图像 → ViT (Image Encoder) → image_embedding [batch, dim]
文本 → Transformer (Text Encoder) → text_embedding [batch, dim]
训练目标: image_embedding · text_embedding 最大化(对角线)
非匹配对的内积最小化
批量内计算:
logits = image_emb @ text_emb.T # [batch, batch]
labels = [0, 1, 2, ..., batch-1] # 对角线 = 正样本
loss = cross_entropy(logits, labels)
这个训练方式被称为 InfoNCE 损失(或对比损失)。在一个 batch 中,只有对角线上的图文对是正样本,其余都是负样本。模型学会将"一张猫的照片"和"a photo of a cat"映射到相近的向量位置,而将"一张狗的照片"和"a photo of a cat"映射到远离的位置。
一句话:CLIP 用相互独立的图像塔和文本塔,把“整张图片”和“整段文字”各压成一个归一化向量,再让正确图文对在 batch 相似度矩阵的对角线上得分最高。
| 路径 | 编码过程 | 最终取哪个位置 |
|---|---|---|
| 图像塔 | 图片 → patch tokens → ViT 的双向 all-to-all attention | [CLS] 的最终 hidden state |
| 文本塔 | BPE tokens → causal Text Transformer | [EOT] 的最终 hidden state |
图像输入: [CLS], patch_1, patch_2, ..., patch_N
↓ ViT
图像摘要: h_cls → image_projection → normalize → I_i
文本输入: token_1, token_2, ..., token_M, [EOT]
↓ Text Transformer
文本摘要: h_eot → text_projection → normalize → T_i
[CLS] 的名字沿用了分类模型的叫法,但它本身并不表示“猫”或“狗”这样的类别。它是一个可学习 token,在 ViT 的每一层关注全部 patch,最后汇总整张图片。CLIP 把这个向量投影到图文共享空间;文本侧用 [EOT] 汇总整句话。类别由图像向量和各个类别 prompt 向量的相似度决定。
S = exp(logit_scale) * I @ T.T # shape: [batch, batch] 对角线 S[i, i] = 正确图文配对 非对角线 S[i, j] = batch 内负样本 loss_i2t = cross_entropy(S, labels) loss_t2i = cross_entropy(S.T, labels) loss = (loss_i2t + loss_t2i) / 2
这个大矩阵不是模型参数,而是每个 batch 根据当前 embeddings 动态算出的 logits。梯度经过矩阵返回图像塔、文本塔、两个 projection 和可学习的 logit_scale,推动对角线相似度升高、非对角线相似度降低。
噪声边界:少量描述不完整或弱相关的图文对可以被大规模数据的冗余信号稀释;错误配对会产生错误的对角线监督,而语义相近的非配对样本还会成为 false negatives。因此 CLIP 对少量弱标注有一定鲁棒性,但仍依赖过滤、去重和足够高的正确配对比例。
与现代 VLM 的区别:原始 CLIP 做检索或零样本分类,只需要一个全局 image embedding;现代 VLM 为了读取文字、位置和局部细节,通常保留或压缩成多个 visual tokens 再送入 LLM,而不是只使用一个 [CLS]。VLM 通常复用 CLIP 视觉塔,丢弃 CLIP 文本塔。
CLIP 最出名的能力是零样本分类。不需要在任何分类数据集上微调,只需要把类别名写成文本 prompt,计算图像与每个 prompt 的余弦相似度,取最高分即可:
类别: ["猫", "狗", "鸟", "汽车", "飞机"]
Prompt: ["一张 {类别} 的照片" for 类别 in categories]
image_embedding = CLIP.encode_image(image)
text_embeddings = CLIP.encode_text(prompts)
scores = cosine_sim(image_embedding, text_embeddings)
predicted_class = argmax(scores)
这种零样本能力来自训练数据的大规模图文对齐。CLIP 训练了 4 亿个图文对,远远超过传统 ImageNet 的 120 万张标记图片,因此学到了更通用的视觉概念表示。
CLIP 的视觉编码器(通常为 ViT-L/14 或 ViT-bigG)被许多 VLM 复用,作为视觉塔的初始化权重。Qwen-VL 的视觉编码器就是从 CLIP ViT-bigG 初始化。它提供了三类直接用途:
| 作用 | 说明 |
|---|---|
| 视觉概念空间已对齐 | CLIP 的视觉编码器输出的 embedding 已经与文本 embedding 空间对齐(通过对比学习)。这使得后续的 VL Adapter / Projector 只需要少量的学习就能将 visual token 送入 LLM。 |
| 零样本泛化的基础 | CLIP 的对齐给 VLM 提供了零样本理解未见类别的能力,即使 VLM 训练中没有见过某类物体,只要 CLIP 预训练见过,视觉特征就有意义。 |
| 冻结复用 | 大多数 VLM 冻结 CLIP 视觉编码器不训练,只训练 VL Adapter 和/或 LLM。因为 CLIP 的对齐已经足够好,解冻它反而可能导致灾难性遗忘。 |
VLM 通常只使用 CLIP 的视觉塔(图像编码器),丢弃文本塔。这是因为: