使用 LlamaIndex 实现多语言和多模态搜索

| 时间:15 分钟 | 级别:新手 | 输出:GitHub |
|---|
概述
当我们结合不同类型的数据时,通常能更有效地理解和分享信息。例如,舒适食物的味道可以触发童年回忆。我们可能会用“pam pam clap”的声音来描述一首歌,而不是写几段文字。有时,我们可能会使用表情符号和贴纸来表达我们的感受或分享复杂的想法。
数据模态,如文本、图像、视频和音频的各种组合,为语义搜索应用形成了有价值的用例。
向量数据库,作为模态无关的,非常适合构建这些应用。
在这个简单的教程中,我们使用两种简单的模态:图像和文本数据。但是,如果你选择正确的嵌入模型来弥合语义鸿沟,你可以创建任何模态组合的语义搜索应用。
语义鸿沟指的是低级特征(如亮度)和高级概念(如可爱度)之间的差异。
例如,LlamaIndex 的vdr-2b-multi-v1 模型专为多语言嵌入而设计,在跨多种语言和领域的视觉文档检索方面特别有效。它允许搜索和查询视觉丰富的多语言文档,而无需 OCR 或其他数据提取管道。
设置
首先,安装所需的库qdrant-client和llama-index-embeddings-huggingface。
pip install qdrant-client llama-index-embeddings-huggingface
数据集
为了简化演示,我们为您创建了一个包含图像及其标题的微型数据集。
图像可以从此处下载。重要的是,将它们放在与您的代码/notebook 相同的文件夹中,并命名为images。
向量化数据
LlamaIndex的vdr-2b-multi-v1模型支持跨语言检索,允许跨语言和领域进行有效搜索。它将文档页面截图编码为密集单向量表示,无需 OCR 和其他复杂的数据提取过程。
让我们将图像及其标题嵌入到共享嵌入空间中。
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
model = HuggingFaceEmbedding(
model_name="llamaindex/vdr-2b-multi-v1",
device="cpu", # "mps" for mac, "cuda" for nvidia GPUs
trust_remote_code=True,
)
documents = [
{"caption": "An image about plane emergency safety.", "image": "images/image-1.png"},
{"caption": "An image about airplane components.", "image": "images/image-2.png"},
{"caption": "An image about COVID safety restrictions.", "image": "images/image-3.png"},
{"caption": "An confidential image about UFO sightings.", "image": "images/image-4.png"},
{"caption": "An image about unusual footprints on Aralar 2011.", "image": "images/image-5.png"},
]
text_embeddings = model.get_text_embedding_batch([doc["caption"] for doc in documents])
image_embeddings = model.get_image_embedding_batch([doc["image"] for doc in documents])
将数据上传到Qdrant
- 为 Qdrant 创建客户端对象.
from qdrant_client import QdrantClient, models
# docker run -p 6333:6333 qdrant/qdrant
client = QdrantClient(url="https://:6333/")
- 为带有标题的图像创建新集合.
COLLECTION_NAME = "llama-multi"
if not client.collection_exists(COLLECTION_NAME):
client.create_collection(
collection_name=COLLECTION_NAME,
vectors_config={
"image": models.VectorParams(size=len(image_embeddings[0]), distance=models.Distance.COSINE),
"text": models.VectorParams(size=len(text_embeddings[0]), distance=models.Distance.COSINE),
}
)
- 将带有标题的图像上传到集合中.
client.upload_points(
collection_name=COLLECTION_NAME,
points=[
models.PointStruct(
id=idx,
vector={
"text": text_embeddings[idx],
"image": image_embeddings[idx],
},
payload=doc
)
for idx, doc in enumerate(documents)
]
)
搜索
文本到图像
让我们看看查询“Adventures on snow hills”会得到什么图像。
from PIL import Image
find_image = model.get_query_embedding("Adventures on snow hills")
Image.open(client.query_points(
collection_name=COLLECTION_NAME,
query=find_image,
using="image",
with_payload=["image"],
limit=1
).points[0].payload['image'])
我们还将在意大利语中运行相同的查询并比较结果。
多语言搜索
现在,让我们使用意大利语查询进行多语言搜索
Image.open(client.query_points(
collection_name=COLLECTION_NAME,
query=model.get_query_embedding("Avventure sulle colline innevate"),
using="image",
with_payload=["image"],
limit=1
).points[0].payload['image'])
响应

图像到文本
现在,让我们使用以下图像进行反向搜索

client.query_points(
collection_name=COLLECTION_NAME,
query=model.get_image_embedding("images/image-2.png"),
# Now we are searching only among text vectors with our image query
using="text",
with_payload=["caption"],
limit=1
).points[0].payload['caption']
响应
'An image about plane emergency safety.'
下一步
即使是图像和文本多模态搜索的用例也数不胜数:电子商务、媒体管理、内容推荐、情感识别系统、生物医学图像检索、口语手语转录等。
设想一个场景:用户想要找到与他们现有图片相似的产品,但他们也有特定的文本要求,例如“米色”。你可以只使用文本或图像进行搜索,并以后期融合方式组合它们的嵌入(求和和加权可能会出人意料地有效)。
此外,通过使用发现搜索结合两种模态,您可以为用户提供单模态无法检索到的信息!
加入我们的Discord 社区,在那里我们讨论向量搜索和相似性学习,进行实验,并享受乐趣!