AI中间件:向量数据库

在2023年上半年,与向量数据库相关的营销(不幸的是,还伴随着一些炒作)大量涌现。如果你正在阅读这篇博文,你可能好奇为什么存在这么多种类,并想知道它们之间有什么区别。

从理论上讲,所有的向量数据库都在做同样的事情(它们都能支持需要语义搜索的各种应用),那么要如何对它们形成明智的看法呢?🤔

在这篇博文中,我将尽可能直观地展示不同向量数据库之间的区别。我还将重点介绍我进行比较的特定维度,以便提供更全面的视角。

选择太多了!🤯 在过去的几个月里,我一直在研究不同的向量数据库及其内部结构,并通过它们的Python API与其互动。我遇到了以下共同问题:

每个数据库供应商都会推销他们自己的功能(这是自然的),同时贬低竞争对手的功能,因此根据你查看的信息源不同,很容易得出有偏见的观点。

有许多向量数据库供应商,需要在多个来源中阅读大量内容,才能将各种信息联系起来,了解这个领域的格局以及存在哪些基础技术。在进行向量搜索时,需要考虑许多权衡:

  • 混合搜索还是关键词搜索?关键词+向量搜索的混合可以产生最佳结果,每个向量数据库供应商都意识到了这一点,并提供了自己定制的混合搜索解决方案。
  • 部署在本地还是云原生?许多供应商将“云原生”作为卖点,好像基础设施是全球最大的痛点,但本地部署在长期内可能更经济实惠,因此更加有效。
  • 开源还是完全托管?大多数供应商都是在源代码可获得或开源代码基础上构建的,以展示其基本方法,然后通过完全托管的SaaS来实现部署和基础设施的部分。虽然仍然有可能自行托管很多解决方案,但这需要额外的人力和内部技能要求。

对比各种向量数据库

截至2023年6月,我正在研究8个专门构建的向量数据库产品以及3个现有的向量搜索附加功能。

在忽略已有的供应商(即已建立的厂商)后,我们可以通过跟踪每个向量数据库创业公司的资金里程碑1来开始。

公司名称总部位于资金
Weaviate🇳🇱 阿姆斯特丹$68M B轮
Qdrant🇩🇪 柏林$11M 种子轮
Pinecone🇺🇸 旧金山$138M B轮
Milvus/Zilliz🇨🇳 / 🇺🇸 红木城$113M B轮
Chroma🇺🇸 旧金山$20M 种子轮
LanceDB🇺🇸 旧金山风险投资
Vespa🇳🇴 / 🇺🇸 印第安纳波利斯雅虎
Vald🇯🇵 东京雅虎日本

很明显,当涉及到向量数据库时,加利福尼亚湾区有很多活动!此外,资金和估值之间存在很大的差异,很明显,数据库的能力与其获得的资金之间不存在任何相关性。

编程语言选择

如今,快速、响应迅速且可扩展的数据库通常使用现代语言如 Golang 或 Rust 进行编写。在专门的供应商中,唯一一个使用 Java 构建的是 Vespa。Chroma 目前是 Python/TypeScript 包装在 Clickhouse 之上的一个包装器,Clickhouse 是用 C++ 构建的 OLAP 数据库,以及一个开源的向量索引,HNSWLib。

img

有趣的是,Pinecone2 和 Lance3(LanceDB 的底层存储格式)都已经被从头开始用 Rust 重写,尽管它们最初是用 C++ 编写的。显然,越来越多的数据库社区正在拥抱 Rust 🦀💪!

时间线

每个向量数据库已经存在多长时间了?

Vespa 是最早在主流的基于 BM25 关键字搜索算法旁边加入向量相似性搜索的厂商之一(有趣的是,Vespa 的 GitHub 仓库 现在已经有近 75000 次提交 🤯)。Weaviate 随后在2018年底推出了一个专门的开源向量搜索数据库产品,到2019年,我们开始在这个领域看到更多的竞争,包括 Milvus(也是开源的)。需要注意的是,在时间线中也显示了 Zilliz,但没有单独列出,因为它是 Milvus 的(商业)母公司,提供了基于 Milvus 构建的完全托管的云解决方案。在2021年,又有三家新的供应商加入了竞争:Vald、Qdrant 和 Pinecone。直到此时,像 Elasticsearch、Redis 和 PostgreSQL 这样的老牌厂商才开始提供向量搜索,比人们原本想象的要晚得多,仅仅在2022年以及之后才开始。

源代码可用性

在列出的所有选项中,只有一个是完全封闭源代码:Pinecone。Zilliz 也是一个完全封闭的商业解决方案,但它完全是建立在 Milvus 之上的,并且可以看作是 Milvus 的母公司。其他所有选项至少在代码基础方面是源代码可用的,确切的许可证决定了代码的可许可性以及部署方式。

提示

作为一个开发者,我发现跟踪每个数据库的开源 GitHub 仓库中的问题、PR 和发布版本,可以很好地了解在路线图中的优先处理事项。GitHub 星标的数量⭐️是项目社区兴趣的一个很好指标,但没有什么比亲身经验更好,所以我总是尽量尝试尽可能多的开源数据库。

托管方式

数据库供应商提供的典型托管方式包括自托管(本地部署)和托管/云原生,两者都遵循客户端-服务器架构。第三种更近期的选择是嵌入模式,其中数据库本身与应用程序代码紧密耦合,以服务器无形式运行。目前,只有 Chroma 和 LanceDB 可用作嵌入式数据库。

