ElasticSearch向量检索技术方案介绍

news2024/11/26 17:26:27

1、背景

      在人工智能快速发展的今天,推荐技术、以文搜图、以文搜视频、以图搜图等技术已经得到了广泛的应用,在百度、小红书、抖音、快手等app上随便输入一段文本,搜索结果已不像早些年那么单一:只有一些文字信息,现在的搜索结果里不仅有文字,还能够搜索出与检索词高度相关的图片、视频、或者商品(电商app),甚至都不用检索,feed流推荐的内容或者商品都是自身感兴趣的,大家一定会有疑问,整个系统背后是如何实现的呢,为什么输入一段文字,就能检索到相关的视频、音频或者图像呢?不同的内容形式,中间是怎么实现的匹配呢?

      答案就是向量匹配,不同形式的内容需要转化成一个统一的结构化数据。

      AI的出现,实现了这个过程,他可以以一定的算法提取文字、图像、音频、视频等各种形式内容的特征向量,实现了将所有内容形式转化为特征向量的过程。

      内容结构化为特征向量后,那么如何进行检索呢?这就涉及到了本文的主题:向量检索了。

2、es向量检索

2.1 检索算法

1、KNN算法

KNN (K-Nearest Neighbor Search)指的是最近邻搜索。它的原理是:计算待查询向量与数据库中所有向量之间的距离,然后按照距离从小到大排序,选择距离最近的 K 个向量作为查询结果。KNN 算法的优点是可以保证精确的结果,但是效率较低。

2、ANN算法

ANN(Approximate Nearest Neighbor Search) 表示近似最近邻搜索,是一种用于高维数据空间中快速查找最近邻点的方法。与KNN(最近邻搜索)相比,ANN 牺牲了一定的精度以换取更高的搜索速度,因此在处理大规模数据集时具有较高的效率。

ANN 会对数据进行预处理,从而在查询时减少计算距离的次数。其优点是速度快、效率高,但精度有所下降。

3、HNSW

HNSW(Hierarchical Navigable Small World) 是一种基于图的高维向量相似性搜索算法。通过构建一张图来表示向量之间的相似度关系,并使用一些优化策略来加速搜索过程。

2.2 向量距离

向量检索的本质就是计算向量之间的距离,向量距离的大小直接反映两个向量的相似程度,距离越小,两个向量越相似,反之,相似度越低。

常用的距离度量有:

  • 欧式距离:l2
  • 余弦距离:cosine
  • 内积:innerproduct

2.3 elasticsearch环境

es使用的是厂内的:百度Elasticsearch,最新版本7.10,支持向量检索。

2.4 创建索引

以下面创建索引的语句为例说明,这个索引即为工作中开发使用到的,只是对字段做了精简。

{
    "settings": {
        "index": {
            "knn": true,
            "number_of_shards": 9,
            "number_of_replicas": 1
        }
    },
    "mappings": {
        "_source": {
            "excludes": [
                "IFV",
                "TFV"
            ]
        },
        "properties": {
            "car_id": {
                "type": "keyword",
                "ignore_above": 256
            },
            "camera_type": {
                "type": "keyword",
                "ignore_above": 256
            },
            "image_id": {
                "type": "keyword",
                "ignore_above": 256,
                "index": false
            },
            "bbox": {
                "properties": {
                    "left": {
                        "type": "integer",
                        "index": false
                    },
                    "top": {
                        "type": "integer",
                        "index": false
                    },
                    "width": {
                        "type": "integer",
                        "index": false
                    },
                    "height": {
                        "type": "integer",
                        "index": false
                    }
                }
            },
            "IFV": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "l2",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            },
            "TFV": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "innerproduct",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            }
        }
    }
}

各重要字段的含义如下: 

字段示例说明
setting{
        "index": {
            "knn": true,
            "number_of_shards": 9,
            "number_of_replicas": 1
        }
    }

knn:设置为ture,开启向量检索功能。

number_of_shards:分片数量,与集群节点数量一致。

number_of_replicas:副本数量,一般设置为1.

excludes
: {
            "excludes": [
                "IMAGE",
                "TEXT"
            ]
        },
这个字段主要是为了减少数据的存储,这样可以大大降低对存储的消耗(IFV、TFV为向量字段)
IMAGE
            "IMAGE": {
                "type": "bpack_vector",
                "index_type": "hnsw_sq8",
                "dims": 768,
                "space_type": "l2",
                "parameters": {
                    "m": 32,
                    "ef_construction": 256
                }
            }

type:向量字段类型固定为 bpack_vector

index_type: 向量检索算法,hnsw算法+sq8量化

dims:向量维度,768维

space_type:距离计算方式,l2,欧式距离

