跳至主要内容
前往文档
⌘U
Weaviate 数据库

使用 Weaviate 的 APIs 和工具开发 AI 应用

部署

部署、配置和维护 Weaviate 数据库

Weaviate Agents

使用 Weaviate 构建和部署智能代理

Weaviate Cloud

在云端管理和扩展 Weaviate

更多资源

集成
贡献者指南
活动 & 工作坊
Weaviate Academy

需要帮助?

Weaviate Logo询问 AI 助手⌘K
社区论坛

向量索引

什么是向量索引?它是向量数据库的关键组成部分,有助于显著提高相似性搜索过程的速度,同时仅需在搜索准确性上做出微小的权衡(HNSW 索引),或者高效地以较小的内存占用存储大量数据子集(扁平索引)。动态索引甚至可以从扁平索引开始,然后在超过阈值后动态切换到 HNSW 索引。

Weaviate 的向量优先存储系统负责使用向量索引处理所有存储操作。以向量优先的方式存储数据不仅允许进行语义或基于上下文的搜索,而且还可以存储非常大量的数据而不会降低性能(假设水平扩展良好或为索引提供足够的碎片)。

Weaviate 支持以下向量索引类型

  • 扁平索引:一种简单、轻量级的索引,专为小型数据集设计。
  • HNSW 索引:一种更复杂的索引,构建速度较慢,但可以很好地扩展到大型数据集,因为查询具有对数时间复杂度。
  • 动态索引:允许您随着对象数量的增加,自动从扁平索引切换到 HNSW 索引

本页解释了什么是向量索引以及它们在 Weaviate 向量数据库中起到的作用。

什么是向量索引?

在向量数据库中,向量索引是一种组织向量嵌入的数据结构,用于实现高效的相似性搜索。正确索引向量数据库对于性能至关重要,不同的索引类型服务于不同的目的——从简单的扁平索引到更复杂的方法,如 HNSW。

为什么需要向量索引?

向量嵌入是表示含义的一种很好的方式。了解如何索引向量对于有效地使用向量数据库至关重要。向量嵌入是能够捕获来自不同数据类型(如文本、图像、视频和其他内容)的含义的元素数组。元素的数量称为维度。高维向量捕获更多信息,但处理起来更困难。

向量数据库使处理高维向量变得更容易。考虑搜索;向量数据库有效地衡量数据对象之间的语义相似性。当您运行相似性搜索时,像 Weaviate 这样的向量数据库使用查询的向量化版本来查找数据库中与查询向量相似的向量的对象。

向量就像多维空间中的坐标。一个非常简单的向量可能代表对象,单词在本例中,在一个二维空间中。

在下面的图中,单词AppleBanana显示彼此靠近。NewspaperMagazine也彼此靠近,但它们与同一向量空间中的AppleBanana相距甚远。

在每个对中,单词之间的距离很小,因为对象具有相似的向量嵌入。对之间的距离更大,因为向量之间的差异更大。直观地说,水果彼此相似,但水果与阅读材料不相似。

有关此表示的更多详细信息,请参阅:(GloVe)和向量嵌入

2D Vector embedding visualization

另一种思考方式是产品在超市中的摆放方式。您期望将Apples放在Bananas附近,因为它们都是水果。但是,当您搜索Magazine时,您会远离ApplesBananas,而是朝向带有例如Newspapers的通道。这就是语义概念如何在 Weaviate 中存储,具体取决于您用于计算向量中数字的模块。不仅可以索引单词或文本作为向量,还可以索引图像、视频、DNA 序列等。请阅读更多关于使用哪个模型的信息此处

Supermarket map visualization as analogy for vector indexing

提示

您可能还对我们的博客文章向量搜索解释感兴趣。

让我们探索如何使用 Weaviate 支持的不同方法索引向量。

向量索引类型

存在许多不同类型的向量索引。大多数都是设计用来通过减少需要比较的向量数量来加速搜索。但是,它们以不同的方式做到这一点,并且每种方法都有其自身的优点和缺点。

