CLIP 和 SigLIP 都是目前多模态领域(特别是图文对齐和生成任务中)极其重要的视觉-语言基础模型。它们的核心目标一致,但在底层的优化逻辑和工程扩展性上有着决定性的差异。
以下是对这两者的详细解析、联系与区别:
1. 什么是 CLIP?
CLIP (Contrastive Language-Image Pre-training)是 OpenAI 于 2021 年提出的一种基于对比学习的多模态预训练模型。
- 架构:采用双塔结构(Dual-encoder),即一个图像编码器(如 ViT 或 ResNet)和一个文本编码器(如 Transformer)。
- 核心机制:通过海量的“图像-文本对”进行预训练。在训练时,它将一个 Batch 内的NNN张图像和NNN段文本分别编码成特征向量,并计算它们两两之间的余弦相似度,形成一个N×NN \times NN×N的相似度矩阵。
- 损失函数:使用基于Softmax 的 InfoNCE 损失。模型被训练来最大化对角线上正样本对(匹配的图文)的相似度,同时最小化非对角线上N2−NN^2 - NN2−N个负样本对(不匹配的图文)的相似度。
2. 什么是 SigLIP?
SigLIP (Sigmoid Loss for Language Image Pre-Training)是 Google 提出的一种对 CLIP 改进的模型。
- 核心痛点解决:传统的 CLIP 高度依赖极大的 Batch Size(例如 32k 甚至更大)来提供足够的负样本以保证对比学习的效果。但在分布式训练中,计算全局 Softmax 需要在所有 GPU/TPU 之间频繁通信(All-gather 操作),这成为了扩展模型规模的巨大工程瓶颈。
- 核心机制:SigLIP 的架构与 CLIP 相同,但它摒弃了 Softmax 对比损失,改用简单的 Sigmoid 二元分类损失。
- 损失函数:它将图文对齐任务转化为一系列独立的二分类问题。对于每一个“图像-文本”对,模型只需判断它们“是否匹配”(正样本标为111,负样本标为−1-1−1),而不再需要计算当前样本与整个 Batch 中所有其他样本的相对概率。
3. 二者的联系
- 目标一致:都是为了实现跨模态对齐(Cross-modal Alignment),构建强大的视觉和语言的联合特征空间。
- 架构相同:都采用了对称的双塔模型(Image Encoder + Text Encoder),推理阶段可以独立提取特征,非常高效。
- 下游应用重合度高:在多模态生成(如作为 Diffusion 模型的条件编码器)、Zero-shot 图像分类、图文检索等任务中,SigLIP 基本可以作为 CLIP 的直接上位替代(Drop-in replacement)。
4. 二者的核心区别
| 维度 | CLIP (Softmax) | SigLIP (Sigmoid) |
|---|---|---|
| 损失函数性质 | 全局对比(Global Contrastive)。每个样本的损失依赖于 Batch 内所有其他样本的特征。 | 局部独立分类(Pairwise Binary Classification)。每个图文对的损失独立计算。 |
| 通信开销 | 极高。需要跨设备的All-gather操作来收集所有设备的特征以计算分母。 | 极低。各设备只需计算本地 chunk 的特征内积,无需跨设备同步整个特征矩阵。 |
| 对 Batch Size 的依赖 | 强。Batch Size 越大,负样本越多,效果越好(通常需要极大的显存支持)。 | 弱。在较小的 Batch Size 下依然能保持优秀性能,且更容易扩展到超大 Batch。 |
| 数学表达差异 | LCLIP∝−logesim(Ii,Ti)∑jesim(Ii,Tj)\mathcal{L}_{CLIP} \propto - \log \frac{e^{sim(I_i, T_i)}}{\sum_{j} e^{sim(I_i, T_j)}}LCLIP∝−log∑jesim(Ii,Tj)esim(Ii,Ti) | LSigLIP∝−∑jlogσ(zij⋅sim(Ii,Tj))\mathcal{L}_{SigLIP} \propto - \sum_{j} \log \sigma(z_{ij} \cdot sim(I_i, T_j))LSigLIP∝−j∑logσ(zij⋅sim(Ii,Tj))(其中匹配时zij=1z_{ij}=1zij=1,不匹配时zij=−1z_{ij}=-1zij=−1) |
| 性能表现 | 在零样本分类和检索上表现优秀,是早期的行业标准。 | 在同等计算资源下,通常能达到更高的零样本准确率,并且能更高效地扩大模型参数和数据规模。 |
总结:
你可以将 CLIP 理解为在一场几万人的大型考试中,要求模型不仅要知道哪份试卷是自己的,还要知道它相对于其他所有人试卷的排名(需要看完全局才能打分)。
而 SigLIP 则是将这场大考拆解成了无数个“判断题”:模型只需要看眼前的任意一张脸和一份卷子,回答“是”或“不是”即可。这种视角的转换,完美解绑了多模态训练中的通信瓶颈,使得 SigLIP 能够以更优雅的方式冲击更大的模型规模和更优的表征能力。
1. 什么是 InfoNCE?
InfoNCE (Information Noise-Contrastive Estimation)是对比学习(Contrastive Learning)中最核心、最常用的损失函数。它最早由 DeepMind 在 CPC (Contrastive Predictive Coding) 模型中提出。CLIP 采用的正是 InfoNCE 损失函数。
你可以把它理解为一个多选题的评分系统:
假设你在做一道多选题,有111个正确答案(正样本)和KKK个干扰选项(负样本)。InfoNCE 的目标就是训练模型,让它给“正确答案”打极高的分,同时给所有的“干扰选项”打极低的分。
在数学本质上,InfoNCE 就是将对比学习任务转化为了一个带有温度系数的多分类交叉熵损失 (Categorical Cross-Entropy Loss)。
2. InfoNCE 的公式
给定一个锚点(查询特征)qqq,一个匹配的正样本特征k+k^+k+,以及KKK个不匹配的负样本特征kik_iki(总共有N=K+1N = K+1N=K+1个候选样本),InfoNCE 的公式如下:
LInfoNCE=−logexp(sim(q,k+)/τ)∑i=1Nexp(sim(q,ki)/τ)\mathcal{L}_{InfoNCE} = - \log \frac{\exp(sim(q, k^+) / \tau)}{\sum_{i=1}^{N} \exp(sim(q, k_i) / \tau)}LInfoNCE=−log∑i=1Nexp(sim(q,ki)/τ)exp(sim(q,k+)/τ)
公式参数解析:
- sim(u,v)sim(u, v)sim(u,v):相似度度量函数,通常是余弦相似度(点积),表示两个特征向量在空间中的距离有多近。
- 分子exp(sim(q,k+)/τ)\exp(sim(q, k^+) / \tau)exp(sim(q,k+)/τ):只关注正样本对(如匹配的图文)的相似度,模型希望这个值越大越好。
- 分母∑i=1Nexp(sim(q,ki)/τ)\sum_{i=1}^{N} \exp(sim(q, k_i) / \tau)∑i=1Nexp(sim(q,ki)/τ):计算当前qqq与所有样本(包括正样本和所有的负样本)相似度的总和。这是 Softmax 的归一化操作。
- τ\tauτ(Temperature):温度超参数。这是一个标量,用来控制模型对“困难负样本”(那些和正样本很像的错误答案)的惩罚力度。τ\tauτ越小,模型越会集中精力去区分那些最难分辨的负样本。
3. PyTorch 代码怎么写?
在实际的图文对比学习(如 CLIP)中,正负样本通常来自同一个 Batch。Batch 内的对角线元素是正样本对,非对角线元素是负样本对。由于它本质上就是 Softmax + Cross-Entropy,代码非常简洁:
importtorchimporttorch.nn.functionalasFdefinfonce_loss(image_features,text_features,temperature=0.07):""" 计算基于 Batch 的对称 InfoNCE 损失 (类似于 CLIP 的做法) 参数: image_features: [batch_size, hidden_dim], 图像特征 text_features: [batch_size, hidden_dim], 文本特征 temperature: float 或可学习的参数, 温度系数 """# 1. 对特征进行 L2 归一化,这样点积就等价于余弦相似度image_features=F.normalize(image_features,dim=-1)text_features=F.normalize(text_features,dim=-1)# 2. 计算相似度矩阵 (Logits)# logits 形状: [batch_size, batch_size]logits=torch.matmul(image_features,text_features.T)/temperature# 3. 构造 Labels# 因为对角线上的图文是匹配的,所以正确答案的索引就是 0, 1, 2... batch_size-1batch_size=image_features.shape[0]labels=torch.arange(batch_size,device=image_features.device)# 4. 计算交叉熵损失# 图像到文本的 Loss (给定图像,找对应文本)loss_i2t=F.cross_entropy(logits,labels)# 文本到图像的 Loss (给定文本,找对应图像)# 注意这里需要对 logits 转置loss_t2i=F.cross_entropy(logits.T,labels)# 5. 返回对称平均 Lossreturn(loss_i2t+loss_t2i)/2# === 测试代码 ===batch_size=4hidden_dim=128img_feats=torch.randn(batch_size,hidden_dim)txt_feats=torch.randn(batch_size,hidden_dim)loss=infonce_loss(img_feats,txt_feats)print(f"InfoNCE Loss:{loss.item():.4f}")4. 对应的 SigLIP 中有类似的概念吗?
有对应概念,但本质逻辑被彻底替换了。SigLIP 最大的贡献就是干掉了 InfoNCE,用Sigmoid 二元分类损失取代了它。
为什么 SigLIP 要抛弃 InfoNCE?
看看上面 InfoNCE 的公式分母(∑\sum∑),你会发现,为了计算这一个 batch_size 中某一张图片的 loss,你需要知道它和当前 batch 内所有文本的相似度。在分布式训练中,为了获得足够多的负样本(比如 32000 的 batch size),数百张显卡之间必须通过All-gather疯狂通信,把其他卡的特征同步过来,这成了极大的性能瓶颈。
SigLIP 的解法 (Sigmoid Loss)
SigLIP 放弃了“多选题”模式(Softmax),改成了**“判断题”模式(Sigmoid)。
对于N×NN \times NN×N个图文组合,SigLIP 不再做全局对比,而是独立做N2N^2N2次二分类:“这幅图和这段字匹配吗?”**
它的公式变为了(简写):
LSigLIP=−∑i,jlogσ(zij⋅sim(Ii,Tj))\mathcal{L}_{SigLIP} = - \sum_{i,j} \log \sigma(z_{ij} \cdot sim(I_i, T_j))LSigLIP=−i,j∑logσ(zij⋅sim(Ii,Tj))
其中σ\sigmaσ是 Sigmoid 函数,zijz_{ij}zij为标签(匹配为111,不匹配为−1-1−1)
对比总结:
- InfoNCE (CLIP)强制要求计算概率分布的归一化(分母),是一个互斥的操作(如果拉近一对,必然要推远其他所有对)。
- SigLIP Loss完全解耦了样本对,各个图文对独立计算 Sigmoid,不需要计算分母。因此它不需要跨 GPU 收集特征,去除了通信瓶颈,这就是它能在显存有限的情况下大幅扩展 Batch Size 和模型规模的根本原因。