写在前面:这个文章是我快速回顾这些知识点的输出,出发点并不是写一个易懂的知识博客,读者多多包涵。
CLIP

CLIP的结构非常简单,输入端是图文对,训练数据中的图文对是具有强相关的,即文本就是图片的描述。
然后图片和文本都会经过一个编特征提取器,一般图片是用ResNet或者VIT,文本用Transfomer Encoder。最终文本和图片都只会输出一个向量,图片端,如果是ResNet,最后走一个池化层,如果是VIT,那就用
cls向量,而文本端一般用最后一个token的last_hidden_state。 之后还会走一个线性层让这两个向量的维度对齐。然后再分别进行一个L2归一化,磨平两个模态的空间长度差距,让后边的对比学习专注两个模态的方向信息注意不要被这个架构图误导了,图片里的以及不是指token或者patch,指的是是每个样本。对角线指的就是数据里适配的一对儿图文对,他们两个的相似度应该是高度一致的。
Contrastive Learning
我们以CLIP中的对比学习来举例,训练的目标是,让图片或者文本与他对应的那个文本或者图片的相似性拉高,与其他样本的图片或者文本相似性拉低。
训练目标
前面说到,每个图片和文本得到一个向量后,会与这个batch里的其他模态的所有数据算一个余弦相似度(其中包含一个和他是一对的数据)。然后要经过一个。之后就可以得到一个矩阵。
上边说到,我们想要每个数据(图片或者文本)与他对应的余弦相似度更高,与其他的余弦相似度更低。那对于这个矩阵 我们希望:
T1 T2 T3 T4
I1 高 低 低 低
I2 低 高 低 低
I3 低 低 高 低
I4 低 低 低 高
对于I_i,希望T_i更高,其他的更低,那对于这一行,这不就是一个分类问题吗?所以label就可以标成
T1 T2 T3 T4
I1 1 0 0 0
I2 0 1 0 0
I3 0 0 1 0
I4 0 0 0 1
对于每一个I_i我们都可以通过交叉熵loss来让他逼近T_i,远离其他T.
所以,自然而然的对于每行做一个softmax得到概率。之后使用交叉熵优化就可以了。
问题又来了:对行做归一化,那对列做归一化呢?他俩是等价的吗?
答案是:不等价
对行做softmax可以理解为:给定图片I在 batch 中所有文本里,哪个文本才是它对应的文本?而如果对每一列做 softmax,问题就变了:给定文本 T 在 batch 中所有图片里,哪个图片才和它匹配?二者是不等价的,以行来做softmax说,分母是其他文本,是文本与文本竞争,而对列来说,分母是所有图片,是图片之间在争夺这一个文本的归属权
所以CLIP是二者都做的,模型要求每张图片都必须找到正确文本,每个文本也得找到正确图片。
所以最终的损失是行列损失的平均
原论文中的伪代码就写的很清晰了:

SigLIP
SigLIP将CLIP中Batch内的全局softmax对比损失,改成了对每一个image-text pair独立计算的pairwise sigmoid loss
原先CLIP会让一个batch中的多个候选文本(或图片)通过 Softmax 相互竞争,而 SigLIP 则将每一个图像-文本对独立看作一个二分类问题,判断这一对是否匹配。
这带来了什么好处?
SigLIP不需要跨整个batch去计算softmax,当batch很大的时候,数据都都横跨多卡,这样不需要横跨多卡,对计算开销省了很多。 SigLIP的Loss计算开销更小,他不需要算两次loss取平均
原论文的伪代码如图所示:

可以看到他将负样本填充成了-1,即:
T1 T2 T3 T4
I1 1 -1 -1 -1
I2 -1 1 -1 -1
I3 -1 -1 1 -1
I4 -1 -1 -1 1
但这样会带来另外一个问题:正负样本不均衡,对于N个图文对,会产生N个正样本和N*(N-1)个负样本。对于一个图片需要预测和N个文本哪个是正例,哪个是负例,但是对于N个文本,只有一个是正例,N-1个负例。这会发生什么?
在初始化阶段,如果图像和文本表示还没有学到对齐关系,并且归一化后的 embedding 大致是各向同性的,那么不同图文向量的点积期望接近 0,通常会集中在 0 附近,维度越高,随机向量越接近正交。也就是说 dot(zimg,ztxt)的期望接近于0。而sigmoid(0)=0.5。也就是说,模型一开始会认为每对图文对会有50%的几率匹配。但是由于大量的负样本,实际上的数据并不是50%的概率匹配,实际上是1/N,这个先验和实际上的数据分布不匹配,就会比较难训。我们希望模型初始化时候的先验是和真实数据分布近似的,也就是说我们希望模型初始化就认为一组数据里没有太多正例,所以SigLIP的logits那里加了一个bias,模型刚开始训练的时候,给每个负例加了一个bias.希望sigmoid(dot(zimg,ztxt)*T+b)=1/N 而上边我们知道dot(zimg,ztxt)的期望接近于0,也就是希望sigmoid(b)=1/N。最终得到b=-10,也就是论文中的设置。
论文原文关于bias的讨论:

