Press "Enter" to skip to content

“深入挖掘 Rust 编写的矢量数据库 Qdrant”

介绍

Vector数据库已经成为存储和索引非结构化和结构化数据表示的首选位置。这些表示是由嵌入模型生成的向量嵌入。向量存储已成为开发带有深度学习模型的应用程序的重要组成部分,尤其是大型语言模型。在向量存储的不断发展中,Qdrant是最近推出的一个功能齐全的向量数据库。让我们深入了解一下。

学习目标

  • 熟悉Qdrant的术语,以更好地理解它
  • 深入研究Qdrant Cloud并创建Clusters
  • 学习如何创建我们的文档的嵌入并将它们存储在Qdrant Collections中
  • 探索在Qdrant中查询的工作原理
  • 在Qdrant中调试过滤器,以检查其工作原理

本文作为Data Science Blogathon的一部分发表。

什么是嵌入?

嵌入是一种以数字形式表示数据的方式,即以n维空间中的数字或数值向量的形式表示不同类型的数据,如文本、照片、音频、视频等。嵌入使我们能够以这种方式对相关数据进行分组。使用特定模型可以将某些输入转换为向量。Google创建的一种广为人知的嵌入模型是将单词转化为向量(向量是具有n维的点),称之为Word2Vec。每个大型语言模型都有一个嵌入模型,用于生成LLM的嵌入。

嵌入的用途是什么?

将单词转换为向量的一个优点是可以进行比较。当拿到两个单词作为数字输入或向量嵌入时,计算机可以进行比较,尽管它无法直接比较它们。可以将具有可比较嵌入的单词分组在一起。因为它们彼此相关,诸如“王”、“皇后”、“王子”和“公主”这些术语将出现在一个聚类中。

从这个意义上讲,嵌入帮助我们找到与给定术语相关的单词。这可以用于句子,我们输入一个句子,提供的数据返回相关的句子。这为许多用例奠定了基础,包括聊天机器人、句子相似性、异常检测和语义搜索。我们开发的用于根据我们提供的PDF或文档回答问题的聊天机器人利用了这种嵌入概念。所有生成式大型语言模型都使用这种方法,以获得与他们提供的查询相关联的内容。

什么是向量数据库?

如前所述,嵌入是各种数据的表示,通常是非结构化数据以数字格式在n维空间中。那么我们该如何存储它们呢?传统的关系型数据库管理系统(RDMS)不能用于存储这些向量嵌入。这就是向量存储/向量数据库发挥作用的地方。向量数据库的设计目的是以高效的方式存储和检索向量嵌入。有许多不同的向量存储器,它们通过所支持的嵌入模型和用于获取相似向量的搜索算法的种类而有所不同。

什么是Qdrant?

Qdrant是一种新型的向量相似性搜索引擎和向量数据库,采用Rust语言构建的可用于生产的服务。Qdrant具有用户友好的API,用于存储、搜索和管理具有元数据的高维点(点就是向量嵌入),这些元数据称为载荷。这些载荷成为有价值的信息,提高搜索精度,并为用户提供有见地的数据。如果您熟悉其他向量数据库,如Chroma,Payload类似于元数据,它包含有关向量的信息。

Qdrant是用Rust编写的,即使在负载很重的情况下也是快速可靠的向量存储。Qdrant与其他数据库的区别在于它提供的客户端API数量。目前,Qdrant支持Python、TypeScript/JavaScript、Rust和Go。它使用HSNW(层次可导航小世界图)进行向量索引,并提供了许多距离度量,如余弦、点和欧氏距离。它还提供了一个内置的推荐API。

了解Qdrant术语

要顺利开始使用Qdrant,熟悉Qdrant向量数据库中的术语/主要组件是一个好习惯。

集合

集合是包含点的命名集合,每个点包含一个向量、一个可选的ID和有效负载。同一集合中的向量必须具有相同的维度,并使用单个选择的度量进行评估。

距离度量

用于测量向量之间的接近程度,距离度量在创建集合时选择。Qdrant提供以下距离度量:点积、余弦和欧氏距离。

点是Qdrant中的基本实体,由向量嵌入、可选的ID和相关负载组成。其中:id:每个向量嵌入的唯一标识符。 vector:数据的高维表示,可以是结构化或非结构化格式,如图像、文本、文件、PDF、视频、音频等。 payload:一个可选的JSON对象,包含与向量相关的数据。这类似于元数据,我们可以用它来筛选搜索过程。

