恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Chinese-CLIP图文检索系统:从原理到代码实现

  • 首页
  • 资讯中心
  • /
  • Chinese-CLIP图文检索系统:从原理到代码实现

相关资讯

CANN/ge变量查询接口 2026/9/10 13:35:55
深入解析 Helm 示例 Chart:从 `helm create alpine` 到 Pod 资源模板 2026/9/10 13:35:55
Onyx 技能开发实战:用 gslides_api.py 通过 Google Slides API 读取与编辑演示文稿 2026/9/10 13:35:55

最新资讯

Ultralytics 引擎深入定制指南:基于 BaseTrainer 与 DetectionTrainer 的自定义训练
OI-wiki 基础篇:模拟算法的核心思想、实现技巧与 Climbing Worm 例题实战
SiYuan v3.3.3 版本更新详解:数据库功能增强、导出优化与 mermaid.js 升级
9Router 集成 Cline:在 VSCode 中通过 Ollama Provider 接入智能路由网关的完整指南
偏好优化方法选型与生产实战:解读 agents24 仓库 llm-finetuning 插件的 preference-optimization Skill
智慧园区电能质量治理:现状、挑战与解决方案

今日推荐

AI搜索重构内容生态:企业从“流量争夺”转向“答案共建”
AI搜索的信任缺口:企业内容如何在答案时代自证可信
Spring Boot+Vue+Node.js售后服务系统开发实战

本周热门

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Chinese-CLIP图文检索系统:从原理到代码实现

