ElasticSearch向量检索技术方案介绍

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、展望

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值