相似搜索算法概述

Hello~

最近大模型(LLM)火得不行,大家都在搞 RAG(检索增强生成),也就是给大模型装个“外挂硬盘”——向量数据库

但是,这个硬盘里装了成千上亿条数据,当我们要找一个答案的时候,机器是怎么在几毫秒内,从大海里把那根针(最匹配的数据)给捞出来的?

这就是咱们今天要聊的核心魔法——相似性搜索 (Similarity Search)

今天我不甩复杂的数学公式,咱们用大白话,配合我画的流程图,把这个事儿彻底讲透!不管你是小白还是半懂不懂,看完这篇保证你通透。


零、 先来认识一下我们的"全程陪跑案例"

在正式开讲之前,我要先给大家介绍一个贯穿整个系列的案例。后面讲到每个算法,我都会用这个案例来演示,这样你就能直观感受到不同算法的差异!

【感谢璐璐姐的建议和提点~】

场景:专利侵权检索

假设你在一家科技公司的搜索研发部实习。公司有一个专利数据库,里面存了 1000 万条各行各业的专利。

现在,研发部的Richard搞了个新发明:“一种基于深度学习的图像去噪方法”。(听不懂 思密达)

老板让你查一下:市面上有没有类似的专利?会不会侵权?有没有可以借鉴的技术?【我们公司想打造一款产品帮助商户向商家亚马逊的时候做一个侵权专利的检测】

数据长啥样?

每条专利经过 Embedding 模型处理后,变成一个 768 维的向量(就是 768 个数字组成的列表)。【因为语义级别的搜索我们以前的关键词匹配是做不到的,我们可以利用向量这个工具来帮助我们达成相似度搜索这一目标,因为高中数学咱们就学过嘛 余弦公式 它就可以用来比较两个向量的远近 或者是直接用坐标公式 后面会细讲~ 在《相似度度量和过滤》那一篇文章中 不理解往后看就行啦~】

我们的查询 "一种基于深度学习的图像去噪方法" 也会变成一个 768 维向量。

数据库里的"真相"

假设我们是上帝视角,已经知道数据库里跟我们查询最相关的 5 条专利是这些:

排名 专利名称 与查询的真实距离 相似程度
🥇 1 基于卷积神经网络的图像降噪系统 0.12 超级像!
🥈 2 深度学习图像增强方法 0.15 很像
🥉 3 图像去噪的自编码器实现 0.18 挺像
4 传统滤波器图像处理方法 0.45 有点关系
5 机械臂控制系统专利 0.92 八竿子打不着

我们的目标:用最快的速度,把排名 1、2、3 的专利找出来!

好,案例介绍完毕。接下来每讲一个算法,我都会告诉你:用这个算法去搜,能不能把这三个"真爱"都找出来?会不会漏掉?会不会找错?

带着这个问题,咱们正式开始!


一、 啥是"向量"?为啥要"算距离"?

首先,在大模型眼里,万物皆是数字。
不管是你发的一句“今天吃啥”,还是你家猫的照片,经过一个叫 Embedding(嵌入) 的模型处理后,都会变成一串长长的数字列表,这就叫向量

1. 怎么判断像不像?

很简单,看距离
在数学空间里,两个东西含义越接近,它们对应的向量距离就越近。

我给你画个图感受一下:

img

向量数据库的任务就是: 当你扔进来一个新向量(问题),它要飞快地计算,把距离最近的 B 和 C 找出来,扔掉 D。


二、 为什么要搞那么多花里胡哨的算法?

你可能会问:“这不简单吗?把库里 1 亿条数据全拿出来,一个个算距离,排个序不就行了?”

这叫 暴力搜索 (Flat/Brute Force)

  • 优点:100% 准确,绝对能找到最近的。
  • 缺点:慢到离谱。等它算完 1 亿次,用户早就关网页走人了。

🔬 专利案例演示:暴力搜索

回到我们的专利检索场景。如果用暴力搜索:

