LLM-向量数据库中的索引算法总结

文章目录

  • 前言
  • 向量数据库介绍
  • 索引方法
    • 倒排索引
    • KNN 搜索
    • 近似 KNN 搜索
    • Product Quantization(PQ)
    • NSW 算法搜索
    • HNSW

前言

向量数据库是当今大模型知识库检索落地实践的核心组件,下图是构建知识库检索的架构图:
image.png

  • 首先会将相关文档数据向量化嵌入到向量化数据库中,然后将用户的查询语句转为向量化查询,从向量数据库中召回相似度高的 TOP N 条数据。
  • 然后在对这 TOP N 进行排序,取其中几条,构造成 prompt ,和 LLM 交互查询。

向量查询的数据与 query 的相似度,直接影响到 prompt 的好坏,本文将对市面上已有的向量数据库进行简单介绍,然后会对其使用到的索引方法进行说明,包括倒排索引,KNN,Approximate KNN, Product Quantization, HSNW 等,会对这些算法的设计理念和方法进行说明。

向量数据库介绍

image.png
目前开源的比较火的三大向量数据库为 Chroma, Milvus, Weaviate,关于他们的介绍与区别这篇文章我觉得讲的不错,感兴趣的可以看下:三大开源向量数据库大比拼。
下边是开源向量数据库的发展历程:
image.png
它们用到的索引方法如下:
image.png

索引方法

倒排索引

image.png
假如现在我有一个使用倒排索引的数据库,其中存储了10的12次方个索引数据,我们在往数据库中存储数据的时候,会将数据切分,然后记录被切分后的单词对应的索引位置有哪些, 因为不同句子可能会出现相同的单词,因此每个单词对应的是一个索引集合:

  • 大模型——>[…]
  • 应用——>[…]

假设现在我有一个 query: 大模型的应用会在2024年有哪些发展?
数据库将我们的查询语句切分为三个关键单词:大模型,2024年,发展。然后查询出每个单词对应的索引结合,求交集,这一查询过程就叫做召回。
此时,我们就拿到了和查询相关联的数据,但是这些数据与查询语句相似度是不同的,我们需要对其进行排序,取 TOP N。
但是这种直接将文本数据和索引对应的查询效率并不高,我们有没有什么办法可以加速相似度检索呢?
这个时候就出现了向量化检索,将数据转化为向量,然后在通过计算向量的相似度距离两方面来检索:
image.png

KNN 搜索

KNN 搜索叫做 K 近邻搜索,将查询语句转换为向量,然后再求该向量与数据库中的向量相似度最高,距离最近的向量集。
image.png
其中时间复杂度为O(N)*O(d), d 为维度,维度数据一般为固定的,假设数据库中存储了 10000个向量数据,其中维度都为 1024,那么查询出 maxSim(q,v)(相似度最高),minDist(q,v)(距离最近)的向量的时间复杂度就位 O(10000)*O(1024)。
这种检索方式的优点是查出来的数据精确度高,缺点就是慢。

近似 KNN 搜索

近似 KNN 搜索就是将搜索空间从点变为块,先确定距离最近的那一块,然后再在该快空间中寻找距离最近,相似度最高的点,下图中左边是KNN搜索,有边是 近似 KNN 搜索:
image.png
其中每个块中都会有一个中心点,计算查询点与块的距离就是计算查询点到每个块的中心点的距离:
image.png
比如说上图中的查询步骤如下:

  • 查询点距离最近的块为 C6(距离C6的中心点最近)
  • 然后查询 C6 中距离最近,相似度最高的点

但是通过我们肉眼可以看出其中红色和橙色的块的中心点虽然离查询点远,但是它们块中的点离查询点近,这个时候就需要扩大搜索块的范围:
image.png
下边是求相似度最高和距离最近的算法公式,其中相似度最高(COS_SIM)是通过余弦计算,距离最近有两种算法,欧式算法和曼哈顿算法,这里就不展开讲解了:
image.png

Product Quantization(PQ)

