使用向量檢索插件(aliyun-knn)
向量檢索插件是阿里云Elasticsearch團(tuán)隊(duì)自主開發(fā)的向量檢索引擎插件,基于阿里巴巴達(dá)摩院proxima向量檢索庫(kù)實(shí)現(xiàn),能夠幫助您快速實(shí)現(xiàn)圖像搜索、視頻指紋采樣、人臉識(shí)別、語(yǔ)音識(shí)別和商品推薦等向量檢索場(chǎng)景的需求。本文介紹如何使用向量檢索插件。
背景信息
應(yīng)用場(chǎng)景
阿里云Elasticsearch向量檢索引擎已成熟應(yīng)用于拍立淘、阿里云圖像搜索服務(wù)、趣頭條視頻指紋采樣、猜您喜歡、搜索個(gè)性化、CrossMedia搜索等大規(guī)模生產(chǎn)應(yīng)用場(chǎng)景。
同時(shí),在阿里巴巴集團(tuán)內(nèi),智能開放搜索OpenSearch-向量檢索版作為阿里自研大規(guī)模分布式搜索引擎,支持淘寶、天貓、菜鳥、優(yōu)酷乃至海外電商等整個(gè)集團(tuán)的搜索業(yè)務(wù)。詳細(xì)信息請(qǐng)參見向量檢索版介紹。
原理
阿里云Elasticsearch向量檢索功能基于Elasticsearch插件擴(kuò)展機(jī)制實(shí)現(xiàn),能夠完全兼容原生Elasticsearch版本,您無(wú)需額外的學(xué)習(xí)成本即可使用向量檢索引擎。向量索引除了支持實(shí)時(shí)增量寫入、近實(shí)時(shí)(Near Real Time,簡(jiǎn)稱NRT)搜索查詢,還具備了所有原生Elasticsearch的分布式能力,同時(shí)支持多副本、錯(cuò)誤恢復(fù)等功能。
說(shuō)明阿里云Elasticsearch向量檢索插件不支持通過(guò)OSS快照、DataWorks等方式進(jìn)行數(shù)據(jù)遷移,建議使用Logstash方式。
算法說(shuō)明
在算法上,目前向量檢索引擎已經(jīng)支持了hnsw算法以及l(fā)inear算法,適用于單機(jī)數(shù)據(jù)量小(全內(nèi)存)的業(yè)務(wù)場(chǎng)景。兩種算法性能對(duì)比如下。
表 1. hnsw算法和linear算法性能對(duì)比 表格中為阿里云Elasticsearch 6.7.0版本環(huán)境實(shí)測(cè)數(shù)據(jù),測(cè)試環(huán)境配置如下:
機(jī)器配置:數(shù)據(jù)節(jié)點(diǎn)16核64 GB*2 + 100 GB SSD云盤。
數(shù)據(jù)集:sift128維float向量。
數(shù)據(jù)總量:2千萬(wàn)條。
索引配置:全部采用默認(rèn)參數(shù)。
性能指標(biāo)
hnsw
linear
top10召回率
98.6%
100%
top50召回率
97.9%
100%
top100召回率
97.4%
100%
延遲(p99)
0.093s
0.934s
延遲(p90)
0.018s
0.305s
說(shuō)明表中的p表示百分比,例如延遲(p99)表示99%的查詢能在多少秒返回。
前提條件
安裝向量檢索插件(英文名稱為aliyun-knn)。插件的默認(rèn)安裝情況與阿里云Elasticsearch的實(shí)例版本和內(nèi)核版本相關(guān),具體說(shuō)明如下。
Elasticsearch版本
內(nèi)核版本
插件安裝情況說(shuō)明
6.7.0
1.2.0以下
需要在插件配置頁(yè)面手動(dòng)安裝向量檢索插件,安裝方法請(qǐng)參見安裝或卸載系統(tǒng)默認(rèn)插件。
不支持使用script檢索和索引預(yù)熱等功能配置。如有需求,建議使用有AliES內(nèi)核版本的實(shí)例,詳細(xì)信息請(qǐng)參見內(nèi)核版本發(fā)布記錄。
創(chuàng)建向量索引時(shí)僅支持默認(rèn)的
SquaredEuclidean
,不支持通過(guò)distance_method
參數(shù)指定具體的距離度量函數(shù)。
6.8
無(wú)
7.4
無(wú)
7.7
無(wú)
6.7.0
1.2.0及以上
向量檢索插件默認(rèn)集成在apack插件中(默認(rèn)已安裝),安裝或卸載向量檢索插件都需對(duì)apack插件進(jìn)行操作。詳細(xì)信息請(qǐng)參見使用apack插件的物理復(fù)制功能。
支持使用script檢索、索引預(yù)熱、擴(kuò)展函數(shù)等擴(kuò)展功能,但需要將內(nèi)核版本升級(jí)至1.3.0及以上,具體操作請(qǐng)參見升級(jí)版本。
如果創(chuàng)建向量索引時(shí)遇到解析mapping報(bào)錯(cuò),請(qǐng)升級(jí)內(nèi)核版本至1.3.0及以上后再重試。
7.10.0
1.4.0及以上
向量檢索插件默認(rèn)集成在apack插件中(默認(rèn)已安裝),安裝或卸載向量檢索插件都需對(duì)apack插件進(jìn)行操作。詳細(xì)信息請(qǐng)參見使用apack插件的物理復(fù)制功能。
內(nèi)核小版本大于等于1.4.0時(shí),apack插件版本已為最新版本,無(wú)需更新。使用時(shí),可通過(guò)GET _cat/plugins?v命令獲取插件版本。
其他版本
無(wú)
不支持向量檢索功能。
說(shuō)明內(nèi)核版本不等同于apack插件版本,使用時(shí)可通過(guò)GET _cat/plugins?v命令獲取apack插件版本。
完成索引規(guī)劃。
算法
適用場(chǎng)景
是否全內(nèi)存
其他
hnsw
單機(jī)數(shù)據(jù)量小。
對(duì)延遲要求高。
對(duì)召回率要求高。
是
hnsw是基于“鄰居的鄰居可能是鄰居”的核心思想,它在距離衡量算法上有一定的限制,需要滿足三角形不等式,即三角形的兩邊之和大于第三邊。例如,對(duì)于內(nèi)積向量空間,由于不滿足三角形不等式,需要轉(zhuǎn)化為歐式空間或球面空間,才能使用hnsw檢索方法。
建議寫入結(jié)束后,在業(yè)務(wù)低峰期定期forceMerge,有助于降低查詢延遲。
linear
暴力檢索。
召回率100%。
延遲與數(shù)據(jù)量成正比。
效果對(duì)照。
是
無(wú) 。
完成集群規(guī)劃。
規(guī)劃項(xiàng)
說(shuō)明
數(shù)據(jù)節(jié)點(diǎn)規(guī)格(必須)
16核64 GB及以上。
說(shuō)明使用aliyun-knn插件構(gòu)建索引時(shí),需要消耗大量的計(jì)算資源。由于小規(guī)格集群極易達(dá)到瓶頸,嚴(yán)重時(shí)會(huì)影響集群穩(wěn)定性,因此建議您使用16核64 GB及以上規(guī)格的集群。
節(jié)點(diǎn)類型
集群中需要有獨(dú)立的專有主節(jié)點(diǎn)。
集群堆外內(nèi)存
大于集群總向量數(shù)據(jù)*2。
示例: 索引中只有一個(gè)960維float字段,索引總文檔數(shù)是400,float類型數(shù)據(jù)占4字節(jié)內(nèi)存,此索引向量數(shù)據(jù)內(nèi)存占用=960*400*4=1.5MB,內(nèi)存空間中堆外內(nèi)存>1.5*2=3MB。
說(shuō)明如果存在forcemerge操作,考慮到新老數(shù)據(jù)會(huì)出現(xiàn)同時(shí)占用內(nèi)存的情況,請(qǐng)?jiān)谏厦婀降幕A(chǔ)上再乘以2。
64GB及以上內(nèi)存規(guī)格,堆外大小≈總內(nèi)存-32G。
寫入限流
向量索引的構(gòu)建屬于CPU密集型任務(wù),建議業(yè)務(wù)控制寫入流量不要太高。以16核64 GB的數(shù)據(jù)節(jié)點(diǎn)為例,建議單節(jié)點(diǎn)寫入峰值控制在5000tps以內(nèi)。
同時(shí),由于在向量索引的查詢過(guò)程中,會(huì)把索引文件全部加載到系統(tǒng)內(nèi)存,因此建議在業(yè)務(wù)查詢期間,不要同時(shí)進(jìn)行大批量的寫入,避免因節(jié)點(diǎn)內(nèi)存緊張導(dǎo)致分片重啟的情況。
說(shuō)明以上均為預(yù)估,以業(yè)務(wù)實(shí)際的應(yīng)用情況為準(zhǔn),建議提前進(jìn)行壓測(cè),并提供充足的內(nèi)存空間。
使用限制
開啟共享彈性存儲(chǔ)功能的6.7版本實(shí)例不支持向量檢索插件。
在安裝向量檢索插件前,需要確保阿里云Elasticsearch實(shí)例的數(shù)據(jù)節(jié)點(diǎn)規(guī)格為16核64 GB及以上。如果不滿足,請(qǐng)先將數(shù)據(jù)節(jié)點(diǎn)規(guī)格升級(jí)至16核64 GB及以上,詳細(xì)信息請(qǐng)參見升配集群。
使用向量檢索插件的場(chǎng)景中,部分AliES內(nèi)核的增強(qiáng)功能將不能使用。以物理復(fù)制功能為例,如果您使用了物理復(fù)制功能,使用向量檢索插件前,需要先關(guān)閉該功能,具體操作請(qǐng)參見使用apack插件的物理復(fù)制功能。
阿里云Elasticsearch向量檢索插件不支持通過(guò)OSS快照、DataWorks等方式進(jìn)行數(shù)據(jù)遷移,建議使用Logstash方式。
創(chuàng)建向量索引
- 登錄目標(biāo)阿里云Elasticsearch實(shí)例的Kibana控制臺(tái),根據(jù)頁(yè)面提示進(jìn)入Kibana主頁(yè)。登錄Kibana控制臺(tái)的具體操作,請(qǐng)參見登錄Kibana控制臺(tái)。說(shuō)明 本文以阿里云Elasticsearch 6.7.0版本為例,其他版本操作可能略有差別,請(qǐng)以實(shí)際界面為準(zhǔn)。
- 在左側(cè)導(dǎo)航欄,單擊Dev Tools。
在Console中執(zhí)行如下命令,創(chuàng)建向量索引結(jié)構(gòu)。
PUT test { "settings": { "index.codec": "proxima", "index.vector.algorithm": "hnsw" }, "mappings": { "_doc": { "properties": { "feature": { "type": "proxima_vector", "dim": 2, "vector_type": "float", "distance_method": "SquaredEuclidean" } } } } }
說(shuō)明在向量索引結(jié)構(gòu)的基礎(chǔ)上,支持添加Elasticsearch支持的其他字段類型。
如果創(chuàng)建向量索引時(shí)遇到解析mapping報(bào)錯(cuò):
"type": "mapper_parsing_exception", "reason": "Mapping definition for [feature] has unsupported parameters: [distance_method : SquaredEuclidean]
,請(qǐng)及時(shí)升級(jí)內(nèi)核版本至最新后重試。
類型
參數(shù)
默認(rèn)值
含義
setting
index.codec
proxima
是否需要底層構(gòu)建proxima knn索引,可選值如下:
proxima(推薦):底層構(gòu)建proxima knn索引,支持向量檢索。
null:創(chuàng)建索引的時(shí)候,底層不構(gòu)建proxima knn索引,只構(gòu)建正排索引。此時(shí),proxima_vector類型字段僅支持script檢索,不支持hnsw或linear檢索。
說(shuō)明當(dāng)數(shù)據(jù)量較大,且對(duì)查詢延遲要求不高的場(chǎng)景,可以把該項(xiàng)配置去掉或設(shè)置為null,此時(shí)可使用script檢索方式進(jìn)行knn向量查詢。支持script檢索方式的版本:實(shí)例版本為6.7.0且apack插件版本≥1.2.1或?qū)嵗姹緸?.10.0且apack插件版本≥1.4.0。
index.vector.algorithm
hnsw
指定向量檢索算法,可選值如下:
hnsw:hnsw算法。
linear:linear算法。
index.vector.general.builder.offline_mode
false
指定knn索引構(gòu)建是否使用離線優(yōu)化模式,可選值如下:
false: 不使用離線優(yōu)化模式。
true: 使用離線優(yōu)化模式,寫入構(gòu)建的segment碎片將會(huì)大幅度減少,提升整體寫入吞吐能力。
說(shuō)明開啟離線優(yōu)化模式需要保證:實(shí)例版本為6.7.0且apack插件版本≥1.2.1或?qū)嵗姹緸?.10.0且apack插件版本≥1.4.0;開啟離線模式構(gòu)建的索引,不支持使用script檢索數(shù)據(jù)。
當(dāng)一次性批量導(dǎo)入全量數(shù)據(jù)時(shí),建議開啟離線優(yōu)化模式。
mapping
type
proxima_vector
向量字段類型。例如:將feature字段指定為proxima_vector,說(shuō)明feature為向量字段。
dim
2
向量維度,必填,僅支持1~2048維。
vector_type
float
向量數(shù)據(jù)類型,可選值如下:
float:浮點(diǎn)型。
short:短整型。
binary:二進(jìn)制類型。
其中binary類型為二進(jìn)制類型,向量數(shù)據(jù)需要用無(wú)符號(hào)的32位十進(jìn)制(uint32)數(shù)組表示,且dim必須為32的整數(shù)倍。
例如:業(yè)務(wù)數(shù)據(jù)為64位二進(jìn)制1000100100100101111000001001111101000011010010011010011010000100,那么寫入vector為[-1994006369, 1128900228]。
說(shuō)明實(shí)例版本為6.7.0且apack插件版本≥1.2.1或?qū)嵗姹緸?.10.0且apack插件版本≥1.4.0,向量數(shù)據(jù)類型支持以上三種類型。否則,向量數(shù)據(jù)類型僅支持float類型。
distance_method
SquaredEuclidean(未開方)
距離度量函數(shù),可選值如下:
SquaredEuclidean:歐氏距離(未開方)。
InnerProduct:內(nèi)積。
Cosine:余弦相似度。
Hamming:漢明距離(僅支持binary類型)。
說(shuō)明實(shí)例版本為6.7.0且apack插件版本≥1.2.1或?qū)嵗姹緸?.10.0且apack插件版本≥1.4.0時(shí),支持以上四種距離度量函數(shù)。其他版本(6.8,7.4和7.7)實(shí)例創(chuàng)建向量時(shí)僅支持使用默認(rèn)的SquaredEuclidean,不支持通過(guò)
distance_method
參數(shù)指定其他距離度量函數(shù)。距離度量函數(shù)詳細(xì)說(shuō)明請(qǐng)參見距離度量函數(shù)。
因Hamming函數(shù)實(shí)現(xiàn)比較特殊,索引使用hnsw或linear時(shí),不支持標(biāo)準(zhǔn)的knn查詢方式,僅支持script方式,且查詢語(yǔ)句兼容script_score。在不同的場(chǎng)景下,您需要根據(jù)具體業(yè)務(wù)測(cè)試查詢語(yǔ)句的可用性。
執(zhí)行如下命令,添加文檔。
POST test/_doc { "feature": [1.0, 2.0] }
說(shuō)明除binary類型外,其他類型數(shù)組長(zhǎng)度必須與dim保持一致,而binary類型的向量數(shù)據(jù)需要轉(zhuǎn)換成無(wú)符號(hào)的32位十進(jìn)制(uint32)數(shù)組表示,且dim必須為32的整數(shù)倍。
向量查詢
標(biāo)準(zhǔn)檢索
執(zhí)行如下命令,對(duì)文檔進(jìn)行標(biāo)準(zhǔn)檢索。
GET test/_search { "query": { "hnsw": { "feature": { "vector": [1.5, 2.5], "size": 10 } } } }
常用參數(shù)說(shuō)明如下。
參數(shù)
說(shuō)明
hnsw
向量查詢算法,與創(chuàng)建索引時(shí)指定的algorithm一致。
vector
查詢的向量數(shù)據(jù),數(shù)組長(zhǎng)度必須與創(chuàng)建索引時(shí),mapping指定的dim保持一致。
size
指定召回的文檔數(shù)。
說(shuō)明向量檢索中的size參數(shù)與Elasticsearch自帶的size參數(shù)存在區(qū)別,前者控制向量檢索插件knn召回的文檔數(shù),后者控制整個(gè)查詢的召回文檔數(shù)。使用時(shí),系統(tǒng)會(huì)先通過(guò)向量檢索中的size參數(shù)召回topN的文檔,然后再由Elasticsearch自帶的size參數(shù)召回整個(gè)查詢的文檔,最終返回結(jié)果。
建議向量檢索中的size參數(shù)值和Elasticsearch自帶的size參數(shù)值(默認(rèn)值為10)保持一致。
說(shuō)明knn向量檢索還提供高級(jí)查詢參數(shù),詳細(xì)信息請(qǐng)參見高階參數(shù)。
script檢索
script向量檢索僅支持在script_score方式下使用。例如使用script_score對(duì)查詢返回的每個(gè)文檔進(jìn)行打分,該分?jǐn)?shù)等于
1/(1+l2Squared(params.queryVector, doc['feature']))
。示例命令如下。GET test/_search { "query": { "match_all": {} }, "rescore": { "query": { "rescore_query": { "function_score": { "functions": [{ "script_score": { "script": { "source": "1/(1+l2Squared(params.queryVector, doc['feature'])) ", "params": { "queryVector": [2.0, 2.0] } } } }] } } } } }
knn向量script檢索不支持X-Pack提供的函數(shù),僅支持以下函數(shù):
函數(shù)
說(shuō)明
l2Squared(float[] queryVector, DocValues docValues)
歐式算法函數(shù)。
hamming(float[] queryVector, DocValues docValues)
漢明距離函數(shù)。
cosineSimilarity(float[] queryVector, DocValues docValues)
cosine(float[] queryVector, DocValues docValues)
余弦相似度函數(shù)。
說(shuō)明阿里云Elasticsearch 6.7版本請(qǐng)使用
cosineSimilarity(float[] queryVector, DocValues docValues)
函數(shù),7.10版本請(qǐng)使用cosine(float[] queryVector, DocValues docValues)
函數(shù)。說(shuō)明使用script檢索功能,需要確保:實(shí)例版本為6.7.0且apack插件版本≥1.2.1版本或?qū)嵗姹緸?.10.0版本且apack插件版本≥1.4.0。您可以通過(guò)GET /_cat/plugins?v命令獲取apack插件版本,如果apack插件版本不滿足要求,可提交工單,由阿里云工程師幫您升級(jí)。
函數(shù)參數(shù):
float[] queryVector:用于表示查詢向量,可傳入形參和實(shí)參。
DocValues docValues:用于指定文檔向量。
script向量檢索不支持處于離線模式(
index.vector.builder.offlineMode = true
)下構(gòu)建的索引。
索引預(yù)熱(降低延遲)
knn索引由于需要進(jìn)行全內(nèi)存檢索,所以在索引冷加載時(shí)會(huì)出現(xiàn)查詢延遲較高的情況。因此knn插件提供了索引預(yù)熱功能,可以在knn索引提供檢索服務(wù)之前,提前對(duì)knn索引進(jìn)行預(yù)熱,加載到本地內(nèi)存,從而大大降低冷啟動(dòng)時(shí)的查詢延遲。
所有向量索引實(shí)現(xiàn)預(yù)熱。
POST _vector/warmup
特定向量索引實(shí)現(xiàn)預(yù)熱能力。
POST _vector/{indexName}/warmup
說(shuō)明使用索引預(yù)熱功能,需要確保:實(shí)例版本為6.7.0且apack插件版本≥1.2.1或?qū)嵗姹緸?.10.0且apack插件版本≥1.4.0。您可以通過(guò)GET _cat/plugins?v命令獲取apack插件版本,如果apack插件版本不滿足要求,可提交工單,由阿里云工程師幫您升級(jí)。
如果集群中向量索引比較多且數(shù)據(jù)量比較大,業(yè)務(wù)只需要對(duì)特定索引實(shí)現(xiàn)向量檢索,建議只對(duì)特定向量使用預(yù)熱能力,提升內(nèi)存檢索能力。
向量打分
向量檢索擁有統(tǒng)一的打分公式,而打分機(jī)制主要依賴距離度量函數(shù)。不同的距離函數(shù)直接性的影響檢索排序。
打分公式:
分?jǐn)?shù)= 1/(向量距離函數(shù)+1)
向量打分機(jī)制默認(rèn)使用未開方的歐式距離。
在實(shí)際應(yīng)用中,您可以通過(guò)查詢分?jǐn)?shù)反推向量間的距離,優(yōu)化向量數(shù)據(jù),提升打分。
距離度量函數(shù)
不同的距離度量函數(shù)對(duì)應(yīng)不同的打分機(jī)制,下面是aliyun-knn插件支持的度量算法:
距離函數(shù) | 定義 | 打分公式 | 應(yīng)用場(chǎng)景 | 示例 |
SquaredEuclidean歐氏距離(未開方) | 歐幾里得度量(euclidean metric)也稱歐氏距離,是一個(gè)通常采用的距離定義,指在m維空間中兩個(gè)點(diǎn)之間的真實(shí)距離,或者向量的自然長(zhǎng)度(即該點(diǎn)到原點(diǎn)的距離)。在二維和三維空間中的歐氏距離就是兩點(diǎn)之間的實(shí)際距離。 | 以兩個(gè)n維向量A = [A1, A2,…, An]和B= [B1, B2,…, Bn]為例:
說(shuō)明 向量打分默認(rèn)使用未開方的歐式距離計(jì)算。 | 歐氏距離能夠體現(xiàn)個(gè)體數(shù)值特征的絕對(duì)差異,所以更多的用于需要從維度的數(shù)值大小中體現(xiàn)差異的分析,例如使用用戶行為指標(biāo)分析用戶價(jià)值的相似度或差異。 | 例如:兩個(gè)二維向量[0,0]和[1,2],未開方歐式距離= (1-0)2 + (2-0)2 = 5。 |
Cosine余弦相似度 | 余弦相似度,又稱為余弦相似性,是通過(guò)計(jì)算兩個(gè)向量的夾角的余弦值來(lái)評(píng)估它們之間的相似性。 | 以兩個(gè)n維向量A = [A1, A2,…, An]和B= [B1, B2,…, Bn]為例:
| 余弦相似度更多的是從方向上區(qū)分差異,而對(duì)絕對(duì)的數(shù)值不敏感,更多的用于用戶對(duì)內(nèi)容評(píng)分來(lái)區(qū)分興趣的相似度和差異,同時(shí)修正了用戶間可能存在的度量標(biāo)準(zhǔn)不統(tǒng)一的問(wèn)題(因?yàn)橛嘞蚁嗨贫葘?duì)絕對(duì)數(shù)值不敏感)。 | 例如兩個(gè)二維向量[1,1]和[1,0],向量余弦相似度=0.707。 |
InnerProduct內(nèi)積 | 內(nèi)積又稱點(diǎn)積,是指接受在實(shí)數(shù)R上的兩個(gè)向量,并返回一個(gè)實(shí)數(shù)值標(biāo)量的二元運(yùn)算。 | 以兩個(gè)n維向量A = [A1, A2,…, An]和B= [B1, B2,…, Bn]為例:
| 內(nèi)積同時(shí)考慮了兩個(gè)向量的夾角及絕對(duì)長(zhǎng)度。當(dāng)向量歸一化后,內(nèi)積與余弦相似度計(jì)算公式等價(jià)。 | 例如兩個(gè)二維向量[1,1]和[1,5],向量?jī)?nèi)積=1+5=6。 |
Hamming漢明距離(僅支持binary類型) | 在信息理論中,Hamming Distance表示兩個(gè)等長(zhǎng)字符串在對(duì)應(yīng)位置上不同字符的數(shù)量,我們以d(x, y)表示字符串x和y之間的漢明距離。從另外一個(gè)方面看,漢明距離度量了通過(guò)替換字符的方式將字符串x變成y所需要的最小的替換次數(shù)。 | 以兩個(gè)n位的二進(jìn)制編碼x和y為例:
| 典型的用例包括數(shù)據(jù)通過(guò)計(jì)算機(jī)網(wǎng)絡(luò)傳輸時(shí)的錯(cuò)誤糾正或檢測(cè)。它可以用來(lái)確定二進(jìn)制字中不同字符的數(shù)目,作為估計(jì)誤差的一種方法。 | 例如:1011101與1001001之間的漢明距離是2。 說(shuō)明 在aliyun-knn插件使用中,binary類型的向量數(shù)據(jù)需要轉(zhuǎn)換成無(wú)符號(hào)的32位十進(jìn)制(uint32)數(shù)組表示,且 |
使用多種距離度量函數(shù),需要確保:實(shí)例版本為6.7.0且apack插件版本≥1.2.1版本或?qū)嵗姹緸?.10.0版本且apack插件版本≥1.4.0。您可以通過(guò)GET _cat/plugins?v命令獲取apack插件版本,如果apack插件版本不滿足要求,則knn距離度量函數(shù)僅支持SquaredEuclidean歐氏距離(未開方)。如果您需要使用其他距離函數(shù),可提交工單,由阿里云工程師幫您升級(jí)插件版本。
您可以在索引mapping中,通過(guò)distance_method參數(shù)指定不同的距離度量函數(shù)。
熔斷參數(shù)
參數(shù) | 描述 | 默認(rèn)值 |
indices.breaker.vector.native.indexing.limit | 如果堆外內(nèi)存使用超過(guò)該值,寫入操作會(huì)被熔斷;等待后臺(tái)構(gòu)建完成釋放內(nèi)存后,寫入恢復(fù)正常。出現(xiàn)熔斷錯(cuò)誤表示當(dāng)前系統(tǒng)內(nèi)存消耗已經(jīng)過(guò)高,建議業(yè)務(wù)上降低寫入流量。 | 70% |
indices.breaker.vector.native.total.limit | 向量索引后臺(tái)構(gòu)建最多使用的堆外內(nèi)存比例。如果實(shí)際使用的堆外內(nèi)存超過(guò)了這個(gè)比例,可能會(huì)發(fā)生shard重啟的情況。 | 80% |
向量熔斷參數(shù)配置屬于集群配置,可通過(guò)GET _cluster/settings命令查看,建議您不要調(diào)整熔斷值。
高階參數(shù)
參數(shù) | 描述 | 默認(rèn)值 |
index.vector.hnsw.builder.max_scan_num | 用于控制構(gòu)圖過(guò)程中的近鄰考察范圍,保證最壞情況的性能。 | 100000 |
index.vector.hnsw.builder.neighbor_cnt | hnsw 0層圖每個(gè)節(jié)點(diǎn)的鄰居數(shù)。建議配置為100。該值越大,離線索引存儲(chǔ)消耗越大,圖構(gòu)建質(zhì)量越高。 | 100 |
index.vector.hnsw.builder.upper_neighbor_cnt | hnsw上層圖(除0層之外)中每個(gè)節(jié)點(diǎn)的鄰居上限數(shù)。一般建議配置為neighbor_cnt的一半,最大不能超過(guò)255。 | 50 |
index.vector.hnsw.builder.efconstruction | 控制圖構(gòu)建過(guò)程中近鄰掃描區(qū)域大小,該值越大,離線構(gòu)圖質(zhì)量越好,索引構(gòu)建越慢。建議初始值設(shè)置為400。 | 400 |
index.vector.hnsw.builder.max_level | hnsw總層數(shù),包含0層圖和上層圖。例如總共1000萬(wàn)文檔,scaling_factor為30,那么層數(shù)可以以max level=30為底,取1000萬(wàn)的對(duì)數(shù)向上取整,計(jì)算得5。 該值對(duì)效果影響不大,一般建議初始配置為6。 | 6 |
index.vector.hnsw.builder.scaling_factor | 下層圖是上層圖數(shù)據(jù)的多少倍,呈指數(shù)關(guān)系。通常設(shè)置在10~100之間。scaling_factor越大,實(shí)際生成的圖層數(shù)越低。建議初始配置為50。 | 50 |
以上參數(shù)需在索引setting中設(shè)置使用,并且僅支持在hnsw算法模型中使用。
參數(shù) | 描述 | 默認(rèn)值 |
ef | 用于控制在線檢索時(shí),考察的子圖范圍大小。該值越大,召回越高,性能越差。建議取值[100,1000]。 | 100 |
查詢示例如下。
GET test/_search
{
"query": {
"hnsw": {
"feature": {
"vector": [1.5, 2.5],
"size": 10,
"ef": 100
}
}
}
}
常見問(wèn)題
Q:如何評(píng)估查詢的召回率?
A:可以同時(shí)創(chuàng)建兩個(gè)索引,一個(gè)為hnsw算法,一個(gè)為linear算法,其他配置相同。客戶端向兩個(gè)索引同時(shí)推送相同的向量數(shù)據(jù),刷新后,用同樣的查詢向量對(duì)比linear索引和hnsw索引召回的文檔ID,交集的文檔ID個(gè)數(shù)/召回總數(shù),即為待測(cè)向量的召回率。
說(shuō)明交集的文檔ID個(gè)數(shù)是指兩個(gè)索引召回的文檔ID的交集。
Q:集群寫入期間報(bào)錯(cuò)
circuitBreakingException
,如何處理?A:這個(gè)錯(cuò)誤表明此時(shí)系統(tǒng)的堆外內(nèi)存使用率超過(guò)了indices.breaker.vector.native.indexing.limit指定的比例(默認(rèn)為70%),觸發(fā)了寫入的熔斷操作,一般等待后臺(tái)的索引構(gòu)建任務(wù)完成后會(huì)自動(dòng)釋放。建議客戶端寫入時(shí)添加錯(cuò)誤重試機(jī)制。
Q:為什么寫入任務(wù)已經(jīng)停止了,CPU依然在工作?
A:向量索引的構(gòu)建發(fā)生在refresh或flush期間,雖然寫入流量已經(jīng)停止,但后臺(tái)的向量索引構(gòu)建任務(wù)可能仍然在繼續(xù)。等待最后一輪refresh結(jié)束后,計(jì)算資源就會(huì)被釋放。
Q:使用aliyun-knn插件查詢時(shí)報(bào)錯(cuò)
class_cast_exception: class org.apache.lucene.index.SoftDeletesDirectoryReaderWrapper$SoftDeletesFilterCodecReader cannot be cast to class org.apache.lucene.index.SegmentReader (org.apache.lucene.index.SoftDeletesDirectoryReaderWrapper$SoftDeletesFilterCodecReader and org.apache.lucene.index.SegmentReader are in unnamed module of loader 'app')
,如何處理?A:關(guān)閉索引的物理復(fù)制功能,具體操作請(qǐng)參見使用apack插件的物理復(fù)制功能。
Q:使用aliyun-knn插件進(jìn)行向量檢索,速度過(guò)慢或出現(xiàn)內(nèi)存熔斷,怎么辦?
A:aliyun-knn插件進(jìn)行向量檢索時(shí),使用的是全內(nèi)存型向量,非常消耗內(nèi)存。當(dāng)索引數(shù)據(jù)量較大時(shí),由于需要將數(shù)據(jù)加載到內(nèi)存,因此會(huì)出現(xiàn)速度慢或內(nèi)存熔斷的情況。建議索引數(shù)據(jù)量是機(jī)器內(nèi)存的一半,在數(shù)據(jù)量無(wú)法變更的情況下,如果內(nèi)存太小,建議您升配集群。
Q:關(guān)于aliyun-knn插件是否有提供最佳實(shí)踐文檔供參考?
A:您可以參見阿里云開發(fā)者社區(qū)提供的aliyun-knn插件業(yè)務(wù)場(chǎng)景和aliyun-knn最佳實(shí)踐。
Q:如果當(dāng)下阿里云Elasticsearch集群的向量檢索能力不滿足業(yè)務(wù)需求,怎么辦?
A:推薦您使用阿里巴巴自主研發(fā)的大規(guī)模分布式搜索引擎OpenSearch-向量檢索版,詳細(xì)信息請(qǐng)參見向量檢索版介紹。
Q:knn場(chǎng)景使用
must_not exists
無(wú)法過(guò)濾出feature字段為空的文檔,如何編寫語(yǔ)句過(guò)濾出feature字段為空的數(shù)據(jù)?A:knn數(shù)據(jù)存儲(chǔ)比較特殊,可能會(huì)存在個(gè)別DSL查詢不兼容的情況,您可以使用以下腳本進(jìn)行過(guò)濾。
GET jx-similar-product-v1/_search { "query": { "bool": { "must": { "script": { "script": { "source": "doc['feature'].empty", "lang": "painless" } } } } } }