向量数据库优缺点分析

在这篇博客中,我将列出一些关键观点以及每个数据库的优缺点。其中一些是我经过多种途径(博客、播客、研究论文、与用户/合作者的交流以及我自己的代码)获取的见解。

Pinecone

  • 优点:非常容易上手(无需托管负担,完全云原生),用户无需了解有关向量化或向量索引的任何知识。根据他们的文档(也非常好),它只是“工作”。
  • 缺点:完全专有,不可能知道底层发生了什么,以及在没有能够在GitHub上跟踪他们的进展的情况下,他们的路线图是什么。此外,某些用户的经验突显了依赖于完全外部的第三方托管服务的危险,以及开发人员在数据库设置和运行方式方面完全缺乏控制。从长远来看,在成本上依赖于完全托管的闭源解决方案可能具有显著影响,考虑到市场上大量的开源、自托管的替代品。
  • 个人观点:在2020-21年,当向量数据库还在非常低调的阶段时,Pinecone在向开发人员提供便利功能方面领先于其他供应商。快进到2023年,坦率地说,现在Pinecone提供的东西很少,其他供应商没有提供的,大多数其他供应商至少提供自托管、托管或嵌入式模式,更不用说它们的算法和底层技术的源代码对终端用户是透明的。
  • 官方网站:pinecone.io

Weaviate

  • 优点令人惊叹的 文档(其中包括技术细节和正在进行的实验)。Weaviate似乎真正专注于构建最佳的开发者体验,通过Docker很容易上手。在查询方面,它可以产生快速的、亚毫秒级的搜索结果,同时提供关键字和向量搜索功能。
  • 缺点:因为Weaviate是使用Golang构建的,可扩展性是通过Kubernetes实现的,而这种方法(类似于Milvus)在数据变得非常大时需要相当多的基础设施资源。在长期内,Weaviate的完全托管方案的成本影响未知,将其性能与其他基于Rust的替代品(如Qdrant和LanceDB)进行比较可能是有意义的(尽管时间将会告诉哪种方法在成本效益最高的情况下扩展得更好)。
  • 个人观点:Weaviate拥有一个强大的用户社区,开发团队正在展示极端可扩展性(数千亿个向量),因此似乎他们的目标市场是那些希望在大量数据上进行向量搜索的大型企业。提供关键字搜索以及向量搜索,并且通常进行强大的混合搜索,使其能够适用于各种用例,直接与Elasticsearch等文档数据库竞争。Weaviate积极关注涉及数据科学和机器学习的领域,通过向量数据库将其从传统的搜索与检索应用扩展出来。
  • 官方网站:weaviate.io

Qdrant

  • 优点:虽然比Weaviate更新,但Qdrant也有很好的文档,可以帮助开发者通过Docker轻松上手。它完全使用Rust构建,提供了开发者可以通过其Rust、Python和Golang客户端利用的API,这些语言是当今后端开发人员最常用的语言。由于Rust的潜在能力,其资源利用似乎低于Golang构建的替代品(至少在我个人的经验中是如此)。可扩展性目前是通过分区和Raft共识协议来实现的,这在数据库领域是标准做法。
  • 缺点:作为一个相对较新的工具,与Weaviate和Milvus等替代品相比,Qdrant在查询的用户界面等方面一直在赶超,尽管这个差距正在迅速减小。
  • 个人观点:我认为Qdrant有望成为许多希望最小化基础设施成本并利用现代编程语言Rust强大能力的公司首选的向量搜索后端。在撰写本文时,混合搜索尚不可用,但根据他们的路线图,正在积极开发中。此外,Qdrant不断发布有关如何优化其内存和磁盘上的HNSW实现的更新,这将极大地有助于实现其长期的搜索准确性和可扩展性目标。显然,Qdrant的用户

社区正在迅速增长(有趣的是,比Weaviate的增长更快),如其GitHub的星标历史所示!也许世界对Rust很感兴趣🦀?无论如何,在我看来,使用Qdrant进行开发非常有趣😀。

  • 官方网站:qdrant.tech

Milvus/Zilliz

  • 优点:作为向量数据库生态系统中存在时间较长的数据库,Milvus具有众多算法,由于其长期存在。提供大量选项用于向量索引,并且完全基于Golang构建,以实现极端可扩展性。截至2023年,它是唯一一个提供有效的DiskANN实现的主要供应商,据说这是最有效的磁盘向量索引。
  • 缺点:在我看来,Milvus似乎是一个将可扩展性问题抛给了可扩展性问题的解决方案,它通过代理、负载均衡器、消息代理、Kafka和Kubernetes的组合来实现高度可扩展性,这使得整个系统变得非常复杂和资源密集。客户端API(例如Python)也没有像Weaviate和Qdrant这样的较新的数据库那样易读或直观,后者更加注重开发者体验。
  • 个人观点:显然,Milvus的构建理念是为向量索引的流式数据提供大规模可扩展性,在许多情况下,当数据的大小不是太大时,Milvus似乎过于庞大。对于更静态和不经常发生的大规模情况,像Qdrant或Weaviate这样的替代品可能更便宜、更快速地投入生产运行。
  • 官方网站:milvus.io 和 zilliz.com