PQ 算法首先会将所有向量划分为多个子空间,和近似 KNN 一样每个子空间都有一个中心点(centroid)。
然后会将原有高维向量拆分为多个低维向量子向量,使用距离该子向量最近的中心点作为该子向量的 PQ ID,然后一个高维向量就由多个 PQ ID 构成,大大压缩了空间。
image.png
比如说上图中1024维的向量被拆分为4个 256维的子向量,然后这四个子向量距离最近的中心点分别为:50,118,29,47。因此,该1024 维的向量就可以用 V=(50,118,29,47) 表示,同时它的 PQ code 也是 (50,118,29,47) 。
因此使用 PQ 算法的向量数据库就需要保存所有中心点的信息以及所有高维向量的 PQ code。
假设现在我们有一个查询语句,需要从向量数据库中查询出相似度最高的向量,使用 PQ 算法该如何查询呢?

  • 首先会将我们的查询语句转换为一个查询向量
  • 然后该查询向量会和每一个向量的 PQ code 进行距离计算,其实也就是和 PQ code 中的每一个中心点进行距离计算然后相加,如下图所示:

image.png

  • 然后按照上边这种方式,和每一个子向量的 PQ code 进行计算,就可以算出距离最近的向量了,但是这种和中心点进行计算的算法会存在误差,如下图所示:

image.png
左边的是误差很小的情况,右边的是误差比较大的情况,一般会存在少数误差,但是大部分误差是比较小的。

使用缓存加速计算
如果说原始查询向量和每一个子向量的 PQ code 都需要进行一次距离计算,那么和近似 KNN 算法没有多大区别,空间复杂度都为O(n)*O(k),那么该算法的意义是什么呢?就只是单纯为了压缩,减少空间存储吗?
假设将所有向量划分为 K 个子空间,每一个子空间中有 n 个点,我们将每个子空间中的点到其中心点的距离提前计算出来,放到一个二维矩阵中,然后查询向量对应的每一个子向量到中心点的距离我们可以直接从矩阵中查询出来,如下图所示:
image.png
最后我们只需要将每个子向量的距离相加开平方根即可。

近似 KNN 与 PQ 算法结合
这两种算法是不冲突的,可以先使用近似 KNN,将所有向量划分为多个子空间,然后将查询向量定位到对应的子空间中。
这样再在子空间中使用 PQ 算法,加速计算。

NSW 算法搜索

在一个给定向量数据集中,按照某种度量方式,检索出与查询向量相近的K个向量(K-Nearest Neighbor,KNN),但由于KNN计算量过大,我们通常只关注近似近邻(Approximate Nearest Neighbor,ANN)问题。
NSW在构图时,每次随机选择点,加入图中。每次加入点都查找与其最近邻的m点以添加边。最终形成如下图所示的结构:

在搜索 NSW 图时,我们从预定义的入口点开始。这个入口点连接到附近的几个顶点。我们确定这些顶点中的哪一个最接近我们的查询向量并移动到那里。

如从A开始,A的临近点C离P的距离更近更新。然后C的临近点D距离P更近,然后D的临近点B和F没有更近,程序停止,即为D点。

HNSW

图的构建从顶层开始。进入图表后,算法贪婪地遍历边,找到与我们插入的向量q最接近的ef邻居——此时ef = 1。
找到局部最小值后,它会向下移动到下一层(就像在搜索期间所做的那样)。重复这个过程,直到到达我们选择的插入层。这里开始第二阶段的建设。
ef值增加到我们设置的efConstruction参数,这意味着将返回更多最近的邻居。在第二阶段,这些最近的邻居是新插入元素q的链接的候选者, 并作为下一层的入口点。
经过多次迭代后,添加链接时还要考虑两个参数。M_max,它定义了一个顶点可以拥有的最大链接数,同样的M_max0,它定义了针对第 0 层中的顶点的最大连接数。

HNSW 代表 Hierarchical Navigable Small World,一个多层图。数据库中的每个对象都在最低层(图片中的第 0 层)中捕获。这些数据对象连接得很好。在最低层之上的每一层上,表示的数据点较少。这些数据点与较低层匹配,但每个较高层中的点呈指数级减少。如果有搜索查询,将在最高层找到最近的数据点。在下面的示例中,这只是多了一个数据点。然后它更深一层,从最高层中第一个找到的数据点中找到最近的数据点,并从那里搜索最近的邻居。在最深层,将找到最接近搜索查询的实际数据对象。
HNSW 是一种非常快速且内存高效的相似性搜索方法,因为只有最高层(顶层)保存在缓存中,而不是最低层中的所有数据点。只有最接近搜索查询的数据点在被更高层请求后才会被加载,这意味着只需要保留少量内存。

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

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

