使用Qdrant向量数据库在RAG中进行重新排序

在检索增强生成(RAG)系统中,不相关或缺失的信息可能会影响模型生成准确、有意义输出的能力。确保你为语言模型提供最相关、上下文丰富的文档的最佳方法之一是通过重新排序。这是一个改变游戏规则的方法。

在本指南中,我们将深入探讨如何使用重排序来提高Qdrant中搜索结果的相关性。我们将从一个简单的用例开始,利用Cohere重排序模型。然后,我们将通过探索ColBERT来提升到一个更高级的方法。完成本指南后,您将知道如何实现混合搜索,微调重排序模型,并显著提高准确性。

准备好了吗?让我们开始吧。

理解重新排序

本节分为关键部分,以帮助您轻松理解重新排序的背景、机制和重要性。

背景

在搜索系统中,两个指标——准确率和召回率——是成功的支柱。但它们是什么意思呢?准确率告诉我们检索到的结果中有多少是真正相关的,而召回率则衡量我们捕捉到了所有相关结果的程度。简单来说:

image5.png

稀疏向量搜索通常能提供高精度,因为它们擅长找到完全匹配的结果。但是,这里有一个问题——当相关文档不包含这些确切的关键词时,你的召回率可能会受到影响。另一方面,密集向量搜索在召回率方面表现出色,因为它们能理解查询的更广泛的语义含义。然而,这可能会导致精度降低,你可能会看到一些仅与查询松散相关的结果。

这正是重新排序发挥作用的地方。它通过广泛的文档网络(提供高召回率),然后根据相关性分数重新排序顶级候选文档,从而提高精确度而不失去广泛的理解。通常,我们在重新排序后只保留前K个候选文档,以专注于最相关的结果。

工作中

想象一下:你走进一个巨大的图书馆,要求一本关于“气候变化”的书。图书管理员为你拿出了十几本书——有些是科学论文,有些是个人随笔,还有一本甚至是小说。当然,它们都相关,但你首先拿到的是小说。这并不完全是你所希望的,对吧?

现在,想象一个更聪明、更直观的图书管理员,他真正理解你在寻找什么。这个图书管理员确切地知道哪些书最有影响力、最新,并且完全符合你的需求。这就是重新排序对你的搜索结果所做的——它不仅仅是抓取任何相关的文档;它智能地重新排序,以便最好的文档出现在你的列表顶部。这就像有一个在你之前就知道你正在寻找什么的图书管理员!

image6.png

重新排序模型优先考虑更好结果的图示

要成为那个聪明、直观的图书管理员,你的算法需要学会如何理解你的查询和它检索到的文档。它必须有效地评估它们之间的关系,以便它能准确地给你提供你正在寻找的内容。

重排序模型的运作方式根据其类型而有所不同,这将在后面讨论,但一般来说,它们会为每个文档-查询对计算一个相关性分数。与嵌入模型不同,嵌入模型将所有内容预先压缩成一个向量,而重排序器通过使用完整的变压器输出来计算相似性分数,从而保持所有重要细节的完整性。结果是什么?精确度。但是,这里有一个权衡——重排序可能会很慢。处理数百万个文档可能需要几个小时,这就是为什么重排序器专注于优化结果,而不是在整个文档集合中进行搜索。

重新排序器有不同类型,每种都有其独特的优势。让我们来分解它们:

  1. Cross Encoder Models: These boost reranking by using a classification system to evaluate pairs of data—like sentences or documents. They spit out a similarity score from 0 to 1, showing how closely the document matches your query. The catch? Cross-encoders need both query and document, so they can’t handle standalone documents or queries by themselves.
  2. Multi-Vector Rerankers (e.g., ColBERT): These models take a more efficient route. They encode your query and the documents separately and only compare them later, reducing the computational load. This means document representations can be precomputed, speeding up retrieval times
  3. Large Language Models (LLMs) as Rerankers: This is a newer, smarter way to rerank. LLMs, like GPT, are getting better by the day. With the right instructions, they can prioritize the most relevant documents for you, leveraging their massive understanding of language to deliver even more accurate results.

每个这些重新排序器都有其独特的方式,确保您快速获得与您需求相关的最佳搜索结果。

重要性

在上一节中,我们探讨了重新排序的背景和机制,但现在让我们来谈谈使用它带来的三大好处:

  • 提高搜索准确性: 重新排序的目的是使您的搜索结果更加精确和相关。在初始排序之后,重新排序器介入,根据更深入的分析重新排列结果,以确保最关键的信息位于最前面和中心位置。研究表明,重新排序器可以显著提升效果——改善约72%搜索查询的顶部结果。这是精确度上的巨大飞跃。
  • 减少信息过载: 如果你感觉自己在搜索结果的大海中溺水,重新排序器可以来救你。它们过滤并微调信息洪流,让你准确得到所需,而不会感到不知所措。它使你的搜索体验更加集中,减少混乱。
  • 平衡速度与相关性: 第一阶段的检索和第二阶段的重新排序在速度和准确性之间达到了完美的平衡。当然,第二阶段可能会因为其处理能力增加一些延迟,但这种权衡是值得的。你得到了高度相关的结果,最终,这才是最重要的。

