AIGC:【LLM(五)】——Faiss:高效的大规模相似度检索库

文章目录

    • 一.简介
      • [1.1 什么是Faiss](#1.1 什么是Faiss)
      • [1.2 Faiss的安装](#1.2 Faiss的安装)
    • 二.Faiss检索流程
      • [2.1 构建向量库](#2.1 构建向量库)
      • [2.2 构建索引](#2.2 构建索引)
      • [2.3 top-k检索](#2.3 top-k检索)
    • 三.Faiss构建索引的多种方式
      • [3.1 Flat :暴力检索](#3.1 Flat :暴力检索)
      • [3.2 IVFx Flat :倒排暴力检索](#3.2 IVFx Flat :倒排暴力检索)
      • [3.3 IVFxPQy 倒排乘积量化](#3.3 IVFxPQy 倒排乘积量化)
      • [3.4 LSH 局部敏感哈希](#3.4 LSH 局部敏感哈希)
      • [3.5 HNSWx](#3.5 HNSWx)

一.简介

1.1 什么是Faiss

Faiss的全称是Facebook AI Similarity Search,是Facebook的AI团队针对大规模相似度检索问题开发的一个工具,使用C++编写,有python接口,对10亿量级的索引可以做到毫秒级检索的性能。

简单来说,Faiss的工作就是把我们自己的候选向量集封装成一个index数据库,它可以加速我们检索相似向量top-K的过程,其中有些索引还支持GPU构建。

1.2 Faiss的安装

bash 复制代码
## cpu版
$ conda install -c pytorch faiss-cpu
## gpu版
$ conda install -c pytorch faiss-gpu

二.Faiss检索流程

2.1 构建向量库

这一部分就是将我们已有的数据转成向量库。

python 复制代码
import numpy as np
d = 64                                           # 向量维度
nb = 100000                                      # index向量库的数据量
nq = 10000                                       # 待检索query的数目
np.random.seed(1234)             
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.                # index向量库的向量
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.                # 待检索的query向量

2.2 构建索引

用faiss 构建index,并将向量添加到index中。这里我们选用暴力检索的方法FlatL2,L2代表构建的index采用的相似度度量方法为L2范数,即欧氏距离。

python 复制代码
import faiss          
index = faiss.IndexFlatL2(d)             
print(index.is_trained)         # 输出为True,代表该类index不需要训练,只需要add向量进去即可
index.add(xb)                   # 将向量库中的向量加入到index中
print(index.ntotal)             # 输出index中包含的向量总数,为100000 

2.3 top-k检索

检索与query最相似的top-k。

python 复制代码
k = 4                     # topK的K值
D, I = index.search(xq, k)# xq为待检索向量,返回的I为每个待检索query最相似TopK的索引list,D为其对应的距离
print(I[:5])
print(D[-5:])

三.Faiss构建索引的多种方式

构建index方法和传参方法可以为:

python 复制代码
dim, measure = 64, faiss.METRIC_L2
param = 'Flat'
index = faiss.index_factory(dim, param, measure)
  • dim为向量维数
  • 最重要的是param参数,它是传入index的参数,代表需要构建什么类型的索引;
  • measure为度量方法,目前支持两种,欧氏距离和inner product,即内积。因此,要计算余弦相似度,只需要将vecs归一化后,使用内积度量即可。

此外,Faiss官方支持八种度量方式,分别是:

1)METRIC_INNER_PRODUCT(内积)

2)METRIC_L1(曼哈顿距离)

3)METRIC_L2(欧氏距离)

4)METRIC_Linf(无穷范数)

5)METRIC_Lp(p范数)

6)METRIC_BrayCurtis(BC相异度)

7)METRIC_Canberra(兰氏距离/堪培拉距离)

8)METRIC_JensenShannon(JS散度)

3.1 Flat :暴力检索

  • 优点:该方法是Faiss所有index中最准确的,召回率最高的方法,没有之一;
  • 缺点:速度慢,占内存大。
  • 使用情况:向量候选集很少,在50万以内,并且内存不紧张。
  • Ps:虽然都是暴力检索,faiss的暴力检索速度比一般程序猿自己写的暴力检索要快上不少,所以并不代表其无用武之地,建议有暴力检索需求的同学还是用下faiss。
  • 构建方法
python 复制代码
dim, measure = 64, faiss.METRIC_L2
param = 'Flat'
index = faiss.index_factory(dim, param, measure)
index.is_trained                                   # 输出为True
index.add(xb)                                      # 向index中添加向量

3.2 IVFx Flat :倒排暴力检索

  • 优点:IVF主要利用倒排的思想,在文档检索场景下的倒排技术是指,一个kw后面挂上很多个包含该词的doc,由于kw数量远远小于doc,因此会大大减少了检索的时间。在向量中如何使用倒排呢?可以拿出每个聚类中心下的向量ID,每个中心ID后面挂上一堆非中心向量,每次查询向量的时候找到最近的几个中心ID,分别搜索这几个中心下的非中心向量。通过减小搜索范围,提升搜索效率。
  • 缺点:速度也还不是很快。
  • 使用情况:相比Flat会大大增加检索的速度,建议百万级别向量可以使用。
  • 参数:IVFx中的x是k-means聚类中心的个数
  • 构建方法
python 复制代码
dim, measure = 64, faiss.METRIC_L2 
param = 'IVF100,Flat'                           # 代表k-means聚类中心为100,   
index = faiss.index_factory(dim, param, measure)
print(index.is_trained)                          # 此时输出为False,因为倒排索引需要训练k-means,
index.train(xb)                                  # 因此需要先训练index,再add向量
index.add(xb)

3.3 IVFxPQy 倒排乘积量化

  • 优点:工业界大量使用此方法,各项指标都均可以接受,利用乘积量化的方法,改进了IVF的k-means,将一个向量的维度切成x段,每段分别进行k-means再检索。
  • 缺点:集百家之长,自然也集百家之短
  • 使用情况:一般来说,各方面没啥特殊的极端要求的话,最推荐使用该方法!
  • 参数:IVFx,PQy,其中的x和y同上
  • 构建方法
python 复制代码
dim, measure = 64, faiss.METRIC_L2  
param =  'IVF100,PQ16'
index = faiss.index_factory(dim, param, measure) 
print(index.is_trained)                          # 此时输出为False,因为倒排索引需要训练k-means, 
index.train(xb)                                  # 因此需要先训练index,再add向量 index.add(xb)
index.add(xb)

3.4 LSH 局部敏感哈希

  • 原理:哈希对大家再熟悉不过,向量也可以采用哈希来加速查找,我们这里说的哈希指的是局部敏感哈希(Locality Sensitive Hashing,LSH),不同于传统哈希尽量不产生碰撞,局部敏感哈希依赖碰撞来查找近邻。高维空间的两点若距离很近,那么设计一种哈希函数对这两点进行哈希计算后分桶,使得他们哈希分桶值有很大的概率是一样的,若两点之间的距离较远,则他们哈希分桶值相同的概率会很小。
  • 优点:训练非常快,支持分批导入,index占内存很小,检索也比较快
  • 缺点:召回率非常拉垮。
  • 使用情况:候选向量库非常大,离线检索,内存资源比较稀缺的情况
  • 构建方法
python 复制代码
dim, measure = 64, faiss.METRIC_L2  
param =  'LSH'
index = faiss.index_factory(dim, param, measure) 
print(index.is_trained)                          # 此时输出为True
index.train(xb) 
index.add(xb)

3.5 HNSWx

  • 优点:该方法为基于图检索的改进方法,检索速度极快,10亿级别秒出检索结果,而且召回率几乎可以媲美Flat,最高能达到惊人的97%。检索的时间复杂度为loglogn,几乎可以无视候选向量的量级了。并且支持分批导入,极其适合线上任务,毫秒级别体验。
  • 缺点:构建索引极慢,占用内存极大(是Faiss中最大的,大于原向量占用的内存大小)
  • 参数:HNSWx中的x为构建图时每个点最多连接多少个节点,x越大,构图越复杂,查询越精确,当然构建index时间也就越慢,x取4~64中的任何一个整数。
  • 使用情况:不在乎内存,并且有充裕的时间来构建index
  • 构建方法
python 复制代码
dim, measure = 64, faiss.METRIC_L2   
param =  'HNSW64' 
index = faiss.index_factory(dim, param, measure)  
print(index.is_trained)                          # 此时输出为True 
index.add(xb)
相关推荐
芝麻粒儿4 小时前
Android修行手册 - 移动端几种常用动画方案对比
aigc·动画·lottie
canonical_entropy4 小时前
DeepSeek AI的技术理解力超越普通程序员--以Delta定制概念的理解为例
低代码·aigc·openai
杀生丸学AI10 小时前
【三维重建】去除瞬态物体Distractor汇总
人工智能·大模型·aigc·三维重建·扩散模型·高斯泼溅·空间智能
几米哥15 小时前
如何构建高效的AI代理系统:LLM应用实践与最佳方案的深度解析
llm·aigc
WebCandy1 天前
EsChatPro 接入国内 DeepSeek 大模型
ai·aigc
云边有个稻草人2 天前
AIGC与娱乐产业:颠覆创意与生产的新力量
aigc·娱乐
猫头虎2 天前
新纪天工 开物焕彩:重大科技成就发布会参会感
人工智能·开源·aigc·开放原子·开源软件·gpu算力·agi
云起无垠2 天前
第79期 | GPTSecurity周报
gpt·aigc
Jeremy_lf2 天前
【生成模型之三】ControlNet & Latent Diffusion Models论文详解
人工智能·深度学习·stable diffusion·aigc·扩散模型
程序员X小鹿2 天前
羡慕了!小红书上3w+点赞的治愈系插图,用这个免费的AI工具,1分钟搞定!(附详细教程)
aigc