存储

Qdrant提供两种存储选项:

  • 内存存储:将所有向量存储在RAM中,通过最小化对磁盘的访问来优化速度。
  • Memmap存储:创建与磁盘上的文件关联的虚拟地址空间,平衡速度和持久性要求。

这些是我们需要了解的主要概念,这样我们就可以快速开始使用Qdrant了。

Qdrant云-创建我们的第一个集群

Qdrant提供可扩展的云服务,用于存储和管理向量。它甚至提供免费永久使用的1GB集群,无需信用卡信息。在本节中,我们将介绍使用Qdrant云服务创建帐户和创建我们的第一个集群的过程。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第1张

访问Qdrant网站,我们将看到上面的首页。我们可以使用Google帐户或GitHub帐户注册Qdrant。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第2张

登录后,我们将看到上面显示的用户界面。要创建一个集群,转到左侧窗格,单击仪表板下的“集群”选项。由于我们刚刚登录,我们还没有集群。单击“创建集群”以创建一个新的集群。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第3张

现在,我们可以为我们的集群提供一个名称。确保将所有配置设置为初始位置,这样我们就可以获得一个免费的集群。我们可以选择上面显示的提供商之一,并选择与其关联的地区之一。

检查当前配置

我们可以在左侧看到当前配置,即0.5 vCPU、1GB RAM和4GB磁盘存储。单击“创建”以创建我们的集群。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第4张

要访问我们新创建的集群,我们需要一个API密钥。要创建新的API密钥,请转到仪表板下的数据访问控制。单击“创建按钮”以创建新的API密钥。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第5张

如上所示,我们将看到一个下拉菜单,在其中选择我们需要为其创建API的集群。由于我们只有一个集群,我们选择该集群并点击确定按钮。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第6张

然后,您将看到上面显示的API令牌。另外,如果我们查看图像的下面部分,还提供了连接我们的集群的代码片段,我们将在下一部分中使用。

Qdrant实战

在本节中,我们将使用Qdrant向量数据库进行操作。首先,我们将开始导入所需的库。

!pip install sentence-transformers!pip install qdrant_client

第一行安装了sentence-transformer Python库。句子转换器库用于生成句子、文本和图像的嵌入。我们可以使用这个库导入不同的嵌入模型来创建嵌入。下一条语句安装了Python的qdrant客户端。让我们首先创建我们的客户端。

from qdrant_client import QdrantClientclient = QdrantClient(    url="您的集群URL",    api_key="您的API密钥",)

QdrantClient

在上面的代码中,我们通过导入QdrantClient类并提供集群URL和刚刚创建的API密钥实例化了客户端。

# 导入我们的嵌入模型from sentence_transformers import SentenceTransformermodel = SentenceTransformer('sentence-transformers/all-mpnet-base-v2')

在上面的代码中,我们使用SentenceTransformer类实例化了一个模型。我们采用的嵌入模型是all-mpnet-base-v2。这是一个广泛流行的通用向量嵌入模型。该模型将文本作为输入并输出一个768维的向量。让我们定义我们的数据。

# 数据documents = [    """大象是最大的陆地动物,展示了非凡的智能和社会联系,它们依靠强大的象鼻进行沟通和承担各种任务,如搬运物品和采集食物。""",    """企鹅是适应水生活的无法飞行的鸟类,展示了强大的社会结构和杰出的育儿技巧。它们流线型的身体有助于高效的游泳,并且它们在紧密的群落中忍受恶劣的南极条件。""",    """汽车是多功能的交通工具,有各种形状和大小,从紧凑的城市车到强大的运动车辆,提供了不同偏好和需求的功能。""",    """摩托车是灵活的两轮机器,提供刺激和自由的骑行体验,吸引那些喜欢速度、敏捷和自由道路的爱好者。""",    """老虎是雄伟的大猫,是独居的猎食者,有着独特的条纹毛发。它们强壮的体格和隐秘的动作使其成为强大的捕食者,但由于栖息地丧失和偷猎,它们的种群受到威胁。"""]

在上面的代码中,我们有一个名为documents的变量,它包含一个由5个字符串组成的列表(我们将每个字符串视为一个单独的文档)。每个数据字符串与特定主题相关联。一些数据与元素相关,一些数据与汽车相关。让我们为数据创建嵌入。

