一、定义
FAISS 是一个专门用来”在一大堆数字向量里快速找相似项”的工具库。
什么是”数字向量”?
就是一串数字,比如 [0.23, -1.5, 0.88, ...]。现代 AI(比如大模型、图像识别)会把文字、图片、音频等都转成这种向量。两个东西越相似,它们的向量就越”靠近”。
二、它解决什么问题?
假设你有 100 万个向量,现在给你一个新的向量,问:”哪 10 个最像它?”
- 如果你用普通方法(一个个算距离),可能要几秒甚至几分钟。
- FAISS 能在几毫秒到几十毫秒内搞定,而且结果几乎一样准。
这就是它的核心价值:快!还能处理海量数据。
三、主要功能
1. 快速搜索相似向量
- 输入一个向量 → 返回最相似的 Top-K 个(比如前 5 个)
- 支持两种”相似”标准:
- 欧氏距离(L2):数值越接近越相似(默认)
- 内积(IP):方向越一致越相似(常用于语义搜索,需提前归一化)
2. 支持超大数据量
- 百万、千万、甚至上亿向量都能处理
- 内存不够?可以用压缩技术(比如 PQ 量化)把向量变小,牺牲一点点精度换速度和省内存
3. GPU 加速(可选)
- 如果你有 NVIDIA 显卡,装
faiss-gpu版本,搜索速度再提 10 倍+
4. 给向量绑定 ID
- 默认返回的是”第几个向量”,但你可以给每个向量配一个自定义 ID(比如数据库主键、商品 SKU)
- 搜索时直接返回你的 ID,不用自己再查一遍
5. 存盘 & 加载
- 建好的索引可以保存到硬盘,下次程序启动直接加载,不用重新建
四、不能做什么?(常见误区)
❌ 不能动态频繁增删向量
- 大部分高效索引(如 IVF、HNSW)建好后不支持随意插入或删除
- 如果你要频繁更新,要么:
- 定期重建索引(适合每天/每周更新)
- 用简单索引(如 IndexFlat,但慢)
- 自己分层管理(新数据放内存,老数据放 FAISS)
❌ 不是数据库
- FAISS 只管”向量相似度”,不管业务逻辑、过滤条件(比如”只要价格<100的商品”)
- 实战中通常和数据库配合:FAISS 找候选集 → 数据库过滤+排序
- (正确做法:先用数据库/代码过滤出候选向量,再用 FAISS 找最相似的。)
五、怎么安装?
情况 1:你只有 CPU(大多数人的电脑)
1 | pip install faiss-cpu |
情况 2:你有 NVIDIA 显卡 + 装了 CUDA(想用 GPU 加速)
1 | pip install faiss-gpu |
⚠️ 注意:
- 不要同时装
faiss-cpu和faiss-gpu,会冲突。 - 如果你不知道有没有 GPU,先装
faiss-cpu,能跑就行。
五、完整代码
1 | # 第 1 步:导入需要的库 |
输出结果:
1 | [[0.2605693 0.4263211 0.90267324 ... 0.8711926 0.09718457 0.56775576] |
整体目标:
给一个句子(向量),在 1 万个句子里快速找出最像它的 3 个。
- 导入工具 → 用 FAISS(搜向量)和 NumPy(处理数字)
- 准备数据 → 假设你有 1 万个句子,每个都被 AI 转成一串 768 个数字(叫”向量”)→ 强制转成 float32 格式(FAISS 的硬性要求)
- 建搜索”引擎” → 选 IndexFlatIP:适合比”语义相似度”(比如两句话意思像不像)
- 标准化向量 → 把所有向量”拉到同一个尺度”(归一化)→ 这样”内积”就等于”余弦相似度”:结果越接近 1,越像
- 把数据喂给引擎 →
index.add(...)相当于”建好数据库” - 准备你要搜的新句子 → 也转成 768 维向量 + 同样做归一化!
- 开始搜索 → 问:”哪 3 个最像这个新句子?” → FAISS 返回:位置编号 + 相似分数
- 看结果 → 比如:第 500、2301、8899 号句子最像,相似度分别是 0.92、0.89、0.85
六、怎么选索引?
| 你的数据有多少? | 你最关心什么? | 推荐用哪个索引? | 为什么? |
|---|---|---|---|
| 少于 1 万条向量 (比如几千个商品、文章) |
“我数据不多,但要结果绝对准确” (比如做实验、小工具) |
IndexFlatL2 或 IndexFlatIP |
这是最简单的”暴力搜索”: 把所有向量都比一遍 结果 100% 准确 数据少,所以也不慢 |
| 1 万 ~ 100 万条 (比如一个中型推荐系统) |
“我要快!准不准稍微差一点没关系” (比如用户搜东西,不能等) |
IndexIVFFlat | 它先把向量分成 100 搜索时只查其中几组,速度提升 10 结果和精确搜索几乎一样好 |
| 超过 100 万条 (比如百万用户、千万商品) |
“内存不够 / 必须极快响应” (比如大厂线上服务) |
IndexIVFPQ 或 IndexHNSW |
- IVFPQ:把向量压缩成更短的编码,省内存 + 更快 - HNSW:用图结构预建”快捷路径”,查得飞快 ⚠️ 两者都会损失一点点精度,但通常不影响业务 |
| 你有 NVIDIA 显卡 (且装了 CUDA) |
“我要在 GPU 上跑,榨干性能” | 安装 faiss-gpu 然后用 IndexIVFFlat |
GPU 能并行算成千上万个距离, 比 CPU 快 10~50 倍, 适合高并发或超大数据 |
1. L2 和 IP 到底怎么选?
- 用 IndexFlatL2:如果你的向量没有归一化,或者你关心”数值差距”(比如图像特征)
- 用 IndexFlatIP:如果你的向量已经归一化(长度=1),并且你关心”方向/语义相似度”(比如文本 embedding)
✅ 简单记:
- 做语义搜索(文字、句子)→ 用 IP + 归一化
- 做图像、音频原始特征 → 用 L2
几种 FAISS 索引的对比:
| 索引类型 | 通俗解释 | 适合场景 |
|---|---|---|
| IndexFlatL2 | 暴力比:把所有向量一个个算”距离”,找最近的 | 数据少(<1万),要绝对准确 |
| IndexFlatIP | 暴力比:把所有向量一个个算”方向相似度”(余弦) | 做文本语义搜索,且向量已归一化 |
| IndexIVFFlat | 先分100组,只查最相关的几组,组内暴力比 | 中等数据(1万~100万),又快又准 |
| IndexIVFPQ | 分组 + 把向量压缩变短,省内存、更快 | 超大数据(>100万),内存有限,可接受稍不准 |
| IndexHNSW | 预先建”快捷导航图”,搜索时快速跳到相似项 | 要极致快,内存够,不需频繁更新 |
💡 补充:
- L2:看数值差距(适合图像等原始特征)
- IP:看方向/语义(适合文本,记得先归一化!)
- 带 IVF 的都能用
nprobe控制”查几组” → 越大越准越慢 - 别一上来就用 PQ 或 HNSW,先用 IndexIVFFlat 足够应付大多数场景
注意:LangChain 的封装
LangChain 为了方便用户,把 FAISS 的复杂细节都藏起来了。
具体表现为:
- 不直接选索引:你在 LangChain 里看不到 IndexFlatL2、IndexHNSW 这些具体的索引名字。
- 默认用简单的:当你用
FAISS.from_texts()创建数据库时,LangChain 会自动、默认地帮你选择最简单的 IndexFlatL2 索引。 - 优缺点:
- 优点:简单、精确,适合数据量不大的情况(几万到几十万条)。
- 缺点:数据量一大(上百万、上亿),搜索速度就会变得非常慢。
总结
- FAISS = 向量搜索引擎
- 核心能力:快 + 准 + 能扛大数据
- 典型用途:RAG 知识召回、推荐系统、以图搜图
- 记住三点:
- 向量必须是
float32 - 用 IP 就要先
normalize_L2 - 大多数索引建完就不能随便改,规划好更新策略
- 向量必须是