Pinecone 是一个矢量数据库,使开发人员只需使用 API 即可轻松地向其应用程序添加矢量搜索功能。
介绍
复杂数据正以惊人的速度增长。这些是非结构化形式的数据,包括 Web 上的文档、图像、视频和纯文本。许多组织将从存储和分析复杂数据中受益,但对于考虑结构化数据构建的传统数据库来说,复杂数据可能很困难。仅使用关键字和元数据对复杂数据进行分类可能不足以完全表示其所有各种特征。
幸运的是,机器学习 (ML) 技术可以通过将复杂数据转换为矢量嵌入来提供更有用的表示。矢量嵌入将复杂的数据对象描述为数百或数千个不同维度的数值。
存在许多用于构建矢量的技术,从单词或句子的矢量表示到跨媒体文本、图像、音频和视频。有几个现有的公共模型是高性能且易于按原样使用的。这些模型可以针对特定应用程序进行微调,您也可以从头开始训练新模型,尽管这种情况不太常见。
矢量数据库专门用于处理矢量嵌入的独特结构。它们通过比较值并查找彼此最相似的值来索引矢量,以便于搜索和检索。然而,它们很难实施。
到目前为止,矢量数据库只保留给少数拥有开发和管理资源的科技巨头。除非正确校准,否则它们可能无法在不花费大量资金的情况下提供用户所需的性能。
使用结构良好的矢量数据库可为您的应用程序提供卓越的搜索功能,同时满足性能和成本目标。有几种解决方案可用于使其更易于实施。这些解决方案的范围从插件和开源项目到处理安全性、可用性和性能的完全托管服务。本文档将介绍矢量数据库的常见用法、核心组件以及如何入门。
什么是矢量数据库?
矢量数据库索引和存储矢量嵌入,以便快速检索和相似性搜索,具有 CRUD 操作、元数据过滤和水平缩放等功能。
矢量
在机器学习中,描述和表示对象各种特征的数值测量数组
数据库
专门为快速搜索和检索而组织的大量数据(如计算机)
当我们说矢量数据库索引矢量嵌入时,我们的意思是它们以一种我们可以将任何矢量相互比较或与搜索查询矢量进行比较的方式组织它们。我们将进一步介绍用于索引矢量的算法。矢量数据库还负责执行 CRUD 操作(创建、读取、更新和删除)和元数据过滤。传统数据库功能与在索引中搜索和比较矢量的能力相结合,使矢量数据库成为它们的强大工具。
矢量数据库擅长相似性搜索或“矢量搜索”。矢量搜索使用户能够描述他们想要查找的内容,而不必知道哪些关键字或元数据分类归因于存储的对象。矢量搜索还可以返回相似或近邻匹配的结果,从而提供更全面的结果列表,否则这些结果可能会保持隐藏状态。
为什么要使用矢量数据库?
生产中的矢量搜索是使用矢量数据库的最常见原因。矢量搜索将多个对象的相似性与搜索查询或主题项进行比较。为了查找相似的匹配项,您可以使用用于创建矢量嵌入的相同 ML 嵌入模型将主题项或查询转换为矢量。矢量数据库比较这些对象的相似性以找到最接近的匹配项,提供准确的结果,同时消除传统搜索技术可能返回的不相关结果。
让我们看一下矢量搜索的一些常见用例:
1. 语义搜索
搜索文本和文档通常可以通过两种方式完成。词法搜索查找模式和确切的单词或字符串匹配项,而语义搜索使用搜索查询或问题的含义并将其置于上下文中。矢量数据库存储和索引来自自然语言处理模型的矢量嵌入,以了解文本、句子和整个文档字符串的含义和上下文,从而获得更准确、更相关的搜索结果。
使用自然语言查询查找相关结果是一种更好的体验,允许用户更快地找到他们需要的内容,而无需了解有关数据分类方式的细节。
2. 图像、音频、视频、JSON 和其他形式的非结构化数据的相似性搜索
图像、音频、视频和其他非结构化数据集在传统数据库中进行分类和存储可能非常具有挑战性。这通常需要手动将关键字、说明和元数据应用于每个对象。一个人对其中一个复杂数据对象进行分类的方式对另一个人来说可能并不明显。因此,搜索复杂数据可能会非常成功。此方法要求搜索者了解数据的结构,并构造与原始数据模型匹配的查询。
请参阅示例代码:图像相似性搜索
3. 排名和推荐引擎
矢量数据库是支持排名和推荐引擎的绝佳解决方案。对于在线零售商,它们可用于建议类似于过去购买的商品或客户正在研究的当前商品。流媒体服务可以应用用户的歌曲评级来创建针对个人量身定制的完美匹配的推荐,而不是依赖于协作过滤或热门列表。
根据最接近的匹配项查找相似项目的能力使矢量数据库成为提供相关建议的理想选择,并且可以根据相似性分数轻松对项目进行排名。
请参阅示例代码:电影推荐器
4. 重复数据删除和记录匹配
矢量相似性搜索的另一个用例是记录匹配和重复数据删除。使用相似性服务查找近似重复的记录可用于广泛的应用程序。考虑一个从目录中删除重复项以使其更易于使用和相关的应用程序。
请参阅示例代码:文档重复数据删除
5. 异常检测
与矢量数据库在查找相似对象方面一样好,它们也可以找到与预期结果相距甚远或不同的对象。这些异常在用于威胁评估、欺诈检测和 IT 运营的应用程序中很有价值。可以识别最相关的异常以进行进一步分析,而不会因误报率高而占用大量资源。
请参阅示例代码:IT 威胁检测
矢量数据库所需的功能
1. 用于搜索和检索的矢量索引
矢量数据库使用专门设计的算法来有效地索引和检索矢量。不同的用例需要优先考虑准确性、延迟或内存使用量,可以使用不同的算法进行微调。选择和优化这些算法本身就是一门科学,为满足用例要求的不同数据集找到最佳算法可能具有挑战性。
除了索引,还有相似性和距离指标。这些指标用于衡量矢量嵌入之间的相关性/相似性。某些指标比其他指标具有更好的召回率和精度性能。矢量索引中的常见指标包括欧氏距离、余弦相似性和点积。
矢量数据库使用“最近邻”索引来评估对象彼此之间或与搜索查询之间的相似程度。传统的最近邻搜索对于大型索引来说是有问题的,因为它们需要在搜索查询和每个索引矢量之间进行比较。比较每个矢量需要时间。
近似最近邻 (ANN) 搜索通过近似和检索大多数相似矢量的最佳猜测来规避此问题。虽然ANN不能保证返回完全相同的最接近匹配,但它平衡了非常好的精度和非常快的性能。
HNSW、IVF或PQ等技术是构建有效ANN指数中最常用的一些组件。每种技术都侧重于改进特定的性能属性,例如使用 PQ 减少内存或使用 HNSW 和 IVF 快速但准确的搜索时间。通常的做法是混合多个组件以生成“复合”索引,以实现给定用例的最佳性能。
如果没有矢量数据库,设计和构建有效的索引并不容易。如果使用像Faiss这样的独立框架,索引的设计和部署需要一支经验丰富的工程师团队,他们很好地掌握了索引和检索算法。至少,这些矢量必须使用另一个存储和检索管道映射回原始数据(因为独立索引不支持此功能)。索引需要定期重新训练和跟踪已删除、替换或新数据的机制。团队必须考虑这些增加的要求和任何正在进行的操作。
2. 单级滤波
过滤允许您根据矢量元数据限制搜索结果。这可以通过基于限制条件返回可用匹配项的子集来提高搜索结果的相关性。
后筛选首先应用近似最近邻搜索,然后将结果限制为元数据筛选器限制。ANN 通常返回一组请求的最接近匹配项,但不知道其中有多少(如果有)将与元数据条件匹配。这通常很快,但可能会返回与过滤器匹配的矢量太少(如果有的话)。
使用元数据预过滤矢量会缩小数据集,并可能返回高度相关的结果。但是,由于预筛选首先对索引中的每个矢量应用匹配条件,因此也会严重降低矢量数据库的性能。
单阶段滤波是有效的矢量数据库的必要条件。它将预过滤的准确性和相关性与后过滤一样快或更快的速度相结合。通过将矢量和元数据索引合并到单个索引中,单阶段筛选提供了两种方法的最佳选择。
3. 数据分片
什么是没有缩放的矢量数据库?ANN算法以极高的效率搜索矢量。但无论其效率如何,硬件都限制了单台机器上的可能性。您可以垂直扩展 — 增加单台机器的容量并并行化 ANN 例程的各个方面。但是你会达到一个极限,你可以走多远,无论是成本还是庞然大物机器的可用性。输入水平缩放。我们可以将矢量划分为分片和副本,以便在许多商品级机器上进行扩展,以实现可扩展且具有成本效益的性能。
想象一下,一个朋友用100张小纸条装满了一个桶。假设她在每张纸条上写下某人的名字以及他们的生日、月份和日期以及实际出生时间。然后她要求:“找到出生日期和时间最接近你的人”。因此,您筛选存储桶以找到最接近的匹配项。这样,纸条就像矢量,你就像一个CPU,桶就像RAM。
现在假设你的朋友给了你一个桶,里面有 1000 个名字和生日——你要搜索一段时间!相反,您将 1000 个名字分成 10 个存储桶,并邀请 10 个朋友提供帮助。你们每个人只搜索 100 个名称以查找存储桶中的最佳匹配项,然后比较每个人找到的结果以找到最佳匹配项。因此,您在 1000 个名称中找到最佳匹配项所需的时间几乎与在 100 个名称中找到最佳匹配项所花费的时间相同。你已经水平扩展了自己!
矢量数据库将矢量平均划分为多个分片,搜索每个分片,并在最后组合所有分片的结果以确定最佳匹配。通常,它会使用 Kubernetes 并授予每个分片自己的 Kubernetes pod,至少有一个 CPU 和一些 RAM。Pod 并行工作以搜索矢量。
因此,只需一个 pod 搜索一个分片所需的时间,您就可以得到答案。有 20M 个矢量?使用 20 个 pod 并在一个 pod 搜索 1M 矢量所需的时间内获得结果,或使用 40 个 pod(每个分片 500K 个矢量)更快地获得结果。它还有更多功能,但简而言之,每个 Pod 的矢量更少,查询延迟更低,并允许您在合理的时间内搜索多达数十亿个矢量。
4. 复制
矢量数据库需要优雅地处理许多请求。分片允许它并行使用许多 pod 来更快地执行矢量搜索。但是,如果您需要同时或快速连续执行许多不同的矢量搜索,该怎么办?如果新请求足够快,即使是快速的矢量搜索也会得到备份。输入副本。
顾名思义,副本复制整组 Pod 以并行处理更多请求。如果我们回想一下我们的桶中名称类比,这就像创建十个桶的副本,并要求另外十个朋友处理任何新的匹配请求。假设 10 个 pod 可以在 100 毫秒内搜索 20M 个矢量。如果你每秒发出一个请求,你就很好。如果每秒发出 <> 个不同的请求,则需要备份。添加一个副本(在本例中还有十个 Pod)以满足需求。
副本还可以提高可用性。机器会失败——这是生活中的事实。矢量数据库需要在发生故障后尽快恢复 Pod。但“尽可能快”并不总是足够快。理想情况下,它需要立即处理故障,而不会错过任何一个节拍。云提供商提供所谓的可用性区域,这些区域极不可能同时失败。
矢量数据库可以将副本分散到不同的可用区,以确保高可用性。但是,您(用户)也可以在这里发挥作用 — 您需要拥有多个副本和副本容量,以便在发生故障时,更少的副本能够以可接受的延迟处理查询负载。
5. 混合存储
矢量搜索通常完全在内存 (RAM) 中运行。对于目录中有超过十亿个项目的公司来说,仅内存成本就可能使矢量搜索过于昂贵而无法考虑。一些矢量搜索库可以选择将所有内容存储在磁盘上,但这可能会以搜索延迟变得高得令人无法接受为代价。
在混合存储配置中,压缩的矢量索引存储在内存中,原始的全分辨率矢量索引存储在磁盘上。内存中索引用于查找一小组要在磁盘上的完整索引中进行搜索的候选项。此方法可提供快速准确的搜索结果,同时将基础架构成本降低多达 10 倍。
混合存储允许您在相同的数据占用空间中存储更多矢量,通过提高整体存储容量来降低矢量数据库的运营成本,而不会对数据库性能产生负面影响。
6. 原料药
矢量数据库应该将构建和维护矢量搜索功能的负担从开发人员身上移开,这样他们就可以专注于使他们的应用程序达到最佳状态。API 使开发人员可以轻松地从任何其他应用程序使用或管理矢量数据库。
应用程序对矢量数据库进行 API 调用以执行操作,例如将矢量更新到数据库中、检索查询结果或删除矢量。
REST API 通过从任何可以进行 HTTPS 调用的环境启动矢量数据库的功能来增加灵活性。开发人员也可以使用 Python、Java 和 Go 等语言通过客户端直接访问它。