图索引

图索引形成一个向量网络,使得相似的向量彼此连接。这允许快速“遍历”图以找到与查询向量相似的向量。

HNSW,或“分层可导航小世界”,是最常见的图索引类型。它创建一组“层”的向量,以实现对图的快速遍历。

它们具有良好的可扩展性,允许增量更新,并且对于高维向量是有效的。

这是 Weaviate 中的默认索引类型。

基于树的索引

基于树的索引将向量划分为树状结构。

ANNOY,或“近似最近邻哦耶”,是一种著名的基于树的索引。它将向量划分为二叉树结构。

它们可以节省内存,并且适合低维向量。但是,随着时间的推移更新索引可能代价高昂,因为可能需要重建树。

基于聚类的索引

基于聚类的索引根据向量的相似性对向量进行分组。因此,搜索空间被减少到最有可能包含最近邻的聚类。

它们的搜索准确性(召回率和精度)通常可能低于基于图的索引,但它们可以更节省内存。

扁平索引

扁平索引是最简单的索引类型。它将所有向量存储在一个列表中,并搜索所有向量以找到最近的邻居。

这非常节省内存,但不能很好地扩展,因为搜索时间与向量的数量线性增长。

第一种方法是 HNSW 索引。

分层可导航小世界 (HNSW) 索引

分层可导航小世界 (HNSW) 是一种适用于多层图的算法。它也是一种索引类型,指的是使用 HNSW 算法创建的向量索引。HNSW 索引能够实现非常快的查询,但当您添加新向量时,重建索引可能会消耗大量资源。

Weaviate 的hnsw索引是自定义实现的分层可导航小世界 (HNSW) 算法,提供完整的CRUD 支持

在构建时,HNSW 算法创建一系列层。在查询时,HNSW 算法使用这些层来快速有效地构建近似最近邻 (ANN) 列表。

考虑使用 HNSW 的向量索引的此图。

HNSW explained

单个对象可以存在于多个层中,但数据库中的每个对象都表示在最低层(图片中的零层)。零层数据对象彼此很好地连接。高于最低层的每一层都有更少的对象,以及更少的连接。较高层中的对象对应于较低层中的对象,但每一层中的对象都比其下方的层少。HNSW 算法利用这些层来有效地处理大量数据。

HNSW search

当收到搜索查询时,HNSW 算法会在最高层找到最匹配的数据点。然后,HNSW 会深入一层,并在该层找到与更高层中的数据点最接近的数据点。这些是最近邻。该算法搜索较低层以创建新的最近邻列表。然后,HNSW 使用新的列表并在下一层重复此过程。当到达最深层时,HNSW 算法会返回与搜索查询最接近的数据对象。

由于较高层上的数据对象相对较少,HNSW 需要搜索的对象也较少。这意味着 HNSW “跳过” 了大量不需要搜索的数据。当数据存储只有一层时,搜索算法无法跳过无关对象。即使它们不太可能匹配,它也必须搜索大量数据对象。

资源需求

HNSW 是一种内存索引,图中的每个节点以及节点之间的每个边都存储在内存中。

这意味着索引在内存中的大小与索引中的向量数量以及向量之间的连接数量直接成正比。

HNSW 索引的大小主要由向量数量决定;请参阅下表以获取示例

组件大小推导典型大小@1M 向量时的尺寸@100M 向量时的尺寸
节点4B (float) x N 维度2-12kB2-12GB200-1200GB
10B x 20 个连接200B200MB20GB

如您所见,HNSW 索引的内存需求会迅速成为瓶颈。 这就是可以使用量化来减小内存中索引大小的原因。

HNSW 是一种快速、内存高效的相似性搜索方法。 内存缓存仅存储最高层,而不是存储最低层中的所有数据对象。 当搜索从较高层移动到较低层时,HNSW 仅添加与搜索查询最接近的数据对象。这意味着 HNSW 使用的内存与其他搜索算法相比相对较少。