相关文章

Python Linux下编译

注意 本教程针对较新Linux系统,没有升级依赖、处理旧版本Linux的openssl等步骤,如有需要可以查看往期文章,例如:在Centos7.6镜像中安装Python3.9 教程中没有使用默认位置、默认可执行文件名,请注意甄别 安装路径&#…

vue3中echarts的使用

1.下载 echartsnpm i -s echarts 2.在main.js中引入import { createApp } from vue import App from ./App.vue// 引入 echarts import * as echarts from echarts const app createApp(App) // 全局挂载 echarts app.config.globalProperties.$echarts echartsapp.mount(#ap…

I18N/L10N 历史 / I18N Guidelines I18N 指南 / libi18n 模块说明

注&#xff1a;机翻&#xff0c;未校对。 文章虽然从 Netscape 客户端展开 I18N/L10N 历史&#xff0c;但 I18N/L10N 的演化早已不仅限适用于 Netscape 客户端。 Netscape Client I18N/L10N History Netscape 客户端 I18N/L10N 历史 Contact: Bob Jung <bobjnetscape.com&…

阿里生态体系

阿里巴巴的“16N”战略框架是一种业务布局战略。具体来说&#xff0c;“1”代表核心电商平台&#xff0c;“6”代表阿里的六大板块&#xff0c;“N”代表众多的新业务和创新业务。以下是对“16N”具体内容的详细说明&#xff1a; 1. 核心电商平台 阿里巴巴电子商务业务&#…

Go语言入门之数组切片

Go语言入门之数组切片 1.数组的定义 数组是一组连续内存空间存储的具有相同类型的数据&#xff0c;是一种线性结构。 在Go语言中&#xff0c;数组的长度是固定的。 数组是值传递&#xff0c;有较大的内存开销&#xff0c;可以使用指针解决 数组声明 var name [size]typename&…

达梦数据库dm8安装步骤及迁移

目录 前言: 一、安装部署 1、下载 2、创建用户及安装目录 3、挂载下载的镜像 4、环境配置 5、安装 二、基本使用 1、DM工具使用 2、兼容性配置 2.1 兼容GBK字符集编码 2.2 兼容UTF-8字符集编码 3、创建用户和密码,表空间 4、整理数据库配置 5、启动脚本设置 …

华为OD机考题(HJ74 参数解析)

前言 经过前期的数据结构和算法学习&#xff0c;开始以OD机考题作为练习题&#xff0c;继续加强下熟练程度。 描述 在命令行输入如下命令&#xff1a; xcopy /s c:\\ d:\\e&#xff0c; 各个参数如下&#xff1a; 参数1&#xff1a;命令字xcopy 参数2&#xff1a;字符串…

JavaSE学习笔记之内部类、枚举类和基本类型包装类

今天我们继续复习Java相关的知识&#xff0c;和大家分享有关内部类等方面的知识&#xff0c;希望大家喜欢。 目录​​​​​​​ 内部类 成员内部类 ​编辑 静态内部类 局部内部类 匿名内部类 枚举类 定义方法 基本类型包装类 自动装箱和拆箱 内部类 成员内部类 成…

使用 Google 的 Generative AI 服务时,请求没有包含足够的认证范围(scopes)

题意&#xff1a; Google generativeai 403 Request had insufficient authentication scopes. [reason: "ACCESS_TOKEN_SCOPE_INSUFFICIENT" 问题背景&#xff1a; I have tried the simple POC for generativeai on its own to do generate_content and it works…

WPS点击Zotero插入没有任何反应

wps个人版没有内置vba&#xff0c;因此即便一下插件安装上了&#xff08;如Axmath&#xff0c;zotero&#xff09;&#xff0c;当点击插件的时候会出现“点不动”、“点击插件没反应的现象。至于islide一类的插件&#xff0c;干脆连装都装不上。 这就需要手动安装一下vba。 针…