m:hnsw算法参数。此参数表示构造期间为每个新元素创建的双向链接数,主要影响内存、存储消耗以及召回率。m值越高,意味着更高消耗的内存和存储,更慢的索引构建时间,以及更好的召回率。建议根据min(向量维度 * 1.5, 32)取值,以保证性能,12-48可以满足大多数场景的需求。

ef_construction:hnsw算法参数。此参数表示在索引构建过程中,最近邻居的动态扫描区域大小。该值越大,越不容易陷入局部最优解,召回率更高,但是索引构建越慢,取值范围为[2,+∞]。需要注意,如果用户业务需求要求检索top k,那设置的ef_construction值需要大于k。

注意,向量检索算法、维数、距离计算方式千万不能出错,否则会出现检索结果相关性降低,甚至是不相关。

索引创建完成后,就可以正是写入数据了。

2.5 检索

检索dsl:

{
    "size": 2,
    "query": {
        "knn": {
            "image-vector": {
                "vector": [
                    3,
                    4,
                    5,
                    6
                ],
                "k": 2,
                "ef": 100,
                "filter": {
                    "term": {
                        "car_id": "A88888"
                    }
                }
            }
        }
    }
}

百度elasticsearch的向量检索与官方8.x版本es的检索语句稍有不同,支持向量检索和标量的组合检索。

3、代码实现(golang)

向量检索与普通检索在代码的实现上区别不大,重点是dsl的构建与普通检索略有不同,目前在自研的dsl包(elasticsearch查询语言DSL构建包使用及实现原理(golang)_golang es包-CSDN博客)也实现了向量检索dsl的构建,可以直接使用,非常方便,使用示例:

package main

import (
	"fmt"

	"github.com/liupengh3c/esbuilder"
)

func main() {
	vector := []float64{0.045727044343948364, 0.029040496796369553,
		0.02996855601668358, 0.0001537138596177101,
		-0.011850773356854916, 0.016586067155003548,
		0.029250113293528557}
	dslQuery := esbuilder.NewDsl()
	knnQuery := esbuilder.NewKnnQuery("IFV")
	knnQuery.SetK(10).SetEf(256).SetVector(vector)
	filter := esbuilder.NewTermQuery("car_id.keyword", "京AJB139")
	knnQuery.Filter(filter)
	dslQuery.SetQuery(knnQuery)
	fmt.Println(dslQuery.BuildJson())
}

构建的dsl如下:

{
    "query": {
        "knn": {
            "IFV": {
                "ef": 256,
                "filter": {
                    "term": {
                        "car_id.keyword": "京AJB139"
                    }
                },
                "k": 10,
                "vector": [
                    0.045727044343948364,
                    0.029040496796369553,
                    0.02996855601668358,
                    0.0001537138596177101,
                    -0.011850773356854916,
                    0.016586067155003548,
                    0.029250113293528557
                ]
            }
        }
    }
}

含义为,检索car_id为京AJB139且与检索条件中向量近似的数据。

4、展望

      向量检索在信息技术和数据处理领域具有广泛的应用前景和重要性。随着技术的不断发展,向量检索的性能和准确性将不断提高,为各个领域带来更多的创新和价值。

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

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

相关文章

算法(第一周)

一周周五,总结一下本周的算法学习,从本周开始重新学习许久未见的算法,当然不同于大一时使用的 C 语言以及做过的简单题,现在是每天一题 C 和 JavaScript(还在学,目前只写了一题) 题单是代码随想…

华为云镜像仓库基本操作

1. 登陆华为云账户,在搜索框输入"镜像容器",如下图所示: 单击 输入名称后单击确定 创建成功 2. 回到这里 单击这里 获得登陆指令 复制到你的云服务器粘贴,回车后提示"Login Succeeded"表示登陆成功. 3. 还是在"总览"这里,单击这里 跟着复制操作…

【1个月速成Java】基于Android平台开发个人记账app学习日记——第10天,登录状态保持与退出登录

系列专栏链接如下,方便跟进: https://blog.csdn.net/weixin_62588253/category_12821860.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12821860&sharereferPC&sharesourceweixin_62588253&sharefromfrom_linkhttps://b…

MySQL系列之如何在Linux只安装客户端

导览 前言Q:如何安装一个Linux环境下的MySQL客户端一、准备文件1. 确认Server版本2. 选择Client安装文件 二、下载并安装1. 下载1.1 寻找文件1.2 文件说明 2. 安装2.1 上传至Linux服务器2.2 执行安装 三、连接验证1. 确认远程授权2. 建立远程连接 结语精彩回放 前言…

arcgis pro 学习笔记

二维三维集合在一起,与arcgis不同 一、首次使用,几个基本设置 1.选项——常规里面设置自动保存时间 2.新建工程文件,会自动加载地图,可以在选项里面设置为无,以提高启动效率。 3.设置缓存位置,可勾选每次…

【论文复现】MSA+抑郁症模型总结(三)

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀MSA抑郁症模型 热门研究领域:情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…

‌STAR法则

