Faiss的学习和基本使用

📅 发布时间:2026/7/10 13:55:54 👁️ 浏览次数:
Faiss的学习和基本使用
Faiss的学习和基本使用Faiss 简介Faiss的核心Faiss工作数据流这种方式的巨大优势局限性也是考虑使用 Qdrant/LanceDB 等数据库的原因Faiss 索引总结与建议Faiss 简介FAISScpugpu[Facebook AI Similarity Search]是针对海量稠密向量进行相似性搜索和聚类的一个高效类库。该开源库针对高维空间中的海量数据稠密向量提供了高效且可靠的相似性聚类和检索方法可支持十亿级别向量的搜索是目前最为成熟的近似近邻搜索库官方资源地址https://github.com/facebookresearch/faiss1.它包含可搜索任意大小的向量集的算法这些向量集的大小甚至都不适合RAM。2.它还包含用于评估和参数调整的支持代码。3.Faiss用C 编写并且有python2与python3的封装代码。4.一些最有用的算法在GPU上有实现。5.Faiss是由Facebook AI Research开发的本质上是一个 C 库提供 Python 绑定通常需要自行嵌入到应用中并管理存储和服务。极致的搜索速度和算法丰富性专注于 ANN 算法由 Meta 开发维护社区活跃。FAISS不提供数据持久化需结合其他存储系统。通过 API 调用搜索算法。适用于学术研究算法实验对搜索速度有极致要求的嵌入应用需要高度自定义存储和服务的场景。主要关注 C 和 Python需要自行处理存储、服务化等周边设施。Faiss的核心Faiss本质上是一个向量矢量数据库。进行搜索时基础是原始向量数据库基本单位是单个向量默认输入一个向量x返回和x最相似的k个向量。其中的核心就是索引index对象Index继承了一组向量库作用是对原始向量集进行预处理和封装一般操作包括train和add可以建成一个索引对象缓存在计算机内存中。所有向量在建立前需要明确向量的维度d大多数的索引还需要训练阶段来分析向量的分布除了IndexFlatL2。当索引被建立就可以进行后续的search操作了。Train目的生成原向量中心点残差(向量中心点的差值)向量中心点部分预计算的距离流程1把原始向量分成M个子空间针对每个子空间训练中心点(如果每个子空间的中心点为n则pq可表达n的M次方个中心点)。2查找向量对应的中心点3向量减去对应的中心点生成残差向量4针对残差向量生成二级量化器。SearchSearch操作时索引的重要部分search方法涉及实际的相似度计算返回的检索结果包括两个矩阵分别为xq中元素与近邻的距离大小和近邻向量的索引序号。Faiss工作数据流在使用Faiss进行query向量的相似性搜索之前需要将原始的向量集构建封装成一个索引文件index file并缓存在内存中提供实时的查询计算。在第一次构建索引文件的时候需要经过Train和Add两个过程。后续如果有新的向量需要被添加到索引文件的话还可以有一个Add操作从而实现增量build索引。索引构建Indexing读取文档库如 PDF、TXT、Word 等。使用嵌入模型Embedding Model将每一段文本转换为向量vector。使用 FAISS 将所有向量构建成一个索引Index。将 FAISS 索引保存到一个文件中通常是.index文件。同时需要将文本内容或指向原文的引用及其对应的元数据如文件名、标题、页码等单独保存到另一个文件中如 JSON、Parquet 或 pickle 文件。这一步至关重要因为 FAISS 只存储向量不存储原始文本。检索Retrieval加载 FAISS 索引文件和文本元数据文件到内存。当用户输入一个查询关键字或问题时先用同样的嵌入模型将其转换为查询向量。使用 FAISS 的search方法在索引中查找与查询向量最相似的 K 个向量。FAISS 返回的是最相似向量的索引 ID 和相似度分数。根据这些索引 ID去之前保存的文本元数据文件中找到对应的原始文本段落。将这些文本段落作为上下文与用户问题一起发送给 LLM 生成最终答案。demoimportfaissimportnumpyasnpfromsentence_transformersimportSentenceTransformer BEG模型 在MTEB/C-MTEB基准测试中综合排名第一中文技术文档适配性最佳 提供多版本选择bge-large-zh1024维、bge-base-zh768维、bge-small-zh512维 支持动态维度压缩技术可在保持95%检索精度下将向量维度降低60% 集成Reranker模型实现「召回精排」两阶段优化流程 encoderSentenceTransformer(./model/bge-large-zh-v1.5)defgenerate_embeddings(texts):生成标准化的嵌入向量# 批量编码embeddingsencoder.encode(texts,convert_to_numpyTrue,batch_size32,show_progress_barFalse)# 转换为float32并L2归一化embeddingsembeddings.astype(np.float32)faiss.normalize_L2(embeddings)returnembeddingsdefreate_faiss_index(embeddings): # 步骤3构建FAISS索引 :return: dimensionembeddings.shape[1]# 自动获取向量维度indexfaiss.IndexFlatIP(dimension)# 使用内积相似度index.add(embeddings)returnindexdefsearch(query,index,records,top_k10):执行语义搜索 query: 需要检索的语句 index: faiss构建的索引 records 构建索引的原始数据 # 生成查询向量query_embeddingencoder.encode([query],convert_to_numpyTrue)query_embeddingquery_embedding.astype(np.float32)faiss.normalize_L2(query_embedding)# 执行搜索distances,indicesindex.search(query_embedding,top_k)# 组装结果results[]fori,(score,idx)inenumerate(zip(distances[0],indices[0])):sourcerecords[idx]results.append({rank:i1,score:float(score),path:source[path],content:source[content]})foriinresults:print(i)return\n\n.join([f#{r.get(path)}\n{r.get(content)}forrinresultsifr.get(score)0.5])这种方式的巨大优势极致的性能FAISS 是为速度而生的其搜索性能通常优于大多数通用的向量数据库。架构简单系统中没有额外的外部数据库依赖只有的应用和几个文件。这大大降低了部署和运维的复杂度。成本极低完全免费无需为数据库服务支付任何费用。轻量级非常适合嵌入式部署、桌面应用或资源受限的环境。局限性也是考虑使用 Qdrant/LanceDB 等数据库的原因当的应用需求超出基本检索时纯 FAISS 方案的短板就会显现元数据过滤Metadata Filtering问题搜索“仅来自2023年财报PDF中、第二章的、与财务数据相关的内容”。这涉及到对文件名、日期、章节等多条件的过滤。FAISS无法实现。FAISS 只能做纯向量相似性搜索。必须先通过向量搜索出所有相似内容然后在内存中自己对结果进行过滤效率低下且不精确。向量数据库原生支持。Qdrant 等可以在执行向量搜索的同时精确地按元数据条件进行过滤高效且准确。动态更新Dynamic Updates问题的文档库需要频繁增删改例如每天新增几篇新闻。FAISS虽然支持增量添加但每次添加新数据后为了最优性能通常需要重新生成整个索引并保存为新文件这是一个很重的操作。向量数据库原生支持实时、低延迟的单条数据插入、删除和更新对应用层完全透明。持久化与管理Persistence Management问题索引文件很大如何版本化管理如何备份如何实现高可用FAISS需要自己写脚本管理不同版本的.index和.json文件这很容易变得混乱。向量数据库内置了数据持久化、备份、监控等功能开箱即用。多模态与生产级特性问题需要处理图片、视频等多模态数据或者需要分布式、访问控制、API 接口等生产环境特性。FAISS不提供这些功能。向量数据库LanceDB 天然支持多模态Qdrant 等提供了完整的生产级分布式解决方案和 REST/gRPC API。Faiss 索引Faiss是为稠密向量提供高效相似度搜索的框架(Facebook AI Research选择索引方式是faiss的核心内容faiss 三个最常用的索引是IndexFlatL2, IndexIVFFlat,IndexIVFPQ。IndexFlatL2/ IndexFlatIP为最基础的精确查找。暴力精确检索全局最优适合数十万级。IndexIVFFlat称为倒排文件索引是使用K-means建立聚类中心通过查询最近的聚类中心比较聚类中的所有向量得到相似的向量是一种加速搜索方法的索引。倒排暴力检索(100聚类后暴力检索)非全局最优但召回高适合数百万级IndexIVFPQ是一种减少内存的索引方式IndexFlatL2和IndexIVFFlat都会全量存储所有的向量在内存中面对大数据量faiss提供一种基于Product Quantizer(乘积量化)的压缩算法编码向量到指定字节数来减少内存占用。但这种情况下存储的向量是压缩过的所以查询的距离也是近似的。检索复杂度log(logn)适合千万上亿规模以及更大规模的图索引缺点是构建索引过程较慢占用很大的存储。总结与建议特性FAISS独立文件模式Qdrant / LanceDB 等向量数据库核心功能极速的向量相似性搜索向量搜索 数据管理架构简单无外部依赖需要单独部署/维护数据库服务元数据过滤困难需在内存中手动处理原生支持高效精确动态更新笨重通常需全量重建原生支持实时高效持久化与运维需自行管理文件内置开箱即用扩展性有限高分布式、多模态、API等对于文档相对静态、不需要复杂元数据过滤、且追求简单性和极致性能的 RAG 项目单独使用 FAISS 是最优解。如果项目出现以下需求时才需要考虑升级到完整的向量数据库。需要对搜索结果进行复杂的条件过滤。文档库需要频繁、实时地更新。系统需要扩展到分布式环境或需要高可用性。不想手动处理索引文件和元数据文件之间的映射关系。许多流行的 RAG 框架如 LangChain, LlamaIndex都同时支持 FAISS 和各类向量数据库也印证了这两种方案在不同的场景下各有其不可替代的价值。愿你我都能在各自的领域里不断成长勇敢追求梦想同时也保持对世界的好奇与善意!