CLIP和SigLIP的使用场景
虽然CLIP和SigLIP是通过图像-文本对进行多模态预训练的,但训练完成后的 Image Encoder 和 Text Encoder 都可以独立使用。因此,CLIP 既可以作为跨模态对齐模型,也可以作为单独的视觉或文本特征提取器(但现代MLLM用的都是视觉特征提取器)
CLIP论文中直接用CLIP对图像分类任务上做zero-shot。具体用法就是讲1000个类别改成"there is a
<label>"把label替换成1000个类别,然后将这1000个文本和原始图片分别输入CLIP,然后计算这1000个文本的向量和这个图片的余弦相似度,相似度最高的那个即为最终推理出的分类结果。
SigLIP2
SigLIP2是谷歌在2025年初放出的工作,他主要是在原本SigLIP训练阶段基础上encoder 加了更多监督目标,让它学到更强的全局语义、局部语义、定位能力等,但最终发布和下游使用时,它仍然主要作为一个预训练好的 vision-language encoder来用。

除了原本的对比学习监督以外,SigLIP2还加了什么任务用来监督?
额外的任务
Image Captioning
因为Image Captioning是个图生文任务,所以还额外挂了一个transformer decoder,
Image
↓
Vision Encoder
↓
patch features
↓
Decoder
↓
"A dog is playing with a ball."
这就要求Vision Encoder中的特征要更细粒度。
Referring Expression Prediction
这个要求模型给定描述某个区域的 caption,预测对应 bounding-box coordinates,原文中称为:automatic referring expression prediction这里的坐标也是通过decoder生成的grounded captioning.
和第二个反过来,给定bounding-box coordinates,然后输出这个区域的caption
除此之外,SigLIP还加了自监督的任务:
自监督任务
Self-Distill
这里的自蒸馏的实现就是,对于同一张图片,进行一些裁剪得到很多局部区域,得到多张局部图片,然后在选取一个最大区域的局部图片作为teacher,其他的作为student,一并输入Vision Encoder,然后将这些特征通过一个MLP映射到一个高维空间,然后做一个softmax,得到专属于自蒸馏的概率分布,然后将每个student和教师的概率分布做交叉熵。这些student得到的loss取个平均作为最终的loss
我个人理解这样训练可以训练模型通过局部信息感知全部信息的能力。
流程图所示:
Original Image
│
┌─────────────────┴────────────────┐
│ │
large random crop 8 small random crops
│ │
↓ ┌────────────┼────────────┐
Global View ↓ ↓ ↓
│ Local1 Local2 ... Local8
↓ │ │ │
EMA Teacher └────────────┼────────────┘
│ ↓
│ Student
↓ │
global feature local features
│ │
MLP head MLP head
↓ ↓
pT pS1 pS2 ... pS8
│ │
center + temperature temperature
│ │
↓ ↓
softmax softmax × 8
│ │
↓ ↓
Teacher P_T ──────────────────→ CE ← Student P_S
│
↓
average over 8 local views
│
↓
L_self-distillation
masked prediction
原文说的很明白:
We replace 50% of the embedded image patches in the student network with mask tokens and train the student to match the features of the teacher at masked locations.
Student的输入里会把50%的image patch embeddings替换成 mask token Teacher 看到同一个 global view 的完整版本。然后在被 mask 的位置,让 Student 去匹配 Teacher 对应位置的 patch feature。 这里这个匹配用的loss和上边的一样,也是teacher和students的向量经过一个MLP,映射到高维空间,然后softmax算出概率分布,然后做交叉熵。只不过这里是作用于每个patch_embedding,前面的自蒸馏是作用于整张被裁剪后的图片上。这个更细粒度,patch可以理解为视觉中的token。这个mask方法也和bert的预训练规则有点像(都是google出品)
训练流程
SigLIP 2 用的是 staged multi-task training(分阶段的多任务联合训练)。论文自己就明确说,为了控制计算和显存开销,他们没有把所有技术一开始就塞进去,而是采用 staged approach。前 80% 的训练,主要联合训练两大块:原始的SigLIP2的对比学习任务和上边说到的额外的任务: Image Captioning、Referring Expression Prediction、grounded captioning.二者是1比1的。
即:
这里就是额外的任务
然后训练到 80% 时,SigLIP 2 才把我们刚讲的两个自监督任务加进来:其中Self-Distill 的权重是1,Masked Prediction的权重是0.25。而对于整个自监督任务,还得套一个参数,不同尺寸的VIT对应不同的
总体架构
再看一下总体架构就很明确了,
值得一提的是,SigLIP2采用了NaFlex,不同尺寸、不同长宽比的图片,不再像VIT一样统一硬缩放到一个固定正方形,而是根据原始分辨率映射成不同数量的视觉token,和后边要学的动态分辨率的思想很像,这里就不再细学了。
Image
│
Vision Encoder
│
┌──────────┴──────────┐
│ │
↓ ↓
Global Representation Patch Features
│ │
│ ├─────────────┐
↓ ↓ ↓
Sigmoid Loss LocCa Decoder Self-Supervised
↑ │ │
│ │ ┌─────┴─────┐
│ │ ↓ ↓
Text Encoder │ Self-Distill Masked Pred.
↑ │
Text │
┌─────────┼─────────┐
↓ ↓ ↓
Caption Text→Box Box→Text









