什么是向量数据库?

一、大模型业务全流程

1.png

  1. AI集群建设:计算、通信、存储建设

  2. 大模型数据:大模型数据集、数据处理、向量数据库

  3. 大模型算法:从传统NLP到预训练LLM大模型

  4. 大模型训练:大模型训练普通算法手段与稳定性分析

  5. 分布式并行:模型并行、数据并行、优化器并行等

  6. 大模型微调:全参微调、低参微调、指令微调算法

  7. 大模型推理:量化压缩、长序列扩充推理、Cache方法

  8. 大模型评测:NLP下游任务、CV下游任务、测评方案

  9. 大模型智能体:RLHF流程、智能体、终生学习

二、向量

熟悉犬类的能够很快的区分他们的品种,之所以能做到这一点,是因为我们从它们不同的角度观察他们的特征,比如体型的大小。
2.png如果我们用一个坐标轴来表示它们的大小特征,这些狗将落在不同的坐标上。然而,单纯依靠体型这一个特征还不够,有的体型十分接近。
3.png我们再观察它的特征,比如毛发的长短,我们再做一个坐标轴,这样就区分了一部分大小一样特征的犬类
4.png但还是有一部分有重叠的,所以要继续从更多的角度来观察,比如鼻子的长短。
5.png我们还可以增加更多的维度,比如眼睛的大小。我们不可在四维空间上作图,但在坐标点的数值上确很容易实现,继续向后追加就好了。
6.png我们还可以从更多的角度,或者说维度来观察一致够的特征,比如腿的粗细,毛发的卷曲,甚至是一些抽象的角度,比如服从性,工具性等等。我们使用的维度越多,对狗的区分能力就越强。同时坐标点所在的空间维度也就越高。
7.png不仅是狗,实际上几乎任何事物都可以被这样表述。可以使具象的, 也可以是抽象的喜怒哀乐,悲欢离合。不同事物在不同的特征维度中有着不同的表现或者说不同的数值,多以最终都会在一个高维的特征空间中对应这一个坐标点。只不过在这些更大的范围内,我们可能需要更高的特征维度才能很好的对事物进行区分。可能几百几千,也可能上万。
8.png但是由于我们无法作出超过三维的图,所以用二维坐标来讲解。
9.png我们会发现哪些概念上更为接近的点将在空间中更为聚集,而那些概念上非常不同的点则举例上很远。跟进一步,如果已坐标原点为起始点,这些坐标点为终点。这就是带有方向和大小的向量。

如果对图片进行向量,通过搜索相似的向量,实现以图搜图的功能
如果对视频进行向量,通过搜索相似的向量,实现相似视频的推荐
如果对商品进行向量,通过搜索相似的向量,针对用户当前浏览商品进行相关的推荐
如果对文本进行向量,就能在一个智能问答系统中,根据用户当前的问题,找到一些已经解决过的相似的问题以供参考

三、向量数据库

伴随着AI的到来,向量将成为一种重要的数据形式。而传统的数据库并不适合用来存储和检索向量数据,因此需要一种专门设计的数据库来处理这些问题,这或许会成为未来数据层面的基础设施。和存储数据表,然后用查询语句精准搜索的传统数据库不同,向量数据库存储的是向量数据,而查询过程则是从数据库中搜索出和查询向量最为相似的一些向量,具有一定的模糊性。

1、向量查询

向量数据的一个主要应用场景就是:给定一个查询向量,然后从众多向量中找到最为相似的一些向量。这就是所谓的最近邻问题,而实现这一点的叫最近邻算法,一种最容易想到的方法可能就是暴力搜索,依次比较所有向量和查询向量的相似度,挑选出相似度最高的几个,而比较两个向量相似度的具体方法有很多,欧氏距离和余弦相似度。
10.png

  • 欧氏距离是指计算两个向量之间的直线距离。在二维坐标系中,假设有两个向量p和q,欧氏距离就是计算p到q中间连的这条直线的距离。在三维坐标系里,每一个向量包含x、y、z三个坐标点,根据公式计算任意两点之间的距离。而在n维坐标系里,有100个坐标点,根据公式计算任意两点之间的距离。距离越短,说明这两个向量在某些维度上相似性越高
    11.png

  • 另一种方式是余弦相似度。除了距离,我们还可以通过向量之间的夹角来描述它们之间的关系。在二维坐标系中,如果夹角越小,说明两个向量之间的关联性越高。我们可以使用公式计算任意两个向量之间的余弦相似度。在三维坐标系里,也可以用同样的原理来计算任意两个向量之间的夹角和余弦相似度。
    12.png
    而如果向量数据过多,这种毫无技术含量的暴力方法将导致极高的搜索时间。但这种搜索质量确实是完美的,因为他真的比较了每一个向量,所以如果数据库库中数据规模比较小,遍历全部向量的时间可以接受,这也不失为一种好的方法,然而时间应用中的数据规模往往都不会太小,所以必须找出一些方法进行优化。