既然你已经了解了为什么重新排序如此具有革命性,那么让我们深入了解实际操作的方面。

实现带重排的向量搜索

在本节中,您将看到如何使用Cohere实现带有重新排序的向量搜索。但首先,让我们分解一下。

概述

一个典型的搜索系统主要分为两个阶段:数据摄取和检索。可以将数据摄取视为数据准备并加载到系统中的过程,而检索则是魔法发生的部分——在这里,您的查询会提取出最相关的文档。

查看下面的架构图,以可视化这些阶段如何协同工作。

image1.png

搜索系统的两个基本阶段:数据摄取和检索过程

数据摄取阶段

  • 文档: 这是一切的起点。系统接收需要为搜索准备的原始数据或文档——这是您的初始输入。
  • 嵌入: 接下来,这些文档被转换为稀疏或密集的嵌入,基本上是向量表示。这些向量捕捉了文本的深层潜在含义,使您的系统能够基于语义进行智能、高效的搜索和比较。
  • 向量数据库: 一旦您的文档被转换为这些嵌入,它们就会被存储在向量数据库中——这本质上是快速、准确相似性搜索的强大后盾。在这里,我们将了解Qdrant向量数据库的功能。

检索阶段

  • 用户查询: 现在我们进入检索阶段。用户提交一个查询,是时候将该查询与存储的文档进行匹配了。
  • 嵌入: 就像文档一样,用户的查询被转换为稀疏或密集的嵌入。这使得系统能够比较查询的含义与存储文档的含义。
  • 向量搜索: 系统通过比较查询的嵌入与向量数据库中的嵌入来搜索最相关的文档,并提取出最接近的匹配项。
  • 重新排序: 一旦初始结果出来,重新排序过程就会启动,以确保您获得最佳结果。我们将使用Cohere的 rerank-english-v3.0模型,该模型擅长重新排序英文文档以优先考虑相关性。它可以处理多达4096个标记,为其提供了大量的上下文。如果您处理的是多语言数据,不用担心——Cohere也有其他语言的重新排序模型。

实现

现在是时候深入实际的实现了。

设置

要跟随本教程,您需要一些关键工具:

  • Qdrant 的 Python 客户端
  • Cohere

让我们使用Python包管理器一次性安装所有你需要的内容:

pip install qdrant-client cohere

现在,让我们在一个整洁的块中引入所有必要的组件:

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import cohere

Qdrant 是一个强大的向量相似性搜索引擎,它为您提供了一个生产就绪的服务,带有易于使用的 API,用于存储、搜索和管理数据。您可以通过本地或云设置与 Qdrant 交互,但由于我们在 Colab 中工作,让我们选择云设置。

设置Qdrant云的步骤:

  1. Sign Up: Head to Qdrant’s website and sign up for a cloud account using your email, Google, or GitHub credentials.
  2. Create Your First Cluster: Once you’re in, navigate to the Overview section and follow the onboarding steps under Create First Cluster.
  3. Get Your API Key: After creating your cluster, an API key will be generated. This key will let you interact with the cluster using the Python client.
  4. Check Your Cluster: Your new cluster will appear under the Clusters section. From here, you’re all set to start interacting with your data.

最后,在概述部分,您将看到以下代码片段:

image7.png

Qdrant 概述部分

添加您的API密钥。这将让您的Python客户端连接到Qdrant和Cohere。

client = QdrantClient(
    url="<ADD-URL>",
    api_key="<API-KEY>",
)

print(client.get_collections())

接下来,我们将设置Cohere进行重新排名。登录到您的Cohere账户,生成一个API密钥,并像这样添加它:

co = cohere.Client("<API-KEY>")

数据摄取

数据摄取有三个关键部分:创建集合、将文档转换为嵌入、以及数据的上传。让我们逐一解析。

创建集合

集合基本上是一个命名的点组(带有数据的向量),你可以进行搜索。集合中的所有向量需要具有相同的大小,并使用一种距离度量进行比较。以下是创建集合的方法:

client.create_collection(
    collection_name="basic-search-rerank",
    vectors_config=VectorParams(size=1024, distance=Distance.DOT),
)

在这里,向量大小设置为1024以匹配我们的密集嵌入,我们使用点积作为距离度量——非常适合捕捉向量之间的相似性,尤其是在它们被归一化时。