发布时间:2026/9/10 13:35:55
Chinese-CLIP图文检索系统:从原理到代码实现 简介多模态图文检索是让图像与中文文本在统一向量空间中进行语义匹配的技术其核心在于双塔结构与对比学习。通过图像编码器和文本编码器分别提取特征并利用对比损失拉近配对样本的表示模型能够理解“一只橘猫趴在窗台上”这类自然语言查询。这类系统在本地图片库语义搜索、视频截图检索、电商以图搜文等场景具有广泛应用。工程落地时通常采用离线抽取图像特征、在线计算余弦相似度的方案并借助FAISS实现大规模向量索引。围绕Chinese-CLIP模型从模型选型、环境配置到特征抽取、Top-K检索实现及RecallK评估可帮助读者快速搭建可演示的图文检索系统。1. 从课程设计到可演示的检索系统先搞清楚Chinese-CLIP在解决什么问题期末和毕设季最常见的场景是你手里已经有了一份“基于Chinese-CLIP的图文检索系统”源码包但程序能跑起来之后反倒不知道该向答辩老师展示什么。这个标题的本质不是训练一个从零开始的模型而是把图片和中文文本送进同一个向量空间给一句“一只橘猫趴在窗台上”从几千张图里捞回相关图片反过来给一张图也能从候选文本里捞回最贴切的描述。整个过程由两条主线组成一是理解Chinese-CLIP双塔结构为什么能完成这个任务二是把“离线抽特征、在线算相似度”的检索流程在Python里落地。适合三类人做计算机视觉大作业的在校生、想给本地图片库加语义搜索的工程师、以及想快速搞懂CLIP系列模型的初级算法工程师。先把它和图像分类、目标检测区分开再动手写代码后面六章的展开才会顺。2. Chinese-CLIP解析双塔对比结构、中文对齐差异与模型选型2.1 双塔结构“双”在编码器和特征空间图文检索系统最核心的结论是图像和文本不共用同一个编码器而是各走一条独立的编码路径最后映射到同一个向量空间。图像分支用ViT或ResNet文本分支用BERT风格的中文模型两支各自输出一个固定维度的特征向量。所谓“双塔”是指在训练和推理阶段两个塔可以分开计算只在最后用点积或余弦相似度做交互。训练阶段的做法是对比学习每一对图文作为正样本batch内其他组合作为负样本目标是让正样本的相似度高于负样本。这个损失在代码里比想象中短核心逻辑如下import torch import torch.nn.functional as F def contrastive_loss(image_features, text_features, temperature0.07): # image_features / text_features 形状都是 (batch_size, dim) # 对角线上的元素代表同一对图文是正样本 logits text_features image_features.T / temperature # (B, B) labels torch.arange(logits.shape[0]) # 对角线位置为正样本 return F.cross_entropy(logits, labels)这里有两个关键参数要解释。一是temperature它控制相似度分布的锐利程度值越小logits被放大越多模型对困难负样本越敏感在CLIP系列里它往往是可学习参数推理时不应该手动乱改。二是batch大小因为负样本全部来自batch内其他pair所以batch越大对比学习看到的负样本越丰富训练效果通常越稳。这也解释了为什么检索模型普遍吃显存——不是模型本身大是batch受限。推理阶段双塔的优势就体现出来了。图库的特征可以离线全部算好存成npy或向量索引线上只有一条文本query需要实时编码一次矩阵乘就能完成全库排序。如果做图搜文流程完全对称。这也是图文检索系统在工程上能落地的根本原因。2.2 Chinese-CLIP在英文CLIP基础上改了什么把OpenAI的CLIP直接拿到中文场景会有一个明显问题它的文本塔和词表是针对英文训练的换到中文后分词被切得七零八落模型对中文语义的理解会打折扣。Chinese-CLIP保留了CLIP的对比学习框架和图像分支结构但把文本侧换成基于中文语料的BERT模型并使用中文图文对数据进行预训练典型的数据来源包括WuKong等中文多模态数据集。模型在训练时也针对中文做了prompt模板设计很多模板是“一张{类别}的图片”这类句式目的是让训练和推理时文本风格更一致。中文和英文在检索任务里有一个实际差异值得注意英文有天然的空格分词中文是字级连续文本同一个意思可以有很多种写法。比如“猫坐在窗台上”和“窗台上有一只猫”英文CLIP的分词器基本稳定但中文换一个语序文本特征的分布就可能偏移。所以使用Chinese-CLIP时query的写作风格越接近训练集的图像描述风格效果越稳定。这也是后续调参章节会再次提到的重点。2.3 不同规模checkpoint怎么选RN50、ViT-B/16还是ViT-L/14模型仓库提供了多个规模的中文CLIP checkpoint对课程设计来说选型直接决定后续每一步的速度和显存占用。以下是按实际使用场景整理的参考模型标识图像骨干显存占用估算FP16推理适合场景OFA-Sys/chinese-clip-rn50ResNet-501GB以内CPU勉强可跑快速验证流程、无GPU环境OFA-Sys/chinese-clip-vit-base-patch16ViT-B/161-2GB课程设计首选显存和效果平衡OFA-Sys/chinese-clip-vit-large-patch14ViT-L/144GB以上指标优先、展示效果优先我一般会给做课程设计的读者推荐chinese-clip-vit-base-patch16。它在CPU上也能完成离线特征抽取只是慢一些在4GB显存的入门显卡上可以比较舒服地做batch推理。如果机器实在没有GPU用chinese-clip-rn50跑通全流程再把结果对比放一栏反而能在答辩里体现出“模型规模对检索效果影响”的思考。至于large版本除非你有较新的GPU否则离线索引阶段会等得比较煎熬。3. 本地跑通Chinese-CLIP环境配置、最小加载代码与首轮排错3.1 用conda隔离Python环境并安装依赖先不要急着在系统Python里pip install图文检索项目涉及torch、transformers、faiss等多个包版本冲突会浪费大量时间。常见做法是先用conda创建独立环境再装依赖conda create -n clip-retr python3.10 -y conda activate clip-retr # CPU环境直接装CPU版torchGPU环境请到pytorch官网按CUDA版本选择命令 pip install torch torchvision pip install transformers4.24 pillow numpy tqdm faiss-cpu创建环境时python版本选3.10比较稳妥太新的版本有时会遇到torch轮子还没跟上的情况。transformers4.24这个下限很重要Chinese-CLIP的模型类是在这个版本附近进入transformers的版本太老会直接报没有ChineseCLIPModel这个类。faiss-cpu这里先装上后面构建大规模索引时会用到纯做课程设计演示的话也可以先不装。在vscode里打开项目后记得用命令面板切到clip-retr这个解释器终端也确认环境已激活。这一步看起来简单却是python新手最容易卡住的地方——装包时用的是conda环境运行时vscode还是系统Python于是出现“明明装了却说找不到包”。3.2 20行加载Chinese-CLIP并做一次图文匹配环境准备好后下面这段代码能完成整个模型加载和一次图文相似度计算是后续所有功能的最小骨架from PIL import Image import torch from transformers import ChineseCLIPProcessor, ChineseCLIPModel model_id OFA-Sys/chinese-clip-vit-base-patch16 processor ChineseCLIPProcessor.from_pretrained(model_id) model ChineseCLIPModel.from_pretrained(model_id).eval() img Image.open(demo.jpg).convert(RGB) texts [一只橘猫趴在窗台上, 远处的摩天大楼] inputs processor(texttexts, imagesimg, paddingTrue, return_tensorspt) with torch.inference_mode(): text_features model.get_text_features( input_idsinputs[input_ids], attention_maskinputs[attention_mask] ) image_features model.get_image_features( pixel_valuesinputs[pixel_values] ) logits model(inputs)[logits_per_image] print(文本特征:, text_features.shape) print(图像特征:, image_features.shape) print(图文匹配分数:, logits)代码里有几个必须理解的细节。processor同时承担两件事文本侧做分词和padding图像侧做resize、归一化和转tensor千万不要自己用ImageNet的mean和std去预处理图片数值对不上会导致检索效果断崖式下降。model.eval()和torch.inference_mode()在推理时一定要加否则dropout和batch norm的统计量会让特征不稳定肉眼可能看不出问题但检索排序会受影响。代码中logits_per_image的形状是(1, 2)表示1张图和2条文本两两匹配的分数分数越高代表越相关。第一次运行会从HuggingFace下载模型权重base模型大约1GB多需要一点耐心。下载完成后会缓存在本地的~/.cache/huggingface/hub目录后续重复加载不再需要网络。3.3 首次运行的高频报错与处理把课程设计群里最常出现的报错整理成一张排查表比反复试错效率高很多报错现象可能原因处理方式ModuleNotFoundError: transformers环境未激活或包没装进当前环境确认终端前缀是(clip-retr)重新执行pip installChineseCLIPModel不存在transformers版本太老升级到4.24及以上版本网络连接失败/模型下载卡住所在网络无法访问HuggingFace让同事把~/.cache/huggingface缓存目录拷给你整体放到相同路径即可离线加载CUDA out of memorybatch过大或显存不够把batch降到1或换成rn50模型图片打开报错图片是RGBA四通道或已损坏在Image.open后加.convert(RGB)第一个报错占全部问题的一半以上本质是环境错位而不是代码问题。遇到CUDA显存不足时除了换小模型还可以在加载后把模型转成float16model.half()前后端特征计算保持一致即可。4. 实现图文检索系统数据集组织、批量特征抽取与索引构建4.1 数据集与标注文件怎么组织图文检索的数据组织方式比图像分类要复杂一层因为一张图通常对应多条文本描述。课程设计如果没有指定数据集常见的公开选择是COCO-CN、MUGE这类中文图文数据集如果自建图库建议把图片和标注分开存放用JSON统一管理映射关系。下面是一个推荐的标注结构{ images: [ { id: img_0001, path: data/images/img_0001.jpg, captions: [ 一只橘猫趴在窗台上晒太阳, 猫在窗边打盹 ] } ] }id用于检索结果回显时定位图片path是图片相对路径captions是这张图的所有候选文本。这里要注意一个评估细节如果一张图有5条候选文本那么检索时这5条文本都应该被视为这张图的相关描述评估指标需要兼容“一个query命中多个正样本”的情况后面第5章会具体实现。4.2 批量抽取图像特征并落盘在线一张一张抽特征是初学者最容易犯的性能错误几百张图速度还能忍上到几万张基本不可用。正确做法是离线把全库图像特征一次性抽完保存成npy文件线上检索只做向量运算import numpy as np import torch from PIL import Image from torch.utils.data import Dataset, DataLoader from tqdm import tqdm class ImageListDataset(Dataset): def __init__(self, img_paths, processor): self.img_paths img_paths self.processor processor def __len__(self): return len(self.img_paths) def __getitem__(self, idx): img Image.open(self.img_paths[idx]).convert(RGB) return self.processor(imagesimg, return_tensorspt) dataset ImageListDataset(img_paths, processor) loader DataLoader(dataset, batch_size32, num_workers4) all_features [] with torch.inference_mode(): for batch in tqdm(loader): # Dataset返回的pixel_values是(1,3,H,W)DataLoader堆叠后多出一个维度 pixel_values batch[pixel_values].squeeze(1).cuda() feats model.get_image_features(pixel_valuespixel_values) feats feats / feats.norm(dim-1, keepdimTrue) # L2归一化 all_features.append(feats.cpu().numpy()) image_features np.concatenate(all_features, axis0) np.save(image_features.npy, image_features) print(特征矩阵形状:, image_features.shape)代码里有三个值得说明的点。第一squeeze(1)是必须的因为Dataset里每张图返回的已经是形状(1,3,H,W)的张量DataLoader自动batching后就变成了(B,1,3,H,W)不压缩维度模型会报错。第二L2归一化在抽取阶段就做掉后面算相似度时可以直接用矩阵乘法代替余弦相似度省掉一次逐行计算。第三batch_size32只是常规值具体要结合显存调整过大不会提升特征质量只会让显存告急。参数建议值说明batch_sizeCPU: 8GPU: 32起显存不足时优先降batch而不是降低图片分辨率num_workers4Windows上不要超过8macOS不需要设置太高pin_memoryTrueGPU训练时减少数据拷贝时间4.3 文本侧编码query与候选文本的同一套规范文本侧的处理逻辑和图像侧对称但多了一个截断问题。Chinese-CLIP沿用了CLIP的context length设定中文文本超过长度限制的部分会被直接截断过长的query会丢失尾部信息。抽取候选文本特征时建议统一加truncationTrue每条文本单独padding到batch内最长而不是全部pad到上限text_inputs processor( textcaptions, paddingTrue, truncationTrue, return_tensorspt ).to(cuda) with torch.inference_mode(): text_feats model.get_text_features(**text_inputs) text_feats text_feats / text_feats.norm(dim-1, keepdimTrue)paddingTrue表示按batch内最长文本补齐而不是填满77个token这样短文本的推理速度快很多。需要特别注意的是query和候选文本必须走完全相同的编码流程不能query用pt的tokenizer、候选文本用另一个分词器特征空间会错位。实际检索时如果候选文本有几万条建议分批抽取再合并不要一次性把所有文本都喂给processor内存会先撑不住。5. 相似度计算、评估指标与效果调参5.1 用numpy实现Top-K图文检索特征全部归一化后相似度计算可以简化成一次矩阵乘法。下面这个函数是图文检索系统中最核心的一段逻辑import numpy as np def topk_match(query_feature, gallery_features, k10): # query_feature: (dim,) 或 (1, dim) # gallery_features: (N, dim)建立索引时已经做过L2归一化 if query_feature.ndim 1: query_feature query_feature.reshape(1, -1) sims gallery_features query_feature.T # (N, 1) sims sims.squeeze(1) # (N,) topk_idx np.argsort(sims)[::-1][:k] return topk_idx, sims[topk_idx]因为图像特征和文本特征都已经做了L2归一化gallery_features query_feature.T的结果就是余弦相似度不需要再对每一行做除法。np.argsort默认从小到大所以翻转后取前k个就是相似度最高的结果。实际调用时先对query文本编码并归一化再传入这个函数就能拿到图片索引和分数。如果图库规模超过10万张numpy的暴力检索会开始变慢这时可以换成faiss的IndexFlatIP它是内积索引正好匹配已归一化的特征import faiss index faiss.IndexFlatIP(feature_dim) index.add(image_features.astype(float32)) scores, idx index.search(query_feature.astype(float32), k10)faiss返回的idx是图库索引和numpy版本完全对齐替换成本很低。5.2 用RecallK和MRR量化检索效果答辩时只说“效果不错”是不够的必须给量化指标。图文检索最常用的是RecallK含义是在前K个检索结果中是否出现了至少一个相关样本。实现如下def recall_at_k(query_feats, gallery_feats, relevance, k5): # query_feats: (M, dim) # gallery_feats: (N, dim) # relevance: (M, N) 的0/1矩阵1表示该图片与query相关 sims query_feats gallery_feats.T # (M, N) rankings np.argsort(-sims, axis1) hits 0 for i in range(len(query_feats)): if relevance[i, rankings[i, :k]].sum() 0: hits 1 return hits / len(query_feats)这里的relevance矩阵是关键。有一张图对应5条caption那么这5条文本query的relevance行里这张图对应位置都是1。这样同一个候选集、同一套特征就能同时评估文搜图和图搜文。常见指标还有MRR它关注正确答案在排序结果中的最靠前位置适用于“只要第一个结果对就对”的问答式场景而RK更贴近“从图库里捞一批候选”的检索习惯。指标含义适用场景R1第一个结果就是相关的比例要求精度极高的检索R5前5个结果中包含相关图的比例课程设计最常用R10前10个结果中包含相关图的比例更宽松的候选召回MRR正确答案位置的倒数均值单正确答案场景评估时有一个常见错误把query自己对应的图片也算进正样本候选然后说R1达到100%这种“作弊”在答辩追问时很容易露馅。正确的做法是评估前把query本身对应的图片从候选集中剔除或者确保relevance矩阵里确实包含正样本。5.3 实验阶段真正值得调整的三个点课程设计阶段不需要去动Chinese-CLIP的模型结构但有几个工程层面的调优点对结果影响明显。第一个是query改写。Chinese-CLIP训练数据大多是完整的图像描述句直接输入“猫”这种短词效果反而不如输入“一只猫坐在窗台上”。检索前把短query展开成描述性句式是对齐训练分布最便宜的手段。第二个是候选集清洗图库里重复图片、带水印截图、纯文字图片都会占据排序头部抽特征前做一遍简单去重能直接提升指标。第三个是temperature参数很多初学者会试图在推理时调低它让分数差距变大但这是训练期学出来的参数推理阶段修改它只会改变分数分布并不改变排序结果对评估指标没有任何帮助。6. 拿到源码包之后看懂目录、跑通评估、把图文检索改成你的Demo6.1 源码包的典型目录与运行顺序一份结构清晰的图文检索课程设计源码通常会把“索引构建”和“在线检索”拆开而不是塞在一个文件里。推荐的目录结构如下retrieval/ ├── requirements.txt # 依赖清单 ├── config.yaml # 路径与模型参数 ├── build_index.py # 离线特征抽取 ├── search.py # Top-K检索接口 ├── evaluate.py # RecallK评估 ├── app.py # 演示页面 └── data/ ├── images/ # 图片库 └── annotations.json # 图文标注拿到源码后先别急着运行按顺序做三件事。第一打开requirements.txt确认依赖版本第二看build_index.py里的图片路径和标注路径是否指向你自己的数据第三跑一次evaluate.py拿到一个baseline指标。很多课程设计源码跑不通不是模型问题而是路径写死成作者的绝对路径。把路径改成相对路径、把图片目录换成自己的数据是最常见也是最重要的修改。6.2 换自有图片库的最小改法如果你不想用源码自带的数据只需要改两处。第一把图片放进data/images目录重写annotations.json字段保持id、path、captions不变第二执行构建索引命令python build_index.py --image-dir ./data/images --output ./data/image_features.npy模型权重不需要重新训练Chinese-CLIP本身就是预训练模型换图库只是重新抽取特征。注意新图库的图片分辨率参差不齐时processor会统一做resize不会报错但超宽全景图会被压缩得厉害检索这类图片时建议先做居中裁剪。最后一个实用技巧把evaluate.py里输出的bad case打印出来。同样一句query看看R5没命中的那些图长什么样往往能直接看出是query描述太抽象还是图库本身缺少对应内容。给答辩演示时准备一句略带场景感的中文描述去检索比干巴巴输入“猫”更能说明这个系统的工作方式。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号