Chroma

  • 优点:为开发人员提供了方便的Python/JavaScript接口,可以快速启动向量存储。它是市场上第一个默认提供嵌入模式的向量数据库,其中数据库和应用层紧密集成,允许开发人员快速构建、原型和展示他们的项目。
  • 缺点:与其他专为此目的构建的供应商不同,Chroma在很大程度上是现有OLAP数据库(Clickhouse)的Python/TypeScript封装,以及现有开源向量搜索实现(hnswlib)的封装。目前(截至2023年6月),它尚未实现自己的存储层。
  • 个人观点:向量数据库市场正在迅速发展,Chroma似乎倾向于采用“观望”哲学,是为数不多的几个供应商之一,它们旨在提供多种托管选项:无服务器/嵌入式、自托管(客户端-服务器)和基于云原生的分布式SaaS解决方案,可能同时支持嵌入式和客户端-服务器模式。根据他们的路线图4,Chroma的服务器实现正在进行中。Chroma正在引入的另一个创新领域是量化“查询相关性”,即返回结果与用户输入查询的接近程度。其路线图还列出了可视化嵌入空间,这是一个创新领域,可让数据库用于除搜索之外的许多其他应用。然而,从长期的角度来看,我们从未见过嵌入式数据库架构在向量搜索领域内获得成功的案例,所以它的发展(与下面描述的LanceDB一样)将是有趣的!
  • 官方网站:trychroma.com

LanceDB

  • 优点:专为多模态数据(图像、音频、文本)的分布式索引和搜索而设计,建立在新兴数据格式Lance之上,这是一种用于机器学习的创新且新颖的列式数据格式。与Chroma一样,LanceDB使用嵌入式、无服务器架构,完全基于Rust从零开始构建,因此除了Qdrant外,这是另一个主要的向量数据库供应商,可以利用Rust的速度🔥、内存安全性和相对较低的资源利用率🦀。
  • 缺点:LanceDB是一个非常年轻的数据库,因此许多功能正在积极开发中,由于工程团队较小,在未来一年左右优先考虑功能可能是一个挑战。
  • 个人观点:我认为在所有向量数据库中,LanceDB与其他数据库的区别最大。主要原因在于它在数据存储层上进行了创新(使用Lance,一种新的、比parquet更快的列式格式,专为非常高效的查找设计),以及基础架构层的创新-通过使用无服务器架构。因此,大大减少了许多基

础设施复杂性,极大地增加了开发者的自由和能力,以分布式的方式直接连接数据湖来构建语义搜索应用。

  • 官方网站:lancedb.com

Vespa

  • 优点:提供最“企业级”的混合搜索功能,将关键字搜索和在HNSW之上的自定义向量搜索相结合。尽管其他供应商如Weaviate也提供关键字和向量搜索,但Vespa是市场上最早提供这种功能的,这给了他们充分的时间来优化他们的产品,使其快速、准确和可扩展。
  • 缺点:开发者体验不如使用性能导向语言(如Go或Rust)编写的现代替代品那么顺畅,这是因为应用层是用Java编写的。此外,直到最近,它没有使通过Docker和Kubernetes等方式设置和拆除开发实例变得非常简单。
  • 个人观点:Vespa确实提供了非常好的功能,但其应用主要是用Java编写的,而后端和索引层则是用C++构建的。这使得它难以随着时间的推移进行维护,因此与其他替代方案相比,它似乎具有较低的开发者友好性。如今,大多数新的数据库都是完全由一种语言编写的,通常是Golang或Rust,而在Weaviate、Qdrant和LanceDB等数据库中,算法和架构方面的创新似乎在迅速发展。
  • 官方网站:vespa.ai

Vald

  • 优点:设计用于通过高度分布式的架构处理多模态数据存储,同时具有诸如索引备份之类的有用功能。使用非常快速的ANN搜索算法NGT(Neighbourhood Graph & Tree),在与高度分布式向量索引结合使用时,这是最快的ANN算法之一。
  • 缺点:似乎比其他供应商的使用率和使用率要低,文档并没有清楚地描述使用了哪种向量索引(“分布式索引”相当模糊)。此外,它似乎完全由一个实体(日本Yahoo!)提供资金支持,几乎没有关于任何其他主要用户的信息。
  • 个人观点:我认为Vald是比其他供应商更为专业的供应商,主要满足日本Yahoo!的搜索需求,并且整体用户社区较小,至少基于其GitHub的星标。部分原因可能是它位于日本,没有像欧盟和湾区的其他更好的位置的供应商那样被广泛推广。
  • 官方网站:vald.vdaas.org

Elasticsearch、Redis和pgvector

  • 优点:如果您已经在使用现有数据存储,如Elasticsearch、Redis或PostgreSQL,那么在不必求助于新技术的情况下,使用它们的向量索引和搜索功能是相当简单的。

  • 缺点:现有的数据库不一定以最优的方式存储或索引数据,因为它们设计为通用数据库,因此对于涉及百万级向量搜索等数据,性能会受到影响。Redis VSS(Vector Search Store)之所以快速,主要是因为它完全在内存中,但一旦数据超过内存大小,就必须考虑替代方案。

  • 个人观点:我认为,专为特定目标构建和专门化的向量数据库将在需要语义搜索的领域逐渐超越已建立的数据库,主要是因为它们正在最关键的组件上进行创新,即存储层。HNSW和ANN算法等索引方法在文献中有详细记录,大多数数据库供应商可以推出自己的实现,但专为此任务优化的专业向量数据库具有任务优化的优势(更不用说它们是用现代编程语言编写的),出于可扩展性和性能的原因,它们在长期内最有可能在这个领域取得成功。

  • 官方网站:

    • Elasticsearch:elastic.co
    • Redis Vector Search Store:Redis Labs
    • PostgreSQL的pgvector扩展:supabase.com

