CLIP 视觉向量本地化:在 NAS 上跑通以文搜图的第一天
发布时间:2026/9/7 16:13:59 锦皓数字建站

CLIP 视觉向量本地化在 NAS 上跑通以文搜图的第一天在手机相册里找照片最让人头疼的是传统的分类相册有的按地点分有的按人物分有的按时间分。但当我们真正想找一张照片时脑海里闪现的往往是一句极其具体的画面描述老爸在西湖边喂鸽子小狗 Token 第一次穿红色雨衣去年中秋节老妈做的那盘清蒸大闸蟹传统的相册元数据检索基于文件名或 GPS 经纬度在面对这种自然语言描述时彻底失效。而将全家两万张私密照片全量上传到公有云商业相册进行 AI 分析又存在无法容忍的隐私泄露隐患。为了让家里的私有 NAS 拥有本地离线、毫秒级、零云端依赖的以文搜图能力我在 NAS 上正式部署并跑通了中文多模态视觉表征模型Chinese-CLIP。flowchart TD PhotoLibrary[NAS 20,000 张本地照片] -- VisionEncoder[Chinese-CLIP ViT-B/16 视觉编码器] VisionEncoder -- ImageEmbeddings[(512 维图像特征向量库 / 本地 Qdrant/Chroma)] UserSearch[长辈自然语言查询:\n小狗穿红色雨衣在草地上] -- TextEncoder[Chinese-CLIP 文本编码器] TextEncoder -- QueryVec[512 维文本查询向量] QueryVec -- DotProduct[点积与余弦相似度极速矩阵检索] DotProduct -- TopMatches[秒级召回 Top-10 高清匹配照片]CLIP (Contrastive Language-Image Pretraining) 的核心底层原理CLIP 模型之所以能做到以文搜图关键在于它在海量图文对上进行了对比学习Contrastive Learning它包含两个平行的编码器图像编码器Vision Transformer / ResNet与文本编码器BERT / Transformer。两个编码器将图片和文本分别映射到同一个512 维的共享跨模态向量空间。如果一张图片的内容是穿红雨衣的狗那么经过 Vision Encoder 算出来的图像向量 $\vec{v}{img}$与经过 Text Encoder 算出来的文本向量 $\vec{v}{txt}$在几何空间中的余弦夹角极小余弦相似度接近 1.0。因此搜图的过程在底层被简化为了纯粹的向量点积与 KNN 邻近检索不需要昂贵的生成式大模型在旁边喋喋不休算力开销极小。基于 ONNXRuntime 与 Python 的本地部署实现为了在没有独立 GPU 的低功耗 NAS如 Intel N100 平台上流畅运行我们将 Chinese-CLIP 模型导出为INT8 量化的 ONNX 格式import numpy as np import onnxruntime as ort from PIL import Image import torchvision.transforms as transforms from typing import List, Tuple class LocalChineseCLIPSearch: def __init__(self, text_onnx_path: str, vision_onnx_path: str): # 针对 CPU 优化推理线程 opts ort.SessionOptions() opts.intra_op_num_threads 4 opts.graph_optimization_level ort.GraphOptimizationLevel.ORT_ENABLE_ALL self.text_session ort.InferenceSession(text_onnx_path, opts, providers[CPUExecutionProvider]) self.vision_session ort.InferenceSession(vision_onnx_path, opts, providers[CPUExecutionProvider]) self.transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.48145466, 0.4578275, 0.40821073], std[0.26862954, 0.26130258, 0.27577711]) ]) def encode_image(self, image_path: str) - np.ndarray: 提取单张图片的 512 维归一化视觉向量 (耗时约 45ms) img Image.open(image_path).convert(RGB) tensor self.transform(img).unsqueeze(0).numpy() inputs {self.vision_session.get_inputs()[0].name: tensor} outs self.vision_session.run(None, inputs) vec outs[0][0] return vec / np.linalg.norm(vec) def encode_text(self, text: str, tokenized_ids: np.ndarray) - np.ndarray: 提取文本查询词的 512 维向量 (耗时约 12ms) inputs { self.text_session.get_inputs()[0].name: tokenized_ids, self.text_session.get_inputs()[1].name: np.ones_like(tokenized_ids) } outs self.text_session.run(None, inputs) vec outs[0][0] return vec / np.linalg.norm(vec) def search_top_k(self, query_vec: np.ndarray, index_matrix: np.ndarray, image_paths: List[str], k: int 5) - List[Tuple[str, float]]: # 矩阵批量点积计算余弦相似度 scores np.dot(index_matrix, query_vec) top_k_indices np.argsort(scores)[::-1][:k] return [(image_paths[idx], float(scores[idx])) for idx in top_k_indices]实测以文搜图表现在 2000 张家庭照片索引库中进行实测老妈在厨房包饺子准确召回去年冬至老妈在厨房擀皮、包芹菜猪肉水饺的 4 张特写照片相似度 0.88阳台开满黄色花的盆栽精准召回老爸春天养的文心兰与菊花耗时仅18ms。记忆被瞬间点亮的力量当老妈坐在客厅沙发上随口说了一句看看当年小狗刚抱回家那几天的样子电视屏幕在半秒钟内直接铺满了 Token 幼犬时期毛茸茸的照片时全家人都由衷地发出了惊呼。不需要复杂的操作不需要费心分类。把最前沿的多模态表征模型带进家庭局域网让每一个模糊的记忆念头都能秒级重现这就是技术赋予生活最纯粹的魔法。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。