向量距离计算 java_Milvus 开发者专栏向量检索的应用

作者:

侯宇,业务架构师,Milvus 社区用户

在深度学习的浪潮下,无论是文本、语音、图像、时间序列还是消费者特征,都可以用一组形如 [0.6, 0.3, 0.7,......0.19] 的实数来表征。 这一组实数被称为特征向量。 那什么是向量检索呢[1]?向量检索就是在一个给定向量数据集合中,检索出与查询向量最相近的 Topk 个向量。

| 常见应用场景

图片、视频、语音、文本等非结构化数据可以通过人工智能技术(深度学习算法)提取特征向量,然后通过对这些特征向量的计算和检索来实现对非结构化数据的分析与检索。针对向量检索常见的应用场景有[2]
  • 图片识别:以图搜图,通过图片检索图片。具体应用如:车辆检索和商品图片检索等。
  • 视频处理:针对视频信息的实时轨迹跟踪。
  • 自然语言处理:基于语义的文本检索和推荐,通过文本检索近似文本。
  • 声纹匹配,音频检索。
  • 文件去重:通过文件指纹去除重复文件。
  • 新药搜索,基因筛选。
| 面临的挑战

向量检索面临的挑战主要在以下几个方面:

  • 高维数据:向量数据维度通常是 256/512 维。
  • 海量数据:在常用的图片或视频处理场景中,向量数据通常在亿级别。
  • 高召回:为保证检索效果,精度召回率通常要求 95% 以上。
  • 高性能:为保证用户体验,向量检索的响应要求毫秒级。
| 向量检索服务

目标

我们知道向量的维度很高,并且规模庞大,这就决定了向量数据在计算时会占用较多内存。比如在 NLP 中,一个词向量可以表示成一个 256 维的矩阵,内存占用将是:

一个词向量:4 (float浮点数) * 256 = 1,024 bytes = 1 K

百万数据集:1,000,000 * 1 K / 1,024 ≈ 1 G

亿级数据集:1 G * 100 ≈ 100 G

可以看出在亿级别的词向量数据规模下,占用内存达到上百 GB。那么除了应对以上挑战,如何减少内存占用也是向量检索服务的目标。

本质

向量检索服务的本质就是把高维空间的数据切分到子空间进行搜索。通过对向量建立索引,减少搜索范围,实现高性能的向量数据分析。关于向量索引的分类有:

  • 基于量化的索引
通过聚类方法把空间里的点划分成多个单元。那么在查询时先把目标向量与所有单元的中心做距离比较,选出最近单元,得到最终结果。 
  • 基于图的索引
将图的中心位置设为导航点,然后通过特定的选边策略来控制每个点的出度。使得搜索时既能减少内存使用,又能快速定位到目标位置附近。
  • 基于树的索引
用超平面把高维空间分割成多个子空间,并把这些子空间以树型结构存储的索引方式。
  • 基于哈希的索引
基于哈希的索引通过设计一个哈希函数,使特征向量经过哈希函数映射后得到哈希值。 向量检索服务 向量检索的软件生态目前并不是十分成熟。当前 GitHub 上的向量检索以向量检索算法库为主。然而工业界都需要将向量检索库服务化,对其进行封装和优化,以适应各自的使用场景。 按照向量索引构建与向量查询是否拆分的原则,可以将向量检索服务分为两种:
  1. 向量索引构建与向量查询分离,索引作为离线服务,查询作为在线服务。优点是查询与索引构建分离,对于查询和构建的并发任务而言互相不干涉;缺点是需要较多的服务器,并且离线与在线的数据一致性也是一个问题。
  2. 向量索引构建与向量查询不分离,以 Milvus 为例。优点是可以利用较少的硬件资源来完成查询和索引构建的任务,可以充分利用磁盘资源存储原始向量,提供查询原始向量的能力;缺点是向量查询和索引构建无法并发,会出现资源抢占,限制了多个业务并发处理的能力。
| 基于 Milvus 的文本召回解决方案

Milvus 是一款开源向量相似度搜索引擎,建立在 Faiss、NMSLIB、Annoy 等向量索引库基础之上,具有功能强大、稳定可靠以及易于使用等特点。本文将介绍一个基于 Milvus 实现的文本召回解决方案。

在推荐系统、搜索系统中,文本召回是整个系统架构的重要组成部分。在深度学习来临之前,文本召回使用的是倒排索引技术。但是随着文本内容的增多和场景含义的丰富, 同一个词在不同文本中的意思可能不尽相同。然而倒排索引中的词本身是无法表征文本含义的,导致召回的文本充满了歧义。

利用文本向量化技术可以对文本含义进行表征,再利用向量检索技术来召回相似文本,可以在一定程度上避免倒排召回的缺点。

文本向量化

在本文的应用场景中,用户问句是最重要的文本形式。问句长度一般情况下为10~30 个词左右。目前生成句向量的方式有很多种:

  • Tfidf:此方式同倒排一样,无法表征句子的意思。
  • 分词,训练词向量模型,然后将问句中的词的词向量相加求平均;这在一定程度上表征了句子信息,在绝大多数场景下够用。
  • 利用 Bert 等预训练模型获取相关的句向量。
