一、向量检索
1、向量的定义
- 计算机只认识数字,它只能通过数字来量化这个世界,用一组数字来表示一个事物,这样的一组数字就是一个向量(Vector)
- 如果一个向量由N个数字组成,它就是一个N维向量。拿目前广泛使用的人脸识别技术来说,计算机从照片或视频中提取出人脸的图像,然后将人脸图像转换为128维或者更高维度的向量。
- 首先我们了解下什么是向量,所谓向量就是由N个数字(二值向量由N个比特组成)组成的数组,我们称之为N维向量。
- 而向量检索就是在一个给定向量数据集中,按照某种度量方式,检索出与查询向量相近的K个向量(K-Nearest Neighbor,KNN),但由于KNN计算量过大,我们通常只关注近似近邻(Approximate Nearest Neighbor,ANN)问题。
2、常见的向量度量
- 欧氏距离、余弦、曼哈顿距离、点积
- 欧几里得度量(euclidean metric)(也称欧氏距离) 是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。
- 余弦距离:也称为余弦相似度。一个向量空间中两个向量夹角间的余弦值作为衡量两个个体之间差异的大小,余弦值接近1,夹角趋于0,表明两个向量越相似,余弦值接近于0,夹角趋于90度,表明两个向量越不相似。
- 曼哈顿距离也称出租车几何,是由十九世纪的赫尔曼·闵可夫斯基所创词汇,是种使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总和。
图中红线代表曼哈顿距离,绿色代表欧氏距离,也就是直线距离,而蓝色和黄色代表等价的曼哈顿距离。
曼哈顿距离——两点在南北方向上的距离加上在东西方向上的距离
- 点积 在数学中,又称数量积(dot product; scalar product),是指接受在实数R上的两个向量并返回一个实数值标量的二元运算。它是欧几里得空间的标准内积。
两个向量a = [a1, a2,…, an]和b = [b1, b2,…, bn]的点积 定义为:a·b=a1b1+a2b2+……+anbn。
3、向量检索的方法
- 向量检索有两类方法 :
- 存在最近邻检索(Nearest Neighbor Search,NN)
- 近似最近邻检索(Approximate Nearest Neighbor Search, ANN)
- NN 主要是说对结果进行穷举 ,计算结果也是最为精确。
- ANN 主要是对结果的一个近似值估计,ANN则是在可接受的精度条件下通过把向量分簇建立索引,大幅提高搜索效率,这也大规模向量检索场景下所使用的主要方法。
- 为什么是近似,而不是我们想要的精确?这就是精度与时间、算力资源的折中,采用了牺牲精度换取时间和空间的方式,从海量的样本中实时获取跟查询最相似的样本。
二、向量的生成
向量可以表示一个事物,一段文字,一张图片,那向量怎么生成呢?
可以使用在HuggingFace中的sentence-transformers的预训练模型来生成我们的向量
查看地址模型介绍:https://www.sbert.net/docs/pretrained_models.html
或者访问HuggingFace模型中心大部分深度学习框架都是PyTorch和TensorFlow,使用的基本都是python
如何通过使用Java调用这些模型呢?可以使用DJL
Deep Java Library (DJL) 是一个用于深度学习的开源、高级、与引擎无关的 Java 框架。
1、转换并导出模型
- 将模型转换为 TorchScript
①、首先安装:sentence-transformers
- 需要安装python环境
pip install -U sentence-transformers
②、使用模型的python代码例子
from sentence_transformers import SentenceTransformer |
③、导出为TorchScript模型
- 为什么要使用TorchScript对模型进行转换?
- TorchScript代码可以在它自己的解释器中调用,它本质上是一个受限的Python解释器。这个解释器不获取全局解释器锁,因此可以在同一个实例上同时处理多个请求。
- 这种格式允许我们将整个模型保存到磁盘上,并将其加载到另一个环境中,比如用Python以外的语言编写的服务器中
- TorchScript提供了一种表示方式,我们可以在其中对代码进行编译器优化,以提供更有效的执行
- TorchScript允许我们与许多后端/设备运行时进行交互
- trace方法首先使用输入数据执行一遍模型,并记录下模型执行过程中的参数,并创建一个torch.jit.ScriptModule实例
- 指定导出设备为CPU执行、批次1、最大分段长度128
from sentence_transformers import SentenceTransformer |
2、代码调用
- 直接使用别人写好的SDK,
- 链接:https://gitee.com/mymagicpower/AIAS/tree/main/2_nlp_sdks/embedding/sentence_encoder_15_sdk
- 我们只需更换预训练模型即可
三、Elasticsearch向量检索
- ES是有向量检索的功能的。
- ES存储向量的类型为:
dense_vector
可参考官方文档的解释:https://www.elastic.co/guide/en/elasticsearch/reference/8.8/dense-vector.html
1、创建索引
- 使用dense_vector类型
PUT vector_test |
2、添加测试数据
- 添加数据
PUT vector_test/_doc/1 |
3、 脚本分数查询
- 相似度查询
// 向量使用的是:今天天气不错 |