• 文章
  • 专为向量搜索而生
返回 Qdrant 内部结构

专为向量搜索而生

Evgeniya Sukhodolskaya & Andrey Vasnetsov

·

2025年2月17日

Built for Vector Search

任何稍具复杂性的问题都需要专门的解决方案。你可以用瑞士军刀开瓶盖或在纸板箱上打孔,但你需要一把斧头来劈柴——软件也是如此。

在本文中,我们将描述向量搜索带来的独特挑战,以及为什么专用解决方案是解决这些挑战的最佳方式。

向量

vectors

让我们来看看向量数据库的核心概念——向量

向量(也称为嵌入)是各种数据点(文本、图像、视频等)的高维表示。许多最先进(SOTA)的嵌入模型生成超过 1,500 维的表示。对于最先进的 PDF 检索,表示可以达到每页超过 100,000 维

这就引出了向量搜索的第一个挑战——向量很“重”。

向量很“重”

为了更直观地理解,考虑在关系数据库中存储一百万条记录。对于现代数据库来说,这相对较少的数据量,许多云提供商的免费层就可以轻松处理。

现在,使用 OpenAI 的 text-embedding-ada-002 模型为每条记录生成一个 1536 维的嵌入,你将需要大约 6GB 的存储空间。因此,向量搜索工作负载,尤其是在未优化的S情况下,将迅速主导非向量数据库的主要使用场景。

将向量作为主数据库的一部分可能引发另一个问题——向量始终是其他数据的转换。

向量是一种转换

向量是从其他真实数据源获得的。如果丢失,可以使用之前使用的相同嵌入模型进行恢复。同时,即使该模型发生微小变化,也可能改变向量空间的几何结构,因此如果你更新或更改嵌入模型,你需要更新并重新索引所有数据以保持准确的向量比较。

如果与主数据库耦合,此更新过程可能导致严重的复杂性,甚至导致整个系统不可用。

然而,向量也具有积极的特性。其中最重要的一点是向量具有固定大小。

向量具有固定大小

嵌入模型旨在生成固定大小的向量。我们必须利用这一优势。

为了实现快速搜索,向量需要能够即时访问。无论是存储在RAM 还是磁盘中,向量都应该以允许快速访问和比较的格式存储。这至关重要,因为向量比较是向量搜索工作负载中一个非常“热”的操作。它通常在每次搜索查询中执行数千次,因此即使是很小的开销也可能导致显著的减速。

对于专用存储,向量的固定大小简直是天赐之物。知道一个数据点需要多少空间,我们就不必处理定位数据通常的开销——存储中元素的位置计算起来很简单。

如果向量与其他数据类型(例如文本或 JSON)一起存储,那么一切都会变得不那么直观。单个数据点的大小不再固定,因此访问它变得不那么简单,尤其是随着时间的推移数据被添加、更新和删除。

Fixed size columns VS Variable length table

固定大小列 VS 变长表

将向量与其他类型的数据一起存储,我们失去了它们特性的所有好处;然而,我们却充分“享受”了它们的缺点,用存储中已有的数据的极其“重”的转换来污染存储。

vector-search

与作为数据存储的传统数据库不同,向量数据库更像是搜索引擎。它们旨在实现可扩展性、始终可用,并且即使在高负载下也能提供高速搜索结果。正如 Google 或 Bing 可以同时处理数十亿次查询一样,向量数据库专为需要快速、高吞吐量、低延迟检索的场景而设计。

Database Compass

数据库指南针

任选其二

分布式系统非常适合可扩展性——这些系统中的横向扩展允许你根据需要添加更多机器。在分布式系统的世界中,一个众所周知的原则——CAP 定理——说明你不能拥有一切。该定理指出,分布式系统只能保证三个属性中的两个:一致性(Consistency)可用性(Availability)分区容错性(Partition Tolerance)

由于网络分区在任何现实世界的分布式系统中都是不可避免的,所有现代分布式数据库都设计时考虑了分区容错性,从而需要在一致性(提供最新数据)和可用性(保持响应)之间进行权衡。

在这种情况下,数据库有两种主要的设计理念

ACID:优先考虑一致性