1
2
3
4
5
6
7
8
📊 暴力搜索结果(耗时:47 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
✅ 第 2 名:深度学习图像增强方法(距离 0.15)
✅ 第 3 名:图像去噪的自编码器实现(距离 0.18)

召回率:100%(3/3 全找到了!)
计算次数:10,000,000 次

结论:结果完美!但是……47 秒??用户等得花儿都谢了。老板会骂死我的 www。

所以为了,我们必须用点"套路"。这就引出了两大流派:

  1. 按数据结构分类:整理数据,做个地图,别瞎找。
  2. 按量化压缩分类:把数据变小,算得快。

咱们一个个拆解。


三、 第一招:按数据结构分类(画地图)

这一招的核心思想是:“不要全库搜,只搜可能存在的区域。”

1. 基于哈希 (Hash-based) —— 代表:LSH

简单粗暴。把空间切成很多个“桶”。通过哈希函数,把长得像的向量,尽可能扔进同一个桶里。
搜索的时候,算出你在哪个桶,就只在那个桶里找。[记住这句话哦 意味着如果你找不到证明可能有些像被划分到了隔壁桶]

1
2
3
4
5
6
7
8
9
10
11
graph LR
Input[输入向量] --> Hash{哈希函数}
Hash --> BucketA[桶 A: 包含相似向量]
Hash --> BucketB[桶 B]
Hash --> BucketC[桶 C]

subgraph 搜索范围
BucketA
end

style BucketA fill:#bfb,stroke:#333
  • 特点:快是快,但有时候不准(因为哈希碰撞,或者边缘数据没分好,嗯就是有可能有那么几个数据在两个分类的交界 )。

🔬 专利案例演示:LSH

用 LSH 来搜我们的专利:

1
2
3
4
5
6
7
8
📊 LSH 搜索结果(耗时:0.8 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
✅ 第 2 名:深度学习图像增强方法(距离 0.15)
❌ 第 3 名:传统滤波器图像处理方法(距离 0.45) ← 啥?这个怎么混进来了?

召回率:67%(3 个真爱只找到 2 个)
漏掉了:图像去噪的自编码器实现(它被哈希到隔壁桶去了……)

发生了什么?
"图像去噪的自编码器实现"这条专利,刚好在哈希切分的边界上,被一刀切到了隔壁桶。而我们只搜了自己的桶,所以它就被漏掉了。

结论:速度飞快!但是会漏人。适合对精度要求不高的粗筛场景。

2. 基于树 (Tree-based) —— 代表:KD-Tree, Annoy

像切蛋糕一样。把空间一分为二,二分为四……最后形成一棵树。
搜索的时候,顺着树枝走,很快就能定位到一小块区域。

1
2
3
4
5
6
7
graph TD
Root[所有数据] -->|左边区域| NodeL[子区域 1]
Root -->|右边区域| NodeR[子区域 2]
NodeL -->|继续切分| Leaf1[最终小区块 A]
NodeL --> Leaf2[最终小区块 B]

style Leaf1 fill:#bfb,stroke:#333
  • 特点:低维数据好用,但现在的向量动不动就 1024 维,树结构就会失效(维度灾难),不过 Annoy 这个算法在工业界还是很常用的滴。【所谓维度,其实就是“描述事物的特征数量”。举个例子,你去相亲,如果只看“身高、体重”这俩指标,这就是 2 维数据;如果你还要考察“学历、收入、房产、爱好、星座、MBTI……”这一下子列了 1024 个指标来综合评分,那就是 1024 维。维度越高,描述越精准,但计算起来也越累!~】

🔬 专利案例演示:KD-Tree

用 KD-Tree 来搜我们的 768 维专利向量:

1
2
3
4
5
6
7
📊 KD-Tree 搜索结果(耗时:12 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
❌ 第 2 名:机械臂控制系统专利(距离 0.92) ← 离谱!
❌ 第 3 名:传统滤波器图像处理方法(距离 0.45)

召回率:33%(3 个真爱只找到 1 个)

发生了什么?
768 维太高了!KD-Tree 在高维空间里,切分变得毫无意义——每一刀切下去,数据分布都差不多乱。最后退化成了"假装在找,实际瞎找"。

结论:树结构在低维(比如 2D、3D 地图坐标)很香,但在高维向量世界里基本躺平。所以现在大模型场景很少用它。不过 Annoy 这个算法在工业界还是很常用的滴~

3. 基于图 (Graph-based) —— 代表:HNSW

这是目前的最火的搜索算法了叭 I think!
它的原理是**“六度人脉”**。把向量当成朋友,相似的就连根线。HNSW 还更进一步,它建了“高架桥”(分层)。
搜索时,先在顶层高架桥快速跳跃,找到大概位置,然后下高速,在地面道路精细查找。 【更精确的图可以查看后续的文章】

1
2
3
4
5
6
7
8
9
graph TD
Start((入口点)) -->|高速跳跃| Mid((中间节点))
Mid -->|快速接近| Target((目标区域))
Target <-->|精细查找邻居| N1(邻居1)
Target <-->|精细查找邻居| N2(邻居2)

style Start fill:#f9f
style N1 fill:#bfb
style N2 fill:#bfb
  • 特点:目前综合性能最强。快,准!就是建图有点慢,稍微有点吃内存。【因为要构建很多层嘛】

🔬 专利案例演示:HNSW

用 HNSW 来搜我们的专利:

1
2
3
4
5
6
7
8
📊 HNSW 搜索结果(耗时:0.003 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
✅ 第 2 名:深度学习图像增强方法(距离 0.15)
✅ 第 3 名:图像去噪的自编码器实现(距离 0.18)

召回率:100%(3/3 全找到了!)
计算次数:约 2000 次(只访问了图上的邻居节点)

发生了什么?
HNSW 先在"高速公路层"快速定位到"图像处理"这个大方向,然后一层层下沉,最后在底层精确找到了所有相关专利。

结论:又快又准!3 毫秒搞定,比暴力搜索快了 15000 倍,而且结果一模一样。这就是为什么它是目前的"当红炸子鸡"!

但是:HNSW 需要额外存储每个节点的"朋友关系",1000 万条数据大概要多占 2-3 GB 内存。土豪随意,穷学生慎选www。

4. 倒排文件 (Inverted File) —— 代表:IVF

先搞个“聚类”。比如把 1 亿个数据聚成 1000 个堆(簇)。每个堆有个中心点。
搜索时,先看你离哪个中心点最近,就只去那个堆里找。

1
2
3
4
5
6
7
8
9
10
11
graph TD
Query[查询向量] -->|对比中心点| Select{选最近的堆}
Select --> Cluster1[堆 1]
Select --> Cluster2[堆 2: 命中!]
Select --> Cluster3[堆 3]

subgraph 实际计算区域
Cluster2
end

style Cluster2 fill:#bfb
  • 特点:非常均衡,工业界用得超级多。

🔬 专利案例演示:IVF

用 IVF 来搜我们的专利(假设分成了 1000 个簇):

场景 A:nprobe = 1(只搜最近的 1 个簇)

1
2
3
4
5
6
7
📊 IVF 搜索结果(nprobe=1,耗时:0.02 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
✅ 第 2 名:深度学习图像增强方法(距离 0.15)
❌ 第 3 名:传统滤波器图像处理方法(距离 0.45)

召回率:67%(漏了 1 个)

场景 B:nprobe = 5(搜最近的 5 个簇)

1
2
3
4
5
6
7
📊 IVF 搜索结果(nprobe=5,耗时:0.08 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(距离 0.12)
✅ 第 2 名:深度学习图像增强方法(距离 0.15)
✅ 第 3 名:图像去噪的自编码器实现(距离 0.18)

召回率:100%(全找到了!)

发生了什么?
"图像去噪的自编码器实现"这条专利,被分到了隔壁簇。当 nprobe=1 时我们没搜那个簇,所以漏了。把 nprobe 调大到 5,多搜几个簇,就找回来了!

结论:IVF 是个"可调节"的算法。nprobe 小 = 快但可能漏;nprobe 大 = 稍慢但更准。你可以根据业务需求自己调!


四、 第二招:按量化压缩分类(搞瘦身)

这一招的核心思想是:“由繁入简,大差不差就行。”
原始向量(float32)太大了,能不能把它变小?虽然精度会丢一丢丢,但速度提升几倍,内存节省几十倍!

1. 标量量化 (SQ - Scalar Quantization)

就像把高清图压缩成 jpg。【璐璐姐的这个比喻真的绝了!】
比如原来一个数是 3.1415926(占 4 字节),我直接记成 3(占 1 字节)。

  • 效果:内存砍掉 75%,计算变快。

🔬 专利案例演示:SQ(标量量化)

用 SQ 压缩后搜索:

1
2
3
4
5
6
7
8
📊 SQ 搜索结果(耗时:0.05 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(估算距离 0.13)
✅ 第 2 名:深度学习图像增强方法(估算距离 0.16)
✅ 第 3 名:图像去噪的自编码器实现(估算距离 0.19)

召回率:100%
内存占用:原来的 25%(省了 75%!)

发生了什么?
距离值稍微有点偏差(0.12 变成了 0.13),但排序没变,结果还是对的!用一点点精度损失,换来了巨大的内存节省。

2. 乘积量化 (PQ - Product Quantization)

这个更狠。它把一个长向量切成几段,每一段用一个简短的代码本(Codebook)里的 ID 来代替。

1
2
3
4
5
6
7
8
9
10
graph LR
Original[长长长长的原始向量] -->|切分| Seg1[段1] & Seg2[段2] & Seg3[段3]
Seg1 -->|查表替换| ID1[代码 5]
Seg2 -->|查表替换| ID2[代码 12]
Seg3 -->|查表替换| ID3[代码 9]

Result[压缩向量: 5, 12, 9]

style Original fill:#f9f
style Result fill:#bfb
  • 效果:极度节省内存,虽然精度损失比 SQ 大,但配合 IVF 算法使用(IVF-PQ),效果极好。

🔬 专利案例演示:PQ(乘积量化)

用 PQ 压缩后搜索:

1
2
3
4
5
6
7
8
📊 PQ 搜索结果(耗时:0.04 秒)

✅ 第 1 名:基于卷积神经网络的图像降噪系统(估算距离 0.14
✅ 第 2 名:图像去噪的自编码器实现(估算距离 0.20) ← 注意:顺序变了!
✅ 第 3 名:深度学习图像增强方法(估算距离 0.21

召回率:100%(都找到了,但顺序有点乱)
内存占用:原来的 1.5%(省了 98.5%!!)

发生了什么?
PQ 压缩太狠了,距离估算有偏差,导致第 2 名和第 3 名的顺序颠倒了。但好消息是:三个"真爱"都在 Top 3 里,没漏!

结论:PQ 是"穷人的救星"。1000 万条专利,原本要 23 GB 内存,用 PQ 压缩后只要 350 MB!代价是排序可能有点乱,但该找的都能找到。


五、 总结:不可能三角

讲了这么多,到底该选哪个?
其实,所有的向量搜索算法,都是在玩一个**“不可能三角”**的游戏:

1
2
3
4
5
6
graph TD
A((性能 Performance)) <--> B((召回率 Recall / 准确度))
B <--> C((内存消耗 Memory))
C <--> A

Note[你只能三选二,或者取平衡]

🔬 专利案例大总结:各算法 PK 一览表

回顾我们的专利检索案例,用同一个查询 "一种基于深度学习的图像去噪方法",不同算法的表现:

算法 耗时 召回率 内存占用 找到的 Top 3 点评
Flat(暴力) 47 秒 100% 100% ✅✅✅ 完美 准但太慢,用户跑了
LSH(哈希) 0.8 秒 67% 30% ✅✅❌ 漏 1 个 快但会漏人
KD-Tree(树) 12 秒 33% 100% ✅❌❌ 漏 2 个 高维下躺平
HNSW(图) 0.003 秒 100% 130% ✅✅✅ 完美 又快又准,但吃内存
IVF(倒排) 0.08 秒 100% 100% ✅✅✅ 完美 均衡之选,可调节
SQ(标量量化) 0.05 秒 100% 25% ✅✅✅ 完美 省内存,精度够用
PQ(乘积量化) 0.04 秒 100% 1.5% ✅✅✅ 顺序略乱 超省内存,穷人救星

一句话选型指南:

  1. 只要最快、最准,不在乎内存(土豪首选)
  • 👉 选 HNSW(基于图)。目前大部分向量数据库的默认推荐。
  1. 数据量超级大(亿级),想省钱省内存
  • 👉 选 IVF + PQ(倒排索引 + 乘积量化)。
  1. 数据量很小(几万条),要求 100% 精准
  • 👉 选 Flat(暴力搜索)。别整那些花里胡哨的,直接算!

好啦,关于向量数据库相似性搜索的宏观流派核心逻辑,今天就聊到这!

相信你现在对“数据结构”和“量化压缩”已经有概念了。但是,HNSW 的图到底是怎么连的?IVF 的中心点是怎么选的?PQ 到底是怎么查表的?

这些具体的算法细节硬核拆解,咱们下篇见!