向量数据库背后原因

为什么当下人们都在谈论矢量数据库?

在深入探讨什么是矢量数据库之前,我们先来看看是什么原因导致了这股在矢量数据库领域的活跃和投资热潮。

大语言模型时代的到来

在2022年11月,OpenAI发布了ChatGPT的早期演示版本(ChatGPT是基于GPT 3.5及以上版本的界面),随后它迅速成为了历史上增长最快的应用程序,仅用了5天就获得了一百万用户 🤯!事实上,如果你查看一些主要开源矢量数据库代码仓库在GitHub上的✨历史记录,就会清楚地发现,在ChatGPT于2022年11月发布以及随后的ChatGPT插件发布之后,一些矢量数据库仓库的星标数量出现了明显的增加。这些因素以及它们在Hacker News和流行媒体等网站上的相关文章1,是解释这个领域出现如此多活动的重要原因之一。

由 ❤️ 制作于 star-history.com

由 star-history.com 精心制作

依赖大语言模型的问题

大语言模型(LLMs)是生成型的,这意味着它们根据用户的提示以顺序的方式产生有意义、连贯的文本。然而,在使用LLMs来回答人类的问题时,它们经常会产生与问题无关或事实不正确的结果。

  • LLMs经常会产生幻觉,即它们会虚构信息,比如引导用户访问URL或捏造不存在的数字。
  • LLMs学习/记忆了其训练数据的压缩版本,尽管它们学得相当好,但并不是完美的 - 模型对数据的内部表示总会有一些信息被“丢失”。
  • LLMs无法知道其训练完成后发生的事实。

矢量数据库有助于解决这些问题,它们作为底层存储层,可以被LLMs高效地查询,以检索事实。与传统数据库不同,矢量数据库专注于将数据本身作为矢量进行本地表示。因此,现在我们可以构建应用程序,让LLMs位于矢量存储层的顶部,这个存储层包含了最近、最新的事实数据(远超过LLMs的训练日期),并且我们可以利用这些数据来“固定”模型,减轻幻觉问题。

尽管矢量数据库(例如Vespa、Weaviate、Milvus)在LLMs出现之前就存在了,但自从ChatGPT发布以来,开源社区以及矢量数据库供应商的营销团队迅速意识到了它们在搜索和检索等主流用例中的潜力,尤其是与高质量文本生成相结合。

什么是Embeddings?

嵌入是一种向量数据库存储的数据编码形式,不仅包括原始数据(可以是图像、音频或文本),还包括其编码形式:嵌入。这些嵌入本质上是由数字列表(即向量)组成的,用于存储数据的上下文表示。直观地说,当我们提到“嵌入”时,我们实际上在谈论数据(图像、文本、音频)的压缩的低维表示,而这些数据实际上存在于更高维度中。

在存储层面,数据库堆叠了 m 个向量,每个向量使用 n 维表示一个数据点,总大小为 m×n。通常,为了查询性能的原因,这些堆栈会通过分片进行分区。

嵌入向量

自然语言处理中的 Transformer 革命为工程师提供了在规模上高效生成这些压缩表示(嵌入)的方法。

  • 一个流行的方法是使用开源库 sentence-transformers,可通过 Hugging Face 模型库 或直接从 源代码仓库 获取。
  • 另一种(更昂贵的)方法是使用许多 API 服务:
    • OpenAI 嵌入 API
    • Cohere 嵌入 API

需要注意的是,底层向量的维度越低,嵌入空间中的表示就越紧凑,这可能会影响下游任务的质量。Sentence Transformers(sbert)提供了维度在 384、512 和 768 范围内的嵌入模型,而这些模型完全免费且开源。需要付费 API 调用才能生成的 OpenAI 和 Cohere 嵌入,由于维度较高,可以考虑具有更高的质量,达到几千维。使用付费 API 生成嵌入的一个合理理由是,如果您的数据是多语言的(Cohere 以拥有高质量的多语言嵌入模型而闻名,其性能优于开源变体)。

向量存储在向量数据库中

由于它们适用于在嵌入空间中操作,向量数据库在多种形式的数据(文本、图像、音频)的语义或相似性搜索中证明非常有用。在语义搜索中,用户发送的输入查询(通常是自然语言)被转换为向量形式,与数据本身在相同的嵌入空间中,从而返回与输入查询最相似的前 k 个结果。下面展示了这一过程的可视化示意图。

如何计算相似性?

各种向量数据库提供不同的相似性计算方法,但对于文本,最常用的两种度量是:

  • 点积(Dot Product):这产生一个非规范化的值,具有任意大小
  • 余弦距离(Cosine Distance):这产生一个规范化的值(介于 -1 和 1 之间)

余弦距离测量的示例

考虑一个简化的示例,其中我们在二维空间中将红葡萄酒和白葡萄酒的标题进行向量化,其中水平轴表示红葡萄酒,垂直轴表示白葡萄酒。在这个空间中,距离较近的点表示具有相似单词或概念的葡萄酒,而距离较远的点则没有太多共同之处。余弦距离被定义为每种葡萄酒在嵌入空间中与原点相连的线之间的夹角的余弦值。

