Muvera-Py:运用 FDE 实现快速多向量检索

July 11, 2025

搜索革新:Muvera-Py助力高效多向量检索

在不断发展的信息检索领域,像基于ColBERT模型的现代搜索系统会利用数百个向量来表示单个文档。尽管这种方法显著提高了准确性,但往往会带来巨大的计算开销和缓慢的搜索时间。MUVERA(通过固定维度编码进行多向量检索)应运而生,这是谷歌开发的一种突破性算法,旨在解决这一挑战。

今天,我们很高兴地推出Muvera-Py,这是MUVERA的一个新的开源Python实现。Muvera-Py的开发旨在提高可访问性,并完全忠实于原始高度优化的C++实现,有望成为处理大规模向量搜索的开发人员和研究人员的游戏规则改变者。

什么是固定维度编码(FDE)?

FDE的核心是解决如何高效搜索数十亿文档的基本问题,而每个文档不是由一个向量,而是由数百个向量表示。传统的搜索系统每个文档使用一个向量,速度快但常缺乏多向量模型细致入微的准确性。另一方面,多向量搜索虽然准确,但速度却出了名的慢。

FDE提供了一个优雅的解决方案,它将这些多个向量转换为一个单一的、固定大小的向量,同时显著地保留了关键的相似性关系。其奥妙在于它能够通过FDE向量之间的简单点积来近似多向量集之间的原始Chamfer相似性。

Muvera-Py:弥合鸿沟

Muvera-Py使这种强大的算法能够在Python生态系统中得以应用。Muvera-Py中的每个函数和参数都经过精心映射到其C++对应项,确保了相同的行为和可靠的性能。这意味着您可以在Python项目中利用谷歌强大的研究成果,而无需牺牲准确性或效率。

主要特性和实现细节:

  • 完全忠实度:复制了原始C++实现的行为,使其成为生产环境中的可靠工具。
  • Pythonic设计:利用Python的dataclasses进行配置,并使用NumPy进行高效的矩阵运算,提供了一个清晰直观的API。
  • 可配置编码:支持不同的编码类型(例如,查询的DEFAULT_SUM,文档的AVERAGE)和投影类型(例如,DEFAULT_IDENTITYAMS_SKETCH),适用于灵活的用例。
  • 内部助手:使用Pythonic最佳实践实现了关键的内部函数,如格雷码转换和随机矩阵生成器(_simhash_matrix_from_seed_ams_projection_matrix_from_seed)。
  • 核心算法_generate_fde_internal()函数封装了空间划分、向量聚合和最终投影的复杂逻辑。
  • 公共API:提供了简单易用的函数,如generate_query_fde()generate_document_fde(),以便于集成。

FDE的工作原理:分步概览

该算法通过一系列智能步骤来压缩多向量表示:

  1. 空间划分:对于每个“重复”操作(使用不同随机种子进行独立运行),应用SimHash来划分向量空间。这利用随机高斯矩阵将向量投影到特定的桶中。
  2. 向量聚合:在每个分区内,向量被聚合。对于查询,向量求和;对于文档,它们求平均。
  3. 重复和连接:步骤1和2会使用不同的随机种子重复多次。然后将每次重复的结果连接起来,形成最终的单个FDE向量。

这个过程确保了原始高维空间中距离相近的向量很可能最终进入相同的分区,并对FDE向量的相同部分做出贡献。这种“局部敏感性”使得FDE的简单点积能够近似复杂的Chamfer相似性。

性能优势

FDE最引人注目的特性之一是其性能概况:

  • 高效生成:FDE生成时间与向量数量、维度、重复次数和SimHash投影呈线性关系(O(n × d × r × k))。
  • 超快搜索:一旦FDE生成完毕,使用标准最大内积搜索(MIPS)库的搜索时间实际上为O(1),使实时检索具有可扩展性。
  • 内存效率:将数百个向量压缩为单个向量的能力显著减少了索引的内存需求。

Muvera-Py入门

将Muvera-Py集成到您的项目中非常简单。这是一个基本示例:

import numpy as np
from fde_generator import FixedDimensionalEncodingConfig, generate_query_fde, generate_document_fde

# 1. 创建配置
config = FixedDimensionalEncodingConfig(
    dimension=128, # 原始向量维度
    num_repetitions=10, # 独立划分次数
    num_simhash_projections=6, # 创建 2^6 = 64 个分区
    seed=42
)

# 2. 准备模拟数据(例如,ColBERT风格的嵌入)
query_vectors = np.random.randn(32, 128).astype(np.float32) # 包含32个向量的查询
doc_vectors = np.random.randn(80, 128).astype(np.float32)   # 包含80个向量的文档

# 3. 生成 FDEs
query_fde = generate_query_fde(query_vectors, config)
doc_fde = generate_document_fde(doc_vectors, config)

# 4. 计算相似度(近似 Chamfer 相似度)
similarity_score = np.dot(query_fde, doc_fde)
print(f"相似度: {similarity_score}")

Muvera-Py代表着在使先进、可扩展的信息检索技术更易于访问方面迈出了重要一步。通过让开发人员能够高效处理复杂的多向量嵌入,它为各个领域更快、更准确的搜索应用程序铺平了道路。

有关更多详细信息、贡献以及探索代码库,请访问Muvera-Py GitHub 仓库

原创文章: 查看原文

分享本文