想象一家跨国婚恋介绍所:左边是“看图顾问”,专门把照片上的场景、人物、光线描述成气质特征;右边是“读字顾问”,专门把文字资料提炼成性格标签。过去,他们必须面对面逐条核对资料,效率极低。后来,介绍所引入一套新规矩:两位顾问不再直接交流,而是各自把观察结果写在一张标准“气质速写卡”上——卡片里是一串数字,记录这个人或这张图的“气质指纹”。新嘉宾一到店,看图顾问当场写卡,读字顾问则把库存文字卡提前归档;匹配机只需比较两张速写卡的接近程度,就能瞬间算出心动指数。这套思路,就是 CLIP 双塔编码器的核心:一座塔负责图像,一座塔负责文本,各自独立编码,却共享同一个嵌入空间,最后用相似度完成匹配。
掌握 CLIP 双塔编码器设计,你就握住了解锁多模态检索、零样本分类与图文理解任务的核心钥匙,是多模态 AI 工程师的必修课。
目录
可视化演示
展示MLOps流水线的数据处理、模型训练、部署发布与监控反馈四大阶段,拖动滑块调节流水线速度观察各环节吞吐。
本节配有交互动效(进入视口后自动加载,约 3KB)。
MLOps流水线 数据-训练-部署-监控四阶段闭环 Throughput = Tasks / CycleTime 自动化流水线提升模型交付效率
双塔架构:两位顾问各写各的速写卡
在跨国婚恋介绍所里,看图顾问和读字顾问并不需要互相对话。他们只需要遵守同一种速写卡格式:左边写照片里的颜色、轮廓、氛围,右边写文字里的主题、情绪、关系。CLIP 的“双塔”正是这样两座独立工作的网络:一座视觉塔接受图片,一座文本塔接受文字,互不干扰,各自输出一组固定长度的数字摘要。
在技术实现上,视觉塔把一张图变成向量 \(\mathbf{v}_i\),文本塔把一句话变成向量 \(\mathbf{t}_j\)。这两个向量被放到同一个嵌入空间里。所谓“同一个空间”,就像是两位顾问统一了速写卡的度量单位:不再出现“图片很亮”与“句子很长”这种无法比较的描述,而是全部变成同一维度上的数字。相似度越高,说明图片和文字越“般配”。
最常用的匹配分是余弦相似度,公式如下:
正因为两座塔完全解耦,介绍所才能提前把所有文字卡归档。新图片来了,只需看图顾问写一张卡,再和库存卡批量比对,这就是双塔架构带来的计算效率优势。
- 图像卡片视觉塔把图片编码成向量 \(\mathbf{v}_i\),它代表图片的语义摘要。
- 文本卡片文本塔把句子编码成向量 \(\mathbf{t}_j\),它代表文字的语义摘要。
- 点积打分\(\mathbf{v}_i\cdot\mathbf{t}_j\) 把两个向量逐位相乘后相加,得到初步的匹配值。
- 长度归一除以两个向量的模长,避免图片分辨率或句子长度影响分数高低。
视觉编码器:看图顾问的“切块”观察法
看图顾问面对一张复杂照片时,不会一口气描述全图,而是把照片分成若干小格子,先看每个格子里有什么,再结合格子之间的空间关系,拼出整体印象。ViT(Vision Transformer)的做法与此几乎一模一样。
ViT 先把 224×224 的图片切成固定大小的 patch,比如 16×16,每个 patch 展平后经过一个线性投影变成 token。为了让模型知道每个 patch 原来在哪个位置,还要加上位置编码。随后这些 token 进入 Transformer 层,依靠自注意力互相“交换信息”,最终输出一个代表整张图的向量。
CLIP 论文中视觉塔既可以用 ViT,也可以用 ResNet。ResNet 通过堆叠卷积层逐步扩大感受野,最后用全局池化得到图像特征。无论哪种骨干网络,它们都只负责“描述图片”,不需要知道文字长什么样。
- 切块把图片切成若干小方块,每个小方块展平成向量,避免直接处理巨大像素矩阵。
- 位置标记加入位置编码 \(\mathbf{p}_{pos}\),告诉模型每个小方块原本在图片里的位置。
- 注意力加工Transformer 层让每个 patch 与全图其他 patch 交互,学习远距离依赖。
- 图像摘要取序列头或全局池化结果,作为整张图片的语义特征。
文本编码器:读字顾问的“上下文理解”
读字顾问读一句话时,不是只看单个词,而是结合前后词来判断含义。“苹果”和“苹果笔记本”里的“苹果”意思完全不同。CLIP 的文本塔用 Transformer 完成这种上下文建模:先把句子切分成 token,映射成词嵌入,再通过多层自注意力让每个词都能“看到”整句话中的其他词。
CLIP 的文本塔通常采用类似 GPT 的 Transformer 结构,使用字节对编码(BPE)处理单词与子词。序列末尾的 [EOS] 标记或对所有 token 做平均池化,会作为整句话的语义特征。
读字顾问由此学会了“一句话的气质”,而不是简单统计关键词。无论句子多长,最终写出的速写卡长度都是固定的,方便与图像卡做统一匹配。
- 分词嵌入把句子转成 token 序列,并映射成词向量。
- 上下文建模Transformer 自注意力让每个 token 聚合全句信息。
- 序列池化取 [EOS] 或平均池化,得到整句话的单一向量。
投影头对齐:统一速写卡模板
两位顾问各自写卡后,问题来了:看图顾问的卡片可能记录的是“海面颜色、天空亮度”,读字顾问的卡片却记录的是“词汇频率、句式结构”。格式不同,没法直接比较。介绍所于是设计了一套标准模板:投影头。
投影头本质上是一层线性映射,把视觉塔和文本塔输出的原始特征分别投影到同一个低维空间中。比如视觉特征从 2048 维映射到 512 维,文本特征也从 512 维映射到 512 维。投影后还要做 L2 归一化,把所有卡片“缩放到同一长度”,让相似度只取决于方向,而不受特征模长干扰。
没有投影头,两座塔的特征就像“中文简历”和“英文简历”,内容再丰富也无法直接匹配。有了统一模板,匹配机才能公平地为所有图文卡打分。
- 线性映射分别用可学习矩阵 \(\mathbf{W}_v,\mathbf{W}_t\) 变换视觉和文本特征。
- 维度对齐让两座塔的输出维度一致,才能进入同一个嵌入空间。
- L2 归一化把向量长度变为 1,使相似度只与夹角有关。
对比学习目标:让对的靠拢,错的推开
介绍所训练两位顾问时,会同时给出很多组“照片 + 文案”的样例。对某一张照片来说,它自己的文案是正样本,同一批其他文案都是负样本。训练目标很简单:让图片卡和它的真命文案卡距离更近,和其他文案卡距离更远。这就是对比学习。
CLIP 在一个批次里构造 \(N\) 对图文数据,得到 \(N\times N\) 的相似度矩阵。理想情况下,矩阵的对角线位置分数最高,其他位置都低。损失函数使用带温度的交叉熵:
温度参数在实现中通常作为可学习参数,初始值约 0.07。它让训练过程更稳定,也决定了最终嵌入空间中的“聚散程度”。
- 相似度矩阵计算 batch 内所有图片卡 \(\mathbf{p}_i\) 和文本卡 \(\mathbf{q}_j\) 的相似度。
- 温度缩放把相似度除以温度参数 \(\tau\),调节分布的陡峭程度。
- Softmax 概率把第 \(i\) 张图片对所有文本卡片的分数转成概率分布。
- 交叉熵鼓励第 \(i\) 张图片与第 \(i\) 条文本的概率最大。
训练流程:大批量相亲训练营
双塔模型需要海量“图片 + 文案”配对数据,CLIP 使用了约 4 亿个从互联网收集的图文对。训练时,每一批数据就像一个相亲训练营:营地里同时出现多对嘉宾,卡片互相比较,形成了丰富的负样本。这些负样本不需要人工标注,因为同一个 batch 中,除了正配对外,其余组合天然就是反面教材。
为了让图片侧和文本侧都被充分训练,CLIP 使用对称损失:先要求“由图片找文本”正确,再要求“由文本找图片”正确,最后取平均。这样两个塔都能得到稳定的梯度信号。
由于对比学习依赖 batch 内负样本,batch size 通常需要很大,几百甚至几千对。因此 CLIP 训练常用分布式多卡并行,把海量图文对同时送进两座塔。
- 图片到文本损失以每张图为查询,在 batch 内找到自己的文本。
- 文本到图片损失以每条文本为查询,在 batch 内找到自己的图片。
- 对称平均两个方向损失取平均,均衡更新两座塔。
- 优化更新用梯度下降同时更新视觉塔、文本塔、投影头与温度参数。
推理与检索:卡片归档后的闪电配对
模型训练完成后,介绍所进入“营业模式”:所有文本卡提前写好、归档;新图片到来时,看图顾问只需现场写一张卡,然后匹配机把它与全部文本卡做一次批量点积,按分数从高到低排序,返回最匹配的文本。整个过程是“一次图片编码 + 一次矩阵乘法”,不需要把图片和每段文字都重新配对编码一遍,这是双塔架构对检索效率的巨大提升。
CLIP 还天然支持零样本分类:把候选类别名称构造成“a photo of a {class}”这样的文本提示,分别经过文本塔编码,再与图像特征计算相似度,取最相似的类别作为预测。
在双塔模式下,文档库的文本嵌入可以离线算好、存入向量数据库。用户输入一张图或一段文字,系统只需编码一个查询,就能在百万级向量库中快速检索。这正是双塔编码器在现代多模态推荐、搜索引擎中被广泛使用的原因。
- 图像卡视觉塔对查询图片编码并投影,得到 \(\mathbf{p}_x\)。
- 文本提示卡为每个候选类别构造一句话,文本塔编码得到 \(\mathbf{p}_{T_k}\)。
- 打分排序计算查询图片与所有文本提示卡的相似度。
- Softmax 概率把分数变成类别概率,最大者即预测结果。
AI 应用场景
电商平台“以图搜同款”
阶段:多模态检索与匹配排序
解决的问题:传统电商搜索依赖文本标签,用户拍了一张商品图却不知道关键词,很难找到同款;CLIP 双塔可以把商品主图与商品标题同时编码成速写卡,实现跨模态查询。
具体案例:用户上传一张街拍外套照片,视觉塔立刻生成图像卡;后台商品库中的文本描述和详情图卡在离线阶段已经归档。系统只需比较新图像卡与全部商品卡,就能返回“相似款外套”,同时支持“深蓝色西装外套”这样的自然语言条件。
零样本图像分类
阶段:推理阶段零样本预测
解决的问题:传统分类模型每新增一个类别就要重新准备数据、训练分类头;CLIP 通过把类别名变成文本提示,在不更新模型的情况下完成新类别识别。
具体案例:工业质检场景中,生产线突然出现一种历史数据中没有的新缺陷。工程师定义提示词“a photo of a scratch defect”,文本塔编码后与每个产品图像卡计算相似度,立马得到缺陷概率,无需重新训练模型。
智能相册自然语言检索
阶段:离线索引与在线查询
解决的问题:个人相册数量庞大,用户想找“去年在海边看日落的照片”,传统标签系统无法覆盖这种细粒度描述;双塔预计算让海量照片可以在毫秒级被自然语言检索到。
具体案例:手机相册App在后台用视觉塔把每张照片编码成图像卡并存入向量索引。用户输入“生日派对上的蛋糕”,文本塔编码后与所有图像卡做相似度排序,秒级返回相关照片。
Python 演示
import torchimport torch.nn as nnimport torch.nn.functional as F class ImageEncoder(nn.Module): def __init__(self, in_dim=8, hidden=16, out_dim=4): super().__init__() self.fc = nn.Sequential( nn.Linear(in_dim, hidden), nn.ReLU(), nn.Linear(hidden, out_dim) ) def forward(self, x): return self.fc(x) class TextEncoder(nn.Module): def __init__(self, vocab_size=16, hidden=16, out_dim=4): super().__init__() self.embedding = nn.Embedding(vocab_size, hidden) self.fc = nn.Linear(hidden, out_dim) def forward(self, tokens): h = self.embedding(tokens).mean(dim=1) return self.fc(h) class CLIP(nn.Module): def __init__(self): super().__init__() self.image_encoder = ImageEncoder() self.text_encoder = TextEncoder() self.temperature = nn.Parameter(torch.tensor(0.07)) def encode_image(self, x): z = self.image_encoder(x) return F.normalize(z, dim=-1) def encode_text(self, tokens): z = self.text_encoder(tokens) return F.normalize(z, dim=-1) def contrastive_loss(image_emb, text_emb, temperature, eps=1e-8): logits = image_emb @ text_emb.t() / temperature labels = torch.arange(logits.size(0)) loss_i2t = F.cross_entropy(logits, labels) loss_t2i = F.cross_entropy(logits.t(), labels) return (loss_i2t + loss_t2i) / 2 def main(): torch.manual_seed(0) images = torch.randn(4, 8) texts = torch.randint(0, 16, (4, 5)) model = CLIP() optimizer = torch.optim.Adam(model.parameters(), lr=1e-2) for step in range(20): optimizer.zero_grad() image_emb = model.encode_image(images) text_emb = model.encode_text(texts) loss = contrastive_loss( image_emb, text_emb, model.temperature.exp() ) loss.backward() optimizer.step() if step % 5 == 0: print(f"step {step}, loss {loss.item():.3f}") if __name__ == "__main__": main()
class ImageEncoder(nn.Module):定义视觉塔,用两层全连接网络模拟特征提取。class TextEncoder(nn.Module):定义文本塔,先做词嵌入,再平均池化得到句子特征。self.temperature = nn.Parameter(torch.tensor(0.07))把温度参数设为可学习参数。F.normalize(z, dim=-1)对嵌入做 L2 归一化,对应“统一速写卡模板”。logits = image_emb @ text_emb.t() / temperature计算图文相似度矩阵,并用温度缩放。labels = torch.arange(logits.size(0))对角线位置是正样本对,作为分类标签。loss_i2t = F.cross_entropy(logits, labels)图像向文本匹配方向的损失。loss_t2i = F.cross_entropy(logits.t(), labels)文本向图像匹配方向的损失。(loss_i2t + loss_t2i) / 2对称损失取平均,均衡训练两个塔。
常见误区
误区CLIP 里的“双塔”是不是一个网络用两次?两个塔应该共享权重,否则没法对齐?
正解双塔指的是两个结构不同、参数独立的编码器。视觉塔处理图像,文本塔处理文本,它们共享的是“嵌入空间”,而不是网络参数。对齐靠的是对比损失和投影头,而不是结构绑定。就像两位顾问可以来自不同国家,只要遵守同一张速写卡格式就能合作。
为何常见:常见双塔推荐模型有时会共享底层特征,容易让人误以为 CLIP 也必须共享权重。
误区温度 \(\tau\) 越小,模型对正样本越严格,那是不是设置成 0.001 效果最好?
正解\(\tau\) 太小会让相似度分数被放大得极大,softmax 迅速饱和,梯度很容易消失或震荡,训练不稳定。CLIP 把 \(\tau\) 设为可学习参数,初始约 0.07,让模型自己找到合适的“挑剔程度”。这也好比相亲要求严苛到“小数点后三位完全一致”,反而没人能匹配成功。
为何常见:人们直觉上认为“越严格越精准”,忽略了温度对梯度尺度的影响。
误区训练好的 CLIP 拿到一张图,应该能直接告诉我它是猫还是狗,就像普通分类模型输出类别 ID。
正解CLIP 本身不做分类,它只输出图像特征与文本特征的相似度。要做零样本分类,必须把每个类别名构造成一段文本提示,再与图像算相似度,取分数最高的类别。没有文本提示,CLIP 无法直接给出标签。
为何常见:习惯了固定分类头的图像模型,容易忽略 CLIP“图文匹配”的本质。
误区已经有一个很好的图像模型和一个很好的文本模型,把它们各自输出的特征拼在一起,不就能当 CLIP 用?
正解单独训练的两个模型特征分布可能完全不同,一个在“颜色空间”,一个在“语义空间”,直接比较没有意义。必须通过对比学习让两个塔在同一个嵌入空间里对齐,并借助投影头和温度参数统一尺度。否则就像分别用中文和法文写简历,内容再好也没法自动匹配。
为何常见:预训练模型都很强,容易让人误以为“强强联合”自然能对齐,忽视了多模态对齐需要专门训练。
面试题
Q1. CLIP 中的“双塔”指的是哪两个模块?
- A.两个分类头
- B.视觉塔与文本塔← 正确答案
- C.两组投影层
- D.两个损失函数
答案:B。CLIP 由视觉编码器和文本编码器两座塔组成,分别处理图像和文本。分类头、投影层和损失函数都只是辅助组件,不是“双塔”的本体。
Q2. 视觉塔使用 ViT 时,第一步通常做什么?
- A.把全图压缩成一个向量
- B.把图片切成固定大小的小块← 正确答案
- C.对每个像素做卷积
- D.计算整张图的颜色直方图
答案:B。ViT 先把图像切成 patch,再展平成 token 并加入位置编码。直接整图压缩或像素级卷积都不是 ViT 的第一步。
Q3. CLIP 的文本塔通常基于哪种结构?
- A.卷积网络
- B.循环网络
- C.Transformer← 正确答案
- D.全连接网络
答案:C。CLIP 文本塔采用 Transformer 结构,通过自注意力建模词与词之间的上下文关系,输出整句语义特征。
Q4. 投影头在 CLIP 中的主要作用是什么?
- A.让两个塔共享全部参数
- B.把特征映射到统一嵌入空间← 正确答案
- C.增加图像分辨率
- D.生成文本候选词
答案:B。投影头用线性映射把视觉特征和文本特征统一到同一维度,再做 L2 归一化,使两座塔的输出可以计算相似度。它不负责共享参数,也不提升图像分辨率。
Q5. 对比损失中温度参数 \(\tau\) 主要控制什么?
- A.梯度裁剪强度
- B.相似度分数的缩放← 正确答案
- C.图像分块大小
- D.文本最大长度
答案:B。\(\tau\) 对相似度矩阵做除法,控制 softmax 分布的平滑度。它不参与梯度裁剪,也不影响输入尺寸。
Q6. CLIP 做零样本图像分类时,类别标签如何参与计算?
- A.作为 one-hot 标签
- B.作为额外训练样本
- C.构造成文本提示再编码← 正确答案
- D.直接输入图像分类器
答案:C。零样本分类要把类别名构造成“a photo of a class”这样的提示句,经文本塔编码后与图像特征算相似度。one-hot 标签和额外训练样本都不是 CLIP 的推理方式。
Q7. 为什么 CLIP 推理时可以预先计算文本嵌入?
- A.因为文本塔不需要训练
- B.因为推理时不更新模型参数
- C.因为双塔结构解耦,文本嵌入与图像无关← 正确答案
- D.因为文本数量远少于图像数量
答案:C。双塔结构中文本编码不依赖图像输入,因此所有文本可以离线编码并缓存。推理时只需编码查询图像,再与缓存文本向量做点积排序。
Q8. 以下哪些是 CLIP 双塔结构的优点?
- A.图文特征可分别预计算← 正确答案
- B.检索时无需逐对编码← 正确答案
- C.适合大规模向量检索← 正确答案
- D.完全不需要训练数据
答案:ABC。双塔解耦使图文嵌入可离线预计算,检索阶段只需一次查询编码和一次矩阵乘法,因此适合大规模向量检索。但 CLIP 仍然依赖海量图文对训练,选项 D 错误。
Q9. 以下哪些符合 CLIP 对比学习的特点?
- A.同批其他图文对作负样本← 正确答案
- B.需要人工标注困难样本
- C.损失鼓励正样本对齐← 正确答案
- D.只有图像到文本一个方向
答案:AC。CLIP 在 batch 内构造负样本,不需要人工标注负样本;损失函数同时包含图像到文本和文本到图像两个对称方向,因此 B、D 错误。
Q10. 如果把温度参数 \(\tau\) 设置得过小,训练时最可能出现什么现象?
- A.logits 被压缩,梯度变得很小
- B.logits 被放大,训练容易不稳定← 正确答案
- C.模型自动退化为普通分类器
- D.文本塔停止更新参数
答案:B。\(\tau\) 过小会让相似度分数除以很小的数后变得非常大,softmax 输出趋于饱和,梯度可能消失或震荡,导致训练不稳定。\(\tau\) 过大才会让 logits 被压缩,梯度变小。