CLIP
CLIP 是一个双塔(dual-tower)模型,它拿图像去和文本提示词打分,而不是去对一个固定的标签集合。LibreYOLO 支持用它做零样本分类和图像/文本嵌入向量,没有训练这一步。
- 任务
- classify, embed
- 尺寸
- 安装
pip install libreyolo- 支持层级
- 兄弟层级,自 v 起。一个独立的产品面,有自己的工厂和契约。
- 许可
- 代码采用 MIT,权重采用 MIT。商用
安装
CLIP 需要它自己的 extra,它会装上其自带的 BPE 分词器复现完全一致的 token id 所用到的包。
pip install "libreyolo[clip]"预测
权重在首次使用时从 Hugging Face 下载,并缓存在本地。
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreCLIPb32-cls.pt")model.set_classes(["a forklift", "an empty aisle", "a spill"])result = model(SAMPLE_IMAGE, save=True) print(model.names[result.probs.top1], float(result.probs.top1conf))# 不调用 set_classes() 时,CLI 的 predict 用的是模型默认加载的# 1,000 个 ImageNet 类别名libreyolo predict model=LibreCLIPb32-cls.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=Truefrom libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreCLIPb32-cls.pt", task="embed")image_embed = model(SAMPLE_IMAGE).embeddings.datatext_embed = model.embed_text("a photo of a forklift") # 两者都做了 L2 归一化,所以直接点积就是余弦相似度similarity = (image_embed @ text_embed.T).item()set_classes() 是让它成为开放词汇分类器的那一个原语:它把每个标签渲染进每一个提示词模板,编码之后取平均,并把得到的 [K, D] 矩阵缓存为分类器 head,所以不会每张图像重算一次。随时再调用一次就能更换类别。如果一次都不调用,LibreCLIP 加载时就已经设好了 1,000 个 ImageNet-1k 类别名。
用 task="embed" 时,预测对每个输入返回一个经过 L2 归一化的图像向量,而不是类别概率;embed_text() 返回同一个向量空间里归一化的文本行,所以两者之间直接点积就是余弦相似度。iou 对这两个任务都没有影响,也没有 NMS 这一步。数据源、流式处理和结果处理见预测。
验证
val() 读取 ImageFolder train/ 划分下的类别文件夹名,用它们调用 set_classes(),然后测量零样本的 top-1 和 top-5 精度。精度取决于这些类别名当作提示词读起来怎么样,而不是取决于任何权重更新,因为这里根本没有东西可训练。验证只覆盖 task="classify",task="embed" 没有数据集验证器。
from libreyolo import LibreYOLO model = LibreYOLO("LibreCLIPb32-cls.pt") # data 是一个带 train/ 划分的 ImageFolder 根目录,它的文件夹名# 会成为本次运行的零样本类别提示词metrics = model.val(data="imagenette160") print(metrics["metrics/accuracy_top1"])print(metrics["metrics/accuracy_top5"])libreyolo val model=LibreCLIPb32-cls.pt data=imagenette160导出
| 任务 | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| classify | classify to ONNX:支持 | classify to TorchScript:支持 | classify to ExecuTorch:支持 | classify to TensorRT:支持 | classify to OpenVINO:支持 | classify to Paddle:不支持 | classify to MNN:不支持 | classify to RKNN:不支持 | classify to ncnn:不支持 | classify to TFLite:不支持 | classify to CoreML:不支持 | classify to Core AI:支持 |
| embed | embed to ONNX:支持 | embed to TorchScript:支持 | embed to ExecuTorch:支持 | embed to TensorRT:支持 | embed to OpenVINO:支持 | embed to Paddle:不支持 | embed to MNN:不支持 | embed to RKNN:不支持 | embed to ncnn:不支持 | embed to TFLite:不支持 | embed to CoreML:不支持 | embed to Core AI:不支持 |
导出会把模型当前的状态固化成一张静态计算图。对 task="classify" 来说,set_classes() 最后设置的那批标签,以及导出时的分辨率,都会被固化进最后一层线性层,所以导出的 ONNX 或 TensorRT 计算图就是一个普通的 [B, K] 图像分类器,没有文本塔,也没有分词器;改动类别或尺寸之后要重新导出。task="embed" 的导出只追踪图像塔。两者都需要 ONNX opset 14 或更高,导出器默认就设成了这个值。
from libreyolo import LibreYOLO model = LibreYOLO("LibreCLIPb32-cls.pt")model.set_classes(["a forklift", "an empty aisle", "a spill"])model.export(format="onnx") # 当前 set_classes() 设置的标签和输入分辨率会被固化进计算图,# 改动其中任何一个之后都要重新导出# 这里没有调用 set_classes(),所以固化进去的是模型默认加载的# 1,000 个 ImageNet 类别libreyolo export model=LibreCLIPb32-cls.pt format=onnxfrom libreyolo import LibreYOLO # task="embed" 只追踪图像塔,不需要类别model = LibreYOLO("LibreCLIPb32-cls.pt", task="embed")model.export(format="onnx")检查点
这个家族已发布的全部权重文件。两个都是从 OpenCLIP 用 LAION-2B 训练的检查点(checkpoint)ViT-B-32 和 ViT-B-16 转换而来,而不是来自任何一次 COCO 训练。
| 文件 | 输入(px) | 权重许可 |
|---|---|---|
| classify | ||
| LibreCLIPb32-cls.pt | mit | |
| LibreCLIPb16-cls.pt | mit | |
上面的每个文件目前都在 LibreYOLO 组织中,并会在首次使用时下载。
LAION-2B 的训练数据有一段被记录在案的 CSAM 内容历史(Stanford Internet Observatory,2023 年 12 月)。LAION 此后发布了 Re-LAION,一个清理过的重新发布版本;如果你要进一步转存这些权重,在有可用版本时优先选择基于 Re-LAION 的检查点。
许可证
请检查你所下载的具体权重在 Hugging Face 仓库中的许可。LibreYOLO 组织里的每个检查点都附有许可,同一家族内也不一定相同。该仓库是权威来源;以下摘要说明本页上次验证时适用的情况。
这里只说明涉及的许可证,不构成法律意见。如果答案对商用很重要,请自行阅读许可证并咨询法律顾问。
- 原始工作
- CLIP / OpenCLIP, OpenAI; LAION / ML Foundations
- 上游许可
- MIT
- LibreYOLO 代码
- MIT
- 权重
- 采用 MIT 许可,重新发布在 huggingface.co/LibreYOLO
- 解读
- MIT is a permissive license, so these weights can be used in commercial and closed-source products. It asks you to keep the license text and copyright notice with any copy you redistribute, and it places no obligation on your own application code. LibreCLIP's tokenizer is vendored from the OpenAI CLIP / OpenCLIP byte-pair-encoding tokenizer (also MIT); its image and text towers are a clean-room re-implementation of the standard CLIP architecture, built without open_clip as a runtime dependency. The shipped checkpoints (b32, b16) are converted from OpenCLIP's LAION-2B-trained weights, which OpenCLIP publishes as MIT-redistributable. Training is not offered for this family: LibreCLIP is zero-shot, and set_classes() replaces the fine-tuning step a trained classifier would otherwise need.
引用
@software{ilharco_gabriel_2021_5143773,
author = {Ilharco, Gabriel and
Wortsman, Mitchell and
Wightman, Ross and
Gordon, Cade and
Carlini, Nicholas and
Taori, Rohan and
Dave, Achal and
Shankar, Vaishaal and
Namkoong, Hongseok and
Miller, John and
Hajishirzi, Hannaneh and
Farhadi, Ali and
Schmidt, Ludwig},
title = {OpenCLIP},
month = jul,
year = 2021,
note = {If you use this software, please cite it as below.},
publisher = {Zenodo},
version = {0.1},
doi = {10.5281/zenodo.5143773},
url = {https://doi.org/10.5281/zenodo.5143773}
}复制自作者在 github.com/mlfoundations/open_clip#citing 上提供的引用块。