Hello,Vector DB|可能是最易上手的 Faiss 教程

news2024/10/10 10:29:11

627507aa870b373914a8dd2087b858b7.png

大家会不会有这样的疑问:

网易云音乐是如何根据我的音乐口味推荐相似歌曲的?淘宝是如何判断我的购买喜好的?手机相册又是如何识别照片中的人脸,并将同一个人的照片归为同一组的?

其实,实现这一切的背后技术就是相似性搜索(有时也被称为最近邻搜索)。相似性搜索在许多人工智能(AI)和机器学习(ML)应用中发挥着核心作用,能够找到与给定查询数据最相似的数据。例如,网易云音乐可以根据用户最喜欢的歌曲,在系统中查询与其最相似的歌曲集,这个过程就叫做相似性搜索。

尽管相似性搜索看起来非常强大,不过背后却存在一个问题,如果数据量非常大,传统的相似性搜索方法可能会十分低效。在此情况下,我们便需要用到 Faiss。Faiss 是 Facebook AI 开发的向量检索库,提供高效可靠的大规模数据相似性搜索解决方案。

本文为 「Hello,Vector Database」系列,将从 Milvus 和 Zilliz Cloud 的源起——Faiss 出发,聚焦 Faiss 的安装方法、最佳实践以及其和向量数据库的对比,话不多说,上 Faiss!

01.

什么是 FAISS?

Faiss 全称为 Facebook AI Similarity Search,也就是 Facebook AI 相似性搜索。Faiss 一个向量检索库,专为处理大规模数据设计。

Faiss 中的核心概念就是“向量相似性”。简单解释一下,向量是一串数字,而向量相似性就是比较两个向量之间有多相似。举个例子,一首歌包含很多元素和特性,我们可以用一个数字来代表一个特性或元素。那么,一首歌就可以用一串数字(也就是向量)来表示。如果你需要搜索与你最喜欢的歌曲相似的歌曲,那么我们就可以通过比较歌曲向量之间的相似性的方法得到答案。

在这个过程中,我们可以使用 Faiss 快速、高效、准确地比较数百万(甚至数十亿)向量之间的相似性 。Faiss 就如同一个超级搜索引擎,能够以闪电般的速度扫描一个大型音乐数据库,从中精准定位到与你最爱歌曲相似的歌曲。

Faiss 的魔力不仅仅只局限在音乐推荐系统,许多日常生活中的应用场景都有可能用到 Faiss,例如图像识别、文本检索、数据聚类、数据分析等。总之,想从海量数据库中迅速找到相似数据,使用 Faiss 准没错。

02.

安装 Faiss

以下教程将展示如何在 Linux 系统上安装 Faiss:

1. 安装 Conda。

在安装 Faiss 之前,先在系统上安装 Conda。Conda 是一个开源软件包和环境管理系统,可在 Windows、macOS 和 Linux 操作系统上运行。根据以下步骤在 Linux 系统上安装 Conda。