ACID 模型确保每个事务(被视为单个单元的一组操作,例如账户之间的转账)要么完全执行,要么根本不执行(回滚),使数据库处于有效状态。当系统是分布式的时,实现 ACID 属性需要节点之间复杂的协调。每个节点都必须就事务状态进行通信和达成一致,这会限制系统可用性——如果一个节点不确定另一个节点的状态,它可能会拒绝处理事务,直到确保存储一致性。这种协调也使得扩展更具挑战性

金融机构在处理转账时使用符合 ACID 的数据库,因为即使账户余额出现短暂差异也是不可接受的。

BASE:优先考虑可用性

另一方面,BASE 模型优先考虑高可用性和分区容错性。BASE 系统将数据和工作负载分布到多个节点,使它们能够立即响应读写请求。它们在最终一致性原则下运行——尽管数据可能暂时不是最新的,但系统会在给定时间后收敛到一致状态。

社交媒体平台、流媒体服务和搜索引擎都受益于 BASE 方法。对于这些应用程序来说,即时响应比严格的一致性更重要。

考虑到向量搜索的特性——其对可用性和可扩展性的需求——它应该基于面向 BASE 的架构。做出此选择是由于需要横向扩展、高可用性、低延迟和高吞吐量。例如,具有面向 BASE 的架构允许我们轻松管理分片重组

当我们记住向量是我们可用的数据的“重”转换时,严格一致的事务性方法也失去了吸引力——如果我们可以通过转换始终恢复向量化数据,那么限制数据保护机制的意义何在?

向量索引

vector-index

向量搜索依赖于高维向量数学,这使得它在规模上计算量很大。暴力相似度搜索需要将查询与数据库中的每个向量进行比较。在一个包含 1 亿个 1536 维向量的数据库中,针对一个查询执行 1 亿次比较对于生产场景来说是不可行的。向量数据库没有采用暴力方法,而是拥有专门的近似最近邻(ANN)索引,这些索引平衡了搜索精度和速度。这些索引需要精心设计的架构,以使其在生产中维护可行。

HNSW Index

HNSW 索引

最流行的向量索引之一是 HNSW(分层可导航小世界),我们选择它是因为它能够同时提供高搜索速度和准确性。高性能伴随着成本——由于一些挑战,在生产中实现它并非易事,因此要使其发挥最大作用,整个系统架构必须围绕它进行构建,以服务这个“任性”的索引。

索引复杂性

HNSW 被构建为多层图。插入新数据点后,算法必须将其与多个现有节点进行比较才能对其进行索引。随着向量数量的增长,这些比较将显著减慢构建过程,使得更新越来越耗时。索引操作很快就会成为系统的瓶颈,从而减慢搜索请求。

构建 HNSW 整体意味着限制解决方案的可扩展性——它的大小必须受到限制,因为它的构建时间与元素数量非线性地扩展。为了保持构建过程可行并确保它不影响搜索时间,我们提出了一种分层架构,将所有数据管理分解为称为的小单元。

Storage structure

存储结构

每个段隔离了向量化语料库的一个子集,并支持对其进行所有集合级操作,从搜索到索引,例如,段在其可用的数据子集上构建自己的索引。对于在集合级别工作的用户,分段的细节是不可察觉的。他们获得的搜索结果涵盖整个集合,因为子结果是从段中收集然后合并和去重的。

通过平衡段的大小和数量,我们可以确保搜索速度和索引时间之间的正确平衡,从而使系统能够灵活应对不同的工作负载。

不变性

通过在段之间分配索引维护,Qdrant 即使在高负载下也能确保高性能,并且额外的优化进一步巩固了这一点。这些优化源于一个想法,即使用不可变结构会带来许多好处:可以使用内部固定大小的列表(因此没有动态更新),根据访问模式对存储数据进行排序(因此没有不可预测的随机访问)。考虑到这一点,为了进一步优化搜索速度和内存管理,我们采用了一种结合和管理可变和不可变段的策略。

可变段这些用于快速摄取新数据和处理现有数据的更改(更新)。
不可变段一旦可变段达到特定大小,优化过程就会将其转换为不可变段,从而构建 HNSW 索引——你可以在此处详细了解这些优化器。例如,这种不变性技巧使我们能够确保有效的租户隔离