左侧的图中,两种葡萄酒(Reserve White 和 Toscana Red)在词汇和概念方面都没有太多共同之处,因此它们的余弦距离接近零(在向量空间中是正交的)。右侧的图中,来自 Napa Valley 的两种 Zinfandel 葡萄酒有更多的共同之处,因此它们的余弦相似度更接近于 1。在这里,极限情况是余弦距离为 1,一个句子总是与其自身完全相似。

当然,在实际情况中,实际数据存在于更高维的向量空间中(远远不止葡萄酒的种类),无法在二维平面上可视化,但是余弦相似性的原则仍然适用。

可扩展的最近邻搜索

一旦生成并存储了向量,在用户提交搜索查询时,相似性搜索的目标是提供与输入查询向量最相似的前 k 个向量。再次,我们可以在一个简化的二维空间中可视化这一过程。

最近邻(kNN)方法,将查询向量与数据库中的每个向量进行比较。然而,随着数据规模扩大到数百万(甚至数十亿)个数据点,所需的比较次数会线性增加,这很快变得过于昂贵。

近似最近邻搜索

每个现有的向量数据库都专注于使搜索高效,不论数据集的大小如何,都通过一类称为近似最近邻(Approximate Nearest Neighbour,ANN)搜索的算法来实现。与对数据库中的每个向量进行详尽比较不同,近似搜索会搜索最近邻,从而在结果中牺牲一些准确性(并不总是返回真正的最近邻),但可以通过使用 ANN 算法获得大幅的性能提升。

索引

数据通过索引存储在向量数据库中,这指的是创建称为索引的数据结构,以便通过快速缩小搜索空间来进行向量的高效查找。通常情况下,使用的嵌入模型存储的向量维度约为 102 或 103,而 ANN 算法试图以尽可能高效的方式在时间和空间上捕捉数据的实际复杂性。

有许多索引算法用于各种可用的向量数据库,它们的详细信息超出了本文的范围(我将在未来的文章中研究这些)。但是,供参考,以下是其中一些:

  • 反向文件索引(IVF)
  • 分层可导航图(HNSW)
  • Vamana(在 DiskANN 实现中使用)

组织向量索引

假设你已经对什么是向量数据库有了清晰的了解,那么值得退一步思考一下,如何使它能够在搜索数百万、数十亿甚至数万亿个向量时如此出色2。

向量数据库的主要目标是提供一种快速高效的方法来存储和进行语义查询数据,以使Vector数据类型成为一流的对象。两个向量之间的相似性是通过诸如余弦距离或点积之类的距离度量来衡量的。在使用向量数据库时,重要的是要区分搜索算法和近似最近邻(ANN)搜索算法操作的底层索引

就像在大多数情况下一样,选择一个向量索引涉及精度(准确率/召回率)与速度/吞吐量之间的权衡。

层次1:数据结构

根据用于构建索引的数据结构组织索引有助于更好地理解。以下是对其进行可视化的最佳方式。

通过底层数据结构拆分向量索引

通过底层数据结构拆分向量索引

基于哈希的索引

基于哈希的索引如 LSH(局部敏感哈希)将高维数据转换为较低维的哈希码,旨在尽量保留原始相似性。在索引过程中,数据集会被多次哈希,以确保相似的点更可能碰撞在一起(与传统的哈希技术相反,其目标是最小化碰撞)。在查询过程中,查询点也会使用与索引过程中相同的哈希函数进行哈希,由于相似的点被分配到相同的哈希桶中,所以检索非常快速。基于哈希的索引的主要优点是在处理大量数据时非常快速,但缺点是它们的准确性不太高。

基于树的索引

基于树的索引结构通过二叉搜索树在高维空间中进行快速搜索。树的构造方式使得相似的数据点更可能位于同一子树中,从而更快地发现近似最近邻。Annoy(Approximate Nearest Neighbours Oh Yeah)就是这样一种方法,它使用了一个二叉搜索树森林,在 Spotify 开发。基于树的索引的缺点是它只对低维数据表现得相对较好,在高维数据上不太准确,因为它无法充分捕捉数据的复杂性。

基于图的索引

基于图的索引的思想是向量空间中的数据点形成一个图,其中节点代表数据值,连接节点的边表示数据点之间的相似性。图的构建方式使得相似的数据点更可能通过边连接起来,而ANN搜索算法则旨在以高效的方式遍历图。基于图的索引的主要优点是,它们能够在高维数据中找到近似的最近邻,同时还能够在内存使用方面更加高效,提高性能。下面将对 HNSW 和 Vamana 进行解释,它们是基于图的索引的示例。

基于图的索引的扩展,包括来自基于树的索引概念的 NGT3(Neighbourhood Graphs and Trees)。由日本雅虎开发,它在索引过程中执行两个构造:一个将稠密 kNN 图转换为双向图,另一个逐步构建一个可导航的小世界(NSW)图。它与纯粹的基于图的索引的不同之处在于,它使用了树

状结构(Vantage-point 或 'VP' 树)来进行范围搜索,这是一种贪婪搜索的变体。由于这两种构造都会导致具有高出度的节点,为了避免组合爆炸,搜索起始的种子顶点使用范围搜索来使遍历更加高效。这使得 NGT 成为了图和树结合的索引。

倒排文件索引