2. 从官网下载 Miniconda 安装包(https://docs.conda.io/projects/conda/en/latest/user-guide/install/linux.html)。

3. 完成安装包 Hash 校验。

4. 打开终端,运行以下命令启动安装程序:

bash Miniconda3-latest-Linux-x86_64.sh

5. 安装时,如不确定某些设置,可以选择默认选项,安装完成后可随时更改设置。

6. 安装完成后,关闭终端并重新打开,这一步骤主要目的是确保激活所有更新。

7. 检查安装是否正确。在终端或 Anaconda Prompt 中输入 conda list 并按下回车键。如果安装正确,将出现安装的软件包列表。

接下来便可以通过 Conda 安装 Faiss。Faiss 提供 2 个版本的软件包:CPU 版(faiss-cpu)和 GPU 版(faiss-gpu)

我们可以通过以下 2 种方式,按需选择安装 CPU 或 GPU 版 Faiss:

1. 通过 PyTorch Conda 安装 Faiss(推荐此种安装方式)。

  • 安装 CPU 版

conda install -c pytorch faiss-cpu
  • 安装 GPU 版

conda install -c pytorch faiss-gpu

2. 通过 conda-forge 安装 Faiss。

  • 安装 CPU 版

conda install -c conda-forge faiss-cpu
  • 安装 GPU 版

conda install -c pytorch faiss-gpu

如需查看 Conda 软件包来源,请使用 conda list 命令。

03.

使用 SQuAD 数据集进行演示

现在,我们可以通过示例演示了解 Faiss 功能。本次示例中,将使用斯坦福的问答数据集(SQuAD)。SQuAD 是一个常用的自然语言处理(NLP)数据集,该数据集基于用户在百科中提出的问题,每个问题的答案都来自于对应阅读段落的一段文本,共计 500 多篇文章中的 10 万多个问答配对。

在我们深入学习示例代码前,请先下载 SQuAD 数据集:

1. 下载 SQuAD 数据集(https://rajpurkar.github.io/SQuAD-explorer/)

本文示例将使用 SQuAD 1.1。你可以在此下载 SQuAD 1.1 数据集。下载完成后,请将下载的 JSON 文件(train-v1.1.json)保存在常用文件目录中。

2. 读取下载的 JSON 文件,可以使用 Python JSON 加载数据。

with open('train-v1.1.json', 'r') as file:
    squad_data = json.load(file)

3. 导入函数库

首先,导入所有必要的函数库,NumPy 用于进行数字运算,Faiss 用于进行相似性搜索,JSON 用于加载数据集,NLTK 用于将文本进行分词(tokenize)。

import numpy as np
import faiss
import json
from nltk.tokenize import word_tokenize

4. 加载和预处理数据

第二步中,首先加载 SQuAD 数据集。该数据集是一个 JSON 文件,因此我们可以使用 JSON 模块的 load 函数来加载数据。

with open('train-v1.1.json', 'r') as file:
    squad_data = json.load(file)

数据集加载完成后,需要预处理数据。我们将使用 NLTK 的 word_tokenize 函数对每个段落进行分词。也就是说,使用这个函数,我们可以将一句话拆分为多个单独的单词。随后,我们将每个单词表示为一个独热编码(one-hot encoding)向量。

vocabulary = set(word for article in squad_data['data'] for paragraph in article['paragraphs'] for word in word_tokenize(paragraph['context']))
word_to_index = {word: index for index, word in enumerate(vocabulary)}

def convert_text_to_vector(text):
    words = word_tokenize(text)
    bow_vector = np.zeros(len(vocabulary))
    for word in words:
        if word in word_to_index:
            bow_vector[word_to_index[word]] = 1    return bow_vector

paragraph_vectors = [convert_text_to_vector(paragraph['context']) for article in squad_data['data'] for paragraph in article['paragraphs']]

5. 构建索引

完成加载和预处理数据后,我们可以为这些数据构建 Faiss 索引。本示例将使用 IndexFlatL2 (基本的 L2 索引)的索引类型。

dimension = len(vocabulary)
index = faiss.IndexFlatL2(dimension)
# 将 NumPy 数组转换为 1 个二维数组
paragraph_vectors = np.stack(paragraph_vectors).astype('float32')
index.add(paragraph_vectors)

6. 相似性搜索

建完索引之后就可以开始在数据集中查找与输入的搜索内容最相似的文本段落。

以下是搜索函数:

def search_for_paragraphs(search_term, num_results):
    search_vector = convert_text_to_vector(search_term)
    search_vector = np.array([search_vector]).astype('float32')
    distances, indexes = index.search(search_vector, num_results)
    for i, (distance, index) in enumerate(zip(distances[0], indexes[0])):
        print(f"Result {i+1}, Distance: {distance}")
        print(squad_data['data'][index]['paragraphs'][0]['context'])
        print()

指定搜索项为 “What is the capital of France?(法国的首都在哪里?)” ,且返回 5 个最相似的结果。

search_term = "What is the capital of France?"search_for_paragraphs(search_term, 5)

search_for_paragraphs()首先将我们的搜索项转换为编码向量。然后,使用索引上的 search 方法。使用 search 方法时需要指定我们需要多少个查询结果(也就是 num_results 的值)。search 方法返回 2 个二维数组:一个是最相似结果的向量距离,一个是其索引。我们可以使用索引在数据集中找到实际的段落,最终打印结果包含排名、向量距离和段落文本。

以上示例展示了如何使用 Faiss 查找相似文本片段。当然,Faiss 可以用于更复杂的应用场景,例如在高维空间中进行搜索。

04.

最佳实践与技巧

  • 熟悉数据:在使用 Faiss 前,需要先花一点时间理解数据。可以问自己一些问题,例如:这个数据集的数据量多大?数据信息是否完整?熟悉数据将有助于选择正确 Faiss 索引类型、确定处理数据的最佳方式。

  • 数据预处理:数据预处理情况会极大影响 Faiss 的使用效果。对于文本数据,可以考虑使用更智能的方法将单词转换为数字,例如 TF-IDF 或 Word2Vec 等模型。对于图片数据,可以尝试使用卷积神经网络(CNN)来处理。

  • 选择最适合的索引类型:Faiss 提供多种索引类型,每类索引都有不同的适用场景。有些索引可以高效处理高维度数据,有些索引适用于处理二进制向量,还有些索引则是专为处理海量数据而设计。因此,可以根据大家的需求和实际情况,选择最适合的索引类型。

  • 批量查询:如果有多个查询需要同时运行,可以使用 Faiss 将其一同处理,一次性运行批量查询会更高效,Faiss 针对批式处理进行了优化。

  • 调整参数:Faiss 支持灵活调参,例如构建索引时可以调节数据聚类数和查询次数(nprobe)。默认值并不一定能够发挥某一索引的最大功效。因此,可以尝试调节参数值,寻找最合适的参数设置。

05.

向量数据库 VS Faiss

Faiss 是高效的近似最近邻(ANN)搜索解决方案,不过当面临数千万个向量需要存储和检索,并且同时需要实时响应或更多高级功能时,Faiss 的能力就有限了。

向量数据库可以有效解决这些问题:

  • 向量数据库支持基本的数据增删改查(CRUD)操作,可调节一致性等级,提供条件过滤等功能;

  • 向量数据库能够提供更强大的数据持久性,在灾难恢复和系统可用性方面表现更出色;

  • 向量数据库采用计算存储分离的分布式架构,支持负载平衡、灵活扩展,系统可用性更高;

  • 向量数据库提供多租户、指标监控、RBAC 等高级功能,提供各种编程语言的 SDK 和 RESTful API。

Milvus 是全球首个开源向量数据库,可以存储、索引和管理十亿级向量数据。Zilliz 将 Milvus 作为孵化项目贡献给了 LF AI & Data 基金会,2021 年 6 月,Milvus 从基金会中毕业。Milvus Lite 是由社区活跃成员嵇斌贡献的轻量级 Milvus 版本。

Zilliz Cloud 是基于 Milvus 构建的全托管向量数据库。使用 Zilliz Cloud,可将向量检索速度提高 10 倍多,方便开发人员轻松部署、灵活扩展向量搜索应用。点击【阅读原文】体验 Zilliz Cloud。

06.

总结

本文介绍了什么是 Faiss、如何安装 Faiss 以及如何使用 Faiss。在本文的最后,我们还对比了向量数据库和 Faiss 之间的区别。Faiss 是一个十分有用的工具,可以帮助我们高效搜索海量数据,适用于不同场景。希望大家通过本文能有所启发,并开启新的探索、学习之旅。当然,也欢迎大家继续深入研究 Faiss 提供的各种索引类型,探索更复杂的数据预处理技术,或是尝试自己上手搭建一些向量相似性搜索应用!

本文作者

cb7cc56454b4e12f72482fcb02bdec18.jpeg

Keshav Malik
系统安全程序员

Keshav Malik 是一名系统安全程序员,热衷于自动化、编写代码和探索各种工具和技术。他希望能够使用创新的方法解决各种复杂问题,且热衷于研究各种前沿技术和工具。

🌟「寻找 AIGC 时代的 CVP 实践之星」 专题活动即将启动!

Zilliz 将联合国内头部大模型厂商一同甄选应用场景, 由双方提供向量数据库与大模型顶级技术专家为用户赋能,一同打磨应用,提升落地效果,赋能业务本身。

如果你的应用也适合 CVP 框架,且正为应用落地和实际效果发愁,可直接申请参与活动,获得最专业的帮助和指导!联系邮箱为 business@zilliz.com。

推荐阅读

ae07ead305a93b0bcf4be62e7e4fff1e.png

fea60651db37b2164aa7b16687e344c8.png

842ebbed77b6f654750e2116a07b5496.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/790354.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【nginx】nginx之location规则详解:

文章目录 一、语法规则:二、优先级:三、验证:1、精确匹配:2、通过^~方式实现匹配:3、通过”~”方式实现匹配:4、通过"~*"方式实现匹配:5、”!~*” 和”!~” 不常用,再次不做介绍6、通…

JWT token

一、为什么使用JWT? 随着分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成token的方式做登录身份验证,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式…

vue/cli 自定义配置

vue/cli 自定义配置 1、更改默认的端口号8080 只需要更改vue.config.js文件 1、更改默认的端口号8080 只需要更改vue.config.js文件

2023年基准Kubernetes报告:6个K8s可靠性失误

云计算日益成为组织构建应用程序和服务的首选目的地。尽管一年来经济不确定性的头条新闻主要集中在通货膨胀增长和银行动荡方面,但大多数组织预计今年的云使用和支出将与计划的相同(45%),或高于计划的(45%)…

Vite+Typescript+Vue3学习笔记

ViteTypescriptVue3学习笔记 1、项目搭建 1.1、创建项目(yarn) D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh packages...success Installed…

MyBatisPlus之DQL编程控制

MyBatisPlus之DQL编程控制 1. 条件查询方式1.1 条件查询1.1.1 方式一:按条件查询1.1.2 方式二:lambda格式按条件查询1.1.3 方式三:lambda格式按条件查询(推荐) 1.2 组合条件1.2.1 并且关系(and)…

【算法 -- LeetCode】(027) 移除元素

1、题目 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

【Linux进程】进程控制(中) {进程等待:等待的必要性,进程等待的方法wait,waitpid,退出状态status,waitpid非阻塞等待}

三、进程等待 3.1 进程等待必要性 之前讲过,子进程退出,父进程如果不管不顾,就可能造成‘僵尸进程’的问题,进而造成内存泄漏。另外,进程一旦变成僵尸状态,那就刀枪不入,“杀人不眨眼”的kill …

easyexcel 将对应列的格式改为数字或者文本格式

1.在easyexcel 导出excel时 需要将某个列的格式指定,例如指定为数字格式 例如 需要把单元格格式设置为数值,并且保留小数点后三位,按道理来说应该是这样子设置 /** * test, 最终导出值 */ ExcelProperty(value "test")…

01 linux基础(1)

环境安装 解压,从vmware打开虚拟机。 设置密码:1 打开终端:ctrlaltt linux介绍 Linux的发展 1)1969年,由kenthompson在AT&T贝尔实验室实现的。使用的是汇编语言。 2)1970年,KenThompson…

