向量数据库Faiss的搭建与利用

打印 上一主题 下一主题

主题 1730|帖子 1730|积分 5194

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Faiss 是 Facebook AI 研究院开发的一种高效的相似性搜索和聚类库,能够快速处理大规模数据,并支持在高维空间中进行相似性搜索。以下是 Faiss 的搭建与利用步骤:
安装 Faiss
首先,需要在体系上安装 Faiss。它支持 Linux、macOS 和 Windows 操作体系,可以通过 Python 的 pip 包管理器进行安装。在终端中输入以下命令:
  1. pip install faiss-cpu
复制代码
假如你的体系有 NVIDIA 的 GPU 而且已经安装了 CUDA,你可以选择安装支持 GPU 的版本:
  1. pip install faiss-gpu
复制代码
基本利用示例
1、导入所需库:
  1.     import numpy as np
  2.     import faiss
复制代码
2、生成随机数据作为向量数据库:
  1.     d = 128  # 维度
  2.     nb = 10000  # 数据库大小
  3.     np.random.seed(1234)  # 使结果可重复
  4.     xb = np.random.random((nb, d)).astype('float32')
复制代码
3、创建索引(这里利用最简朴的 L2 距离索引):
  1.     index = faiss.indexflatl2(d)  # 构建索引
  2.     print(index.is_trained)  
复制代码
4、将数据添加到索引中:
  1.     index.add(xb)  # 添加向量到索引
  2.     print(index.ntotal)  
复制代码
5、生成查询向量并进行搜索:
  1.     nq = 5  # 查询向量数量
  2.     k = 4  # 想要的相似向量数量
  3.     xq = np.random.random((nq, d)).astype('float32')
  4.     d, i = index.search(xq, k)  # 进行搜索
复制代码
在上述示例中,i 是一个数组,它包含了每个查询向量的最近的 k 个向量的索引;d 是一个数组,它包含了这些向量的距离。

利用 Faiss 进行图片或文件搜索

图片搜索时,通常需要通过深度学习模型(如 CNN)将图片转换为向量。比方利用预练习的 ResNet 模型将图片转换为向量:
  1. from torchvision import models, transforms
  2. from PIL import Image
  3. # 加载预训练模型
  4. model = models.resnet50(pretrained=True)
  5. model = model.eval()
  6. # 定义图片变换
  7. transform = transforms.Compose([
  8.     transforms.Resize(256),
  9.     transforms.CenterCrop(224),
  10.     transforms.ToTensor(),
  11.     transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
  12. ])
  13. # 加载图片
  14. image = Image.open('image.jpg')
  15. # 应用变换并获取图片向量
  16. image = transform(image).unsqueeze(0)
  17. image_vector = model(image).detach().numpy()
复制代码
然后将这个向量添加到 Faiss 的索引中,进行相似图片搜索。
文件搜索时,一样平常通过自然语言处理模型(如 BERT)将文件转换为向量。比方利用预练习的 BERT 模型将文本文件转换为向量:
  1. from transformers import BertModel, BertTokenizer
  2. # 加载预训练模型和分词器
  3. model = BertModel.from_pretrained('bert-base-uncased')
  4. tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
  5. # 加载文本文件
  6. with open('file.txt', 'r') as f:
  7.     text = f.read()
  8. # 分词并获取文本向量
  9. inputs = tokenizer(text, return_tensors='pt')
  10. outputs = model(**inputs)
  11. text_vector = outputs.last_hidden_state.mean(dim=1).detach().numpy()
复制代码
再将该向量添加到 Faiss 索引中,实现相似文件搜索。
Faiss 中不同索引范例的先容与选择


  • indexflatl2:利用欧氏距离(L2)进行准确检索。假如采用此索引结构,查询向量需要和索引中每个向量计算 L2 距离,然后进行排序,末了将距离较小的前 k 个结果返回。注意:indexflatl2 索引不需要练习过程。
  • indexivfflat:利用倒排索引结构,将数据集划分为多个聚类空间,以加速搜索。在查询阶段,首先定位到大概包含相似向量的聚类中央,然后在该聚类中央附近进行准确搜索。构建索引时需要指定聚类空间的数量 nlist,并进行练习。
  • indexivfpq:利用 product quantization(PQ)技术进行有损压缩,以节省内存。在查询阶段,返回近似结果。需要指定空间拆分的数量 m 和聚类空间的数量 nlist,同样要进行练习。
  • indexhnswflat:基于图索引的方式,包括 regular graph(图中每个顶点具有相同数目的邻居)、random graph(图中每个顶点的邻居数是随机的)和 small world graph(介于 regular 与 random 之间)。此中 hnsw 是 hierarchical navigable small world 的缩写,即分层的 NSW。它整体可分为图构造过程和图检索过程,通过构建分层的 NSW 图来进步搜索服从。
在选择索引范例时,可以考虑以下因素:



  • 简朴场景:假如只需较少次查询,发起利用 “flat” 索引直接计算,由于建索引时间不能被查询时间弥补。假如全部数据不能放入 RAM 内存,则可分多次构建小索引,末了再将小索引查询结果合并。假如需要确切结果,则需要利用 indexflatl2 大概 indexflatip。
  • 内存考量:假如不关注(如内存较大或数据集较小),hnsw 是较好的选择,它不仅快而且准。比 hnsw 更快的选择是 ivf1024, pqnx4fs, rflat。假如稍微考虑内存,则采用先聚类再 “flat” 索引的方式。假如内存比力紧张,则采用 opqm_d,…, pqmx4fsr,此中 opq 用来降维,pq 对向量进行量化。假如非常紧张,则采用 opqm_d,…, pqm,此中 d 和 m 有特定要求。
  • 数据集大小:假如数据集大小在 100 万以下,可采用 …, ivfk,…;在 100 万到 1000 万之间,可采用 …, ivf65536_hnsw32,…,练习向量数发起在 30 * 65536 和 256 * 65536 之间;在 1000 万到 1 亿之间,可采用 …, ivf262144_hnsw32,…,练习向量数发起在 30 * 262144 和 256 * 262144 之间;在 1 亿以上,可采用 …, ivf1048576_hnsw32,…,练习向量数发起在 30 * 1048576 和 256 * 1048576 之间。

实际应用中,需根据详细的需求和数据特点来选择符合的索引范例,以平衡搜索速度、准确性和内存占用等因素。同时,Faiss 还提供了一些高级功能和优化选项,可以根据详细环境进一步调解和优化搜索性能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表