前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何让PostgreSQL的向量数据速度与Pinecone一样快

如何让PostgreSQL的向量数据速度与Pinecone一样快

作者头像
云云众生s
发布2024-06-12 09:42:10
870
发布2024-06-12 09:42:10
举报
文章被收录于专栏:云云众生s云云众生s

了解我们如何为 PostgreSQL 配备高级索引技术,使其与其他专门的向量数据库(如 Pinecone)一样快。

译自 How We Made PostgreSQL as Fast as Pinecone for Vector Data,作者 Matvey Arye。

我们最近宣布开源 pgvectorscale,这是一个新的 PostgreSQL 扩展,为向量数据提供了高级索引技术。Pgvectorscale 为 pgvector 数据提供了一种新的索引方法,显著提高了近似最近邻 (ANN) 查询的搜索性能。这些查询对于利用现代向量嵌入技术来促进,它允许查找与查询语义搜索类似的内容含义至关重要。反过来,这支持了诸如检索增强生成 (RAG)、摘要、聚类或通用搜索之类的应用程序。

在我们的公告文章中,我们描述了我们的新 StreamingDiskANN 向量索引如何让我们比为此目的创建的定制专用数据库(如 Pinecone)更快地执行向量搜索。我们还观察到,如果定制数据库不更快,那么就没有理由使用它们,因为它们不可能与 PostgreSQL 等通用数据库丰富的功能集和生态系统竞争。

在本文中,我们将深入探讨允许我们“突破速度障碍”并在 PostgreSQL 中创建快速向量索引的技术贡献。我们将介绍我们做出的三项技术改进:

实现 DiskANN 算法,允许将索引存储在 SSD 上,而不是必须驻留在内存中。由于 SSD 比 RAM 便宜得多,因此这极大地降低了存储大量向量的成本。支持流式后过滤,即使应用了辅助过滤器,也能进行准确的检索。相比之下,如果过滤器排除了前 ef_search 个向量,则 HNSW(分层可导航小世界)索引将无法准确检索数据。Pinecone 之前在将自己与 pgvector 进行比较时抱怨过这个问题。猜猜看;通过开源的力量,这个问题已经得到解决。开发一种全新的向量量化算法,我们称之为 SBQ(统计二进制量化)。与现有的 BQ(二进制量化)和 PQ(乘积量化)算法相比,该算法提供了更好的准确性与性能权衡。

增强 PostgreSQL 以处理向量数据

实现 DiskANN 算法以优化 SSD 存储

DiskANN 算法是由微软开发,它的目标是存储非常大量的向量(想想微软的规模)。在如此大的规模下,将所有内容存储在内存中在经济上是不可行的。因此,该算法旨在支持在 SSD 上存储向量并使用更少的 RAM。它的细节在论文中描述得很好,因此我下面只会提供一些直觉。

DiskANN 算法是一种基于图的搜索算法,如 HNSW。此领域的基于图的算法有一个众所周知的问题:查找与起始位置“非常远”的项目很昂贵,因为它需要大量跳跃。

HNSW 通过引入一个分层系统来解决这个问题,其中第一层(顶部)只有“远程”边,可以快速让你进入正确的邻近区域,并具有指向较低层节点的指针,允许你以更精细的方式遍历图。这解决了远程问题,但通过分层系统引入了更多间接,这需要更多随机访问,从而迫使图进入 RAM 以获得良好的性能。

相比之下,DiskANN 使用单层图,并通过允许引用远端节点的邻居边在图构建期间解决远程问题。单层结构简化了算法并减少了搜索期间必要的随机访问,从而可以有效地使用 SSD。

支持流式检索以进行准确的元数据过滤

通常,在搜索语义上相似的项目时,你希望使用其他过滤器来约束搜索。例如,文档通常与一组标签相关联,你可能希望通过要求标签匹配和向量相似性来约束搜索。

表示两阶段过滤的图表
表示两阶段过滤的图表

图 1:两阶段后过滤的问题在于,如果匹配记录未位于第一阶段截止之前,最终答案将不正确。

已更正的 Markdown 文本

对于许多基于 HNSW 的索引(包括 pgvector 的实现)来说,这是一个挑战,因为索引从索引中检索预设数量的记录(由 hnsw.ef_search 参数设置,通常设置为 1,000 或更少)应用辅助过滤器之前。如果检索到的集合中没有足够的项目(例如,前 1,000 个项目)与辅助过滤器匹配,则会错过这些结果。