【Linux后端服务器开发】HTTPS协议

目录 一、加密算法 二、中间人攻击 三、CA认证 一、加密算法 HTTPS协议是什么?HTTPS协议也是一个应用层协议,是在HTTP协议的基础上引入了一个加密层。 HTTP协议内容是按照文本的方式明文传输的,这就导致在传输过程中出现一些被篡改的情况…

Java使用FFmpeg实现mp4转m3u8

Java使用FFmpeg实现mp4转m3u8 前言FFmpegM3U8 一、需求及思路分析二、安装FFmpeg1.windows下安装FFmpeg2.linux下安装FFmpegUbuntuCentOS 三、代码实现1.引入依赖2.修改配置文件3.工具类4.Controlle调用5.Url转换MultipartFile的工具类 四、播放测试1.html2.nginx配置3.效果展示…

QT读写ini文件

QT读写ini文件 源代码文件结构mysql.hmysql.cppmain.cpp my.ini文件截图运行截图QSettings 最开始的需求是使用qt读取不同电脑上的MySQL的my.ini文件实现在不同电脑上也可以成功登录数据库,不用担心密码和用户名不同的问题 到之后发现其实并没有什么用,因…

一文搞定Java IO流,输入流、输出流、字符流、缓冲流,附详细代码示例

目录 一、InputStream1、FileInputStream的代码示例2、ByteArrayInputStream的代码示例3、PipedInputStream的代码示例 二、 OutputStream1、FileOutputStream代码示例2、ByteArrayOutputStream代码示例:3、PipedOutputStream代码示例: 三、字符输入流Re…