# 对数据进行嵌入embeddings = model.encode(documents)print(embeddings.shape)

我们使用模型对象的encode()函数对数据进行编码。要进行编码,我们直接将文档列表传递给encode()函数,并将结果向量嵌入存储在embeddings变量中。我们甚至打印了嵌入的形状,这里将打印(5, 768)。这是因为我们有5个数据点,即5个文档,对于每个文档,都创建了一个768维的向量嵌入。

创建您的集合

现在我们将创建我们的集合。

from qdrant_client.http.models import VectorParams, Distanceclient.create_collection(    collection_name = "我的集合",    vectors_config = VectorParams(size=768,distance=Distance.COSINE))
  • 要创建一个集合,我们使用客户端对象的create_collection()函数,并将“Collection_name”传入我们的集合名称,即“my-collection”
  • VectorParams:这个来自qdrant的类用于向量配置,比如向量嵌入大小是多少,使用的距离度量是什么等等
  • Distance:这个来自qdrant的类用于定义查询向量要使用的距离度量
  • 现在我们将我们的配置参数传递给vector_config变量,即向量嵌入的大小为786,要使用的距离度量是COSINE

添加向量嵌入

我们现在成功创建了我们的集合。现在我们将向量嵌入添加到这个集合中。

from qdrant_client.http.models import Batchclient.upsert (    collection_name = "my-collection",    points = Batch(        ids = [1,2,3,4,5],        payloads= [            {"category":"animals"},            {"category":"animals"},            {"category":"automobiles"},            {"category":"automobiles"},            {"category":"animals"}        ],        vectors = embeddings.tolist()    ))
  • 要将数据添加到qdrant中,我们调用upsert()方法,并传入集合名称和数据点。如上所述,一个Point由向量、可选索引和负载组成。qdrant的Batch类允许我们批量添加数据,而不是逐个添加。
  • ids:给我们的文档分配一个ID。目前,我们为值范围从1到5的文档分配了ID,因为我们列表中有5个文档。
  • payloads:正如我们之前所见,payload包含向量的信息,如元数据。我们以键值对的形式提供它。对于每个文档,我们都在这里提供了一个payload,我们为每个文档分配了类别信息。
  • vectors:这些是文档的向量嵌入。我们将其从numpy数组转换为列表,并进行传递。

因此,在运行此代码后,向量嵌入将被添加到集合中。要检查它们是否已添加,我们可以访问Qdrant Cloud提供的云仪表板。为此,我们执行以下操作:

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第7张

我们点击仪表板,然后会打开一个新页面。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第8张

这是qdrant仪表板。在这里检查我们的“my-collection”集合。点击它以查看其中的内容。

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第9张

在Qdrant云中,我们观察到我们的Points(向量+载荷+ID)确实添加到了集群中的集合中。在后续部分中,我们将学习如何查询这些向量。

查询Qdrant向量数据库

在本节中,我们将介绍查询向量数据库甚至尝试添加一些过滤器以获取筛选结果。要查询我们的qdrant向量数据库,我们首先需要创建一个查询向量,可以通过以下方式完成:

query = model.encode(['动物生活在森林中'])

查询嵌入

上述代码将创建我们的query嵌入。然后我们将使用它来查询我们的向量存储以获取最相关的向量嵌入。

client.search(collection_name = "my-collection", query_vector = query[0], limit = 4)

搜索() 查询

要查询,我们使用客户端对象的search()方法,并传入以下参数:

  • collection_name: 我们的集合名称
  • query_vector: 我们想要在向量存储中搜索的查询向量
  • limit: 我们希望search()函数限制的搜索结果数量

运行该代码将产生以下输出:

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第10张

我们可以看到,对于我们的查询,检索到的前几个文档属于动物类别。因此我们可以说搜索是有效的。现在让我们尝试使用其他查询来获得不同的结果。向量默认情况下不会被显示/获取,因此设置为None。

query = model.encode(['车辆正在污染世界'])client.search(collection_name = "my-collection", query_vector = query[0], limit = 3)

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第11张

这次我们给出了一个与车辆相关的查询,向量数据库成功获取了与相关类别(汽车)相关的文档。那么,如果我们想要进行一些过滤怎么办?我们可以这样做:

from qdrant_client.http.models import Filter, FieldCondition, MatchValuequery = model.encode(['动物生活在森林中'])custom_filter = Filter(    must = [        FieldCondition(            key = "category",            match = MatchValue(                value="animals"            ),        )    ])
  • 首先,我们创建了查询嵌入/向量
  • 在此处我们从qdrant库导入了FilterFieldConditionMatchValue类。
  • Filter: 使用此类创建一个Filter对象
  • FieldCondition: 此类用于创建过滤条件,例如我们想要在哪个关键字上过滤我们的搜索
  • MatchValue: 此类用于告诉qdrant向量数据库在给定关键字的情况下如何进行过滤

因此,在上述代码中,我们基本上是在说我们正在创建一个Filter,它检查Payload中的“category”键是否与MatchValue中的“animals”值匹配。这看起来有点冗长,但是当我们处理包含大量信息并希望根据多个关键字进行过滤的Payload时,这种方法会让我们的代码更加结构化。现在让我们在搜索中使用该过滤器。

client.search(collection_name = "my-collection", query_vector = query[0], query_filter = custom_filter, limit = 4)

查询过滤器

在这里,这次我们甚至提供了一个名为query_filter的变量,该变量接受我们定义的Custom Filter。注意,我们已经设置了限制为4,以检索前4个匹配的文档。查询与动物相关。运行该代码将产生以下输出:

“深入挖掘 Rust 编写的矢量数据库 Qdrant” 四海 第12张

在输出中,我们仅收到了前3个最近的文档,尽管我们有5个文档。这是因为我们设置了过滤器仅选择动物类别,并且只有3个具有该类别的文档。通过这种方式,我们可以将向量嵌入存储在qdrant云中,执行向量搜索检索最接近的文档,甚至应用过滤器对输出进行过滤:

应用

以下应用可以使用Qdrant向量数据库:

  • 推荐系统: Qdrant可以通过高效匹配高维向量来支持推荐引擎,在流媒体服务、电子商务或社交媒体等平台上,适用于个性化内容推荐。
  • 图像和多媒体检索: 利用Qdrant处理代表图像和多媒体内容的向量的能力,应用可以实现对图像数据库或多媒体档案的有效搜索和检索功能。
  • 自然语言处理(NLP)应用: Qdrant对向量嵌入的支持使其在处理大量文本数据集的应用中非常有价值,如语义搜索、文档相似性匹配和内容推荐等NLP任务。
  • 异常检测: Qdrant的高维向量搜索可以用于异常检测系统。通过将代表正常行为的向量与传入数据进行比较,可以在网络安全或工业监控等领域中识别异常。
  • 产品搜索和匹配: 在电子商务平台上,Qdrant可以通过匹配代表产品特征的向量来改善产品搜索能力,从而根据用户的偏好提供准确高效的产品推荐。
  • 社交网络中基于内容的过滤: Qdrant的向量搜索可以应用于社交网络的基于内容的过滤。用户可以根据向量表示的相似性获取相关内容,提高用户参与度。

结论

随着对数据高效表示的需求增加,Qdrant凭借其在可靠和安全中心的Rust语言编写的开源功能丰富的向量相似性搜索引擎脱颖而出。Qdrant包含了所有流行的距离度量指标,并提供了强大的向量搜索过滤功能。凭借其丰富的功能,云原生架构和强大的术语,Qdrant为向量相似性搜索技术开启了新时代的大门。虽然它在该领域还很新颖,但它提供了许多编程语言的客户端库,并提供了一个能够有效扩展的云。

主要要点

其中一些主要要点包括:

  • Qdrant采用Rust编写,确保速度和可靠性,即使在重负载下,也是高性能向量存储的最佳选择。
  • Qdrant的独特之处在于其对客户端API的支持,满足了Python、TypeScript/JavaScript、Rust和Go开发者们的需求。
  • Qdrant利用HSNW算法,并提供不同的距离度量方式,包括Dot、Cosine和Euclidean,让开发者能够选择与其特定用例相符合的指标。
  • Qdrant具有可扩展的云服务,可无缝过渡到云端,为探索提供了免费层次选项。其云原生架构保证了无论数据量大小,都能实现最佳性能。

常见问题

本文中展示的媒体不归Analytics Vidhya所有,仅由作者决定使用。

Leave a Reply

Your email address will not be published. Required fields are marked *