不可变段对用户来说是透明的实现细节——他们可以随时删除向量,而添加和更新则应用于可变段。这种可变性和不变性的结合允许搜索和索引同时平稳运行,即使在高负载下也是如此。这种方法最大限度地减少了索引时间对性能的影响,并允许在集合级别进行即时配置更改(例如启用或禁用数据量化)而无需停机。

可过滤索引

向量搜索在历史上并不是为过滤而设计的——对结果施加严格约束。它本质上是模糊的;每个文档在某种程度上都与任何查询相似且不相似——没有二进制的“符合/不符合”的区分。因此,向量搜索算法最初并非以过滤为目的构建的。

同时,过滤在许多向量搜索应用中是不可避免的,例如电子商务搜索/推荐。搜索圣诞礼物时,你可能希望过滤掉所有价格超过 100 欧元的商品,同时仍能受益于向量搜索的语义性质。

在许多向量搜索解决方案中,过滤有两种处理方式:预过滤(在运行 HNSW 搜索之前计算所有符合条件的向量的二进制掩码)或后过滤(照常运行 HNSW,然后过滤结果)。

预过滤计算向量掩码的线性复杂度,对于大型数据集来说会成为瓶颈。
后过滤后过滤的问题与向量搜索的“一切都符合,但同时又不符合”的本质有关:想象一个低基数过滤器,它在数据库中只留下少量匹配元素。如果它们中没有一个与查询足够相似以出现在前 X 个检索结果中,那么它们都将被过滤掉。

Qdrant 进一步推进了向量搜索中的过滤,认识到预过滤和后过滤策略的局限性。我们开发了 HNSW 的一个变体——可过滤 HNSW——它还可以在图遍历期间实现就地过滤。为了实现这一点,我们将 HNSW 索引构建基于可能的过滤条件,这些条件由payload 索引(基于向量元数据构建的倒排索引)反映。

Qdrant 的设计核心是向量索引。 这使得围绕向量索引组织优化器、payload 索引和其他组件成为可能,从而解锁了构建可过滤 HNSW 的潜力。

Filterable Vector Index

可过滤向量索引

一般来说,优化向量搜索需要一种定制的、精细调整的数据和索引管理方法,即使数据动态增长和变化也能确保高性能。这种专业架构是专用向量数据库在生产环境中始终优于通用数据库的关键原因。

超越 RAG 的向量搜索

Vector Search is not Text Search Extension

向量搜索不是文本搜索的扩展

许多关于向量数据库目的的讨论都集中在检索增强生成 (RAG)——或其更高级的变体,代理式 RAG——其中向量数据库用作知识源,用于检索大型语言模型 (LLM) 的上下文。这是一个合法的用例,然而,RAG 解决方案的炒作浪潮掩盖了向量搜索的更广泛潜力,它超越了增强生成式 AI

发现

向量搜索的优势在于其促进发现的能力。向量搜索允许你在搜索时细化你的选择,而不是从固定查询开始。例如,你点餐时不知道自己确切想要什么——只是它应该包含肉而不是汉堡,或者应该是带奶酪的肉而不是玉米饼。向量搜索不是搜索特定的菜肴,而是帮助你根据相似性和不相似性导航选项,引导你找到符合你口味的东西,而无需你预先定义它。

推荐

向量搜索非常适合推荐。想象一下浏览一本新书或一部电影。你可能不是寻找精确匹配,而是寻找捕捉某种情绪或主题,但在关键方面与你已知内容不同的故事。例如,你可能想要一部有巫师但没有“哈利·波特”系列熟悉感觉的电影。这种灵活性之所以可能,是因为向量搜索不与二进制的“匹配/不匹配”概念绑定,而是在向量空间中的距离上操作。

大数据非结构化数据分析

向量搜索的性质也使其成为大数据非结构化数据分析的理想选择,例如异常检测。在大型、非结构化且通常未标记的数据集中,向量搜索可以通过分析数据点之间的距离关系来帮助识别聚类和异常值。

根本不同

超越 RAG 的向量搜索不仅仅是另一个功能——它是我们与数据交互方式的根本性转变。专用解决方案原生集成了这些功能,并从头开始设计,以处理高维数学和基于(不)相似性的检索。相比之下,具有向量扩展的数据库是围绕不同的数据范式构建的,因此无法有效地支持高级向量搜索功能。