图 1 说明了在使用 hnsw.ef_search=5 查找与给定查询最接近的两个向量并且匹配标签“department=engineering”时遇到的此问题。在此场景中,具有正确标签的第一个项目是与查询最接近的第七个向量。

由于向量搜索仅返回最接近的五个项目,并且没有一个与标签过滤器匹配,因此不会返回任何结果!这是一个没有留下任何结果的极端示例,但只要检索到的集合中匹配过滤器的项目少于 k 个项目,就会出现一些准确性损失。

表示流式过滤的图表
表示流式过滤的图表

图 2:流式过滤通过公开一个*get_next()*函数来产生正确的结果,该函数可以连续调用,直到找到正确数量的记录。

相比之下,我们的 StreamingDiskANN 索引没有“ef_search”类型截止。相反,如图 2 所示,它使用流式模型,允许索引连续检索给定查询的“下一个最接近”项目,甚至可能遍历整个图!Postgres 执行系统将不断请求“下一个壁橱”项目,直到它匹配满足附加过滤器的 LIMIT N 个项目。这是一种后过滤形式,绝对不会降低准确性。

顺便说一句,Pinecone 在其比较中对“ef_search”类型限制对 pgvector 进行了大肆宣传](https://www.pinecone.io/blog/pinecone-vs-pgvector/?ref=timescale.com)。但是,随着 StreamingDiskANN 的引入,此批评不再适用。这只是展示了开源项目快速减轻限制的能力。

统计二进制量化 (SBQ):一种新的量化算法

许多向量索引使用压缩来减少向量存储所需的空间,并以牺牲一些准确性为代价使索引遍历更快。常见的算法是乘积量化 (PQ) 和二进制量化 (BQ)。事实上,pgvector 的 HNSW 索引刚刚在其最新的 0.7.0 版本中添加了 BQ(欢呼!)。

大多数向量数据库检索 K 个结果的工作方式如下。系统首先使用近似量化差异检索 N 个结果(N>K),然后通过重新评分来“纠正”误差。它计算 N 个结果的完全距离,按完全距离对列表进行排序,并返回距离最小的 K 个项目。然而,即使重新评分,准确性也很重要,因为它允许您减小 N(从而更快地查询)并增加准确结果位于 N 个预取结果集合中的机会。

我们研究了 BQ 算法,并对其产生的准确性损失感到不满意。我们还立即看到了一些可以改进它的捷径。在调整算法时,我们开发了一种新的压缩算法,我们称之为统计二进制量化 (SBQ)。

BQ 压缩算法以一种非常简单的方式将浮点向量转换为二进制向量:对于向量中的每个元素,如果值大于 0.0,则将二进制值设为 1;否则,将二进制值设为 0。然后,距离函数简单地变为 XOR 函数。为什么是 XOR?好吧,你会发现许多数学解释(我们都不太喜欢),但我们使用的直觉是二进制向量将空间划分为象限,如图 3 所示,而 XOR 函数只是计算从一个象限到另一个象限需要穿过多少个平面。

表示 BQ 的图表
表示 BQ 的图表

图 3:三个维度的 BQ。象限 1 由二进制向量 1,1,1 表示,任何落入该象限的向量都将具有 0 的距离。与其他象限中的向量的距离随着不同维度的数量而增加。

让我们感到奇怪的一件事是每个维度的截止值始终为 0.0。这很奇怪,因为在分析真实的嵌入时,我们之前发现每个维度的平均值甚至不近似为 0.0。这意味着我们在 BQ 中定义的象限没有将点空间一分为二,从而错失了差异化的机会。

直觉上,您希望切割平面的“原点”位于所有动作的中间,但在 BQ 中,它偏离了中心。解决方案非常简单:我们使用学习通道来推导出每个维度的平均值,然后将浮点值截断设置为平均值,而不是 0.0。因此,当且仅当浮点值大于维度的平均值时,我们将元素的二进制值设置为 1。

但随后我们又注意到另一件奇怪的事情:压缩算法对 1,536 个维度比对 768 个维度效果更好。这几乎没有道理,因为文献强烈暗示维度更高的难题比维度更低的问题更难(所谓的“维度灾难”)。但在这里,情况恰恰相反。

然而,从象限类比的角度思考,这似乎有道理——在 768 个维度中,象限会更少,每个象限都会更大,因此差异性更小。所以我们问自己,我们能否用 768 个维度创建更多象限?

我们的方法是将每个浮点维度转换为两位(我们稍后进行了概括)。其想法是使用平均值和标准差来推导出 z 分数(一个值与平均值的距离,由标准差标准化),然后将 z 分数划分为三个区域。然后我们将三个区域编码为两位,以便相邻区域的 XOR 距离为 1,并且距离随着 z 分数距离而增加。在具有三个区域的两位情况下,编码为 00、01、11。

通过实验,我们发现两比特编码确实有助于提高 768 维情况下的准确性。因此,默认情况下,我们对维度少于约 900 的任何数据使用两比特编码,否则使用一位编码。在一个具有 768 个维度的数据集的代表性示例中,从一位编码切换到两比特编码时,召回率从 96.5% 提高到 98.6%,在如此高的召回率水平下,这是一个显著的改进。

总之,这些技术帮助我们实现了更好的准确性/性能权衡。

更出色的 PostgreSQL,适用于向量数据

我们在本文中介绍的三种技术使我们能够为 PostgreSQL 中的向量数据开发一流的索引,其性能可与 Pinecone 等定制数据库相媲美。我们通过利用 PostgreSQL 提供的大部分基础设施(包括缓存、WAL(预写式日志记录)和关联的恢复基础设施以及坚如磐石的磁盘写入系统)来实现这一点,而团队规模很小。

我们使用 Rust 编写了此内容,使用 框架来编写 PostgreSQL 的 Rust 扩展。这进一步加快了开发速度,因为我们可以依靠 Rust 和 PGRX 提供的一些安全保证,同时为代码的棘手部分(如磁盘 I/O)开发我们自己的安全包装器。我们认为,这种工具组合对于开发数据库功能和扩展 PostgreSQL 的覆盖范围非常有用且强大。PGRX

后续步骤

在过去的几个月里,我们的团队一直在不知疲倦地为 PostgreSQL 配备这些针对向量数据的新型高级索引技术。我们的目标是帮助 PostgreSQL 开发人员成为 AI 开发人员。但为此,我们需要您的反馈。

以下是如何参与:

  • 与您的朋友和同事分享新闻:在 X/Twitter 和 Threads 上分享我们宣布 pgai 和 pgvectorscale 的帖子。我们承诺会转发。LinkedIn
  • 提交问题和功能请求:我们鼓励您提交问题和功能请求,以获取您希望看到的、您发现的错误以及您认为可以改进这两个项目的功能。
  • 做出贡献:我们欢迎社区对 pgvectorscale 和 pgai 的贡献。Pgvectorscale 用 Rust 编写,而 pgai 使用 Python 和 PL/Python。特别是对于 pgai,请告诉我们您希望看到支持哪些模型,尤其是开源嵌入和生成模型。请参阅 pgai GitHub了解更多信息。
  • 在您的 PostgreSQL 云中提供 pgvectorscale 和 pgai 扩展:Pgvectorscale 和 pgai 是 Apache 2.0 许可证 下的开源项目。我们鼓励您在您的托管 PostgreSQL 数据库即服务平台上提供 pgvectorscale 和 pgai,我们甚至可以帮助您传播信息。通过我们的 联系我们表格 进一步讨论 pgai 和 pgvectorscale。
  • 立即使用 pgai 和 pgvectorscale:您可以在 pgai GitHubpgvectorscale GitHub 存储库中找到安装说明。您还可以在 Timescale 的云 PostgreSQL 平台上的任何数据库服务中访问 pgai 和 pgvectorscale。对于生产向量工作负载,我们提供对使用 Timescale 上的 pgvector 和 pgvectorscale 的向量优化数据库的私有测试版访问。在此注册以获得优先访问权限

相关文章:

  1. PostgreSQL 与 MySQL:如何选择以及何时选择
  2. 向量搜索如何影响客户购物习惯
  3. 如何获得正确的向量嵌入
  4. Milvus 2023:开源向量数据库年度回顾
  5. 增强文本搜索的SQL向量数据库
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-112,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 增强 PostgreSQL 以处理向量数据
    • 实现 DiskANN 算法以优化 SSD 存储
      • 支持流式检索以进行准确的元数据过滤
        • 已更正的 Markdown 文本
          • 统计二进制量化 (SBQ):一种新的量化算法
          • 更出色的 PostgreSQL,适用于向量数据
            • 后续步骤
              • 相关文章:
              相关产品与服务
              向量数据库
              腾讯云向量数据库(Tencent Cloud VectorDB)是一款全托管的自研企业级分布式数据库服务,专用于存储、检索、分析多维向量数据。该数据库支持多种索引类型和相似度计算方法,单索引支持千亿级向量规模,可支持百万级 QPS 及毫秒级查询延迟。腾讯云向量数据库不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、自然语言处理等 AI 领域。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档