faiss的简单使用
简介
faiss是为稠密向量提供高效相似度搜索和聚类的框架。由Facebook AI Research研发。 具有以下特性。
- 1、提供多种检索方法
- 2、速度快
- 3、可存在内存和磁盘中
- 4、C++实现,提供Python封装调用。
- 5、大部分算法支持GPU实现
下面给出一些快速链接方便查找更多内容。
github
官方文档
c++类信息
Troubleshooting
官方安装文档
安装
文档中给出来编译安装,conda等安装方式。因为公司服务器编译安装需要权限,所有我们一般使用conda的方式安装python Module。
# 更新conda
conda update conda
# 先安装mkl
conda install mkl
# faiss提供gpu和cpu版,根据服务选择
conda install faiss-cpu -c pytorch # cpu
conda install faiss-gpu -c pytorch # gpu
# 校验是否安装成功
python -c "import faiss"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Quick Start
这里先给出官方提供的demo来感受一下faiss的使用。
首先构建训练数据和测试数据
import numpy as np
d = 64 # dimension
nb = 100000 # database size
nq = 10000 # nb of queries
np.random.seed(1234) # make reproducible
xb = np.random.random((nb, d)).astype('float32')
xb[:, 0] += np.arange(nb) / 1000.
xq = np.random.random((nq, d)).astype('float32')
xq[:, 0] += np.arange(nq) / 1000.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
上面我们构建了shape为[100000,64]
的训练数据xb
,和shape为[10000,64]
的查询数据xq
。
然后创建索引(Index)。faiss创建索引对向量预处理,提高查询效率。
faiss提供多种索引方法,这里选择最简单的暴力检索L2距离的索引:IndexFlatL2
。
创建索引时必须指定向量的维度d。大部分索引需要训练的步骤。IndexFlatL2
跳过这一步。
当索引创建好并训练(如果需要)之后,我们就可以执行add
和search
方法了。add
方法一般添加训练时的样本,search
就是寻找相似相似向量了。
一些索引可以保存整型的ID,每个向量可以指定一个ID,当查询相似向量时,会返回相似向量的ID及相似度(或距离)。如果不指定,将按照添加的顺序从0开始累加。其中IndexFlatL2
不支持指定ID。
import faiss # make faiss available
index = faiss.IndexFlatL2(d) # build the index
print(index.is_trained)
index.add(xb) # add vectors to the index
print(index.ntotal)
- 1
- 2
- 3
- 4
- 5
我们有了包含向量的索引后,就可以传入搜索向量查找相似向量了。
k = 4 # we want to see 4 nearest neighbors
D, I = index.search(xq, k) # actual search
print(I[:5]) # neighbors of the 5 first queries
print(D[-5:]) # neighbors of the 5 last queries
- 1
- 2
- 3
- 4
上面代码中,我们定义返回每个需要查询向量的最近4个向量。查询返回两个numpy array对象D
和I
。D
表示与相似向量的距离(distance),维度,I
表示相似用户的ID。
我们可以得到类似于下面的结果
[[ 0 393 363 78]
[ 1 555 277 364]
[ 2 304 101 13]
[ 3 173 18 182]
[ 4 288 370 531]]
[[ 0. 7.17517328 7.2076292 7.25116253]
[ 0. 6.32356453 6.6845808 6.79994535]
[ 0. 5.79640865 6.39173603 7.28151226]
[ 0. 7.27790546 7.52798653 7.66284657]
[ 0. 6.76380348 7.29512024 7.36881447]]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
加速搜索
如果需要存储的向量太多,通过暴力搜索索引IndexFlatL2
速度很慢,这里介绍一种加速搜索的方法的索引IndexIVFFlat
。翻译过来叫倒排文件,其实是使用K-means建立聚类中心,然后通过查询最近的聚类中心,然后比较聚类中的所有向量得到相似的向量。
创建IndexIVFFlat时需要指定一个其他的索引作为量化器(quantizer)来计算距离或相似度。
这里同使用IndexFlatL2
对比,在add
方法之前需要先训练。
下面简述示例中的几个参数。
faiss.METRIC_L2
: faiss定义了两种衡量相似度的方法(metrics),分别为faiss.METRIC_L2
、faiss.METRIC_INNER_PRODUCT
。一个是欧式距离,一个是向量内积。
nlist
:聚类中心的个数
k
:查找最相似的k个向量
index.nprobe
:查找聚类中心的个数,默认为1个。
代码示例如下
nlist = 100 #聚类中心的个数
k = 4
quantizer = faiss.IndexFlatL2(d) # the other index
index = faiss.IndexIVFFlat(quantizer, d, nlist, faiss.METRIC_L2)
# here we specify METRIC_L2, by default it performs inner-product search
assert not index.is_trained
index.train(xb)
assert index.is_trained
index.add(xb) # add may be a bit slower as well
D, I = index.search(xq, k) # actual search
print(I[-5:]) # neighbors of the 5 last queries
index.nprobe = 10 # default nprobe is 1, try a few more
D, I = index.search(xq, k)
print(I[-5:]) # neighbors of the 5 last queries
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
减少内存
2018-02-22之后版本添加了磁盘存储inverted indexes的方式,使用可参考demo.
上面我们看到的索引IndexFlatL2
和IndexIVFFlat
都会全量存储所有的向量在内存中,为满足大的数据量的需求,faiss提供一种基于Product Quantizer(乘积量化)的压缩算法编码向量大小到指定的字节数。此时,存储的向量时压缩过的,查询的距离也是近似的。关于乘积量化的算法可自行搜索。
下面给出demo。类似IndexIVFFlat
,这里使用的是IndexIVFPQ
nlist = 100
m = 8 # number of bytes per vector
k = 4
quantizer = faiss.IndexFlatL2(d) # this remains the same
index = faiss.IndexIVFPQ(quantizer, d, nlist, m, 8)
# 8 specifies that each sub-vector is encoded as 8 bits
index.train(xb)
index.add(xb)
D, I = index.search(xb[:5], k) # sanity check
print(I)
print(D)
index.nprobe = 10 # make comparable with experiment above
D, I = index.search(xq, k) # search
print(I[-5:])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
之前我们定义的维度为d = 64
,向量的数据类型为float32
。这里压缩成了8个字节。所以压缩比率为 (64*32/8) / 8 = 32
返回的结果如下,第一个向量同自己的距离为1.40704751,不是0。因为如上所述返回的是近似距离,但是整体上返回的最相似的top k的向量ID没有变化。
[[ 0 608 220 228]
[ 1 1063 277 617]
[ 2 46 114 304]
[ 3 791 527 316]
[ 4 159 288 393]]
[[ 1.40704751 6.19361687 6.34912491 6.35771513]
[ 1.49901485 5.66632462 5.94188499 6.29570007]
[ 1.63260388 6.04126883 6.18447495 6.26815748]
[ 1.5356375 6.33165455 6.64519501 6.86594009]
[ 1.46203303 6.5022912 6.62621975 6.63154221]]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
简化索引的表达
通过上面IndexIVFFlat
和IndexIVFPQ
我们可以看到,他们的构造需要先提供另外一个index。类似的,faiss还提供pca、lsh等方法,有时候他们会组合使用。这样组合的对构造索引会比较麻烦,faiss提供了通过字符串表达的方式构造索引。
如,下面表达式就能表示上面的创建IndexIVFPQ
的实例。
index = faiss.index_factory(d, "IVF100,PQ8")
- 1
这里有一点文档中没有提到的,通过查看c++代码,index_factory
方法还有第三个参数,就是上面说的metric。可传入的就上面两种。
Index *index_factory (int d, const char *description_in, MetricType metric)
- 1
更多的组合实例可以看demo
每类索引的简写可查询Basic indexes
GPU使用
注意有些索引不支持GPU,哪些支持哪些不支持可查询Basic indexes
可通过faiss.get_num_gpus()
查询有多少个gpu
ngpus = faiss.get_num_gpus()
print("number of GPUs:", ngpus)
- 1
- 2
使用gpu的完整示例。
1、使用一块gpu
# build a flat (CPU) index
index_flat = faiss.IndexFlatL2(d)
# make it into a gpu index
gpu_index_flat = faiss.index_cpu_to_gpu(res, 0, index_flat)
- 1
- 2
- 3
- 4
2、使用全部gpu
cpu_index = faiss.IndexFlatL2(d)
gpu_index = faiss.index_cpu_to_all_gpus(cpu_index) # build the index
gpu_index.add(xb) # add vectors to the index
print(gpu_index.ntotal)
k = 4 # we want to see 4 nearest neighbors
D, I = gpu_index.search(xq, k) # actual search
print(I[:5]) # neighbors of the 5 first queries
print(I[-5:]) # neighbors of the 5 last queries
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
faiss的简单使用的更多相关文章
- Centos 7.3 编译 & 安装 & 测试 facebook faiss
许多 AI 系统训练完毕,正式上线时的基本操作往往可以抽象为:在高维向量空间中,给定一个向量,寻找与之最相近的 k 个向量.当向量数目异常巨大时,如何快速地执行这一基本操作,便成为 AI 系统在工程应 ...
- faiss索引基于数量级和内存限制的选择
它是一个能使开发者快速搜索相似多媒体文件的算法库.而该领域一直是传统的搜索引擎的短板.借助Faiss,Facebook 在十亿级数据集上创建的最邻近搜索(nearest neighbor search ...
- faiss CPU版本+GPU版本安装
faiss安装 faiss是facebook开发的有CPU版本和GPU版本的求密集向量相似性和进行密集向量聚类的库. faiss用c++编写,安装faiss需要在github上下载其c++源码并用ma ...
- Faiss教程:入门
Faiss处理固定维度d的数据,矩阵每一行表示一个向量,每列表示向量的一项.Faiss采用32-bit浮点型存储. 假设xb为数据集,维度为\(nb\times{d}\):xq是查询数据,维度为\(n ...
- 揭开Faiss的面纱 探究Facebook相似性搜索工具的原理
https://www.leiphone.com/news/201703/84gDbSOgJcxiC3DW.html 本月初雷锋网报道,Facebook 开源了 AI 相似性搜索工具 Faiss.而在 ...
- facebook 相似性搜索库 faiss
faiss 个人理解: https://github.com/facebookresearch/faiss 上把代码clone下来,make编译 我们将CNN中经过若干个卷积/激励/池化层后得到的激活 ...
- Faiss流程与原理分析
1.Faiss简介 Faiss是Facebook AI团队开源的针对聚类和相似性搜索库,为稠密向量提供高效相似度搜索和聚类,支持十亿级别向量的搜索,是目前最为成熟的近似近邻搜索库.它包含多种搜索任意大 ...
- milvus和faiss安装及其使用教程
写在前面 高性能向量检索库(milvus & faiss)简介 Milvus和Faiss都是高性能向量检索库,可以让你在海量向量库中快速检索到和目标向量最相似的若干个向量,这里相似度量标准可以 ...
- Faiss源码剖析:类结构分析
摘要:在下文中,我将尝试通过Faiss源码中各种类结构的设计来梳理Faiss中的各种概念以及它们之间的关系. 本文分享自华为云社区<Faiss源码剖析(一):类结构分析>,原文作者:HW0 ...
随机推荐
- BOSCH汽车工程手册————混合驱动
首先放一波资源,一千两百多页的pdf 链接:https://pan.baidu.com/s/15IsvHqOFCnqAKwY_SR4-lA提取码:6wmz 混合驱动 混合驱动有串联驱动并联驱动以及两种 ...
- [转]Tomcat中8005/8009/8080/8443端口的作用
8005:关闭tomcat进程所用.当执行shutdown.sh关闭tomcat时就是连接8005端口执行“SHUTDOWN”命令--由此,我们直接telnet8005端口执行“SHUTDOWN”(要 ...
- 使用docker 部署python 项目
使用python 开发了一个restfu api程序,使用docker镜像部署.主要有如下步骤,简单记录以供以后参考. 1. 创建DockerFile文件 创建一个DockerFile文件,文件名为D ...
- HTML基础汇总
一.HTML的概述(了解) a.html是什么 : hypertext markup language 超文本标记语言 超文本:音频,视频,图片称为超文本.. ...
- python 引流
Python给抖音自动点赞和评论,实现自动化运营! 都说抖音有毒,一刷就停不下来了.看来抖音这款产品紧紧抓住了人们内心深处的某些需求.当然今天不是来探讨抖音这款产品的啊.今天我们来学习如何用 Pyth ...
- wpf的控件style
前段时间一直在做wpf的UI开发,每次想做些控件style定制的时候都很头疼 很多控件不知道他的controltemplate是什么样的 为了方便大家写style 特别奉上wpf的style大全 从此 ...
- 如何利用Nginx的缓冲、缓存优化提升性能
使用缓冲释放后端服务器 反向代理的一个问题是代理大量用户时会增加服务器进程的性能冲击影响.在大多数情况下,可以很大程度上能通过利用Nginx的缓冲和缓存功能减轻. 当代理到另一台服务器,两个不同的连接 ...
- Python学习之==>面向对象编程(二)
一.类的特殊成员 我们在Python学习之==>面向对象编程(一)中已经介绍过了构造方法和析构方法,构造方法是在实例化时自动执行的方法,而析构方法是在实例被销毁的时候被执行,Python类成员中 ...
- 安装kafka 记录
sudo ./zoo /zoo /bin/zkServer.sh start sudo ./kafkacluster/kafka1/bin/kafka-server-start.sh ./kafkac ...
- 逻辑回归2-scikit-learn参数介绍
1.1 scikit-learn参数介绍 1.1.1 导入 from sklearn.linear_model import LogisticRegression 1.1.2 版本 sci ...