openai/CLIP · 上手攻略
- 仓库:openai/CLIP
- 链接:https://github.com/openai/CLIP
- 分类:ai · multimodal · zero-shot
- 作者:Tom
- 更新:2026-08-18
是什么
CLIP(Contrastive Language-Image Pre-Training)是 OpenAI 在 2021 年发布的图文多模态模型,论文为 Learning Transferable Visual Models From Natural Language Supervision。它的核心思想是用大规模图文配对数据训练一个联合 embedding 空间,让图像和文本的向量在该空间里可以对齐——模型不再依赖固定的类别标签,而是可以直接用自然语言进行 zero-shot 推理。
CLIP 在 4 亿对图文数据上做对比学习,训练时同时拉近匹配图文对的 embedding、推远不匹配对的 embedding。推断时,给定一张图片和一组文本描述,模型返回相似度最高的那个文本。
解决什么问题
传统图像分类模型(如 ImageNet 预训练模型)有几个核心局限:
- 固定类别:训练时定义多少类,推断时就只能识别多少类,新增类别必须重新训练。
- 需要大量标注数据:每类都需要大量人工标签,成本高、扩展难。
- 分布偏置:模型往往对训练分布过拟合,泛化到真实场景时性能下降明显。
CLIP 用自然语言作为图像监督信号,从根本上绕开了这些问题。它可以直接根据文本描述来识别任意概念,实现真正的 zero-shot 分类、检测、图像检索等任务,且无需在目标数据集上做任何训练。
快速安装
依赖:PyTorch ≥ 1.7.1 + torchvision + ftfy + regex + tqdm
# GPU 机器(CUDA 11.0 为例)
conda install --yes -c pytorch pytorch=1.7.1 torchvision cudatoolkit=11.0
pip install ftfy regex tqdm
pip install git+https://github.com/openai/CLIP.git
# CPU only 机器
conda install --yes -c pytorch pytorch=1.7.1 torchvision cpuonly
pip install ftfy regex tqdm
pip install git+https://github.com/openai/CLIP.git
⚠️ 注意:原文推荐 PyTorch 1.7.1,但该版本已较老。实测 PyTorch 1.12+ / 2.x 多数情况下可正常加载模型,若遇兼容问题建议用 conda 创建独立环境隔离。
核心用法
Zero-shot 图像分类
import torch
import clip
from PIL import Image
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
image = preprocess(Image.open("image.jpg")).unsqueeze(0).to(device)
text = clip.tokenize(["a diagram", "a dog", "a cat"]).to(device)
with torch.no_grad():
image_features = model.encode_image(image)
text_features = model.encode_text(text)
logits_per_image, _ = model(image, text)
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
print("Label probs:", probs) # e.g. [[0.993, 0.004, 0.003]]
在 CIFAR-100 上做 Zero-shot 评估
import os, clip, torch
from torchvision.datasets import CIFAR100
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)
cifar100 = CIFAR100(root=os.path.expanduser("~/.cache"), download=True, train=False)
image, _ = cifar100[3637]
image_input = preprocess(image).unsqueeze(0).to(device)
text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in cifar100.classes]).to(device)
with torch.no_grad():
image_features = model.encode_image(image_input)
text_features = model.encode_text(text_inputs)
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1)
values, indices = similarity[0].topk(5)
for v, i in zip(values, indices):
print(f"{cifar100.classes[i]:>16s}: {100 * v.item():.2f}%")
CLIP 模型一览
| 模型 | 图像 encoder | 参数量 | ImageNet zero-shot |
|---|---|---|---|
| ViT-B/32 | ViT-B/32 | ~151M | ~63% |
| ViT-B/16 | ViT-B/16 | ~151M | ~67% |
| ViT-L/14 | ViT-L/14 | ~428M | ~76% |
| ViT-L/14@336px | ViT-L/14(336px) | ~428M | ~81% |
⚠️ 具体精度以 model-card.md 为准,上表为论文报告值,2026 年已有多次重训版本。
提取图文特征用于下游任务
from sklearn.linear_model import LogisticRegression
from torch.utils.data import DataLoader
# 提取特征
def get_features(dataset):
all_features, all_labels = [], []
with torch.no_grad():
for images, labels in DataLoader(dataset, batch_size=100):
feats = model.encode_image(images.to(device))
all_features.append(feats)
all_labels.append(labels)
return torch.cat(all_features).cpu().numpy(), torch.cat(all_labels).cpu().numpy()
train_features, train_labels = get_features(train_set)
test_features, test_labels = get_features(test_set)
# 逻辑回归分类器
classifier = LogisticRegression(random_state=0, C=0.316, max_iter=1000)
classifier.fit(train_features, train_labels)
accuracy = (classifier.predict(test_features) == test_labels).mean() * 100
print(f"Accuracy = {accuracy:.1f}%")
典型适用场景
- Zero-shot 分类:给定任意文本标签,无需训练即可对图像分类,适合快速原型和开放域识别。
- 图像检索:用文本从图库中搜图,或用图像搜相似图像。
- 数据标注辅助:输入候选标签列表,用 CLIP 打标预筛选,降低人工标注成本。
- 多模态 embedding:将图像和文本投影到同一空间,用于跨模态排序、推荐或相似度计算。
- distribution-free 视觉推理:CLIP 在大量真实图文对上训练,对自然场景图像泛化能力较强。
坑与注意
- PyTorch 版本兼容性:官方示例用 PyTorch 1.7.1,新版本(2.x)基本兼容,但某些 CUDA 版本组合可能有细微数值差异,建议先用
clip.available_models()确认模型可加载。 - 图像预处理规格:不同 ViT 变体对输入分辨率有要求(如 ViT-L/14@336px 需要 336px),
clip.load()返回的preprocesstransform 已自动处理对应尺寸,无需手动 resize。 - 文本 prompt 工程:文本描述的质量影响 zero-shot 效果,建议用
"a photo of a {class}"格式包裹类别名,而非裸类别词。论文建议多种 prompt 集成效果更好。 - CLIP 不擅长精细粒度任务:对于高度专业化、细粒度的视觉任务(如医学影像、卫星图像),CLIP 的 zero-shot 能力可能不够,建议用下游数据微调。
- 中文支持:CLIP 原版模型基于英文训练,对中文文本支持极弱;如需中文场景,可考虑 OpenCLIP 的多语言版本。
- 部署资源:ViT-L/14 参数量约 428M,推理需要至少 8GB 显存;ViT-B/32 约 151M,可在消费级 GPU 运行。
与同类对比
| 方案 | 训练方式 | 多语言 | 开源程度 | 适合场景 |
|---|---|---|---|---|
| CLIP(官方) | 图文对比学习 | 英文为主 | ✅ 开源 | 英文 zero-shot 分类/检索 |
| OpenCLIP | 同 CLIP,多社区重训 | ✅ 多语言(支持中文等) | ✅ 完全开源 | 多语言场景、更大模型 |
| Hugging Face CLIP | 同架构 | ✅ 多语言版可选 | ✅ 开源 | HF 生态集成 |
| ALIGN | 图文对比(更大数据) | 英文 | Google闭源 | 精度优先但不可用 |
| Flamingo | LLM + 图文前缀 | 英文 | 部分开源 | 多模态对话/推理 |
| BLIP | 图文理解和生成 | 英文 | ✅ 开源 | 图文描述生成 + 理解 |
简单说:英文 zero-shot 场景直接用 CLIP;需要多语言或更大模型(ViT-G)用 OpenCLIP;需要图文caption/生成能力用 BLIP/Flamingo。
一句话推荐结论
CLIP 是图文多模态入门必知的基础模型——用自然语言做视觉推理的思路简洁优雅,适合快速实现 zero-shot 分类、图像检索和跨模态 embedding,2026 年仍是众多多模态模型的前置基座。