倒排文件索引(IVF)将向量空间分成许多被称为 Voronoi 图的区域,这些区域类似于聚类,它们减少了搜索空间,使得寻找最近邻只需要定位最近 Voronoi 区域的质心,然后仅在该区域内搜索。IVF的好处在于,它可以帮助设计快速缩小到感兴趣相似性区域的ANN算法,但其原始形式的缺点在于在非常大量的数据上进行的向量空间的分割步骤可能会很慢。因此,IVF通常与量化方法(如产品量化,PQ)结合使用以提高性能,后面会详细描述。

层次2:压缩

第二个层次是索引的压缩程度:一个"flat"或"brute force"索引是将向量以未修改的形式存储的索引。当接收到查询向量时,它会与数据库中的每个向量进行逐个比较,如下面在3D空间中的简化示例所示。实际上,使用这样的索引就像进行kNN搜索,返回结果是与查询向量最近的k个邻近向量的确切匹配。正如你所想象的,返回结果所需的时间会随着数据量的增加而线性增加,在数据集中应用于拥有数十万个以上向量的情况下是不切实际的。

kNN(穷举)搜索的flat索引:图片灵感来自 Pinecone 博客

kNN(穷举)搜索的flat索引:图片灵感来自 Pinecone 博客

为了提高搜索效率,以及在检索时牺牲一些检索精度,采用压缩的方法。这个过程被称为量化,在这个过程中,索引中的底层向量被分成由更少字节组成的块(通常通过将浮点数转换为整数来实现),以减少内存消耗和搜索时的计算成本。

img

Flat 索引

在使用 ANN(非穷举)搜索时,像 IVF 或 HNSW 这样的现有索引,被称为“flat”索引,当它直接计算查询向量与数据库向量之间的距离时。与量化变体区分开来。在这种用法下,它们被称为 IVF-Flat、HNSW-Flat 等。

量化索引

量化索引是将现有索引(IVF、HNSW、Vamana)与像量化之类的压缩方法结合起来的索引,以减少内存占用并加速搜索。量化通常是两种类型之一4:标量量化(Scalar Quantization,SQ)或产品量化(Product Quantization,PQ)。标量量化将向量中的浮点数转换为整数(在字节大小上要小得多),通过对每个维度中的最小值和最大值进行对称分割,将向量分为 bin。

PQ 是一种更复杂的方法,它考虑了每个向量维度上的值的分布,执行同时压缩和数据降维4:PQ 的背后思想是将较大维度的向量空间分解为较小维度子空

间的笛卡尔乘积,通过将每个子空间量化为其自己的簇,向量被短码表示,从而可以从其码(称为复制值)有效地估计它们之间的距离。使用不对称的分桶过程(不像 SQ),它增加了精度5,因为它将每个子空间内向量的分布作为近似距离估计的一部分进行了考虑。然而,这会在很大程度上减小召回率6。

常见向量索引方法

在所有列出的索引方法中,大多数专用的向量数据库仅实现其中的一些。这是一个发展非常迅速的领域,所以当您阅读这篇文章时,这里的许多信息可能已经过时了。强烈建议您查阅您感兴趣的数据库的最新文档,以了解它们支持哪些索引。在这个部分,我将重点介绍一些受多个供应商关注的热门和新兴索引。

IVF-PQ

IVF-PQ 是在数据库如 Milvus 和 LanceDB 中提供的组合索引。索引的 IVF 部分用于缩小搜索空间,而 PQ 部分用于加速查询向量与数据库向量之间的距离计算,并通过量化向量来减少内存需求。将这两部分组合起来的一个很大的优点是,由于 PQ 组件的存在,速度大大提高了,而 IVF 组件通过补偿 PQ 组件本身的牺牲来提高召回率。

PQ 组件可以根据下面的图示进行分解。表示数据点的每个向量由固定数量的维度d(取决于上游使用的嵌入模型的数量,大约为数百或数千个)组成。由于在大型数据集上存储这么多32位或64位浮点数可能会非常昂贵,因此产品量化通过两个阶段来解决这个问题:第一个阶段是粗量化阶段,其中向量被分成m个子向量,每个子向量的维度为d/m,并且每个子向量被分配一个量化值(称为“复制值”),将原始向量映射到该子空间中点的质心7。

第二个阶段类似于k-means聚类,通过最小化原始向量与量化向量质心之间的距离来学习值的“码本”。通过将一个大的高维向量映射到较小的低维子向量中,只需存储量化值的码本,使内存占用量大大减小。

产品量化:图片灵感来自 Pinecone 博客

产品量化:图片灵感来自 Pinecone 博客

然后,在 PQ 向量空间中应用 IVF,对于空间中的每个点都有一个相应的区域,称为 Voronoi 单元,其中包含所有距离源点(种子)比距离其他任何点近的空间中的点。这些种子点用于创建一个倒排索引,将每个质心与空间中的向量列表相关联。

img

根据查询向量落在哪里,它可能靠近多个 Voronoi 单元的边界,使得不清楚从哪些单元返回最近邻,导致边界问题。因此,IVF-PQ 索引涉及设置额外的参数 n_probes,该参数告诉搜索算法要向外扩展到由 n_probes 参数指定的单元数量。

要有效地构建 IVF-PQ 索引,需要做出两个选择:PQ 步骤的子向量数量,以及 IVF 步骤的分区数量。子向量数量越大,每个子空间就越小,从而减少由于压缩引起的信息损失。然而,较大数量的子向量也会导致每个 PQ 步骤内的 I/O 和计算增加,因此必须将该数字最小化以保持计算成本低。

