LEANN:基于选择性重计算的本地向量检索,实现97%存储压缩

发布时间:2026/5/15 21:16:08

LEANN:基于选择性重计算的本地向量检索,实现97%存储压缩 1. 项目概述LEANN一个重新定义本地向量检索的开源项目如果你和我一样对当前AI应用生态里动辄需要将个人数据上传到云端、依赖昂贵且臃肿的向量数据库感到厌倦那么LEANN的出现绝对会让你眼前一亮。这不仅仅是一个工具更像是一个宣言个人AI的算力和数据主权应该回归到用户自己的设备上。LEANN的核心目标极其清晰——它要成为“世界上最小的向量索引”。这听起来像是一个营销口号但当你看到它的数据时会意识到这是一个技术事实。它通过一种名为“基于图的选择性重计算”和“高保真度剪枝”的技术实现了在保持与传统向量数据库相同搜索精度的前提下将存储占用减少高达97%。这意味着什么意味着你可以将包含6000万个文本块的庞大数据集塞进一个仅有6GB的索引文件中而传统的方案比如直接存储所有嵌入向量可能需要超过200GB。这个数字对比足以让任何关心数据隐私和本地化部署的开发者心跳加速。我最初接触LEANN是因为一个非常实际的需求我想在自己的笔记本电脑上构建一个能够语义搜索我过去几年所有工作文档、邮件、甚至浏览器历史记录的“第二大脑”。但无论是Faiss、ChromaDB还是其他本地向量库要么索引文件巨大迁移困难要么内存占用惊人让我的MacBook Pro风扇狂转。LEANN的承诺——将个人数据全部留在本地无需任何云端成本同时保持极致的轻量——完美地击中了我的痛点。这个项目由yichuan-w发起并维护它不仅仅是一个库更是一个完整的生态系统。它内置了对多种个人数据源的原生支持从PDF文档、Apple Mail邮件到Chrome浏览器历史、微信聊天记录再到ChatGPT和Claude的对话导出甚至可以通过MCP协议接入Slack、Twitter等实时数据流。你可以把它理解为一个“万能胶水”将你散落在各处的数字碎片粘合成一个可被智能检索的统一知识库。最吸引我的是它的理念你的数据只属于你的硬盘。没有OpenAI的API调用没有云服务商的条款没有数据被用于模型训练的风险。这种“离线优先”的隐私设计在当今数据泄露频发的时代显得尤为珍贵。2. 核心架构与工作原理为什么它能如此“瘦身”要理解LEANN为何能实现如此惊人的存储压缩我们需要深入其技术内核。传统向量数据库如基于Faiss的方案的工作模式是“预计算-存储-检索”在构建索引时为每一个文本块chunk计算一个高维向量嵌入并将所有这些向量持久化存储。检索时直接在这些存储的向量中进行近邻搜索。这种方法的瓶颈显而易见存储成本与数据量线性增长海量数据意味着巨大的磁盘空间和内存占用。LEANN则采用了一种截然不同的“按需计算”范式。它的核心创新在于一个高度优化的图结构索引结合了选择性重计算和智能剪枝策略。让我来拆解一下这个过程2.1 图索引不只是存储向量更是存储关系LEANN底层使用HNSWHierarchical Navigable Small World或DiskANN作为其索引后端。与单纯存储向量不同图索引的核心是存储节点代表数据点和边代表相似性关系。当你向LEANN添加一段文本时它并不会立即计算并永久存储其嵌入向量。相反它只是将这个文本“注册”到图中成为一个待计算的节点。这个图结构非常高效。通过使用压缩稀疏行格式存储邻接关系以及应用“高保真度剪枝”算法LEANN能够在构建阶段就剔除图中大量冗余的、对搜索精度贡献微弱的边从而极大地压缩了图本身的存储开销。你可以把它想象成一张精心绘制的地铁线路图我们只保留了连接主要枢纽的干线而省略了所有次要的、迂回的小径但这张精简后的地图依然能高效地指引你到达任何目的地。2.2 选择性重计算真正的“魔法”所在这是LEANN节省97%存储的关键。当进行搜索查询时LEANN收到一个查询语句。此时它才会调用嵌入模型为这个查询实时计算一个查询向量。接下来搜索算法在这个精简的图上启动。算法从若干入口点开始沿着图的边进行“游走”。在游走到每一个候选节点时LEANN并不会去读取一个预先存储好的向量因为根本没有存储取而代之的是它按需地、即时地为该节点对应的原始文本计算嵌入向量。计算完成后立即与查询向量进行相似度比较以决定下一步的游走方向。这个过程听起来计算量很大但LEANN通过两个策略使其变得可行局部性原理由于图结构保证了相似的数据点彼此靠近搜索算法在绝大多数情况下只需要访问图中很小一部分节点即与查询最相关的那部分而非全部节点。因此需要重计算的向量数量远小于数据总量。缓存与复用在一次查询中如果一个节点的向量被计算过它会被短暂缓存。在后续相似的查询中或者在图构建的后期优化阶段这些缓存可以被复用避免重复计算。简单来说传统方案是“计算所有存储所有检索时直接读取”。LEANN是“存储关系图检索时按需计算最关键的那几个”。对于个人数据场景查询是稀疏的、随机的这种按需模式将存储负担转移为可控的计算开销而现代CPU/GPU完全能够轻松应对这种即时计算。2.3 工作流程全景图让我们结合一个具体的文档处理场景看看LEANN的完整工作流数据摄入与分块你指向一个包含PDF、TXT、MD文件的文件夹。LEANN会使用LlamaIndex等工具库将这些文档按设定的块大小和重叠度进行智能分块生成一个个文本片段。图索引构建对于每一个文本块LEANN并不计算嵌入而是将其作为节点加入图。系统会根据节点间的近似关系初期可能基于轻量级特征或小模型建立边并执行剪枝优化最终生成一个.leann索引文件。这个文件主要包含文本内容、图结构邻接列表、以及必要的元数据。嵌入向量不在其中。查询与检索你提出一个问题如“LEANN用了哪些核心技术”。LEANN用相同的嵌入模型将问题转化为查询向量。随后它在.leann索引文件加载的图上执行近似最近邻搜索。搜索路径上的节点文本被动态计算嵌入并与查询比对最终返回最相关的几个文本块。生成回答可选检索到的文本块被组合成上下文发送给配置好的本地LLM如通过Ollama运行的Llama 3.2 1B由LLM生成一个连贯的答案。整个过程中你的原始文档和生成的索引始终在你的机器上。嵌入模型和LLM也可以是本地运行的。实现了一个真正的、端到端的隐私保护RAG流水线。实操心得理解“重计算”的代价与收益很多人的第一反应是动态计算会不会很慢在我的实测中使用text-embedding-3-small这类轻量模型在CPU上对于返回Top-20的查询延迟通常在几百毫秒到一两秒之间对于个人使用完全可接受。它的收益是巨大的一个10GB的文档集传统索引可能超过50GB而LEANN索引可能只有1GB。这意味着你可以轻松地将整个知识库放在U盘里随身携带或者同步到云端备份成本极低。这是一种典型的“以时间换空间”策略但在个人计算场景下空间存储往往是更稀缺的资源。3. 从零开始环境配置与实战安装指南理论很美好现在让我们动手把它装到你的电脑上。LEANN推荐使用uv这个现代的Python包管理器和安装器它能很好地处理依赖隔离和构建。3.1 基础环境搭建首先你需要安装uv。如果你的系统没有一条命令就能搞定# 安装 uv curl -LsSf https://astral.sh/uv/install.sh | sh安装完成后重启你的终端或者运行source ~/.bashrc或source ~/.zshrc来让uv命令生效。接下来获取LEANN的代码。我建议直接克隆仓库因为里面包含了所有精彩的示例应用git clone https://github.com/yichuan-w/LEANN.git leann cd leann现在创建一个干净的Python虚拟环境并安装LEANN包。使用PyPI安装是最快的方式# 创建虚拟环境 uv venv # 激活虚拟环境Linux/macOS source .venv/bin/activate # 对于Windows PowerShell用户使用.venv\Scripts\Activate.ps1 # 安装LEANN核心包 uv pip install leann至此核心安装就完成了。你可以运行python -c “import leann; print(leann.__version__)”来验证是否成功。3.2 处理平台特定的构建依赖如果你想从源码构建或者运行需要diskann后端一种针对磁盘优化的ANN库的示例则需要安装一些系统依赖。这部分稍微复杂但按照指南操作一般没问题。对于macOS用户brew install libomp boost protobuf zeromq pkgconf uv sync --extra diskann注意DiskANN要求macOS 13.3或更高版本。对于Ubuntu/Debian用户sudo apt-get update sudo apt-get install -y \ libomp-dev libboost-all-dev protobuf-compiler libzmq3-dev \ pkg-config libabsl-dev libaio-dev libprotobuf-dev \ libmkl-full-dev uv sync --extra diskann这里安装libmkl-full-dev是为了给DiskANN提供Intel MKL数学库加速。如果你的机器是纯CPU且不想装MKL也可以使用OpenBLASlibopenblas-dev但需要在后续构建时调整参数。对于Windows用户Windows上的构建最为复杂需要Visual Studio构建工具和vcpkg。除非你有强烈的需求或开发目的否则我强烈建议Windows用户直接使用PyPI预编译包或者通过WSL2运行Linux环境来获得最佳体验。3.3 模型配置隐私链条的最后一环LEANN的强大在于其离线能力而这离不开本地运行的嵌入模型和LLM。项目提供了极其灵活的配置。1. 嵌入模型配置LEANN支持多种嵌入模型后端。对于完全离线的场景我推荐使用sentence-transformers本地模型。# 在代码中指定或在命令行使用 --embedding-mode 参数 --embedding-mode sentence-transformers --embedding-model all-MiniLM-L6-v2 # 一个非常轻量且效果不错的模型all-MiniLM-L6-v2模型只有80MB左右在CPU上运行速度很快是入门首选。如果你有GPU可以尝试更大的模型如BAAI/bge-small-en-v1.5。2. LLM配置用于问答生成这是实现完全离线RAG的关键。Ollama是管理本地LLM的最佳工具。# 安装并启动OllamaLinux/macOS curl -fsSL https://ollama.ai/install.sh | sh ollama serve # 拉取一个适合你硬件的小模型 ollama pull llama3.2:1b # 1B参数消费级硬件友好 ollama pull qwen2.5:1.5b # 或Qwen2.5 1.5B中文能力更强然后在运行LEANN的应用时指定LLM后端为Ollama--llm ollama --llm-model llama3.2:1b3. 备用方案兼容OpenAI的本地API如果你已经使用了LM Studio、text-generation-webui等工具在本地运行了大模型它们通常提供了兼容OpenAI的API端点。你可以这样配置LEANN使用它们export OPENAI_BASE_URLhttp://localhost:1234/v1 # LM Studio的默认端口 export OPENAI_API_KEYlm-studio # API密钥可任意填写但必须设置 # 运行LEANN应用时 --llm openai --llm-model local-model # 这里填写你在LM Studio中加载的模型名称这种方式让你可以灵活地切换不同的本地模型而无需修改LEANN的代码。避坑指南GPU内存分配如果你有多个GPU或者想精确控制哪个模型用哪个GPU可以使用环境变量export LEANN_EMBEDDING_DEVICEcuda:0 # 嵌入模型使用第一块GPU export LEANN_LLM_DEVICEcuda:1 # LLM使用第二块GPU对于苹果芯片Mac用户将设备设置为“mps”可以启用Metal Performance Shaders加速。4. 实战演练打造你的个人数字记忆库安装配置完毕让我们进入最激动人心的环节用LEANN处理你的真实数据。我将以几个最实用的场景为例带你走通全流程。4.1 场景一个人文档库的语义搜索假设你有一个~/Documents/MyPapers文件夹里面堆满了各种研究论文、技术报告和笔记。你想快速找到任何一篇中讨论过“注意力机制”的内容。步骤1构建索引进入LEANN项目目录并确保虚拟环境已激活。cd leann source .venv/bin/activate运行文档RAG应用。首次运行会自动下载指定的嵌入模型。python -m apps.document_rag \ --data-dir ~/Documents/MyPapers \ --embedding-model all-MiniLM-L6-v2 \ --embedding-mode sentence-transformers \ --llm ollama \ --llm-model llama3.2:1b \ --chunk-size 512 \ --chunk-overlap 128--data-dir: 指定你的文档目录。--chunk-size 512: 将文档切成约512个token的块。对于学术论文可以适当增大到1024。--chunk-overlap 128: 块之间重叠128个token防止关键信息被切断。首次运行会花费较长时间因为它要读取所有文件、分块、并构建图索引。进度会在终端显示。步骤2交互式查询上述命令如果不加--query参数会进入交互模式。构建完成后你会看到提示符Query:。Index built successfully! Size: 47.3 MB Entering interactive mode. Type quit to exit. Query: What papers discuss the attention mechanism?直接输入你的问题。LEANN会先检索相关文本块然后发送给本地LLM生成总结性答案。你也可以要求它引用来源。步骤3单次查询如果你只有一个明确问题可以在构建时直接指定python -m apps.document_rag \ --data-dir ~/Documents/MyPapers \ --query “对比一下Transformer和RNN的优缺点” \ --llm ollama \ --llm-model qwen2.5:1.5b实操心得分块策略的艺术--chunk-size和--chunk-overlap是影响检索效果的关键参数没有放之四海而皆准的值。通用文档从256或512开始。较小的块检索更精准但可能丢失上下文较大的块包含更多上下文但可能引入噪声。代码文件使用--enable-code-chunking参数如果应用支持它会基于抽象语法树进行分块保持函数、类的完整性。对话记录对于微信、iMessage使用较小的块如192因为单条消息通常较短。重叠度通常设置为块大小的10%-25%。对于结构严谨的文档如论文可以低一些对于流式文本如聊天记录可以高一些。 一个技巧是先用小规模数据测试不同参数观察检索到的片段是否完整回答了你的测试问题。4.2 场景二将整个浏览器历史变成可搜索的知识库你的Chrome历史记录里藏着无数你曾浏览过、学习过但已遗忘的宝藏。LEANN可以索引它。步骤1定位Chrome数据在macOS上Chrome数据通常位于~/Library/Application Support/Google/Chrome/Default如果你使用了多用户 profile路径可能是Profile 1,Profile 2等。步骤2运行浏览器历史RAGpython -m apps.browser_rag \ --chrome-profile “~/Library/Application Support/Google/Chrome/Default” \ --max-items 5000 \ # 如果历史记录太多可以先索引一部分测试 --query “我上周看的关于Python异步编程的教程有哪些”这个应用会读取你的HistorySQLite数据库提取URL、标题和访问时间并将其作为文本进行索引。潜在问题与解决权限错误macOS的沙盒机制可能阻止Python直接读取Chrome数据。你需要为终端或你使用的IDE如VSCode授予“完全磁盘访问权限”。前往系统设置 隐私与安全性 完全磁盘访问权限添加你的终端应用。数据库锁闭如果Chrome正在运行它可能会锁住历史数据库文件导致读取失败。最简单的办法是先完全退出Chrome浏览器再运行索引命令。4.3 场景三深度挖掘微信聊天记录微信承载了我们大量的社交和工作记忆。LEANN通过整合WeChatTweak-CLI导出工具实现了对微信本地数据库的读取和索引。步骤1安装导出工具# 使用Homebrew安装macOS brew install sunnyyoung/repo/wechattweak-cli # 或使用项目内置脚本 sudo ./packages/wechat-exporter/wechattweak-cli install安装后务必重启微信。你可能会在微信启动时看到一个关于插件的提示选择允许。步骤2运行微信RAGpython -m apps.wechat_rag \ --export-dir ./wechat_export \ # 指定导出数据存放目录 --force-export \ # 强制重新导出确保获取最新聊天记录 --chunk-size 192 \ # 微信消息短块大小设小 --query “去年三月份我和张三讨论过的那个项目启动会是什么时间”程序会调用wechattweak-cli导出所有聊天记录联系人、群聊到指定目录然后进行索引。导出过程可能需要几分钟取决于聊天记录的数量。重要警告隐私与合规此功能依赖于第三方导出工具请确保你了解并遵守微信的用户协议及当地法律法规。仅用于索引你个人设备上、属于你本人的聊天记录。切勿用于导出或索引他人的聊天信息这是不道德且可能违法的行为。LEANN项目提供此功能是出于技术展示和个人数据管理的目的请负责任地使用。4.4 场景四与AI对话的记忆延伸——索引ChatGPT/Claude历史如果你经常使用ChatGPT或Claude你的对话历史本身就是个高质量的知识库。你可以从这些平台导出你的历史数据。以ChatGPT为例登录ChatGPT网页版。点击左下角个人头像 -Settings Beta-Data controls。点击Export data确认导出。OpenAI会给你发送一封包含下载链接的邮件。下载ZIP文件并解压你会得到一个包含HTML文件的文件夹。索引你的AI对话python -m apps.chatgpt_rag \ --export-path ./path/to/your/chatgpt/export/folder \ # 指向解压后的文件夹或单个HTML文件 --separate-messages \ # 将每条消息单独作为块检索更精细 --llm ollama \ --llm-model llama3.2:1b \ --query “我之前问过关于Python装饰器的最佳实践是什么”现在你可以像搜索自己的笔记一样搜索你与AI的所有对话。这对于找回某个具体的代码片段、学习某个概念的详细解释或者复盘你的思考过程具有不可思议的价值。5. 高级配置与性能调优当你的数据量从几千条增长到几十万、上百万条时默认参数可能不再是最优的。理解并调整这些参数能让LEANN在速度和精度之间达到最佳平衡。5.1 索引后端选择HNSW vs. DiskANNLEANN支持两种图索引后端选择取决于你的数据规模和硬件。特性HNSW (默认)DiskANN工作原理全内存索引多层导航小世界图。基于磁盘的索引图结构存储在SSD上部分热点数据缓存在内存。速度极快。搜索在内存中完成延迟极低。较快。受磁盘IO影响但优化后对于大规模数据仍表现良好。内存占用较高。需要将整个图加载到内存。极低。主要占用磁盘空间内存仅用于缓存。数据规模适合中小规模数据集例如 1000万向量。适合超大规模数据集数千万到数亿。使用场景个人电脑数据量在GB级别追求极致检索速度。服务器或需要处理海量数据的场景内存有限。构建命令--backend-name hnsw--backend-name diskann如何选择对于绝大多数个人用户HNSW是首选。它的速度优势在交互式应用中体验明显。只有当你明确需要处理数千万级别的文档并且机器内存不足时才考虑使用DiskANN。5.2 图构建参数平衡精度与效率构建索引时有两个关键参数影响图的质量和大小--graph-degree(默认 32): 图中每个节点的最大连接数出边。这个值越大图的连通性越好搜索精度越高但索引也会更大构建更慢。对于数据分布均匀、维度不高的嵌入如all-MiniLM-L6-v2的384维32是一个很好的平衡点。如果你的数据非常复杂或嵌入维度很高如1024维可以尝试增加到48或64。--build-complexity(默认 64): 在构建图时为每个新节点寻找邻居的候选池大小。值越大构建出的图质量越高但构建时间呈线性增长。除非你对索引质量有极致要求否则不建议修改。一个针对高质量索引的构建命令示例python -m apps.document_rag \ --data-dir ./large_corpus \ --backend-name hnsw \ --graph-degree 48 \ --build-complexity 128 \ --chunk-size 7685.3 搜索参数控制召回与速度查询时你可以调整以下参数--top-k(默认 20): 返回最相似结果的数量。对于RAG通常5-10个片段就足够LLM生成答案。设置过大如50会拖慢检索和生成速度。--search-complexity(默认 32): 搜索时访问的节点数量上限。相当于传统ANN搜索中的efSearch参数。值越大搜索越彻底召回率越高但速度越慢。对于大多数查询32已足够。如果你发现某些查询召回效果不好可以适当提高到64或100。一个经验法则在交互式应用中优先保证速度search-complexity32, top-k10。在后台批处理或对精度要求极高的场景再调高这些值。5.4 存储优化紧凑模式与重计算开关这是LEANN最核心的两个特性它们通常一起工作--compact/--no-compact: 是否使用紧凑存储格式。务必保持默认的--compact开启它能显著减少索引文件大小。--recompute/--no-recompute: 是否启用选择性重计算。这是节省97%存储的根源必须开启默认。--no-recompute模式会像传统向量数据库一样预先计算并存储所有嵌入向量这将导致索引文件急剧膨胀失去LEANN的核心优势。重要警告构建索引时如果使用了--recompute搜索时也必须使用--recompute默认。反之如果构建时用了--no-recompute搜索时也必须用--no-recompute。模式不匹配会导致搜索失败或结果错误。6. 常见问题与故障排查实录在实际使用中你可能会遇到一些“坑”。这里记录了我踩过的一些以及社区常见的解决方案。6.1 构建或搜索时出现“Killed”或内存不足现象进程突然终止终端显示“Killed”。原因通常是系统内存OOM Killer或uv虚拟环境内存不足。解决方案减少数据量使用--max-items参数先索引一小部分数据测试。调整分块增大--chunk-size减少总块数。使用DiskANN如果数据量真的巨大切换到--backend-name diskann后端它是为磁盘设计的。增加Swap空间Linux/macOS为系统提供更多虚拟内存。检查uv环境确保在uv虚拟环境中操作有时全局Python环境包冲突会导致内存问题。6.2 嵌入模型下载失败或速度极慢现象卡在Downloading (…)或报网络错误。原因Hugging Face或模型源连接不稳定。解决方案使用镜像源设置环境变量。export HF_ENDPOINThttps://hf-mirror.com手动下载可以先通过huggingface-cli或网站手动下载模型到本地然后在代码中指定本地路径具体方式取决于使用的嵌入后端如sentence-transformers允许指定cache_folder。更换更小的模型尝试all-MiniLM-L6-v2或paraphrase-MiniLM-L3-v2它们体积小下载快。6.3 搜索结果不相关或质量差现象LLM生成的答案胡言乱语或者检索到的文本块与问题无关。排查步骤检查检索结果本身在交互模式或代码中先打印出searcher.search()返回的原始文本块看看它们是否真的与查询相关。如果不相关问题出在检索阶段。调整分块策略不相关的块往往因为分块不合理。尝试调整--chunk-size和--chunk-overlap。对于长文档块太小会失去上下文块太大会引入噪声。检查嵌入模型不同的嵌入模型在不同领域如中文、代码、专业术语表现差异很大。如果你在处理中文资料可以尝试BAAI/bge-small-zh-v1.5。在命令行中通过--embedding-model指定。提升搜索深度增加--search-complexity如到100和--top-k如到30让搜索更充分。检查查询本身尝试将你的问题改写得更明确、更接近文档中的表述。6.4 Ollama本地LLM响应慢或内容空洞现象答案生成很慢或者LLM总是回答“根据以上文档……”而不给出具体内容。解决方案升级模型llama3.2:1b虽然快但能力有限。尝试qwen2.5:1.5b或llama3.2:3b在速度和能力间取得更好平衡。优化提示词LEANN内部会将检索到的上下文和问题组合成提示词发送给LLM。虽然不能直接修改但你可以通过优化检索结果见上一点来间接提供更好的上下文。检查GPU加速确保Ollama使用了GPU。运行ollama ps查看模型运行情况或使用ollama run llama3.2:1b直接测试生成速度。调整“思考预算”如果使用o3-mini等推理模型可以设置--thinking-budget medium来获得更深度的思考。6.5 在Apple Silicon Mac上构建失败现象安装diskann额外依赖时编译错误。原因某些C依赖在macOS ARM架构上需要特定配置。解决方案跳过DiskANN对于个人使用HNSW后端完全足够。安装时不要加--extra diskann。uv sync # 只安装核心依赖确保Xcode命令行工具已安装xcode-select --install使用Rosetta不推荐如果实在需要DiskANN可以尝试在x86_64架构的终端下编译但这会引入兼容层可能不稳定。经过以上步骤你应该已经成功地将LEANN部署起来并开始用它来管理你的个人数字世界。从我自己的使用体验来看最大的转变不是技术上的而是心理上的我不再担心“这个文件该放哪里以便以后找到”因为我知道只要它在我电脑的某个角落LEANN就能帮我把它“想”出来。这种随时可以调用全部个人记忆的感觉才是真正意义上的“第二大脑”。项目的路线图显示团队还在计划增加GPU加速、更多数据源集成可以预见这个“世界上最小的向量索引”未来还会带来更多惊喜。

相关新闻