LEANN 的重算式向量索引

LEANN 的重算式向量索引

💡 原文中文,约2900字,阅读约需7分钟。
📝

内容提要

LEANN是一种重算式向量索引,不存储向量,仅存剪枝图,搜索时实时计算向量,将索引从201GB降至6GB,节省97%存储。它通过跨进程通信、图剪枝和两级搜索优化性能,适合个人数据索引,但需GPU支持,延迟在RAG场景下可比,传统索引装得下时无需使用。

🔎

延伸解读

存储瓶颈的根源

文章指出,传统向量索引的存储开销主要来自高维嵌入向量本身,而非原始文本。以768维float32向量为例,每条占3KB,六千万条即180GB。这意味着索引大小与文本实际字数关系不大,而是由向量维度和条数决定。LEANN通过不存储向量、实时计算,将索引压缩至原始数据的约5%,但需注意其对比数据未说明嵌入模型、维度及硬件环境,实际效果可能因配置而异。

跨进程通信的权衡

LEANN的检索流程中,图遍历的每一跳都需通过ZeroMQ跨进程通信,将节点ID发送至Python侧计算嵌入后再返回。这种设计看似低效,但通过批量处理邻居节点、两级搜索和剪枝优化,减少了计算次数和通信开销。然而,这也意味着每次检索都依赖嵌入服务的可用性,冷启动延迟较高,且对GPU性能有要求。在RAG场景下延迟可比,但若用于在线低延迟检索,可能不占优势。

适用场景与限制

LEANN适合个人设备上索引邮件、聊天记录等大规模数据,因为传统索引可能无法容纳。但若索引不大、无GPU或对延迟敏感,则不建议使用。项目提供recompute_embeddings参数,关闭后即退回传统存储模式,但此时不如直接使用其他索引。此外,真正的算法实现位于faiss和DiskANN的分叉中,主仓库仅为Python编排层,阅读源码需拉取子模块。

Q&A

LEANN是什么?它如何解决向量索引存储过大的问题?

LEANN是一种重算式向量索引,它不存储向量,只存储剪枝后的图结构,在搜索时实时计算向量。这样可以将索引大小从201GB降至6GB,节省97%的存储空间。

LEANN的索引大小能减少多少?与传统索引相比如何?

根据论文,LEANN的索引最多可缩小到原来的五十分之一,约占原始数据的5%。在六千万条维基文本上,传统索引需要201GB,而LEANN仅需6GB,节省97%;在二百一十万条DPR数据上,从3.8GB降至324MB,节省91%;在七十八万封邮件上,从2.4GB降至79MB,节省97%;在三万八千条浏览记录上,从130MB降至6.4MB,节省95%。

LEANN的检索流程是怎样的?为什么需要跨进程通信?

LEANN的检索流程是:先对查询进行嵌入,然后进入图遍历。在遍历过程中,当需要计算与邻居的距离时,会将节点ID通过ZeroMQ发送给Python后端,Python端根据ID获取原文,批量计算嵌入向量,再返回给C++端。这个跨进程通信是必要的,因为向量是实时计算的,需要调用嵌入模型。

LEANN的图剪枝策略是什么?为什么需要剪枝?

LEANN采用高度数保留剪枝策略,保留高度数的枢纽节点,砍掉冗余连接。这是因为近邻图中少数节点承担了大部分连通性,删除它们的边会导致搜索路径变长甚至中断,而低度数节点之间的边可以省略。剪枝后使用压缩稀疏行格式存储,避免邻接表占用过多空间。

LEANN支持哪些后端?它们有什么区别?

LEANN默认支持HNSW和DiskANN两种后端。HNSW后端完全重算向量,索引中不存储向量,存储节省最狠;DiskANN后端使用乘积量化过的向量进行图遍历,再实时重排,速度和精度的折中更好,但索引中保留了一份压缩的粗向量。

LEANN的安装和使用方法是什么?

安装使用LEANN只需三条命令:`uv pip install leann`,`leann build my-docs --docs ./documents`,`leann search my-docs "查询内容"`,以及`leann ask my-docs --interactive`。它支持多种数据源,如文件系统、Apple Mail、浏览器历史、微信、iMessage等,还提供MCP服务。

LEANN的延迟表现如何?在什么场景下适用?

LEANN的延迟在RAG应用下与传统的可比,但不是更快,因为RAG本身需要等待大模型生成,检索多花的几十毫秒被掩盖。对于延迟敏感的在线检索场景,结论不一定成立。LEANN适合个人数据索引,如邮件、聊天记录、浏览历史等,当传统索引装不下时使用;如果索引不大、没有GPU或对延迟要求高,则不适合。

🏷️

标签

➡️

继续阅读