向量搜索常見的八大坑及避坑指南
破了的放大镜。作者拍摄的照片。
向量搜索在纸上看起来很简单,但实际上 — 将一些嵌入向量存入数据库中,查询它们,然后就能得到结果了。但一旦从爱好项目跃升到实际应用时,你很快就会发现“魔法”变成了一个充满爆炸性云账单、奇怪的幻觉和完全不准确搜索结果的雷区。我见过团队花了数周时间优化流水线,但仍然被同样的问题困扰:延迟激增、无关的片段以及高昂的成本无法证明其合理性。
下面我来分享八个我经常看到的常见问题——特别是在缺乏计划的情况下扩展向量搜索的团队。我还会提供一些实用的策略来避免这些问题,这样你就能节省时间、金钱,减少很多压力。
1. 一上来就忽视评估结果为什么这是一个问题
你设置了一个高级嵌入搜索,但很快发现有些查询失败而有些成功——你搞不清楚其中的原因。当你没有一个合适的评估(eval)框架就开始进行向量搜索时,就会遇到这种情况。你无法解决你无法衡量的问题。
可以做什么替代
- 创建一个小而靠谱的评估集:即使只有50到100个标注的查询也足以凸显巨大的差距。
- 用标准的指标:NDCG、MRR 或召回率——随便用哪个。先随便选一个开始,然后不断优化。
- 监控改进情况:每次调整分块或更换嵌入时,都要重新评估。
许多团队对高级分段技术或“上下文检索”甚至“知识图”之类的东西感到兴奋,但并不清楚这些改变是否真的有帮助。评估让你告别猜测。
2. 忽略混合搜索功能为什么这是一个问题
仅仅依赖嵌入相似度可能会遗漏明显的关键词匹配。如果嵌入没有针对特定领域进行调整,或者用户查询一个少见的术语,系统可能无法应对。而此时,标准的关键词搜索(如BM25等)则能抓到这些内容。
能做啥代替
- 混合搜索:将基于向量的搜索结果和基于关键词的搜索结果合并。
- 提高召回率:这种方法在许多向量数据库(例如KDB.AI可以同时存储BM25和向量索引)中易于实现。
- 重新排序合并结果:从两种方法中返回的顶部结果,让重新排序器来决定。
越来越常见的是,团队直接转向使用嵌入,却常常发现简单的查询被忽略了。未经微调的嵌入在非标准数据集上往往比简单的关键词搜索,例如BM25,表现得更差。这时,混合搜索就可以发挥作用了——通过结合嵌入和关键词搜索,可以在不增加延迟的情况下大大提升召回率。这应该是优化你的向量搜索流程的第一步。
这里有个混合搜索功能的实际例子,展示如下。
作者提供的混合搜索图示。
3. 过度优化(尤其是没有实际评估的情况下)为什么这是一个问题
在没有先建立一个清晰的基线的情况下,就盲目追求某种新的检索方法。如果你无法衡量其效果,你就无法判断它是否真的有效。
该用什么来替代
- 设定基准:一个很好的起点通常是混合搜索加上一个小的重排器。
- 测量:在你的标注数据集评估它。
- 逐步引入变化:看看性能是否真的因为这些更改而有所提升。
如果你的流程非常复杂(而且使用像LlamaIndex这样的工具很容易创建非常复杂的流程),因此你可能更好从头开始构建一个简单的RAG流程。
看看LlamaIndex上的这些检索模型!没有评估,你永远不知道它们是否真的有用。
Llamaindex 检索工具。图片来源:https://docs.llamaindex.ai/en/stable/examples/retrievers/composable_retrievers/
即使像延迟分块这样简单的技术,这种技术往往几乎不需要额外工作就能提高性能,也可能可能降低你结果的质量。但最糟糕的是你可以在复杂的办法上浪费几天时间(我经常看到人们看到一项新研究就想着“我得试试看”),却发现他们的性能比最初时还差,无论是延迟还是记忆方面。
始终测量,不确定时就简化。
4. 不要对embedding进行量化为什么这是一个问题
3k维的嵌入效果很好,直到你有了数千万个这样的嵌入——然后内存成本会变得很高。过度的嵌入不仅会拖慢查询速度,还会使你的云账单猛增。
可以做些什么代替
- 使用量化:比如可以利用诸如Matryoshka Representation Learning (MRL) 或二值量化等技术,将嵌入层压缩到较小规模,同时保持较小的损失。
- 可以试试64维或128维:特别是如果你有超过2-3M的向量。你可能几乎不会注意到召回率有任何下降——但你肯定会看到成本的降低。
- 依赖于重排序:第一次检索结果可能已经足够好,如果你用更准确的方法对前N个结果进行重排序。
- 考虑使用二值量化:二值量化通常和其他方法比如MRL结合得很好,但是一定要确保模型能够和它兼容哦!
我曾和一些开发者交流过,他们每月花费100美元以上用于一个无服务器数据库服务,但这个数据库只含有100万个1536维的向量。我还跟一些工程师聊过,他们认为他们“需要”3000维才能在PDF上搜索得很好。我向你保证,你并不需要那么多。切换到64维或128维能极大地减少存储和CPU使用,几乎可以免费。如果你再加上二值量化,你可以再将你的嵌入所占空间减少32倍。
又一次,我们的评估告诉我们能量化到什么程度而不会丢失太多召回。
5. 在大规模数据处理时未使用磁盘索引为什么这是一个问题
一旦你的向量数量达到500万到1000万以上,将它们全部存储在RAM中通常过于昂贵。你可能不得不升级到更昂贵的硬件层级或更大的托管数据库层级,以将这些嵌入保存在内存中。
还可以试试什么
- 磁盘上的索引:像KDB.AI中的qHNSW这样的索引允许你将向量存储在磁盘上,从而大幅降低内存使用。
- 注意规模:如果你发现自己正朝着5000万或1亿个向量迈进,计划使用磁盘索引解决方案。
- 注意延迟:现代磁盘索引其实相当快,因此你可能几乎察觉不到差异——但始终要进行测量。KDB.AI的qHNSW索引实际实现了比默认HNSW索引高3倍的吞吐量,同时保持了几乎相同的延迟。
为什么这是一个问题
现成的嵌入模型(例如来自OpenAI、Cohere的)在处理一般查询时非常有用,但可能无法捕捉到特定领域的细微差别——比如医学术语、化学化合物或特定品牌的引用,这些在特定领域内的细微差别可能被忽略。
可以做什么:
- 微调嵌入:即使是1,000个标记对也能产生影响。
- 微调重排序器:交叉编码器或其他重排序器通常所需的示例比你想象的要少。即使几百个对也能产生影响,但更多总是更好。
- 使用你的评估集:在开始训练前和训练之后进行测试。跟踪微调带来的帮助程度。
15–25%的召回效果提升并不罕见,只需要少量特定领域的训练样本即可实现。如果领域重要,忽略微调就是放弃了提升准确率的机会。微调嵌入模型和重排序模型越来越容易。
这里有个不错的关于训练句子嵌入的博客:你可以在这里查看:
7. 混淆向量检索和全面的向量数据库为什么这是一个问题
很容易下载 Faiss 或 Annoy,拼凑一个近似最近邻搜索就草草收场。但生产数据库处理的远不止是简单的向量查找——比如混合搜索、并发处理、元数据过滤、数据分区等。大多数内存向量库甚至不提供边添加新数据边搜索的功能。
还可以做什么
- 选择一个向量数据库:工具如 KDB.AI 解决了事务处理、可扩展性和高级查询等问题。
- 确保混合搜索是可用的选项:混合搜索已经成为文本检索的标准,对于实际应用场景来说非常重要。
- 元数据过滤:真实的查询通常会说“找到所有与该向量接近的文档,并且也是创建于最近7天内的文档”。确保你的数据库能够做到这一点。KDB.AI 还支持基于元数据的分区,因此如果你的数据与时间有关,可以大大减少延迟时间!
每当数据变化时都得从头重建索引相当麻烦——如果你仅仅依赖一个单纯的Faiss索引,你就会面临这样的困境。
8. 别害怕查看(并编辑)数据为什么这会成为一个问题
这么多团队把他们的块或嵌入视为黑盒子——“这仅仅是AI的职责。”然后他们不知道为什么某些查询会失败或产生无意义的结果。
替代方案是什么
- 检查你的文本块:看看文本是如何被分割的,确保没有将句子切半。是否有关键短语被截断了?
- 手动修复问题点:如果某个文本块表现不佳,不要害怕添加关键词或优化其描述。如果用户查询没有得到预期的结果,可能需要手动调整该文本块的文本。
- 基于真实反馈进行迭代:如果某个查询很受欢迎但不断失败,快速更新文本块以突出正确的关键词。有时最简单的解决方法只是对原始数据进行小调整。
关键洞察
向量数据库其实并不神秘。就像调整索引或优化关系数据库一样,你可以修改文本分块、重命名字段或标注部分内容。没错,虽然这可能是手动的,但它可以迅速解决许多实际问题。
向量搜索能大大提升语义查询的效果,但如果忽视了以下八个问题,可能会导致事与愿违。不论是基于100万个向量建立推荐系统,还是扩展到1亿个向量用于大型企业知识库,都需要注意这些错误及其相应的解决办法。
- 尽早加入评估以便你可以跟踪真正的进度。
- 使用混合搜索来捕捉语义和精确匹配的结果。
- 不要过度优化高级RAG或分块,除非有数据作为支持。
- 进行量化以控制内存和账单。
- 使用磁盘索引如果你的规模很大,内存成本会很高。
- 微调嵌入或重新排序器如果特定领域的细节非常重要。
- 采用完整的向量数据库而非基础库。
- 查看你的数据——不要害怕手动解决看到的分块问题。
直面这些问题,你就能打造出一套始终提供相关结果的向量搜索系统——而且不会让你的钱包空空如也。如果你的向量数量少于约500万,你可以将嵌入存储在64维度的磁盘上,将所有内容保持在免费的KDB.AI云端级别内,并仍然保持在200毫秒以内。如果有查询出了问题,只需快速调整一下分块,就可能解决它。
查询愉快!
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章