Python酷库之旅-第三方库Pandas(017)

目录 一、用法精讲 41、pandas.melt函数 41-1、语法 41-2、参数 41-3、功能 41-4、返回值 41-5、说明 41-5-1、宽格式数据(Wide Format) 41-5-2、长格式数据(Long Format) 41-6、用法 41-6-1、数据准备 41-6-2、代码示例 41-6-3、结果输出 42、pandas.pivot函数 …

【单片机毕业设计选题24059】-太阳能嵌入式智能充电系统研究

系统功能: 系统由太阳能电池板提供电源&#xff0c; 系统上电后显示“欢迎使用智能充电系统请稍后”&#xff0c; 两秒钟后进入主页面显示。 第一行显示太阳能电池板输入的电压值 第二行显示系统输出的电压值 第三行显示采集到的太阳能电池板温度 第四行显示设置的太阳能…

回归损失和分类损失

回归损失和分类损失是机器学习模型训练过程中常用的两类损失函数&#xff0c;分别适用于回归任务和分类任务。 回归损失函数 回归任务的目标是预测一个连续值&#xff0c;因此回归损失函数衡量预测值与真实值之间的差异。常见的回归损失函数有&#xff1a; 均方误差&#xff…

【UNI-APP】阿里NLS一句话听写typescript模块

阿里提供的demo代码都是javascript&#xff0c;自己捏个轮子。参考着自己写了一个阿里巴巴一句话听写Nls的typescript模块。VUE3的组合式API形式 startClient&#xff1a;开始听写&#xff0c;注意下一步要尽快开启识别和传数据&#xff0c;否则6秒后会关闭 startRecognition…

004-基于Sklearn的机器学习入门:回归分析(下)

本节及后续章节将介绍机器学习中的几种经典回归算法&#xff0c;包括线性回归&#xff0c;多项式回归&#xff0c;以及正则项的岭回归等&#xff0c;所选方法都在Sklearn库中聚类模块有具体实现。本节为下篇&#xff0c;将介绍多项式回归和岭回归等。 目录 2.3 多项式回归 2…

Point Cloud Library (PCL) for Python - pclpy 安装指南 (1)

以下所有的版本号务必按照说明安装。 1.安装 Python 3.6 https://www.python.org/ftp/python/3.6.8/python-3.6.8-amd64.exe #或 百度网盘 2.确认 Python 版本为 3.6.x python #Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on…

给后台写了一个优雅的自定义风格的数据日志上报页面

highlight: atelier-cave-dark 查看后台数据日志是非常常见的场景,经常看到后台的小伙伴从服务器日志复制一段json数据字符串,然后找一个JSON工具网页打开,在线JSON格式化校验。有的时候,一些业务需要展示mqtt或者socket的实时信息展示,如果不做任何修改直接展示一串字符…

将有序数组转化成二叉搜索数

1 问题 将一个按照升序排列的有序数组&#xff0c;转换为一棵高度平衡二叉搜索树。本题中&#xff0c;一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。 2 方法 采用递归的方法找到root结点&#xff0c;以及左子树和右子树。 代码清单 1 clas…

自动驾驶的规划控制简介

自动驾驶的规划控制是自动驾驶系统中的核心组成部分&#xff0c;它负责生成安全、合理且高效的行驶轨迹&#xff0c;并控制车辆按照这个轨迹行驶。规划控制分为几个层次&#xff0c;通常包括行为决策&#xff08;Behavior Planning&#xff09;、轨迹规划&#xff08;Trajector…

学习笔记——动态路由——IS-IS中间系统到中间系统(特性之路由撤销)

6、路由撤销 ISIS路由协议的路由信息是封装在LSP报文中的TLV中的&#xff0c;但是它对撤销路由的处理和OSPF的处理方式类似。 在ISIS中撤销一条路由实则是将接口下的ISIS关闭&#xff1a; 撤销内部路由&#xff1a; 在ISIS中路由信息是由IP接口TLV和IP内部可达性TLV共同来描…