7.25 作业 QT

手动实现登录框&#xff1a; widget.cpp: #include "widget.h" #include <QMovie> Widget::Widget(QWidget *parent): QWidget(parent) {//设置尺寸this->resize(800,600); //设置宽高//设置固定尺寸this->setFixedSize(800,600);//窗口标题操作qDebu…

C数据结构与算法——顺序栈 应用(C语言纯享版 迷宫)

实验任务 (1) 掌握顺序栈及其C语言的表示&#xff1b; (2) 掌握入栈、出栈等基本算法的实现&#xff1b; (3) 掌握顺序栈的基本应用&#xff08;求解迷宫通路&#xff09;。 实验内容 使用C语言实现顺序栈的类型定义与算法函数&#xff1b;编写main()函数并根据需要修改、补…

❓“如何创业?互联网创业又该如何入手?

&#x1f31f;5大创业建议&#xff0c;让你轻松入门&#xff01; 作为一名互联网创业者&#xff0c;我想分享一下我的创业经验。下面是我的五个建议&#xff0c;希望对你有所帮助&#xff01; &#x1f31f;了解市场需求 在创业之前&#xff0c;了解市场需求非常重要。你需要研…

【Rust日报】2023-07-24 使用 Rust 重写的InfluxDB 3.0

使用 Rust 重写的InfluxDB 3.0 InfluxDB 是一个开源的、分布式的时序数据库&#xff0c;用于存储和分析时间序列数据, 于 2013 年由 Brian Bondy 和 Nicholas Zakhariev 创立。 InfluxDB 最初是用 Go 语言编写的。 2018 年&#xff0c;InfluxData 决定将 InfluxDB 重写为 Rust …

kotlin 编写一个简单的天气预报app(一)

使用Android Studio开发天气预报APP 今天我来分享一下如何使用Android Studio开发一个天气预报APP。在文中&#xff0c;我们将使用第三方接口获取实时天气数据&#xff0c;并显示在APP界面上。 步骤一&#xff1a;创建新项目 首先&#xff0c;打开Android Studio并创建一个新…

Flutter 最佳实践和编码准则

Flutter 最佳实践和编码准则 视频 前言 最佳实践是一套既定的准则&#xff0c;可以提高代码质量、可读性和可靠性。它们确保遵循行业标准&#xff0c;鼓励一致性&#xff0c;并促进开发人员之间的合作。通过遵循最佳实践&#xff0c;代码变得更容易理解、修改和调试&#xff…