文档到嵌入

让我们设置一些示例数据。这里有一个查询和一些用于演示的文档:

query = "What is the purpose of feature scaling in machine learning?"

documents = [
    "In machine learning, feature scaling is the process of normalizing the range of independent variables or features. The goal is to ensure that all features contribute equally to the model, especially in algorithms like SVM or k-nearest neighbors where distance calculations matter.",
   
    "Feature scaling is commonly used in data preprocessing to ensure that features are on the same scale. This is particularly important for gradient descent-based algorithms where features with larger scales could disproportionately impact the cost function.",
   
    "In data science, feature extraction is the process of transforming raw data into a set of engineered features that can be used in predictive models. Feature scaling is related but focuses on adjusting the values of these features.",
   
    "Unsupervised learning algorithms, such as clustering methods, may benefit from feature scaling as it ensures that features with larger numerical ranges don't dominate the learning process.",
   
    "One common data preprocessing technique in data science is feature selection. Unlike feature scaling, feature selection aims to reduce the number of input variables used in a model to avoid overfitting.",
   
    "Principal component analysis (PCA) is a dimensionality reduction technique used in data science to reduce the number of variables. PCA works best when data is scaled, as it relies on variance which can be skewed by features on different scales.",
   
    "Min-max scaling is a common feature scaling technique that usually transforms features to a fixed range [0, 1]. This method is useful when the distribution of data is not Gaussian.",
   
    "Standardization, or z-score normalization, is another technique that transforms features into a mean of 0 and a standard deviation of 1. This method is effective for data that follows a normal distribution.",
   
    "Feature scaling is critical when using algorithms that rely on distances, such as k-means clustering, as unscaled features can lead to misleading results.",
   
    "Scaling can improve the convergence speed of gradient descent algorithms by preventing issues with different feature scales affecting the cost function's landscape.",
   
    "In deep learning, feature scaling helps in stabilizing the learning process, allowing for better performance and faster convergence during training.",
   
    "Robust scaling is another method that uses the median and the interquartile range to scale features, making it less sensitive to outliers.",
   
    "When working with time series data, feature scaling can help in standardizing the input data, improving model performance across different periods.",
   
    "Normalization is often used in image processing to scale pixel values to a range that enhances model performance in computer vision tasks.",
   
    "Feature scaling is significant when features have different units of measurement, such as height in centimeters and weight in kilograms.",
   
    "In recommendation systems, scaling features such as user ratings can improve the model's ability to find similar users or items.",
   
    "Dimensionality reduction techniques, like t-SNE and UMAP, often require feature scaling to visualize high-dimensional data in lower dimensions effectively.",
   
    "Outlier detection techniques can also benefit from feature scaling, as they can be influenced by unscaled features that have extreme values.",
   
    "Data preprocessing steps, including feature scaling, can significantly impact the performance of machine learning models, making it a crucial part of the modeling pipeline.",
   
    "In ensemble methods, like random forests, feature scaling is not strictly necessary, but it can still enhance interpretability and comparison of feature importance.",
   
    "Feature scaling should be applied consistently across training and test datasets to avoid data leakage and ensure reliable model evaluation.",
   
    "In natural language processing (NLP), scaling can be useful when working with numerical features derived from text data, such as word counts or term frequencies.",
   
    "Log transformation is a technique that can be applied to skewed data to stabilize variance and make the data more suitable for scaling.",
   
    "Data augmentation techniques in machine learning may also include scaling to ensure consistency across training datasets, especially in computer vision tasks."
]

我们将使用Cohere的embed-english-v3.0模型为这些文档生成嵌入,该模型生成1024维向量:

model="embed-english-v3.0"

doc_embeddings = co.embed(texts=documents,
                          model=model,
                          input_type="search_document",
                          embedding_types=['float'])

这段代码利用了Cohere API的强大功能,为您的文档列表生成嵌入。它使用了embed-english-v3.0模型,将输入类型设置为“search_document”,并要求以浮点格式获取嵌入。结果如何?一组密集的嵌入,每一个都代表了您文档的深层语义含义。这些嵌入将存储在doc_embeddings中,随时准备使用。

插入或更新数据

我们需要将这些密集嵌入转换为Qdrant可以处理的格式,这就是Points的作用。Points是Qdrant的构建块——它们是由向量(嵌入)和可选的有效载荷(如您的文档文本)组成的记录。

以下是我们如何将这些嵌入转换为点:

points = []
for idx, (embedding, doc) in enumerate(zip(doc_embeddings.embeddings.float_, documents)):
    point = PointStruct(
        id=idx,
        vector=embedding,
        payload={"document": doc}
    )
    points.append(point)