再次查看该图;它演示了 HNSW 算法如何搜索。 顶层中的搜索向量连接到第一层中的部分结果。 第一层中的对象引导 HNSW 到第零层的结果集。 这允许 HNSW 跳过与搜索查询无关的对象。

将向量插入 HNSW 索引的方式类似。 HNSW 算法在最高层找到最接近的数据对象,然后向下移动到下一层。 它继续进行,直到找到插入新向量的最佳位置。 然后,HNSW 算法将新向量连接到该层中的现有向量。

HNSW insertion

管理搜索质量与速度的权衡

可以调整 HNSW 参数以调整搜索质量与速度之间的关系。

HNSW parameters

ef 参数是平衡搜索速度和质量之间权衡的关键设置。

ef 参数决定了 HNSW 算法在搜索过程中使用的动态列表的大小。 较高的 ef 值会导致更广泛的搜索,从而提高准确性,但可能会降低查询速度。

相反,较低的 ef 会使搜索更快,但可能会牺牲准确性。 在速度或准确性优先的情况下,这种平衡至关重要。 例如,在需要快速响应的应用中,即使牺牲一些准确性,较低的 ef 也可能更可取。 相反,在分析或研究环境中,如果精度至关重要,则即使查询时间增加,较高的 ef 也更合适。

ef 可以显式配置或动态配置。 此功能在具有不同查询模式的环境中特别有用。 当 ef 动态配置时,Weaviate 会根据实时查询需求优化速度和召回率之间的平衡。

要启用动态 ef,请将 ef 设置为 -1。 Weaviate 会根据查询响应限制调整 ANN 列表的大小。 计算还会考虑 dynamicEfMindynamicEfMaxdynamicEfFactor 的值。

动态 ef

ef 参数控制查询时 ANN 列表的大小。 您可以配置特定的列表大小,也可以让 Weaviate 动态配置列表。 如果您选择动态 ef,Weaviate 将提供几个选项来控制 ANN 列表的大小。

列表的长度由您在查询中设置的查询响应限制决定。 Weaviate 使用限制作为锚点,并根据您为 dynamicEf 参数设置的值修改 ANN 列表的大小。

  • dynamicEfMin 设置列表长度的下限。
  • dynamicEfMax 设置列表长度的上限。
  • dynamicEfFactor 设置列表的范围。

动态列表大小将设置为查询限制乘以 dynamicEfFactor,并由 dynamicEfMin 的最小值和 dynamicEfMax 的最大值进行修改。

在代码中,这可以表示为

ef = min(max(dynamicEfMin, queryLimit * dynamicEfFactor), dynamicEfMax)

为了保持较高的搜索召回率,实际的动态 ef 值即使查询限制足够小以建议较低的值,仍保持在 dynamicEfMin 以上。

为了即使在检索大型结果集时也能保持合理的搜索速度,动态 ef 值限制为 dynamicEfMax。 即使查询限制足够大以建议更高的值,Weaviate 也不会超过 dynamicEfMax。 如果查询限制高于 dynamicEfMax,则 dynamicEfMax 不起作用。 在这种情况下,动态 ef 值等于查询限制。

为了确定 ANN 列表的长度,Weaviate 将查询限制乘以 dynamicEfFactor。 列表范围由 dynamicEfMindynamicEfMax 修改。

考虑此 GraphQL 查询,该查询设置了限制为 4。

{
Get {
JeopardyQuestion(limit: 4) {
answer
question
}
}
}

假设集合配置了动态 ef

  "vectorIndexConfig": {
"ef": -1,
"dynamicEfMin": 5
"dynamicEfMax": 25
"dynamicEfFactor": 10
}

生成的搜索列表具有以下特征。

  • 潜在长度为 40 个对象 ( ("dynamicEfFactor": 10) * (limit: 4) )。
  • 最小长度为 5 个对象 ("dynamicEfMin": 5)。
  • 最大长度为 25 个对象 ("dynamicEfMax": 25)。
  • 实际大小为 5 到 25 个对象。