类似地,IVF 步骤的分区数量必须在召回率和查询速度之间取得平衡。将分区数限制为数据集中的向量数的情况是穷举搜索的限制情况,它是最准确的(召回率为1),但它实际上使其成为 IVF-Flat 索引。

事实上,LanceDB IVF-PQ 索引文档8描述了在创建索引时进行这些种类的权衡,因此值得深入研究这些概念,以了解如何在实际情况中应用它们。

HNSW

分层可导航小世界(Hierarchical Navigable Small-World,HNSW)图是构建向量索引的最流

行的方法之一,适用于大多数向量数据库。其核心思想是将数据点映射到一个由顶点和边组成的图上,该图被设计为在高维空间中具有“小世界”属性,即高度连通性,从而使得相似的向量更有可能在相对较少的步骤中被找到。

HNSW 由 Google 开发,具有可扩展性、高效性和准确性。在 HNSW 图中,每个数据点都表示为一个节点,其属性包括一个固定数量的近邻(k 个最近邻居),这些近邻被认为是该节点的“导航点”。图中的边表示节点之间的相似性,距离度量(例如余弦距离)通常用于确定相似性。

在构建 HNSW 图时,首先随机选择一个节点作为起始点,然后选择几个最近的节点作为其近邻。接下来,为每个新节点选择若干近邻,这些近邻在搜索过程中将被用作导航。在 HNSW 图中,节点之间的连接越多,搜索所需的步骤越少。

在搜索时,HNSW 图提供了一种方法来在图中导航,从而更快地找到相似的节点。搜索过程从起始点开始,然后根据节点之间的相似性选择下一个节点,直到达到与查询向量最相似的节点。这种搜索方法通过在搜索过程中逐渐减小搜索半径来保持高效性。

HNSW 索引的一个优点是其高效的搜索速度,特别是在高维度空间中。然而,为了达到更高的召回率,可能需要牺牲一些精度。HNSW 图的构建和调整需要一些经验和实验,以确保达到预期的性能和召回率。

NGT

近邻图(Neighborhood Graph and Trees,NGT)是一种将图和树结合起来的索引方法,由日本雅虎开发。NGT 的目标是在高维空间中实现高效的近似最近邻搜索。

NGT 使用了两个主要构造:一个是将稠密 kNN 图转换为双向图,另一个是构建可导航的小世界(Navigable Small World,NSW)图。这两种构造的目标是将图与树相结合,以在搜索过程中同时保持高效的导航和高质量的近似性能。

NGT 的特点之一是它支持多种距离度量,包括 L2、角度余弦和 Jaccard 等,使其适用于不同类型的数据。它还具有自适应搜索半径的能力,这在不同的数据分布和查询上非常有用。

选择合适的向量数据库

在讨论向量数据库时,索引只是一个更大的问题的一小部分。为了区分各种向量数据库的提供方式,我们需要理解以下组件之间的关系:

  • 应用层及其位置
  • 数据层以及与数据库和应用层的关系
  • 索引策略以及与内存和 CPU 使用的关系
  • 存储层设计
  • 在所有这些方面考虑的可扩展性和成本考虑因素

每个组件都涉及其自己的权衡。我已经将它们分成以下类别 - 我确信还有一些我错过的,但这是一个开始。🤓 话不多说,让我们深入探讨。

1. 自建 vs. 云托管

许多供应商强调他们的“云原生”功能,好像从可扩展性的角度来看,这是自切片面包以来最好的事情。然而,在从成本的角度决定哪种解决方案最适合的时候,重要的是首先考虑首次如何分解托管选项。嵌入式数据库架构现在也是选项之一!🎉

考虑以下组合:

  • 云原生(托管)+ 客户端-服务器
  • 自建(自托管)+ 嵌入式
  • 云原生(托管)+ 嵌入式

通过视觉方式比较这些组合更容易。

img

很明显,客户端-服务器架构是最常见的数据库架构,这是因为多年来各种其他数据库已经经过了大量的实战测试。嵌入式/无服务器托管模型在下面的描述中特别有趣,因为以下原因。

客户端-服务器 vs. 嵌入式架构

自从DuckDB通过MotherDuck1对其开源嵌入式SQL数据库进行了商业化,它已经成为其他新兴数据库供应商的灵感之源。在向量领域,有一个供应商在这方面表现出色:LanceDB2,一个相对较新的参与者 - 它采用了嵌入式、无服务器的设计,其开源版本从一开始就可以使用并且可以扩展。

lancedb.com

lancedb.com

另一个众所周知的方案是Chroma,它也提供了嵌入式选项,但它是纯内存且在单台机器上运行的,因此他们似乎更倾向于转向在云上托管的经过试验的客户端-服务器模型3。Zilliz4,将Milvus的无服务器版本封装起来,也为其在云上的免费版本提供了嵌入式数据库。然而,LanceDB是唯一一家默认构建为嵌入式的公司。

对于那些在本地和云存储中都拥有大量数据的组织来说,嵌入式/无服务器的向量数据库为开发人员在将数据层连接到应用层(用户与数据交互的地方)时提供了很多自由和灵活性,尤其是在涉及隐私和安全性的情况下。

尽管许多供应商提供完全托管的云托管解决方案,并在虚拟专用云(VPC)中部署了安全端点,但组织可能会不愿意将所有数据和向量计算迁移到云中。这对于拥有高度敏感数据且必须与不是云原生的遗留系统进行接口的大型组织尤其如此。在这些情况下,将嵌入式向量数据库(如LanceDB)轻松部署在本地,并与应用层轻松连接可能更容易。

