【原理分析】向量数据库的索引

向量嵌入是从图像、文本和音频等数据源转换而来的数字表示,旨在通过为每个项目创建一个数学向量来捕捉其语义或特征。这种表示方式使得计算系统更容易理解这些数据,并且与机器学习模型兼容,从而能够识别不同项之间的关系和相似性。

通常,用于存储这些向量嵌入的专门数据库被称为向量数据库。这些数据库利用了嵌入的数学特性,即能够将相似的项聚集在一起存储。向量数据库采用不同的向量索引技术,可以将相似的向量放置在一起,而将不相似的向量分开存储, 并且提高向量检索的效率。

1. 什么是向量索引?

向量索引是一种以向量作为键的索引机制。它是原始向量数据的浓缩形式,旨在提供高效且快速的搜索能力。与直接处理原始嵌入相比,向量索引的紧凑性显著降低了内存需求,并提升了数据可访问性。作为一种核心的数据结构,向量索引能够有效地管理高维向量数据,便于执行快速相似性搜索和最近邻查询。

向量索引采用了先进的算法来有序地组织高维向量,以便进行高效的搜索。这种排列并非随机,而是通过将相似的向量聚集在一起来实现的。这样,向量索引就能支持快速而精确的相似性搜索和模式识别,尤其适用于大型和复杂的数据集。

假设每个图像都对应一个向量,该向量捕捉了图像的特征。向量索引能够有效地组织这些向量,使得寻找相似图像变得简单快捷。你可以将其想象成一个系统,其中每个人的图像都被单独整理和存储。因此,如果你需要找到某个特定事件中某个人物的照片,你无需浏览所有照片,只需查看该人物的图像集,就能轻松定位到所需的照片。

向量索引与传统索引的区别如下表所示:

特性 向量索引 传统索引
数据类型 多维向量(嵌入) 标量(数字、字符串、日期等)
目的 相似度搜索,近邻检索 基于精准匹配的快速过滤和检索
搜索类型 近似性匹配,查找相关性条目 精准匹配,按值检索
结构 特别是树和图 B树系列,哈希表,倒排索引
用例 多媒体搜索,推荐系统,NLP任务 数据库查询、文本搜索过滤

aa

2. 常用的向量索引技术

平面索引(FLAT)是一种直接且简洁的索引策略,它按原样存储每个向量,不进行任何修改。这种策略非常适合在需要100%召回率的情况下搜索相对较小(百万级)的数据集。一个基于FAISS的向量索引示例如下:


import faiss
import numpy as np
# Example of Generating a dataset of random vectors (documents)
dimension = 768
num_vectors = 10000
vectors = np.random.random((num_vectors, dimension)).astype('float32')
# Create an index using L2 or Euclidean distance
index = faiss.IndexFlatL2(dimension)
# Add vectors to the index
index.add(vectors)
# Perform a search for the nearest neighbors of a query vector
query_vector = np.random.random((1, dimension)).astype('float32')
k = 5
distances, indices = index.search(query_vector, k)
# Output the indices and distances of the nearest neighbors
print("Nearest Neighbors:", indices)
print("Distances:", distances)

平面索引具有简单、易于实现的特点,并且能够提供完美的准确性。然而,其不足之处在于速度较慢。在平面索引中,需要计算查询向量与索引中其他向量之间的相似度,然后返回具有最小相似性得分的K个向量。

当完美的精度是必要条件且速度不是主要考虑因素时,平面索引是一个合适的选择。此外,如果我们正在处理的数据集较小,平面索引也可能是一个不错的选择,因为在这种情况下,搜索速度仍然是可接受的。

2.1 基于哈希的索引——LSH

局部敏感哈希(LSH)是一种索引策略,它通过利用向量的相似性来快速找到一个近似最近邻,而不是进行穷举搜索来找到实际的最近邻。在平面索引中,这种方法避免了在整个空间中计算相似度度量,从而显著减少了搜索量并提高了查询速度。