如果您使用 docker-compose.yml 文件来自 Weaviate 来运行您的本地实例,则 QUERY_DEFAULTS_LIMIT 环境变量设置了一个合理的默认查询限制。 为了防止内存不足错误,QUERY_DEFAULTS_LIMIT 明显低于 QUERY_MAXIMUM_RESULTS

要更改默认限制,请在配置 Weaviate 实例时编辑 QUERY_DEFAULTS_LIMIT 的值。

删除

清理是一个异步过程,在删除和更新后重建 HNSW 图。 在清理之前,对象被标记为已删除,但它们仍然连接到 HNSW 图。 在清理期间,边被重新分配,对象被永久删除。

异步索引

此功能与向量索引相关,特别是仅与 HNSW 索引相关。

可以通过选择加入以下方式启用异步索引

  • 开源用户可以通过将 ASYNC_INDEXING 环境变量设置为 true 来执行此操作。
  • Weaviate Cloud 用户可以通过在 Weaviate Cloud Console 中切换 Enable async indexing 开关来执行此操作。

使用同步索引时,向量索引与对象存储同步更新。 更新 HNSW 索引可能是一项代价高昂的操作,尤其是随着索引大小的增长。 因此,索引操作可能成为系统中的瓶颈,从而减慢用户请求完成的时间。

当启用异步索引时,所有向量索引操作都通过队列进行。 这适用于不仅批量导入,还适用于单个对象导入、删除和更新。

这意味着对象存储可以快速更新以完成用户请求,而向量索引在后台更新。 异步索引对于导入大量数据特别有用。

这意味着对象创建和对象可用于使用 HNSW 索引进行向量搜索之间将存在短暂的延迟。 可以如这里所示在每个节点上监视队列中的对象数量。

v1.28 中的更改

在 Weaviate v1.22v1.27 中,异步索引功能仅影响批量导入操作,使用内存队列。


v1.28 开始,异步索引功能已扩展到包括单个对象导入、删除和更新。 此外,内存队列已被替换为持久的、基于磁盘的队列。 这种更改允许对索引操作进行更强大的处理,并通过减少锁定争用和内存使用来提高性能。


使用基于磁盘的队列可能会导致磁盘使用量略有增加,但预计这将是总磁盘使用量的很小百分比。

平面索引

v1.23 中添加

平面索引是数据库中实现向量索引的基本方法之一。 顾名思义,它是一种简单、轻量级的索引,构建速度快,内存占用量小。 对于每个最终用户(即租户)拥有自己隔离数据集的使用场景,例如 SaaS 产品或隔离记录集数据库,此索引类型是一个不错的选择。

顾名思义,平面索引是磁盘支持的数据对象的单层,因此内存占用量很小。 平面索引是小型集合的不错选择,例如用于多租户使用场景。

平面索引的一个缺点是它无法很好地扩展到大型集合,因为它具有与数据对象数量成线性关系的时间复杂度,而 hnsw 索引具有对数时间复杂度。

动态索引

实验特性

v1.25 版本开始可用。这是一个实验性功能。请谨慎使用。

动态索引需要 ASYNC_INDEXING

动态索引需要异步索引。要在自托管的 Weaviate 实例中启用异步索引,请将 ASYNC_INDEXING 环境变量 设置为 true。如果您的实例托管在 Weaviate Cloud 中,请使用 Weaviate Cloud 控制台启用异步索引。

扁平索引非常适合用于对象数量较少的用例,并提供较低的内存开销和良好的延迟。随着对象数量的增加,HNSW 索引提供了一种更可行的解决方案,因为 HNSW 可以加速搜索。动态索引的目标是在扩展时以更大的内存占用为代价缩短查询时的延迟。

通过配置动态索引,您可以自动从扁平索引切换到 HNSW 索引。当对象数量超过预先指定的阈值(默认值为 10,000)时,将发生此切换。此功能仅适用于启用异步索引的情况下。当在导入时达到阈值时,所有数据都会堆积在异步队列中,HNSW 索引会在后台构建,并在准备就绪时完成从扁平索引到 HNSW 索引的切换。