这里发生了什么?我们正在从嵌入中构建一个点列表:

  • 首先,我们从一个空列表开始。
  • 然后,我们使用enumerate()同时遍历doc_embeddingsdocuments,以获取索引(idx)。
  • 对于每一对(一个嵌入及其对应的文档),我们创建一个PointStruct。每个点包含:
    • 一个id(来自idx)。
    • 一个向量(嵌入)。
    • 一个有效载荷(实际的文档文本)。
  • 每个点都被添加到我们的列表中。

完成后,是时候使用 upsert() 函数将这些点发送到您的 Qdrant 集合中了:

operation_info = client.upsert(
    collection_name="basic-search-rerank",
    points=points
)

检索

这里的前几个步骤与我们摄取数据时的操作相似——就像之前一样,我们需要将查询转换为嵌入:

query_embeddings = co.embed(texts=[query],
                          model=model,
                          input_type="search_query",
                          embedding_types=['float'])

之后,我们将继续使用向量搜索检索结果,并对结果应用重新排序。这个两阶段过程非常高效,因为我们首先抓取了一小部分最相关的文档,这比重新排序一个庞大的数据集要快得多。

此代码片段使用查询嵌入从您的Qdrant集合中获取前10个最相关的点。

search_result = client.query_points(
    collection_name="basic-search-rerank", query=query_embeddings.embeddings.float_[0], limit=10
).points

它的工作原理如下:我们使用query_points方法在“basic-search-rerank”集合中进行搜索。它将查询嵌入(query_embeddings中的第一个嵌入)与所有文档嵌入进行比较,提取出10个最接近的匹配项。匹配的点存储在search_result中。

这里是你将从向量搜索中获得的内容的预览:

ID文档分数
0在机器学习中,特征缩放是归一化独立变量范围的过程…0.71
10在深度学习中,特征缩放有助于稳定学习过程,使得…0.69
1特征缩放通常用于数据预处理,以确保特征在…0.68
23机器学习中的数据增强技术也可能包括缩放以确保…0.64
3无监督学习算法,如聚类方法,可能受益于特征…0.64
12在处理时间序列数据时,特征缩放可以帮助标准化输入…0.62
19在集成方法中,如随机森林,特征缩放并不是严格必要的…0.61
21在自然语言处理(NLP)中,当处理数值数据时,缩放可能是有用的…0.61
20特征缩放应一致地应用于训练和测试数据集…0.61
18数据预处理步骤,包括特征缩放,可以显著影响性能…0.61

从表面上看,提取的数据与您的查询高度相关。现在,有了这个坚实的结果基础,是时候通过重新排序进一步优化它们了。

重新排序

这段代码从搜索结果中获取文档,并根据您的查询重新排序,确保您最相关的结果排在顶部。

首先,我们从搜索结果中提取文档。然后我们使用Cohere的重新排序模型来优化这些结果:

document_list = [point.payload['document'] for point in search_result]

rerank_results = co.rerank(
    model="rerank-english-v3.0",
    query=query,
    documents=document_list,
    top_n=5,
)

这里发生了什么?在第一行,我们通过从每个搜索结果点获取“document”字段来构建文档列表。然后,我们将此列表与原始查询一起传递给Cohere的rerank方法。使用rerank-english-v3.0模型,它会重新排列文档,并返回与查询最相关的前5个文档。

这是重新排序后的结果表,包含新的顺序及其相关性分数:

索引文档相关性评分
0在机器学习中,特征缩放是归一化独立变量或特征范围的过程。0.99995166
1特征缩放通常用于数据预处理,以确保特征在同一尺度上。0.99929035
10在深度学习中,特征缩放有助于稳定学习过程,从而实现更好的性能和更快的收敛。0.998675
23机器学习中的数据增强技术也可能包括缩放,以确保训练数据集之间的一致性。0.998043
3无监督学习算法,如聚类方法,可能会从特征缩放中受益。0.9979967

正如你所见,重新排序发挥了作用。文档10和1的位置发生了交换,这表明重新排序器已经对结果进行了微调,以将最相关的内容放在顶部。

结论

重新排序是提升RAG系统中搜索结果相关性和精确度的一种强大方法。通过将Qdrant的向量搜索能力与Cohere的重新排序模型或ColBERT等工具结合,您可以优化搜索输出,确保最相关的信息排在前面。

本指南展示了如何在不牺牲召回率的情况下通过重新排序提高精度,提供更清晰、上下文丰富的结果。借助这些工具,您将能够创建提供有意义且具有影响力的用户体验的搜索系统。开始实施重新排序,将您的应用程序提升到新的水平!

这个页面有用吗?

感谢您的反馈!🙏

我们很抱歉听到这个消息。😔 你可以在GitHub上编辑这个页面,或者创建一个GitHub问题。