案例目标
本案例展示了如何使用VoyageAI多模态嵌入模型和MongoDB Atlas向量搜索构建一个高效的图像检索系统。该系统能够通过文本查询检索相关图像,实现了跨模态检索功能。具体目标包括:
- 从HuggingFace数据集加载图像数据
- 使用VoyageAI多模态嵌入模型生成图像嵌入向量
- 将图像嵌入存储在MongoDB Atlas向量数据库中
- 实现基于文本查询的图像检索功能
- 展示检索结果并评估系统性能
技术栈与核心依赖
本案例使用了以下技术栈和核心依赖:
# 核心依赖 pip install datasets pip install llama-index-embeddings-voyageai pip install llama-index-vector-stores-mongodb pip install llama-index-indices-multi-modal pip install pymongo pip install matplotlib pip install pillow- datasets: 用于从HuggingFace加载数据集
- llama-index-embeddings-voyageai: 提供VoyageAI多模态嵌入模型
- llama-index-vector-stores-mongodb: 提供MongoDB Atlas向量搜索集成
- llama-index-indices-multi-modal: 提供多模态索引功能
- pymongo: MongoDB Python客户端
- matplotlib: 用于图像可视化
- pillow: 用于图像处理
环境配置
在运行本案例之前,需要配置以下环境变量:
# 设置环境变量 export MONGO_URI="your_mongodb_atlas_connection_string" export VOYAGE_API_KEY="your_voyageai_api_key"注意:请确保您已经创建了MongoDB Atlas账户并设置了向量搜索索引。同时,您需要从VoyageAI获取API密钥。
案例实现
1
导入必要的库
import os import base64 from io import BytesIO from PIL import Image import matplotlib.pyplot as plt from datasets import load_dataset from llama_index.core import SimpleDirectoryReader, Settings, StorageContext from llama_index.core.schema import ImageDocument from llama_index.multi_modal_llms.openai import OpenAIMultiModal from llama_index.embeddings.voyageai import VoyageEmbedding from llama_index.vector_stores.mongodb import MongoDBAtlasVectorSearch from llama_index.indices.multi_modal import MultiModalVectorStoreIndex from pymongo import MongoClient2
定义图像显示函数
def plot_images(image_data_list, image_indices=None): """ 显示图像列表 参数: image_data_list: 图像数据列表 image_indices: 要显示的图像索引列表 """ if image_indices is None: image_indices = range(len(image_data_list)) num_images = len(image_indices) fig, axes = plt.subplots(1, num_images, figsize=(15, 5)) if num_images == 1: axes = [axes] for i, idx in enumerate(image_indices): image_bytes = image_data_list[idx] image = Image.open(BytesIO(image_bytes)) axes[i].imshow(image) axes[i].set_title(f"Image {idx}") axes[i].axis('off') plt.tight_layout() plt.show()3
从HuggingFace加载数据集
# 从HuggingFace加载数据集 print("Loading dataset...") dataset = load_dataset("princeton-nlp/CharXiv", split="validation") print(f"Dataset loaded with {len(dataset)} examples") # 只取前50张图像作为示例 image_bytes = [] for i in range(min(50, len(dataset))): image_data = dataset[i]["image_bytes"] image_bytes.append(image_data)4
显示加载的图像
# 显示图像 print("Showing images...") plot_images(image_bytes, [x for x in range(len(image_bytes))])5
创建图像文档
print("Creating documents...") documents = [ ImageDocument(image=base64.b64encode(img), metadata={"index": ndx}) for ndx, img in enumerate(image_bytes) ]6
设置MongoDB Atlas和VoyageAI
# 连接到MongoDB Atlas print("Setup...") # 使用环境变量存储敏感凭据 MONGO_URI = os.environ.get("MONGO_URI", "") VOYAGE_API_KEY = os.environ.get("VOYAGE_API_KEY", "") db_name = "multimodal_test" collection_name = "test" client = MongoClient(MONGO_URI) # 设置图像存储用于图像嵌入 image_store = MongoDBAtlasVectorSearch( client, db_name=db_name, collection_name=f"{collection_name}_image", vector_index_name="image_vector_index", ) image_store.create_vector_search_index( dimensions=1024, path="embedding", similarity="cosine" ) # 设置文本存储用于文本嵌入(如果将来需要) text_store = MongoDBAtlasVectorSearch( client, db_name=db_name, collection_name=f"{collection_name}_text", vector_index_name="text_vector_index", ) text_store.create_vector_search_index( dimensions=1024, path="embedding", similarity="cosine" ) # 创建存储上下文 storage_context = StorageContext.from_defaults( vector_store=text_store, image_store=image_store ) # 初始化Voyage AI嵌入模型 Settings.embed_model = VoyageEmbedding( voyage_api_key=VOYAGE_API_KEY, model_name="voyage-multimodal-3", truncation=False, ) Settings.chunk_size = 100 Settings.chunk_overlap = 107
将图像存储到MongoDB Atlas
# 将文档存储到MongoDB Atlas向量搜索 print("Storing documents in MongoDB Atlas Vector Search...") # 创建一个知道如何路由不同文档类型的多模态索引 index = MultiModalVectorStoreIndex.from_documents( documents, storage_context=storage_context, show_progress=True, image_embed_model=Settings.embed_model, ) print("Finished storing images.")8
测试图像检索
# 创建一个专门使用图像存储的检索器 retriever = index.as_retriever(similarity_top_k=2) # 执行查询 print("Performing query...") nodes = retriever.text_to_image_retrieve( "3D loss landscapes for different training strategies" )9
显示检索结果
# 显示结果 print(f"Found {len(nodes)} results:") result_images = [] for i, node in enumerate(nodes): ndx = node.metadata["index"] result_images.append(ndx) plot_images(image_bytes, result_images) print("Querying finished")10
关闭MongoDB连接
client.close() print("MongoDB connection closed")案例效果
本案例实现了一个高效的跨模态图像检索系统,具有以下效果:
- 跨模态检索:能够使用文本查询检索相关图像,实现了文本到图像的跨模态检索功能
- 高效存储:使用MongoDB Atlas向量搜索存储和检索图像嵌入,支持大规模图像数据
- 高质量嵌入:使用VoyageAI多模态嵌入模型生成高质量的图像嵌入向量
- 易于扩展:系统架构支持轻松添加更多图像和扩展功能
案例实现思路
本案例的实现思路可以概括为以下几个步骤:
- 数据准备:从HuggingFace数据集加载图像数据,并将其转换为适合处理的格式
- 嵌入生成:使用VoyageAI多模态嵌入模型为每张图像生成嵌入向量
- 向量存储:将图像嵌入向量存储在MongoDB Atlas向量数据库中,并创建适当的索引
- 查询处理:接收文本查询,使用相同的嵌入模型生成查询向量
- 相似度搜索:在MongoDB Atlas中执行向量相似度搜索,找到最相关的图像
- 结果展示:将检索结果可视化展示给用户
扩展建议
基于本案例的实现,可以考虑以下扩展方向:
- 多模态查询:支持图像+文本的混合查询,提供更精确的检索结果
- 图像标注:添加自动图像标注功能,丰富图像元数据
- 高级过滤:实现基于元数据的高级过滤功能,如按类别、日期等过滤
- 性能优化:优化嵌入生成和向量搜索性能,支持更大规模的数据集
- 用户界面:开发直观的用户界面,提供更好的用户体验
- 实时更新:支持实时添加新图像并更新索引
- 多语言支持:支持多语言文本查询,扩大应用范围
总结
本案例展示了如何使用VoyageAI多模态嵌入模型和MongoDB Atlas向量搜索构建一个高效的图像检索系统。该系统实现了文本到图像的跨模态检索功能,能够根据文本查询找到相关图像。通过结合VoyageAI的高质量多模态嵌入和MongoDB Atlas的强大向量搜索能力,我们构建了一个可扩展、高效的图像检索解决方案。
这种跨模态检索技术在许多实际应用场景中都非常有用,例如电子商务产品搜索、数字资产管理、内容推荐系统等。通过本案例的学习,您可以了解如何构建类似的系统,并根据实际需求进行定制和扩展。