使用LanceDB和Roboflow Inference构建图像搜索引擎

随着技术的发展,图像和文本嵌入的存储需求日益增长。向量数据库,如LanceDB,因其高效的搜索能力而成为存储嵌入的首选。CLIP模型,由OpenAI开发,是计算图像嵌入的常用工具,这些嵌入随后可用于构建语义搜索引擎,支持通过图像或文本进行查询。本文将指导如何利用Roboflow Inference将图像嵌入加载到LanceDB中。

LanceDB简介

LanceDB是一个开源的无服务器向量搜索数据库,适用于生产规模的向量搜索。它提供了持久化存储,简化了嵌入的检索、过滤和管理。可以将向量与其他类型的数据(如文本或数字)一起存储。LanceDB支持在设备上或LanceDB云中存储向量(在撰写本文时处于私有测试阶段)。LanceDB提供了Python和JavaScript的SDK。

LanceDB可以作为依赖于LLM(大型语言模型)或LMM(大型多模态模型)系统的组成部分,例如用于检索图像和文本的检索增强生成(RAG)流程,这些图像和文本随后用于LLM或LMM。

步骤1:安装Roboflow Inference

Roboflow Inference是一个使能够以最少的配置运行最先进的计算机视觉模型的工具。它支持从微调的对象检测、分类和分割模型到像CLIP这样的基础模型。将使用Inference来计算CLIP图像嵌入。

Inference提供了一个HTTP API,通过该API可以运行视觉模型。Inference是Roboflow托管API的动力来源,并且作为一个开源工具提供。在本指南中,将在本地运行Inference,使能够在自己的硬件上计算CLIP嵌入。还将展示如何使用托管的Roboflow CLIP API,这在需要扩展且不想管理一个用于计算嵌入的系统时非常理想。

pip install inference-cli

接下来,安装Docker。请参考官方Docker安装指南为操作系统设置Docker。一旦Docker准备就绪,可以使用以下命令启动Inference:

inference server start

Inference服务器将在以下地址开始运行:

http://localhost:9001

步骤2:设置LanceDB向量数据库

现在已经运行了Inference,可以设置LanceDB向量数据库了。可以在JavaScript和Python中运行LanceDB。在本指南中,将使用Python API。但是,如果需要,可以将下面进行的HTTP请求更改为JavaScript。

在本指南中,将搜索COCO 128数据集,该数据集包含广泛的对象。这个数据集中存在的对象的多样性使其成为展示向量搜索能力的一个很好的数据集。如果想使用这个数据集,可以从Roboflow Universe下载COCO 128。话虽如此,可以搜索任何想要的图像文件夹。

pip install lancedb

创建一个新的Python文件,并添加以下代码:

import cv2 import supervision as sv import requests import lancedb import os import base64 db = lancedb.connect("./embeddings") IMAGE_DIR = "images/" API_KEY = os.environ.get("ROBOFLOW_API_KEY") SERVER_URL = "http://localhost:9001" results = [] for i, image in enumerate(os.listdir(IMAGE_DIR)): infer_clip_payload = { "image": { "type": "base64", "value": base64.b64encode(open(IMAGE_DIR + image, "rb").read()).decode("utf-8"), }, } res = requests.post( f"{SERVER_URL}/clip/embed_image?api_key={API_KEY}", json=infer_clip_payload, ) embeddings = res.json()['embeddings'] print("Calculated embedding for image: ", image) image = {"vector": embeddings[0], "name": os.path.join(IMAGE_DIR, image)} results.append(image) tbl = db.create_table("images", data=results) tbl.create_fts_index("name")

要使用上述代码,需要一个Roboflow API密钥。了解如何获取Roboflow API密钥。在环境变量中设置API密钥:

export ROBOFLOW_API_KEY=""

将IMAGE_DIR的值替换为存储图像的文件夹路径,以便计算嵌入。如果想使用Roboflow CLIP API来计算嵌入,请将SERVER_URL的值替换为https://infer.roboflow.com。

运行上述脚本以创建一个新的LanceDB数据库。该数据库将存储在本地计算机上。数据库将被称为embeddings,表将被称为images。

上述脚本计算了文件夹中所有图像的嵌入,然后创建了一个新的表。要添加更多图像,请使用以下代码:

def make_batches(): for i in range(5): yield [ {"vector": [3.1, 4.1], "name": "image1.png"}, {"vector": [5.9, 26.5], "name": "image2.png"} ] tbl = db.open_table("images") tbl.add(make_batches())

将make_batches()函数替换为加载图像嵌入的代码。

步骤3:运行搜索查询

现在可以运行搜索查询了。要运行搜索查询,需要一个代表文本查询的文本嵌入。可以使用这个嵌入在LanceDB数据库中搜索条目。

让计算查询“cat”的文本嵌入,然后运行搜索查询:

infer_clip_payload = { "text": "cat", } res = requests.post( f"{SERVER_URL}/clip/embed_text?api_key={API_KEY}", json=infer_clip_payload, ) embeddings = res.json()['embeddings'] df = tbl.search(embeddings[0]).limit(3).to_list() print("Results:") for i in df: print(i["name"])

这段代码将搜索与提示“cat”最相关的三张图像。最相似的三张图像的名称将被打印到控制台。以下是三个顶级结果:

dataset/images/train/000000000650_jpg.rf.1b74ba165c5a3513a3211d4a80b69e1c.jpg dataset/images/train/000000000138_jpg.rf.af439ef1c55dd8a4e4b142d186b9c957.jpg dataset/images/train/000000000165_jpg.rf.eae14d5509bf0c9ceccddbb53a5f0c66.jpg

让打开顶部的图像:

顶部的图像是一只猫。搜索成功了。

LanceDB是一个向量数据库,可以使用它来存储和高效地搜索图像嵌入。可以使用Roboflow Inference,这是一个可扩展的计算机视觉推理服务器,来计算可以存储在LanceDB中的CLIP嵌入。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485