向量检索将加速深度学习的落地与应用,向量检索的应用场景如下图所示,它几乎覆盖了大部分的可以应用AI的业务场景
这里的KNN其实是ANN,与传统的KNN算法相比ANN在性能和召回准确性方面做了平衡,传统的KNN检索性能损耗是暴力线性增长的,仅能处理百万内的数据量。
首先,在创建索引时需要选择dense_vector类型并指定index为true,并定义索引时文档间相似度量算法,此时es在索引文档时会为knn搜索生成新的索引文件,新的索引文件采用的是树加链表的存储结构,并根据similarity指定的相似算法计算文档间距离,特征相近的数据会存储在临近的分支里
PUT my-approx-knn-index
{
"mappings": {
"properties": {
"my-image-vector": {
"type": "dense_vector",
"dims": 5,
"index": true,
"similarity": "l2_norm"
},
"my-tag": {
"type": "keyword"
}
}
}
}
文档索引后就可以通过knn_search语法进行topK近邻检索了。这里需要注意的时返回的K个数据为近似最优解 ,并不是真实的最近邻数据。
GET my-approx-knn-index/_knn_search
{
"knn": {
"field": "my-image-vector",
"query_vector": [-0.5, 90.0, -10, 14.8, -156.0],
"k": 10,
"num_candidates": 100
},
"fields": [
"my-image-vector",
"my-tag"
]
}
其中num_candidates是检索分片时获得的候选集数量。
下个版本_knn将支持filter
目前knn查询还处于试验阶段不能和DSL语法混合使用,官方正在努力解决,预估在8.2之后版本会逐步增加布尔查询及filter操作,不过采用的是多路归并的方式,即分别检索标签和向量再进行结果合并,虽可以解决部分问题,但多数情况下结果不甚理想。主要原因在于,向量检索无范围性,其目标是尽可能保证 TOPK 的准确性,TOPK 很大时,准确性容易下降,造成归并结果的不准确甚至为空的情况。
当结果低于K个时会触发精准最近邻检索,也就是前面说的KNN
GET my-approx-knn-index/_search
{
"size": k,
"query": {
"script_score": {
"query" : {
"bool" : {
"filter" : {
"term" : {
"my-tag" : "易企秀"
}
}
}
},
"script": {
"source": "cosineSimilarity(params.queryVector, 'my-image-vector') + 1.0",
"params": {
"queryVector": [-0.5, 90.0, -10, 14.8, -156.0]
}
}
}
}
}
写在最后
随着 AI 技术的广泛应用以及数据规模的不断增长,向量检索作为深度学习中的主流方法,其具备的泛检索和多模态搜索的能力也将进一步得到发挥。
网友评论