2、向量索引

前面讲述了向量数据库的检索原理,但实际上,在向量数据库中进行相似度匹配时,不能完全按照公式计算,因为向量数据库的数据量通常很大,维度也很高。如果使用公式计算两个1000维向量之间的相似度,计算量比较大,而且对CPU的计算密集型需求很高。那如果有一亿个向量,每个都要计算一遍的话,时间和计算成本都会更加高。因此,我们此处引入了一个概念叫做向量索引。
向量索引与关系数据库中的索引类似,但有一点不同。在向量数据库中,通过向量索引找到的是近似结果,而不是100%准确的结果。向量索引描述的是相似度的程度高和低。因此,我们称之为近似最邻近搜索(ANS)。 如果没有向量索引的话,寻找一个向量的相似度就类似于关系数据库中的全表搜索。但是,在全表搜索之上还要多加一层的运算,因此成本比关系数据库中的全表搜索要高很多。
根据实现的方式,ANNS向量索引可分为四大类:

  • 基于树的索引

  • 基于图的索引

  • 基于哈希的索引

  • 基于量化的索引

1、基于树的方法

基于树的方法主要思想是将数据进行划分,类似二叉查找树,搜索时减小了搜索的空间,达到快速检索的目的。但是这种方法不适合高维空间。基于树的方法主要有KDTree(K-Dimensional Tree)和Annoy(Approximate Nearest Neighbors Oh Yeah)。
1.1 KDTree
KDTree的构建同样基于递归划分的思想,首先选取方差最大的维度,以该维度上所有数据的中位数作为切分点,将超矩形区域切割成两个子区域,小于中位数的划分到左边,小于中位数的划分到右边,递归的构建左右子树,直到所有的数据被划分完成为止。
13.png

基于KDTree的搜索流程:
1、查询数据p,当前节点的划分维度d,判断数据p在维度d的坐标值与节点值的大小,如果大于走左子节点,小于则走右子节点;
2、直到遍历到叶节点,标记为已访问,计算与叶节点的距离为最近距离;
3、在叶子节点进行回溯操作,每次回溯都判断p与父节点中未被访问到的分支的距离。
a)假如该分支节点与p的距离大于当前最近距离,则继续向上回溯,直至根节点;
b)假如该分支节点与p距离小于当前最近距离,则使用该分支,走步骤1和步骤2直到叶子节点,更新叶子与Q的最近距离。
14.png

1.2Annoy
Annoy使用超平面来对空间进行划分,超平面的是借助KMeans(k=2)来寻找两个聚类中心,中心的连线的法平面即为划分的超平面,不对迭代,直到每个子空间的数据个数低于指定阈值。
 15.png16.png17.png

18.png

要搜索这个空间中的任何一点,可以从根开始遍历二叉树。每个中间节点(上面树中的小方块)都定义了一个超平面,因此可以根据超平面来判断接下来继续的是左子节点还是右子节点。搜索一个点可以在对数时间内完成,即树的高度。

优点:低位数据准确率较高 缺点:无法充分捕获数据复杂性,高维数据准确性较低

2、基于图的方法

基于图的方法主要是使用图这种数据结构,利用邻居节点之间的连通性构建高速公路,将问题转化为图的遍历,能快速缩小搜索范围,加快检索速度。但是图这种数据结构比较复杂,为了达到极致的检索速度,一般会将整个图加载到内存,造成其内存占用非常高,但是检索快,召回率高。

目前常用的图搜索算法主要是HNSW(Hierarchical Navigating Small World),而NSW(Navigating Small World)则是其前置算法,也需要了解一下。
2.1 NSW
NSW在朴素构图的基础上,增加了如下约定:所有的节点必须有相邻的节点;相邻的节点必须有连线;邻近友元的个数作为超参,由用户指定。主要用来解决朴素构图法的一些局限。
19.pngNSW构图过程:
插入一个新节点时,先查找与新节点最近的m个节点,连接新节点与这m个节点。
NSW搜索过程:
查询数据q,从图中随机寻找一个entry point节点以及其邻居节点,计算entry point以及邻居节点与p的距离,如果有邻居与p的距离小于p与entry point的距离,设置最小距离点,直到最后找到一个point,其所有邻居和query的距离都大于这个point。
如上图所示,要从构建好的近邻图中搜索和绿色节点query最近的节点,从随机挑选的entry points开始,一开始通过红色的long-link迅速到了query附近的节点,再通过黑色的short-link找到满足的点。
NSW同样也是一种近似计算,不能保证是真实的最近邻。先插入的点冗余边多,更有可能形成高速公路,越往后插入的点,拥有高速公路的可能性越低。
2.1 HNSW
HNSW是一种基于NSW的改进方案,主要是利用跳表的思想,使用分层来实现,每层都是一个NSW,即也可以叫做分层的NSW方法。越上层,节点数稀疏,节点之间距离越远,越往下,节点变多,连接也增加,平均距离越近。
20.png