Milvus 提供支持 Milvus 是一个开源的向量检索中间件,支持常见的向量检索场景,具备以下特点:
  • 支持基于 Python / Java / Go / C++ 的 SDK 和 RESTful API
  • 支持 Annoy、Faiss、HNSW 等多种算法库
  • 支持 CPU 和 GPU 运算
  • 以 collection 为基本的管理单元,在 collection 中再划分 partition 为基准,支持粗粒度与细粒度的数据管理
  • 支持原始向量存储与查询
系统方案 本文介绍的文本召回系统主要分为以下几个步骤:
  1. 创建一个 collection,用于插入向量和构建向量索引。
  2. 在查询时,指定 collection 进行向量检索,返回 Topk 个向量。
  3. 当存在索引更新的时候,则建立一个新的 collection,重复步骤1。当新的 collection 及索引建立完毕,手动释放掉旧的 collection。此步骤一般放在低频访问时段。
整体系统架构及流程如下图所示: 50fbd8e3a110d00e31ecbdb37320ac27.png | 总结 从向量检索中间件的角度来衡量,Milvus 是极具市场潜力的开源组件。Milvus 本身的丰富特性就在一定程度上可以灵活地支持业务场景。 从业务场景的角度考虑, 拥有了 Milvus 可以更加专注地做业务逻辑上的处理和适配,而不用担心向量检索的速度与读取。这使得业务开发人员更专注于业务上的逻辑变更,更有利于业务的快速迭代和演进。此外,Milvus 的 RoadMap 能看出它当前是一个向量检索引擎,但是后续会向混合查询方向优化,具备更强的非结构化数据的存储和查询能力。 参考文献
  1. [1]https://zhuanlan.zhihu.com/p/90677337
  2. [2]https://milvus.io/cn/docs/v0.6.0/reference/application.md
| 欢迎加入 Milvus 社区 github.com/milvus-io/milvus  | 源码 milvus.io  | 官网 milvusio.slack.com  | Slack 社区 zhihu.com/org/zilliz-11/columns |  知乎 zilliz.blog.csdn.net |  CSDN 博客 space.bilibili.com/478166626 |  Bilibili dea548ecb0ea54f959430dbd21f3283d.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
功能设计 ​ 系统功能模块较为简单,主要功能就是**新增人脸**和**人脸搜索**两个功能,其中新增人脸使用页面上传和压缩包批量上传两个方式,压缩包上传时文件名称为用户名,下面主要说明人脸搜索的功能流程 ##### Milvues ​ 在介绍前需要说明一下Mulvus ​ Milvus 向量数据库能够帮助用户轻松应对海量非结构化数据(图片 / 视频 / 语音 / 文本)检索。单节点 Milvus 可以在秒内完成十亿级的向量搜索 ​ 因此虹软的SDK只能提取向量及对比的功能,在大规模人脸识别中,需要搜索引擎对于人脸数据进行初步筛选到一个较小的范围后在利用虹软的SDK进行测试,值得一提的是,博主多次测试后Milvues返回的匹配率足以满足人脸匹配的要求,Milvus的安装部署和使用文档参考 https://milvus.io/cn/docs/v2.0.x ​ **特别说明的是**虹软提取的数组是一个经过归一后的1032长度的byte数组,我们需要对数组进行转换,去除前8位的版本号,并将1024长度的byte转为256长度的float向量,这部分可以利用Arrays提供的方法进行转换,代码中也有相应的工具类 ##### 人脸上传(单张) ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
作为一个人工智能引擎,Milvus可以与Java编程语言集成,为开发者提供高效的数据存储和检索功能。以下是使用JavaMilvus进行集成的步骤: 1. 下载并安装Java SDK和Milvus服务器。 2. 在Java项目中添加Milvus的依赖项。 3. 连接到Milvus服务器。 ```java import io.milvus.client.*; MilvusClient client = new MilvusGrpcClient("localhost", 19530); ``` 4. 创建集合。 ```java String collectionName = "my_collection"; int dimension = 128; CollectionMapping collectionMapping = CollectionMapping.newBuilder() .setCollectionName(collectionName) .setDimension(dimension) .setIndexFileSize(1024) .setMetricType(MetricType.L2) .build(); client.createCollection(collectionMapping); ``` 5. 插入向量数据。 ```java List<FloatVector> vectors = new ArrayList<>(); vectors.add(FloatVector.newBuilder().addValue(1.0f).addValue(2.0f).build()); vectors.add(FloatVector.newBuilder().addValue(2.0f).addValue(3.0f).build()); List<Long> ids = client.insert(collectionName, vectors); ``` 6. 进行向量检索。 ```java SearchParam searchParam = SearchParam.newBuilder() .setCollectionName(collectionName) .setQueryRecordNum(10) .setQueryRangeArray( Range.newBuilder() .setStartValue(0.0) .setEndValue(1.0) .build() ).build(); SearchResponse searchResponse = client.search(searchParam); ``` 7. 删除数据和集合。 ```java client.deleteByIds(collectionName, ids); client.dropCollection(collectionName); ``` 以上是使用JavaMilvus进行集成的基本步骤。开发者可以根据自己的需求进行定制化开发,以实现更高效的数据存储和检索

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值