FAISS是什么
FAISS(Facebook AI Similarity Search) 是由 Meta(原 Facebook)开发的开源向量检索引擎,专为"海量向量的高效相似度搜索"而设计。它不是数据库,而是一个超高性能的 C++/Python 向量索引库,可以让你在本地环境下进行数百万级别的向量匹配操作。
它到底能干啥?
- 语义检索:根据问句的语义找到最接近的文档片段
- RAG 系统:作为大模型上下文召回的向量库
- 文本聚类:找出相似内容或主题群组
- 图像 / 视频搜索:嵌入图像特征后进行相似内容比对
特点
| 特点 | 优势说明 |
|---|---|
| 🚀 性能极强 | 支持百万向量以内毫秒级响应(本地 CPU / GPU) |
| 🧩 部署轻量 | 不需要服务器,不需要 Docker,一句 pip 即可 |
| 🔐 本地私有化友好 | 所有数据都在你机器上,无外泄风险 |
| ⚙️ 模块组合灵活 | 提供 10 多种索引结构,适配不同精度 / 速度场景 |
和 Milvus / Qdrant 有什么区别
| 对比点 | FAISS | Milvus | Qdrant |
|---|---|---|---|
| 部署复杂度 | ✅ 超简单(即插即用) | ⛔ 较高(需集群支持) | ⚠️ 中等(需服务端部署) |
| 本地部署友好度 | ✅ 完美支持 | ❌ 依赖服务端环境 | 🟡 支持但资源占用较大 |
| 量化搜索支持 | ✅ 全面(PQ/OPQ/HNSW等) | ✅ 支持 | ✅ 部分支持 |
| REST API | ❌ 需自行封装 | ✅ 原生提供 | ✅ 原生提供 |
| 适用场景 | 本地/轻量/嵌入式系统 | 云原生大型项目 | 中型服务项目 |
FAISS 在 RAG 系统中的角色
在现代 RAG(检索增强生成)系统中,FAISS 扮演着**"语义中间人"**的角色:帮大模型找出最有可能相关的上下文
python
知识库构建过程:
【文档】
↓
【文档内容向量化】
↓
【FAISS 向量索引存储】
提问过程:
【用户问题】
↓
【句子向量化】
↓
【FAISS 向量索引读取、检索】
↓
【相关文段 TopK】
↓
【Prompt 拼接】
↓
【大模型生成回答】
为什么大模型必须搭配向量检索?
- 大模型不能**"凭空知道"你给的知识**;
- 文档直接塞进 prompt 会超长、杂乱、失真;
- FAISS 帮你精准提取与问题最相关的语义片段,极大提升准确率。
向量搜索基础知识快速入门
向量搜索(Vector Search)是当前语义检索的核心机制,相较传统关键词搜索,它能理解"意思相近但表达不同"的文本。
我们先从底层原理讲起,帮助你真正理解 FAISS 是在干什么。
向量 VS 关键词
传统关键词搜索(例如 Elasticsearch)基于的是词面匹配,而向量搜索是把文本编码成数学空间中的一个"点",然后找距离最近的点。
项目对比
| 搜索方式 | 关键词搜索 | 向量搜索 |
|---|---|---|
| 匹配方式 | 精确关键词匹配 | 语义相似度模糊匹配 |
| 示例问句 | "股东责任" | "投资人需要承担什么后果?" |
| 命中结果 | 包含"股东责任"的文本段落 | 包含"出资方责任"的文本段落 |
什么是"向量"
一句话可以用一个固定长度的向量表示。例如用 768 维向量表示一段文本:
[0.24, -0.88, 0.12, ..., 0.01] ← 共 768 个维度
这些向量一般由预训练模型生成,如:
text2vec-basebge-large-zh-v1.5sentence-transformers系列
向量检索
向量检索的本质是:你给我一个向量,我从海量向量中找到它的"邻居"们。
常见的相似度度量方式有两种:
1. 欧氏距离(L2 距离)
衡量两个向量在空间中的"直线距离",距离越近表示越相似。
D(x, y) = √[(x1 - y1)^2 + (x2 - y2)^2 + ... + (xn - yn)^2]
FAISS 中采用的索引类型为 IndexFlatL2
2. 余弦相似度(Cosine Similarity)
衡量两个向量之间的夹角,夹角越小相似度越高,值越接近 1 表示越相似。
cos(θ) = (x · y) / (||x|| × ||y||)
其中:
x · y表示两个向量的点积||x||是向量的 L2 范数(模长)
FAISS 中使用:IndexFlatIP + 向量归一化。
示例对比(实战感知)
python
query = "法人责任如何界定?"
匹配结果(L2): "公司法人应承担的财务责任包括..."
匹配结果(Cosine): "董事会成员的责任范围主要涵盖..."
什么是 Top-K 检索
你给出一个查询向量,FAISS 会返回前 K 个最相似的向量及其原文索引。
python
D, I = index.search(query_vector, k=3)
D是距离值(越小越相似)I是命中向量的索引列表(用来查原文)
这就是 RAG 系统中"文档召回"最关键的一步。
向量检索让 AI 系统不再死记硬背关键词,而是真正"理解语义",这正是构建智能问答系统的关键基石。
实战一:FAISS构建本地向量检索系统
基于 FAISS 的向量检索系统:输入一份文档,转成向量后存入 FAISS,然后查询问句并返回最相关的段落。
1. 安装基础依赖
使用 sentence-transformers 生成文本向量,FAISS 做向量检索:
python
pip install faiss-cpu sentence-transformers # sentence-transformers嵌入模型
如需 GPU 支持,可使用:
pip install faiss-gpu
2. 文本准备(示例为法律文档)
创建一个简单的样本文本,内容如下(law.txt):
python
第七条:公司是企业法人,有独立的法人财产。
第八条:公司以其全部财产对公司债务承担责任。
董事会对公司的经营决策具有最终权力。
股东大会是公司的最高权力机构。
3. 文本切片 + 嵌入向量生成
python
from sentence_transformers import SentenceTransformer
# 读取文本内容、切块 后续可以使用langchain读取不同类型的文本、切块、优化切块
with open("law.txt", "r", encoding="utf-8") as f:
texts = [line.strip() for line in f if line.strip()]
# 加载 embedding 模型(可替换为 bge/text2vec)
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
# 生成向量(默认维度 384)
embeddings = model.encode(texts, normalize_embeddings=True)
print(f"共生成 {len(embeddings)} 个向量,每个维度为 {embeddings.shape[1]}")
离线下载使用sentence-transformers
python
# 下载 text2vec-base-chinese 400MB
model = SentenceTransformer('shibing624/text2vec-base-chinese')
model.save('./text2vec-base-chinese')
# 或下载 bge-small-zh-v1.5 100MB
model = SentenceTransformer('BAAI/bge-small-zh-v1.5')
model.save('./bge-small-zh-v1.5')
# 使用:替换成本地目录
model = SentenceTransformer("./bge-small-zh-v1.5")
4. 构建 FAISS 索引
python
# 创建 IndexFlatIP(使用 Cosine 相似度需先归一化)
dim = embeddings.shape[1]
index = faiss.IndexFlatIP(dim)
index.add(embeddings.astype('float32'))
实战二:向量检索 + 问句匹配(含代码)
完成索引构建后,我们就可以让系统回答"语义问题"了。
1. 输入问句,向量化
python
# 查询向量
query = "公司法人要承担哪些责任?"
query_vec = model.encode([query], normalize_embeddings=True)
2. 使用 FAISS 执行搜索
python
# 查询最相似的 top-k 向量
k = 2
D, I = index.search(query_vec.astype('float32'), k)
# 输出检索结果
for rank, idx in enumerate(I[0]):
print(f"[Top {rank+1}] {texts[idx]}")
>>>:
[Top 1] 第七条:公司是企业法人,有独立的法人财产。
[Top 2] 第八条:公司以其全部财产对公司债务承担责任。
3. 构建简单 QA 返回结构
python
def ask(query: str):
query_vec = model.encode([query], normalize_embeddings=True)
D, I = index.search(query_vec.astype('float32'), k=3)
context = "\n".join([f"[{i+1}] {texts[j]}" for i, j in enumerate(I[0])])
prompt = f"请根据以下资料回答问题:\n{context}\n\n问题:{query}"
return prompt
将 prompt 输入本地 LLM完成 RAG 闭环。
4. 保存与加载索引
python
# 保存向量索引
faiss.write_index(index, "law_faiss.index")
# 保存原文
import json
with open("law_docs.json", "w", encoding="utf-8") as f:
json.dump(texts, f, ensure_ascii=False, indent=2)
# 读取向量索引
index = faiss.read_index("law_faiss.index")
# 读取原文json文件
with open("law_docs.json", "r", encoding="utf-8") as f:
docs = json.load(f)
保存向量索引作用:
-
将当前内存中的 Faiss 索引对象
index序列化并保存成文件law_faiss.index。 -
类似于"模型持久化",以后可直接加载,无需再次计算向量或重新构建索引。
保存向量索引内容包含:
-
所有向量 embedding
-
索引结构(IndexFlatIP 或其他结构)
-
元数据如:维度、数量等
为什么要保存原文?
FAISS 只保存向量,不保存文本。
未来做查询时返回的是文本下标,比如:
python
I = [[3, 1]]
必须加载原始文档使向量查询返回的文本下标与文本内容对应上,才能得到:
python
docs[3] → "第八条..."
docs[1] → "股东大会..."
实战小结
| 步骤 | 内容描述 |
|---|---|
| 文本处理 | 对文本进行段落分割处理,并清除空行 |
| 向量生成 | 使用 sentence-transformers 模型将文本编码为向量 |
| FAISS 索引构建 | 采用 IndexFlatIP 方法构建索引(支持余弦相似度计算) |
| 查询处理 | 将查询问句向量化后,返回 TopK 个最相似的原文段落 |
| 模型输入 | 将检索结果组织成 Prompt 格式输入大语言模型(详见下一节 RAG 集成说明) |
优化与进阶:提升 FAISS 检索性能与准确率
1. 使用索引结构提升搜索效率
在实际项目中,当你面对的是成千上万条向量数据 ,或者需要更高检索精度与更快响应 时,仅靠 IndexFlatIP 已经不够。
FAISS 提供了丰富的高级索引结构与优化手段,以下是最推荐实用的几种。
IndexFlatIP(默认)
- 精度:⭐⭐⭐⭐⭐
- 速度:⭐⭐
- 特点:暴力精确匹配,慢但稳
- 适合小规模数据(≤5万条)
IndexIVFFlat(倒排索引)
python
quantizer = faiss.IndexFlatIP(dim)
index = faiss.IndexIVFFlat(quantizer, dim, nlist)
index.train(embeddings)
index.add(embeddings)
- 精度:⭐⭐⭐⭐
- 速度:⭐⭐⭐⭐
- 特点:先聚类再搜索,仅查部分分区
- 适合 10万~100万 级别数据
nlist(聚类数)建议设置为 sqrt(N)
IndexHNSWFlat(图结构检索)
python
index = faiss.IndexHNSWFlat(dim, M=32)
- 精度:⭐⭐⭐⭐⭐
- 速度:⭐⭐⭐
- 特点:构建小世界图,性能介于暴力和倒排之间
- 适合中等规模数据、精度要求高场景
2. 向量归一化 + Cosine 相似度
很多向量模型输出本质是方向(单位向量),不是位置。因此推荐使用余弦相似度:
python
# 对所有向量归一化(单位向量)
embeddings = embeddings / np.linalg.norm(embeddings, axis=1, keepdims=True)
# 使用 IndexFlatIP(点积 = 余弦相似度)
index = faiss.IndexFlatIP(dim)
index.add(embeddings)
3. 向量去重与裁剪高频信息
- 若一个段落多次出现,或多个片段高度相似,会导致"TopK 全部命中一样的内容";
- 建议引入 hash 或简单文本比较去重;
- 可以对嵌入向量用 PCA 做降噪压缩处理(参考:
faiss.PCAMatrix)
4. 分类型构建多个索引(可选)
faiss_index_law.index → 法律文档向量库
faiss_index_policy.index → 政策类向量库
faiss_index_case.index → 判例向量库