向量数据库入坑指南:聊聊来自元宇宙大厂 Meta 的相似度检索技术 Faiss

本文介绍了Facebook Research的开源项目Faiss,这是一种用于相似度检索的高效解决方案,广泛应用于推荐系统、风控、听歌识曲等领域。文章详细阐述了Faiss的工作机制、环境准备、向量数据构建、索引类型以及性能优化,旨在帮助初学者逐步掌握这一技术。此外,还探讨了不同索引类型的性能和准确性权衡,以及在不同业务场景下的适用性。
摘要由CSDN通过智能技术生成

我们日常使用的各种 APP 中的许多功能,都离不开相似度检索技术。比如一个接一个的新闻和视频推荐、各种常见的对话机器人、保护我们日常账号安全的风控系统、能够用哼唱来找到歌曲的听歌识曲,甚至就连外卖配送的最佳路线选择也都有着它的身影。

相信很多同学是第一次听说它,或者只知道它的大名,而不知该如何使用它。本篇文章,我们就来聊聊 faiss,分享这个“黑科技”是如何发挥神奇的“魔法”的。

写在前面

faiss 是相似度检索方案中的佼佼者,是来自 Meta AI(原 Facebook Research)的 开源项目 ,也是目前最流行的、效率比较高的相似度检索方案之一。虽然它和相似度检索这门技术颇受欢迎,在出现在了各种我们所熟知的“大厂”应用的功能中,但毕竟属于小众场景,有着不低的掌握门槛和复杂性。

所以,不要想着一口气就完全掌握它,咱们一步一步来。

当然,如果你实在懒得了解,希望能够和写简单的 Web 项目一样,写几行 CRUD 就能够完成高效的向量检索功能,可以试试启动一个 Milvus 实例 。或者更懒一些的话,可以试着使用 Milvus 的 Cloud 服务 ,来完成高性能的向量检索。

了解 Faiss 的工作机制和适用场景

在正式使用 faiss 之前,我们需要先了解它的工作机制。

当我们把通过模型或者 AI 应用处理好的数据喂给它之后(“一堆特征向量”),它会根据一些固定的套路,例如像传统数据库进行查询优化加速那样,为这些数据建立索引。避免我们进行数据查询的时候,需要笨拙的在海量数据中进行一一比对,这就是它能够实现“高性能向量检索”的秘密。

我们熟知的互联网企业中比较赚钱的“搜广推”(搜索、广告、推荐)业务中,会使用它解决这些场景下的向量召回工作。在这些场景下,系统需要根据多个维度进行数据关联计算,因为实际业务场景中数据量非常大,很容易形成类似“笛卡尔积”这种变态的结果,即使减少维度数量,进行循环遍历,来获取某几个向量的相似度计算,在海量数据的场景下也是不现实的。

而 Faiss 就是解决这类海量数据场景下,想要快速得到和查询内容相似结果(Top K 个相似结果),为数不多的靠谱方案之一。

和我们在常见数据库里指定字段类型一样, Faiss 也能够指定数据类型,比如 IndexFlatL2、IndexHNSW、IndexIVF等二十来种类型,虽然类型名称看起来比较怪,和传统的字符串、数字、日期等数据看起来不大一样,但这些场景将能够帮助我们在不同的数据规模、业务场景下,带来出乎意料的高性能数据检索能力。反过来说,在不同的业务场景、不同数据量级、不同索引类型和参数大小的情况下,我们的应用性能指标也会存在非常大的差异,如何选择合适的索引,也是一门学问。(下文会提到)

除了支持丰富的索引类型之外,faiss 还能够运行在 CPU 和 GPU 两种环境中,同时可以使用 C++ 或者 Python 进行调用,也有开发者做了 Go-Faiss ,来满足 Golang 场景下的 faiss 使用。

对 Faiss 有了初步认识之后,我们来进行 Faiss 使用的前置准备。

环境准备

为了尽可能减少不必要的问题,本篇文章中,我们使用 Linux 操作系统作为 faiss 的基础环境,同时使用 Python 作为和 faiss 交互的方式。

在之前的文章中,我介绍过如何准备 Linux 环境 和 Python 环境,如果你是 Linux 系统新手,可以阅读这篇文章,从零到一完成系统环境的准备:《 在笔记本上搭建高性价比的 Linux 学习环境:基础篇 》;如果你不熟悉 Python 的环境配置,建议阅读这篇文章 《用让新海诚本人惊讶的 AI 模型制作属于你的动漫视频》 ,参考“准备工作”部分,完成 “Conda” 的安装配置。

在一切准备就绪之后,我们可以根据自己的设备状况,选择使用 CPU 版本的 faiss 还是 GPU 版本的 faiss,以及选择是否要指定搭配固定 CUDA 版本使用:

# 创建一个干净的环境
conda create -n faiss -y
# 激活这个环境
conda activate faiss
# 安装 CPU 版本
conda install -c pytorch python=3.8 faiss-cpu -y
# 或者,安装 GPU 版本
conda install -c pytorch python=3.8 faiss-gpu -y
# 或者,搭配指定 CUDA 版本使用
conda install -c pytorch python=3.8 faiss-gpu cudatoolkit=10.2 -y

在配置安装的时候,推荐使用 3.8 版本的 Python,避免不必要的兼容性问题。在准备好环境之后,我们就能够正式进入神奇的向量数据世界啦。

构建向量数据

前文提到了,适合 faiss 施展拳脚的地方是向量数据的世界,所以,需要先进行向量数据的构建准备。

本文作为入门篇,就先不聊如何对声音(音频)、电影(视频)、指纹和人脸(图片)等数据进行向量数据构建啦。我们从最简单的文本数据上手,实现一个“基于向量检索技术的文本搜索功能”。接下来,我将以我最喜欢的小说 “金庸射雕三部曲”中的《射雕英雄传》为例,你可以根据自己的喜好调整要使用的文本数据。从网络上下载好要处理为向量的文本数据(txt 文档)。

简单针对数据进行 ETL

我这里的原始 TXT 文档尺寸是 3 MB 大小,为了减少不必要的向量转化计算量,我们先对内容进行必要的预处理(数据的 ETL 过程),去掉不必要的重复内容,空行等:

cat /Users/soulteary/《哈利波特》.txt | tr -d ' ' | sed '/^[[:space:]]*$/d' > data.txt

打开文本仔细观察,数据中有一些行中的文本数据格外长,是由好多个句子组成的,会对我们的向量特征计算、以及精准定位检索结果造成影响的。所以,我们还需要进行进一步的内容调整,将多个长句拆成每行一个的短句子。

为了更好的解决句子换行的问题,以及避免将一段人物对话中的多个句子拆散到多行,我们可以使用一段简单的 Node.js 脚本来处理数据:

const { readFileSync, writeFileSync } = require("fs");

const raw = readFileSync("./hp.txt", "utf-8")
  .split("\n")
  .map((line) => line.replace(/。/g, "。\n").split("\n"))
  .flat()
  .join("\n")
  .replace(/“([\S]+?)”/g, (match) => match.replace(/\n/g, ""))
  .replace(/“([\S\r\n]+?)”/g, (match) => match.replace(/[\r\n]/g, ""))
  .split("\n")
  .map((line) => line.replace(/s/g, "").trim().replace(/s/g, "—"))
  .filter((line) => line)
  .join("\n");

writeFileSync("./ready.txt", raw);

我们执行 node . 将文本处理完毕之后,当前文件夹中将出现一个名为 ready.txt 的文本文件。

为了方便后文中,我们更具象的了解向量数据库的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值