成本考虑因素

提供云原生、托管解决方案的数据库通常根据存储的数据量和查询的数量收费。对于那些拥有大量数据但不想为传输和存储数据的基础设施付费的组织来说,这是一个很好的模式。然而,对于已经拥有大型内部数据基础设施团队,准备支持自建或嵌入式托管的组织来说,将数据发送到云中,无论是用于索引还是查询,几乎没有任何意义。

虽然很难定义一个组织规模的“临界点”,在这个临界点之后可以做出这种区分,但重要的是要知道

这种区分。例如,对于一个每天生成并存储TB级别数据的公司,将数据迁移到云中可能会导致显着的成本增加,而不是将数据留在自己的硬件上,只需按需购买新硬件。或者,对于需要将大量存储库查询和查询响应性能与大量持久性存储一起考虑的应用程序,将数据存储在本地并使用嵌入式向量数据库可能是更具成本效益的解决方案。

2. 向量数据库与应用层的交互方式

当涉及将数据从向量数据库传输到应用程序时,有几种基本方法可以选择。这些方法包括:

  • 直接连接数据库: 这种方法涉及从应用程序代码中直接连接到向量数据库。这种连接可能通过数据库的客户端库或驱动程序进行,应用程序代码会编写查询以检索或插入数据。

  • RESTful API: 向量数据库可以通过RESTful API公开数据。这允许应用程序通过HTTP请求与数据库进行通信,从而实现数据的检索和插入。

  • 消息队列/事件总线: 应用程序可以通过将请求和响应发布到消息队列或事件总线来与向量数据库通信。向量数据库和应用程序之间可以使用消息传递模式来进行通信,允许解耦和异步处理。

  • 中间件: 有些中间件层可以用作向量数据库和应用程序之间的接口。这些中间件可以处理与数据库的交互,从而减轻了应用程序的负担。

选择哪种交互方式取决于多个因素,包括应用程序的性质、数据的使用模式、安全性需求等。例如,直接连接数据库可能对于需要实时响应的应用程序更合适,而RESTful API可能更适用于需要与其他系统进行集成的场景。

3. 可扩展性和性能

在选择向量数据库解决方案时,考虑其可扩展性和性能至关重要。以下是一些相关的问题和注意事项:

  • 水平扩展: 能否轻松地将数据库扩展到处理更多的数据和请求?水平扩展是在需要更多资源时增加节点或服务器的能力。这通常比垂直扩展(为单个节点添加更多资源)更可取,因为它提供了更好的性能和容错性。

  • 负载均衡: 向量数据库是否支持自动负载均衡?负载均衡确保请求被分发到可用的资源上,从而提高了性能和可靠性。

  • 查询性能: 数据库的查询性能如何?查询性能涉及到数据的检索、过滤和计算等操作。一些数据库可能在特定类型的查询上表现更好,因此需要根据实际的查询需求进行评估。

  • 索引策略: 数据库是否支持多种索引策略?选择适合数据类型和查询模式的索引策略可以提高查询性能。

  • 持久性 vs. 内存: 一些向量数据库完全基于内存,而另一些可能将数据持久存储在磁盘上。内存数据库通常具有更快的查询性能,但磁盘存储可以处理更大量的数据。

  • 数据分区和副本: 数据库是否支持数据分区和副本?数据分区可以将数据划分为更小的块,从而实现更好的并行处理。数据副本可以提高数据的可用性和冗余性。

在评估性能时,可以进行基准测试来模拟真实的负载,并测量不同数据库解决方案的性能表现。

4. 安全性和隐私保护

安全性是任何数据库解决方案都必须考虑的重要因素之一,尤其是当处理敏感数据时。以下是一些与安全性和隐私保护相关的问题:

  • 数据加密: 数据库是否支持数据加密功能,包括数据在传输和存储过程中的加密?

  • 访问控制: 数据库是否提供细粒度的访问控制机制?这允许您定义谁可以访问数据库中的哪些数据。

  • 认证和授权: 数据库是否支持身份验证和授权机制,以确保只有经过授权的用户可以执行特定操作?

  • 数据审计: 是否可以跟踪和监控对数据库的访问和操作?数据审计可以帮助检测潜在的安全问题。

  • 隐私保护: 如果处理的数据涉及用户隐私,数据库解决方案是否具有符合隐私法规的功能,如GDPR?

确保数据库解决方案符合您组织的安全和隐私标准非常重要。

5. 社区支持和文档

考虑到数据库解决方案的长期维护和可用性,社区支持和文档变得至关重要。一个活跃的社区可以提供问题解答、新功能的建议和贡献等。此外,清晰、全面的文档可以帮助您更轻松地了解如何配置、使用和维护数据库。

在选择数据库解决方案时,查看其是否拥有活跃的社区论坛、GitHub存储库、文档站点以及是否有可靠的技术支持选项。

原始博客链接

https://thedataquarry.com/posts/vector-db-1
https://thedataquarry.com/posts/vector-db-2
https://thedataquarry.com/posts/vector-db-3
https://thedataquarry.com/posts/vector-db-4

 竞赛交流群 邀请函  #

△长按添加竞赛小助手

每天大模型、算法竞赛、干货资讯

与 36000+来自竞赛爱好者一起交流~

内容中包含的图片若涉及版权问题,请及时与我们联系删除