优点:能在高维数据中找到相似的近邻,从而提高搜索性能,缺点:构图方式复杂,影响内存效率。

3、基于哈希的方法

基于哈希的方法主要是利用哈希函数的特性,相似度高的数据其哈希值也相似。哈希函数可以将高维数据转换成低维数据,极大提高建设效率。但是哈希函数同样也有另一个局限性,哈希值相似的数据并不一定相似,导致这种方法的召回率并不是很高。基于哈希的方法主要是LSH(Locality-Sensitive Hashing)。假设两个向量相似,那么他们的哈希值也是相似的。利用哈希函数将相似的向量映射到相同的桶里面。查询时先找到与查询向量最相似的桶,再对桶内的数据进行查询计算最相似的topk。
21.pngLSH(位置敏感hash)也是一种基于空间划分的方式,实现方法,如下图,随机生成一条直线,这条线区分正反两侧,如果一个向量在这条线的正侧,那么他就是1,反侧就是0,然后再随机生成一条直线,同样正侧是1,反侧是0;如此我们生成多条这样的直线, 就为每个向量算出了4个0或者1,各自得到一个4位的二进制编码。现在我们观察下这4个二进制编码的相似程度。
22.png23.png24.png25.png26.png27.png

优点:扩展到大数据时数据非常快,缺点:正确性一般

5、基于量化(Quantized)的索引

5.1、聚类
假如为查询向量能划定一个大致的范围进行搜索,再进行搜索,可大大提高搜索速度。我们先选定一个想要分类的数量,比如下图4个分类,随机生成4个中心点,然后这些向量离哪个中心点最近,就被分到哪个中心点。然后用当前被分配到一类的向量计算出一个平均向量点,把中心点位置修改为平均向量点,再判断哪个向量点里中心点最近,重新分类。如此反复的过程叫训练,最后这些中心点将趋于稳定或者叫收敛。在进行搜索时,只要找出跟查询向量最近的聚类中心,搜索这个聚类中心的向量即可。也就实现了缩小搜索范围的目的
29.png29.png

5.2、量化(Quantization)
但对于海量的向量数据,除了搜索速度以外,内存开销也是一个巨大的挑战。实际上在真实的应用场景中,上千的向量维度和上亿的向量数据都不稀奇,所以内存的开销会很严重。
30.png

从上面的聚类中了解到中心点,其实叫质心,我们能不能用质心代表聚类中的点了。应该是可以的,其实这种方法就是典型的有损压缩 ,如果用图片举例就是如下:
31.png32.png

这虽然会丢失部分向量值,但考虑到聚类质心和他所在分类中向量的相关程度,所以在很大程度上保留着一些原始的信息。而相比这个有损压缩导致一部分的细节丢失,所带来的好处是非常可观的。可根据下图进行存储,如此在使用某个向量的时候,用他的编码值在码本中找到对应的质心,再复原出质心对应的具体值,把向量用质心编码表示,也就是所谓的向量量化(Quantization)
33.png

5.3、乘积量化 PQ(Product Quantization)
对向量量化处理后,却多出了一个码本,向量本身的内存开销肯定是降下来了,但这个码本会产生新的内存开销,而且是相当大。这在低维还不明显,但在真实场景的上百上千的向量维度中,这个码本会变得非常恐怖。在数量一定的情况下,要保证量化的质量,分布越稀疏的向量就需要越多的聚类向量。
34.png35.png36.png37.png39.png39.png


对于实际应用中几百上千的向量维度,数据将非常稀疏,因此在高维的空间中,为了保证量化的质量,我们可能需要非常多的聚类数量,一个典型的情况如下图:一个128维的向量可能需要2的64次方个聚类中心,因为这将导致用来记录质心编码的码本变得非常巨大。而为了保存这个码本所消耗的内存已经远远超越了量化本身所节省下来的内存
40.png解决这个问题的办法是先把高维向量分割成若干个低维字向量,然后在这些低维子向量上独立进行量化。比如把128维的高维向量分割成8个16位的子向量,然后再8个16维的字向量中分别独立的进行聚类训练。
42.png42.png

于是每个向量可以用8个子空间的训练结果对自己对应的8个子向量进行量化,而且每个字向量的维度是16,不是很高,因此每个16维的子空间只需要256个聚类数量就能得到还不错的量化效果,所以每个字向量的编码值在0-255范围,把8个子向量的量化编码合在一起就得到了原始向量最终的量化编码值,也就是说现在一个向量被量化成8个编码值,同样每个子空间也会构建自己的子码本,在使用的过程中,用8个编码值分别从子码本中查出8个16维的字向量再合并起来,复原出一个128维的向量
45.png45.png45.png46.png


评论区