目前,这仅是从扁平索引到 HNSW 索引的单向升级,即使由于删除导致对象数量低于阈值,也不支持切换回扁平索引。

这在多租户设置中特别有用,其中为每个租户构建 HNSW 索引会引入额外的开销。使用动态索引,随着单个租户的增长,其索引将从扁平索引切换到 HNSW 索引,而较小租户的索引将保持扁平索引。

向量缓存注意事项

为了获得最佳的搜索和导入性能,先前导入的向量需要位于内存中。磁盘查找向量比内存查找慢几个数量级,因此应谨慎使用磁盘缓存。但是,Weaviate 可以限制内存中的向量数量。默认情况下,创建新集合时此限制设置为一万亿(1e12)个对象。

在导入期间,将 vectorCacheMaxObjects 设置为足够高,以便所有向量都可以保存在内存中。每次导入都需要多次搜索。当内存不足以容纳缓存中的所有向量时,导入性能会大幅下降。

导入后,当您的工作负载主要为查询时,尝试使用小于总数据集大小的向量缓存限制。

当前不在缓存中的向量如果仍有空间,将被添加到缓存中。如果缓存已满,Weaviate 会删除整个缓存。所有未来的向量必须第一次从磁盘读取。然后,后续查询将针对缓存运行,直到它再次填满,并且该过程重复。请注意,如果您拥有大型数据集,并且很大一部分用户仅查询特定子集向量,则缓存可能是一个非常有价值的工具。在这种情况下,您可以从缓存为最大的用户组提供服务,同时为“不规则”查询需要磁盘查找。

向量索引常见问题解答

我可以在向量量化中使用向量索引吗?

是的,您可以在 向量量化(压缩) 中了解更多信息。

哪种向量索引适合我?

一个简单的启发式方法是,对于 SaaS 产品等用例,其中每个最终用户(即租户)都有自己的隔离数据集,flat 索引是一个不错的选择。对于具有大型集合的用例,hnsw 索引可能是一个更好的选择。

在选择索引类型时,请将以下内容作为指导

  • 扁平索引:用于大小已知的较小集合。
  • HNSW 索引:用于大小已知的较大集合。
  • 动态索引:用于大小未知或可能随时间增长的集合。

请注意,向量索引类型参数仅指定数据对象的向量如何索引。索引用于数据检索和相似性搜索。

vectorizer 参数确定如何创建数据向量(向量包含哪些数字)。vectorizer 指定一个 模块,例如 text2vec-contextionary,Weaviate 用于创建向量。 (您也可以将 vectorizer 设置为 none,如果您想导入自己的向量)。

要了解有关配置集合的更多信息,请参阅 此操作指南页面

我可以使用哪些距离度量与向量索引一起使用?

所有 距离度量,例如余弦相似度,都可以与任何向量索引类型一起使用。

如何在 Weaviate 中配置向量索引类型?

可以通过 集合定义 设置来为每个数据集合指定索引类型,具体取决于可用的 向量索引设置

何时跳过索引

在某些情况下,对集合进行向量化没有意义。例如,如果集合仅由两个其他集合之间的引用组成,或者如果集合包含大部分重复元素。

将重复向量导入 HNSW 非常昂贵。导入算法会提前检查候选向量的距离是否大于最差候选向量的距离。当存在大量重复向量时,此提前退出条件永远无法满足,因此每次导入或查询都会导致详尽的搜索。

要避免索引集合,请将 "skip" 设置为 "true"。默认情况下,集合已编制索引。

有哪些 ANN 算法?

有不同的 ANN 算法,您可以在 此网站 上找到对它们的很好的概述。

是否有 Weaviate 的 ANN 性能的指示性基准测试?

ANN 基准测试页面 包含各种向量搜索用例和相对基准测试。此页面是查找与您的数据集相似的数据集并了解最优化设置的理想选择。

更多资源

问题和反馈

如果您有任何问题或反馈,请在 用户论坛 中告诉我们。