LSH索引是使用散列函数生成的,其中相邻的向量嵌入被散列到同一个桶中。这样,所有相似的向量都可以存储在一个表或桶中。当提供一个查询向量时,通过对查询向量进行散列,可以找到与其散列值相同的向量集合。然后,只需计算这个集合中所有向量的相似度量,而不需要在整个数据集上进行计算。

与平面索引相比,LSH索引的主要优势在于它能够显著减少搜索空间,从而提高查询效率。然而,需要注意的是,由于LSH是基于散列的技术,它可能会引入一些误差,即返回的可能是近似最近邻而不是精确最近邻。因此,在选择使用LSH索引时,需要根据应用场景权衡精度和效率的需求。

2.2 基于量化/聚类的索引——文件倒排索引(IVF)

IVF是最基本的量化索引技术之一。它使用类似于K-means算法的技术将整个数据集分成几个组。数据库中的每个向量都被分配到一个特定的集群中。这种结构化的向量排列允许用户更快地进行搜索查询。当一个新的查询到来时,系统不会遍历整个数据集,而是首先标识出最接近或最相似的集群,然后在这些集群中进行搜索以找到特定的文档。

因此,通过仅在相关的群组中应用暴力搜索法,而不是在整个数据库中进行搜索,不仅提高了搜索速度,而且显著减少了查询时间。

根据应用程序的具体需求,IVF存在不同的变体。

IVFFLAT

IVFFLAT 是一种更简单的IVF。IVF_FLAT 将向量数据划分为若干个聚类单元(nlist) ,然后比较目标输入向量与每个聚类中心之间的距离。根据系统被设置为查询的集群数量(n 探测) ,最近邻搜索结果将根据目标输入与最相似集群中的向量之间的比较返回ーー这大大减少了查询时间。但是,在每个集群中,它使用一个FLAT索引来存储向量。IVFFLAT 旨在优化搜索速度和准确性之间的平衡。

在每个集群中,向量存储在一个简单的列表或数组中,没有额外的细分或层次结构。当一个查询向量被分配给一个集群时,最近的邻居通过执行一个暴力搜索法,检查集群列表中的每个向量并计算它到查询向量的距离来找到。IVFFLAT 用于数据集不太大的场景,其目标是在搜索过程中实现高精度。

IVFPQ

IVFPQ(Inverted File Vector Product Quantization)是IVF的一个高级变体,代表通过乘积量化实现的倒排文件索引。它同样将数据分割成簇,但在每个簇中,向量被进一步分解为更小的向量片段,每个部分通过乘积量化编码或压缩成有限的比特数。

对于查询向量,一旦识别出相关的聚类,该算法将查询的量化表示与聚类中向量的量化表示进行比较。这种比较比原始向量的比较更快,因为通过量化降低了维度和大小。相比以前的方法,这种方法具有两个显著优点:

  • 存储紧凑:向量以紧凑的方式存储,占用的空间比原始向量更少。
  • 查询快速:查询过程更加高效,因为它不比较所有原始向量,而是比较编码后的向量。

IVFSQ

IVFSQ,像其他IVF变体一样,也将数据分割成集群。然而,其主要区别在于其量化技术。在IVFSQ中,集群中的每个向量都通过标量量化传递。这意味着向量的每个维度都是单独处理的。

 

简单地说,对于向量的每个维度,我们都设置一个预定义的值或范围。这些值或范围有助于确定向量属于哪个集群。然后,我们将向量的每个分量与这些预定义值进行匹配,以找到它在集群中的位置。这种分解和量化每个维度的方法使得过程更加简单。它对于低维数据特别有用,因为它简化了编码并减少了存储所需的空间。

2.3 基于树的索引 ——MSTG

IVF 将向量数据集划分为多个簇,但这一方法的一个主要局限在于它导致了大量数据集索引大小的显著增长,因为需要存储众多的代表性集群向量。这种内存消耗限制了 IVF 的可扩展性。

