向量数据库正在彻底改变我们搜索和分析复杂数据的方式,已成为RAG中重要的基础组件。但是要理解其工作方式还是很难的,因为里面涉及到大量的数学公式计算。 Tom Yeh教授的手算图解系列让对数学特别是矩阵掌握不好的人也能通过简单的数学计算对整个过程有直观的认知。
1. 输入设定三个句子的数据集,每个句子有 3 个单词(token)。分别是how are you,who are you,who am I
当然实际的数据集可能包含数百万或数十亿个句子。 token的最大数量可能是数万个。
现在要处理的查询是 am I you。
这个图片里面现在已经有的这一些矩阵(那堆数字),就可以认为是我们所说的“模型”,模型包含整个结构和每个结构里面的参数。可以看到这些矩阵有不同的大小(长宽),这个大小可以认为是结构,里面的数字可以认为是参数。 我们说的大模型,就是说比起我们这个图来说,整个多了很多很多的矩阵,这些矩阵的大小也大很多,每个矩阵里面的数字也不同。 所谓训练模型,就是要通过大量的数据和方法,将这些矩阵里面的数字(参数)固定下来。
2.Word Embeddings对于每个单词,从 22 个向量的表中查找相应的单词嵌入向量,其中 22 是词汇量大小,维度为4。embedding的过程可以使用已有的模型来处理,也可以直接进行查表,反正就是把输入的文字转换为一组向量,然后才能给后面的使用。这儿是how are you,查询出来的值如下。
实践中,词汇量可能达到数万。 词嵌入维度为数千(例如,1024、4096)
3.编码将词嵌入序列输入编码器以获得一系列特征向量,每个输入向量一个。这里编码器是一个简单的单层感知器(线性层 + ReLU)。这里面看一下具体是怎么算出来的,整体就是公式就是矩阵乘法和向量加法,比如输出的1行1列的值,为ReLU([1 1 0 0]*[1 0 1 0]+0) = ReLU(1)=1,输出的4行4列的值为ReLU([1 -1 0 0]*[0 1 0 0]+0)=ReLU(-1)=0。
实际上会使用到的编码器是一个Transformer结构或其许多变体之一,而且会是多层的。
4.Mean Pooling使用“平均池化”将特征向量序列合并为单个向量,即跨列求平均值。结果是单个向量。 我们通常称之为“文本嵌入”或“句子嵌入”。其他池化技术也是可能的,例如 CLS。 但平均池化是最常见的。比如这儿,第一行是3个3,平均值就是3/3,第二行是0 1 1,平均值就是2/3。
5.Indexing通过投影矩阵减少文本嵌入向量的维度,这儿的减少率为50%(4->2)。实际项目中,该投影矩阵中的值更加随机。目的与散列的目的类似,都是为了获得简短的表示形式以允许更快的比较和检索。完成之后将得到的降维索引向量保存在向量存储中。这儿也还是一个矩阵乘法,将投影矩阵乘以mean pooling之后的4维向量,得到一个2维向量。
6.处理who are you重复上面的2到5步,对who are you进行相同的处理,并存入向量数据库。
7.处理who am I重复上面的2到5步,对who am I进行相同的处理,并存入向量数据库。
到这儿我们就完成了对语料(和我们问题相关的原始信息)的处理,并索引存储到了一个向量数据库中供后面快速查询。
向量数据库的核心功能就是对向量提供快速的存入和查询。查询的话最主要的就是将相似度高的向量输出。
8.处理查询这儿要查询am I you,对查询同样的使用2到5步。得到一个查询的2为向量。供下一步检索使用。
9.向量点积(计算向量相似度)计算查询向量和数据库向量之间的点积。 它们都是二维的。目的是使用点积来估计相似度。
过程就是将存储的三个向量分别和查询向量做点积。
这儿可以将查询向量做一个转置,变成1*2的,那么就可以做一个1*2 和 2*3 矩阵的乘法,得到3个值。
10.最近邻居通过线性扫描得到最大点积作为输出。比如这儿点积最高的句子是who am I。
实际项目不会用全扫描,因为存储的数据集很大,会使用似然的方法来快速查询出相似度最大的向量。