即使你想改造这些功能,这也不仅仅是添加一个新功能的问题——这是一个结构性问题。支持高级向量搜索需要专用接口,这些接口能够灵活地使用向量搜索,从多阶段过滤到高维空间的动态探索。

当底层架构最初不是为此类交互而设计时,集成接口就是软件工程团队的噩梦。你最终会破坏现有的假设,强制采用低效的变通方法,并且通常会引入向后兼容性问题。这就是为什么试图将向量搜索修补到传统数据库上无法与专用系统的效率相媲美的原因。

打造最先进的向量搜索

vector-search-state-of-the-art

现在,让我们将重点转向专用解决方案的另一个关键优势——它们能够跟上该领域最先进解决方案的能力。

向量数据库是专为向量检索而构建的,因此,它们提供最前沿的功能,这些功能对于依赖向量搜索的 AI 企业通常至关重要。向量数据库工程师投入大量时间和精力研究和实现执行向量搜索的最优方法。许多此类创新对于向量原生架构来说是自然而然的,而增加了向量功能的通用数据库可能难以高效地适应和复制这些优势。

考虑 Qdrant 中实现的一些高级功能

  • GPU 加速索引
    通过将索引构建任务卸载到 GPU,Qdrant 可以显著加快数据索引过程,同时保持低成本。这在热数据场景中处理大型数据集时尤其有价值。

    Qdrant 中的 GPU 加速是我们的核心团队中的一位爱好者开发的定制解决方案。它是无供应商的,并原生支持 Qdrant 的所有独特架构功能,从可过滤 HNSW 到多向量。

  • 多向量
    一些现代嵌入模型输出整个矩阵(向量列表)而不是单个向量。Qdrant 原生支持多向量。

    此功能在使用最先进的检索模型(例如ColBERT、ColPali 或 ColQwen)时至关重要。例如,ColPali 和 ColQwen 会生成多向量输出,原生支持它们对于最先进 (SOTA) 的 PDF 检索至关重要。

除此之外,我们还不断寻求改进

内存效率和压缩诸如量化HNSW 压缩等技术可减少存储需求
检索算法支持最新的检索算法,包括稀疏神经检索混合搜索方法和重新排序器
向量数据分析与可视化诸如距离矩阵 API 等工具提供向量化数据的洞察,而Web UI 允许直观地探索数据。
搜索速度和可扩展性包括针对多租户环境的优化,以确保高效和可扩展的搜索。

这些进步不仅仅是渐进式的改进——它们定义了为向量搜索优化系统与适应向量搜索的系统之间的区别。

保持向量搜索的前沿不仅仅关乎性能,还关乎跟上不断发展的 AI 格局。

总结

conclusion-vector-search

在向量搜索方面,使用专用向量搜索解决方案与扩展数据库以支持向量操作之间存在明显区别。

对于处理多达一百万个数据点的小规模应用程序或原型,未经优化的架构可能就足够了。然而,随着向量数量的增长,未经优化的解决方案将很快成为瓶颈——减慢搜索操作并限制可扩展性。专用向量搜索解决方案从头开始设计,以高效处理海量高维数据。

最先进(SOTA)的向量搜索发展迅速。如果您计划基于最新进展进行构建,使用向量扩展最终会阻碍您。专用向量搜索解决方案原生集成了这些功能,确保您受益于持续创新而不会影响性能。

向量搜索的强大功能延伸到大数据分析、推荐系统和基于发现的应用程序等领域,为了支持这些向量搜索功能,需要一个专用解决方案。

何时选择专用数据库而不是扩展

  • 高容量、实时搜索:适用于需要快速、持续访问搜索结果的应用程序,拥有大量并发用户——例如搜索引擎、电子商务推荐、社交媒体或流媒体服务。
  • 动态、非结构化数据:非常适合数据不断变化且目标是从数据模式中发现洞察的场景。
  • 创新应用:如果您希望实现推荐引擎、混合搜索解决方案或探索性数据分析等高级用例,而传统精确或基于令牌的搜索存在局限性。

如果你的应用程序依赖大规模向量搜索、紧跟趋势或需要的不仅仅是简单的微型相似度搜索,那么投资专用向量搜索引擎将提供成功所需的性能和灵活性。

此页面有用吗?

感谢您的反馈!🙏

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