为了克服这一问题,MyScale 开发了多阶段树图(MSTG)。与 IVF 仅使用一层集群向量不同,MSTG 采用了多层设计,从而减少了需要长期存储的质心数量。例如,如果一个数据集在 IVF 中需要 10,000 个集群向量,那么所有这 10,000 个向量都必须被存储,这将占用大量内存。而在 MSTG 中,通过使用每层包含 100 个簇的两层结构,只需存储 200 个向量——即 100 个顶层向量及其对应的 100 个子向量。

MSTG 结合了树算法和基于图的算法的优势。它将向量嵌入组织成一个层次结构,允许通过递归遍历树进行高效的搜索。近似最近邻搜索算法,如近似最近邻树(ANNOY)和优势位置树(VP 树),通常用于这类树型索引。这种方法不仅构建速度快,搜索效率高,而且在不同的过滤搜索比率下都能保持快速和准确,同时具有资源和成本效益。

2.4 基于图的索引—— HNSW

HNSW 是一种高效存取数据的复杂方法。其图形结构的灵感来自两种不同的技术: 概率跳表(skip list)和 NSW。

概率跳表是一种高级的数据结构,它结合了两种传统结构的优点: 链表的快速插入能力和数组的快速检索特性。它通过其多层架构来实现这一点,其中数据跨多层组织,每一层包含数据点的子集。从包含所有数据点的底层开始,每个后续层都会跳过一些点,因此数据点较少,最终最顶层的数据点最少。要在跳过列表中搜索数据点,我们从最高层开始,从左到右搜索每个数据点。在任何时候,如果查询的值大于当前数据点,我们将返回到下一层中的前一个数据点,从左到右继续搜索,直到找到确切的点。

NSW 类似于近似图,其中节点根据彼此之间的相似程度连接在一起。利用贪婪方法搜索最近邻点。我们总是从一个预定义的入口点开始,它连接到多个附近的节点。我们确定这些节点中哪些最接近我们的查询向量,然后移动到那里。这个过程迭代,直到没有比当前向量更接近查询向量的节点为止,作为算法的停止条件。

HNSW 的工作原理

HNSW 创建了类似概率跳表的层。但是对于数据点之间的连接,它在节点之间建立了一个图形化的连接。每一层的节点不仅连接到当前层的节点,而且连接到下层的节点。当我们向下到较低的层时,顶部的节点非常少,强度增加。最后一层包含数据库的所有数据点。下图是 HNSW 的结构示意。

算法从最顶层的预定义节点开始。然后计算当前层的连接节点和下面层的连接节点之间的距离。如果到该层中的一个节点的距离小于到当前层中的节点的距离,则该算法移动到较低的层。这个过程一直持续到达最后一层,或者到达与所有其他连接节点距离最小的节点。最后一层,0层,包含所有数据点,提供了数据集的全面和详细的表示。这一层对于确保搜索包含所有潜在的最近邻居是至关重要的。

就像 IVFFLAT 和 IVFSQ 一样,一个存储原始向量,另一个存储量化范围,同样的过程也适用于 HNSWFLAT 和 HNSWSQ。在 HNSWFLAT,原始向量按原样存储,而在 HNSWSQ,向量以量子形式存储。除了数据存储的这个关键差异外,HNSWFLAT 和 HNSWSQ 的索引和搜索的整体过程和方法是相同的。

HNSW 的应用场景

具体来说,以下是 HNSW 索引最有意义的场景:

  • 高维数据:HNSW 特别适合处理数百到数千维的高维数据。
  • 快速最近邻搜索:HNSW 能够迅速找到与给定查询点最相似的数据点,适用于推荐系统、基于内容的图像检索和自然语言处理等任务。
  • 近似最近邻搜索:虽然 HNSW 主要用于精确的最近邻搜索,但它也支持近似搜索,以减少计算成本。
  • 大规模数据集:HNSW 的设计使其能够扩展到大规模的数据集,满足大数据应用的需求。
  • 实时和动态数据:HNSW 能够适应实时更新的数据,适合需要处理动态变化数据的应用场景。
  • 高资源环境:HNSW 的性能不仅限于单台机器的内存限制,适合在分布式和并行计算环境中使用。

综上所述, 具有代表性的向量索引技术对比如下:

特性 FLAT HNSW IVFPQ
检索速度 非常高
索引构建速度 非常高
存储空间
数据库大小
精度 非常高
维数 非常高
内存占用
查询体量

3. 向量索引的选择

选择恰当的索引对于确保相似性检索的效率和准确性至关重要。向量索引的选择取决于多个因素,包括数据集的大小、嵌入的维数、搜索结果的期望精度以及可用的计算资源。这一决策不仅影响系统的性能,还直接关系到用户体验和数据驱动应用程序的操作效率。

3.1 搜索频率裁剪索引选择

在选择合适的索引类型时,搜索操作的频率是一个关键因素。对于执行搜索次数较少的应用程序,基于计算密集型的平面索引提供了一种简单而有效的解决方案。这种方法特别适合处理超出可用内存容量的数据集,因为它允许顺序地构建和搜索较小的索引部分。

3.2 使用平面索引实现精确搜索结果

当对准确性有严格要求,不能有任何妥协时,平面索引如 LlamaIndex 中的 IndexFlatL2 或 IndexFlatIP 通过避免向量压缩来确保精确的结果。这种索引类型也得到了 GPU 的支持,为评估其他索引性能提供了一个基准。

3.3 平衡内存使用和搜索精度

随着数据集的增长,有效地管理内存变得至关重要。因此,索引的选择应当反映对记忆约束的仔细考虑,以及所期望的准确性和速度之间的折衷:

  • 内存丰富: 对于内存不是限制因素的情况,HNSW 或 IVF 变体由于其速度和准确性而代表最佳选择。
  • 内存受限: 对于内存受限的情况,聚类技术后面跟一个“平面”索引提供了一个可行的中间地带,在优化内存使用的同时保持准确性。
  • 严格的内存限制: 量化方法的优点在于显著地压缩数据,促进在有限的内存空间中存储大型数据集,代价是损失一些精度。

3.4 数据集大小在聚类策略中的作用

数据集的大小对聚类方法的选择有显著影响,而不同的聚类方法又会反过来影响索引策略的制定。以下是针对不同规模数据集的推荐策略:

  • 小型数据集(低于1M个向量):对于这种规模的数据集,一个简单的IVF聚类通常足够使用。可以根据数据集的具体大小来调整聚类的粒度,以获得最佳的性能和精度平衡。

  • 中等规模数据集(1M至10M个向量):在这个数据量级上,将IVF与HNSW聚类相结合是一个有效的策略。这种方法可以在保持较高精度的同时,合理分配计算资源,达到效率和性能之间的良好平衡。

  • 大型数据集(10M至100M个向量):处理这样大规模的数据集时,需要采用更高级的聚类策略,如两级聚类。这种方法能够在不显著增加计算开销的前提下,维持系统的高性能。

  • 极大数据集(100M至1B个向量):在这个巨大的数据规模下,优化训练过程和实施多层聚类方法变得至关重要。这有助于有效地管理庞大的计算和内存需求,确保系统的稳定性和可扩展性。

3.5 利用外部洞见加强决策

选择最近邻搜索指数是一项多方面的挑战,从广泛的角度来看,这项挑战将带来巨大好处。利用外部资源可以加深对索引选择细微差别的理解,能够提供更多的见解。值得注意的参考文献包括:

  • “最近邻搜索: 度量空间方法”由 Zezula 等人编写,提供了关于度量空间中的最近邻搜索和索引原理的基础知识。
  • Facebook 的 FAISS 库为最近邻搜索提供了一套全面的优化算法,包括索引类型和使用场景的详细文档。
  • Malkov 和 Yashunin 的“有效近似最近邻搜索与接近图”深入讨论了 HNSW 算法,为其在大规模数据集中的应用提供了有价值的背景。

4. 小结

向量数据库彻底改变了数据的存储方式,不仅提升了存储速度,而且在人工智能和大数据分析等多个领域展现了巨大的实用性。在数据以指数级增长的时代,特别是在非结构化形式的数据中,向量数据库的应用潜力几乎是无限的。向量索引技术进一步提升了这些数据库的功能和效率。

5