一:STAR法则 STAR法则是一种简单而实用的表现技巧,常被用于求职过程中的个人经历描述,富有条理性,可以帮助你在职场中脱颖而出。“STAR”分别对应的是situation-task-action-result,通过情境、目标、行动和结果四个方面…

java:使用Multi-Release Jar改造Java 1.7项目增加module-info.class以全面合规Java 9模块化规范

common-java是一个我维护了好多年的一个基础项目,编译目标为Java 1.7 现在整个团队的项目要做Java 9以上的技术迁移准备,就需要对这个在内部各项目中被广泛引用的基础项目进行改造,以适合Java 9的模块化规范。 Automatic-Module-Name Java 9的模块化规范(即Java Platform Mod…

力扣题库——75.颜色分类

这道题采用三路快速排序,快速排序思路看这里快速排序。将数列分为三组:小于基准、等于基准、大于基准。和快排一样,对左右递归进行快速排序。 先将题目简化,如果只有数字0和1,扫描一遍数组,遇到数字1不用管…

python - leetcode【数据结构-算法】-入门/通关手册

python的算法入门/通关/手册 前言:算法通关手册(LeetCode)-githubHello 算法:python数据结构和算法 - 中文版The Algorithms - Python最后刷题思维: python-leetcode刷题常用语法:变量定义:逻辑与或非和按位…

使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能

提示:CSDN 博主测评ONLYOFFICE 文章目录 引言技术栈环境准备安装 ONLYOFFICE 文档服务器获取 API 密钥安装 Flask 和 Requests 创建 Flask 应用项目结构编写 app.py创建模板 templates/index.html 运行应用功能详解文档上传生成编辑器 URL显示编辑器回调处理 安全性…

EasyUI弹出框行编辑,通过下拉框实现内容联动

EasyUI弹出框行编辑,通过下拉框实现内容联动 需求 实现用户支付方式配置,当弹出框加载出来的时候,显示用户现有的支付方式,datagrid的第一列为conbobox,下来选择之后实现后面的数据直接填充; 点击新增:新…

C# 选择导入文件的路径、导出文件的路径

通过C#代码,调出windows风格的文件选择对话框和存储文件对话框。提供界面来选择文件的位置,并将完整路径以字符串形式返回。 1、选择导入文件,获取其路径 C#通过这段代码将弹出一个文件选择对话框,允许用户选择一个文件&#xff…

数据结构-并查集专题(1)

一、前言 因为要开始准备年底的校赛和明年年初的ACM、蓝桥杯、天梯赛,于是开始按专题梳理一下对应的知识点,先从简单入门又值得记录的内容开始,并查集首当其冲。 二、我的模板 虽然说是借用了jiangly鸽鸽的板子,但是自己也小做…

二手交易平台测试用例设计和执行

🎄欢迎来到边境矢梦的csdn博文🎄 🎄追求开源思想和学无止境思想一直在提升技术的路上 🎄 🌈涉及的领域有:Java、Python、微服务架构和分布式架构思想、基本算法编程🌈 🎆喜欢的朋友可…

计算机图形学论文 | 多边形中的点可见性快速算法

🦌🦌🦌读论文 🐨🐨摘要 针对点的可见性计算这一计算几何中的基础问题,提出一种支持任意查询点的可见多边形快速计算的基于多边形Voronoi图的点可见性算法。以与Voronoi骨架路径对应的Voronoi通道概念&…

Redis 高并发分布式锁实战

目录 环境准备 一 . Redis 安装 二:Spring boot 项目准备 三:nginx 安装 四:Jmeter 下载和配置 案例实战 优化一:加 synchronized 锁 优化二:使用 redis 的 setnx 实现分布式锁 优化三:使用 Lua 脚本…

LLM大模型学习精华系列:VLLM性能优化部署实践——全面加速从推理到部署的流程

训练后的模型会用于推理或者部署。推理即使用模型用输入获得输出的过程,部署是将模型发布到恒定运行的环境中推理的过程。一般来说,LLM的推理可以直接使用PyTorch代码、使用[VLLM]等框架,也可以使用[llama.cpp]等c推理框架。 常见推理方法 G…

【大数据学习 | kafka高级部分】kafka的快速读写

1. 追加写 根据以上的部分我们发现存储的方式比较有规划是对于后续查询非常便捷的,但是这样存储是不是会更加消耗存储性能呢? 其实kafka的数据存储是追加形式的,也就是数据在存储到文件中的时候是以追加方式拼接到文件末尾的,这…

SpringCloud篇(微服务)

目录 一、认识微服务 1. 单体架构 2. 分布式架构 3. 微服务 3.1. 特点 3.2. 优点 3.3 缺点 二、微服务设计、拆分原则 1. AKF 拆分原则 2. Y轴(功能)关注应用中功能划分,基于不同的业务拆分 3. X轴(水平扩展&#xff09…