向量索引介紹
向量召回是指將商品或者內容等以向量的形式表達,並建立向量索引庫,索引庫上支援輸入一個或多個使用者或商品向量來根據向量距離召回topK的商品或內容。
向量索引配置
不帶類目的向量配置
{
"table_name": "test_vector",
"summarys": {
"summary_fields": [
"id",
"vector_field"
]
},
"indexs": [
{
"index_name": "pk",
"index_type": "PRIMARYKEY64",
"index_fields": "id",
"has_primary_key_attribute": true,
"is_primary_key_sorted": false
},
{
"index_name": "embedding",
"index_type": "CUSTOMIZED",
"index_fields": [
{
"boost": 1,
"field_name": "id"
},
{
"boost": 1,
"field_name": "vector_field"
}
],
"indexer": "aitheta2_indexer",
"parameters": {
"enable_rt_build": "false",
"min_scan_doc_cnt": "20000",
"vector_index_type": "Qc",
"major_order": "col",
"builder_name": "QcBuilder",
"distance_type": "SquaredEuclidean",
"embedding_delimiter": ",",
"enable_recall_report": "false",
"is_embedding_saved": "false",
"linear_build_threshold": "5000",
"dimension": "128",
"search_index_params": "{\"proxima.qc.searcher.scan_ratio\":0.01}",
"searcher_name": "QcSearcher",
"build_index_params": "{\"proxima.qc.builder.quantizer_class\":\"Int8QuantizerConverter\",\"proxima.qc.builder.quantize_by_centroid\":true,\"proxima.qc.builder.optimizer_class\":\"BruteForceBuilder\",\"proxima.qc.builder.thread_count\":10,\"proxima.qc.builder.optimizer_params\":{\"proxima.linear.builder.column_major_order\":true},\"proxima.qc.builder.store_original_features\":false,\"proxima.qc.builder.train_sample_count\":3000000,\"proxima.qc.builder.train_sample_ratio\":0.5}"
}
}
],
"attributes": [
"id",
"vector_field"
],
"fields": [
{
"field_name": "id",
"field_type": "INTEGER"
},
{
"user_defined_param": {
"multi_value_sep": ","
},
"field_name": "vector_field",
"field_type": "FLOAT",
"multi_value": true
}
]
}
帶有類目的向量配置
{
"table_name": "test_vector",
"summarys": {
"summary_fields": [
"id",
"vector_field",
"category_id"
]
},
"indexs": [
{
"index_name": "pk",
"index_type": "PRIMARYKEY64",
"index_fields": "id",
"has_primary_key_attribute": true,
"is_primary_key_sorted": false
},
{
"index_name": "embedding",
"index_type": "CUSTOMIZED",
"index_fields": [
{
"boost": 1,
"field_name": "id"
},
{
"field_name": "category_id",
"boost": 1
},
{
"boost": 1,
"field_name": "vector_field"
}
],
"indexer": "aitheta2_indexer",
"parameters": {
"enable_rt_build": "false",
"min_scan_doc_cnt": "20000",
"vector_index_type": "Qc",
"major_order": "col",
"builder_name": "QcBuilder",
"distance_type": "SquaredEuclidean",
"embedding_delimiter": ",",
"enable_recall_report": "false",
"is_embedding_saved": "false",
"linear_build_threshold": "5000",
"dimension": "128",
"search_index_params": "{\"proxima.qc.searcher.scan_ratio\":0.01}",
"searcher_name": "QcSearcher",
"build_index_params": "{\"proxima.qc.builder.quantizer_class\":\"Int8QuantizerConverter\",\"proxima.qc.builder.quantize_by_centroid\":true,\"proxima.qc.builder.optimizer_class\":\"BruteForceBuilder\",\"proxima.qc.builder.thread_count\":10,\"proxima.qc.builder.optimizer_params\":{\"proxima.linear.builder.column_major_order\":true},\"proxima.qc.builder.store_original_features\":false,\"proxima.qc.builder.train_sample_count\":3000000,\"proxima.qc.builder.train_sample_ratio\":0.5}"
}
}
],
"attributes": [
"id",
"vector_field",
"category_id"
],
"fields": [
{
"field_name": "id",
"field_type": "INTEGER"
},
{
"user_defined_param": {
"multi_value_sep": ","
},
"field_name": "vector_field",
"field_type": "FLOAT",
"multi_value": true
},
{
"field_name": "category_id",
"field_type": "INTEGER"
}
]
}
引入分類的目的是為了支援按照分類進行向量檢索,比如一個圖片有不同的類別,如果不指定分類構建向量索引,只是對檢索出來的向量進行過濾很可能會出現無結果的情況。
在配置的向量索引時,若為管理員模式,build_index_params和search_index_params的參數內容要去除轉義。
欄位含義
field_name:構建向量索引的欄位,必須為RAW類型,最少包括2個欄位,一個是主鍵(或者是主鍵的hash值),欄位值必須是整數,另一個是包含向量的欄位。如果需要對向量按照分類構建索引,可以新增一個類別欄位,欄位類型為RAW類型,欄位值為整數。這些欄位在索引中的順序必須和在fields配置的順序相同,而且必須是按照主鍵、類目(如果有)、向量這個順序。
index_name:向量索引的名稱。
index_type:索引類型,必須為CUSTOMIZED。
indexer:構建向量索引的外掛程式,目前僅支援aitheta2_indexer。
parameters:向量索引的構建參數和查詢參數。
dimension:維度
embedding_delimiter: 向量分隔字元,預設是","
distance_type:距離類型,目前僅支援如下兩種
InnerProduct (內積)
SquaredEuclidean(平方歐式距離),經過歸一化的資料請配置SquaredEuclidean。
major_order: 資料存放區方式,目前支援如下兩種
col (按列存, 對dimension有要求,必須是2的冪次方, 效能更優)
row(按行存,預設使用)
builder_name: 索引構建類型,建議配置下面兩種(更多參數請聯絡我們)
QcBuilder
LinearBuilder(線性構建,資料文檔數量少於1w時,推薦使用)
searcher_name: 索引檢索類型,和builder_name對應,如果有GPU需求請聯絡我們。
QcSearcher(CPU檢索,對應QcBuilder)
LinearSearcher (CPU暴力檢索,對應LinearBuilder)
build_index_params:索引構建參數,和builder_name參數對應,具體見Proxima Builder配置。
search_index_params:索引檢索參數,和searcher_name參數對應,具體見search_index_params配置。
linear_build_threshold:線性構建的閾值,若文檔數量低於該閾值,則會使用LinearBuilder構建, LinearSearcher檢索。預設是10000,用線性構建的好處是可以節省記憶體,召回結果無損, 但是若資料規模較大時,效能極差。
min_scan_doc_cnt: 召回候選集的個數最小值,預設10000,和proxima.qc.searcher.scan_ratio的概念類似。兩者都配置的情況下,取兩者的最大值
scan_ratio&min_scan_doc_cnt不是越大越好。太大的話,會極大影響效能&延遲
一般而言, 若召回topk個向量,min_scan_doc_cnt的建議大小為max(10000, 100*topk),scan_ratio為max(10000, 100*topk)/total_doc_cnt, 具體的還得結合資料規模、召回率以及效能等參數。
之所以存在兩個類似參數,主要是由於即時以及多類目情境下的需求。一般使用者只需要配置scan_ratio即可
enable_recall_report: 是否開啟召回率指標彙報,預設關閉
is_embedding_saved: 是否儲存原始向量,預設關閉。如果開啟INT8/FP16量化且開啟即時檢索,務必開啟該選項,否則會導致批次增量構建失敗
enable_rt_build:是否支援即時索引,預設開啟
ignore_invalid_doc:是否忽略有問題的向量資料,預設開啟
rt_index_params:即時索引參數,當enable_rt_build為true時,可配置,如:
{ "proxima.oswg.streamer.segment_size": 2048 }
查詢文法
通用查詢
HA3文法:
query=index_name:'0.1,0.2,0.98,0.6;0.3,0.4,0.98,0.6...'
註:index_name為向量索引名,後面是要查詢的向量
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["0.892704,0.783731"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量
指定top n查詢
HA3文法:
query=index_name:'0.1,0.2,0.98,0.6;0.3,0.4,0.98,0.6&n=10'
註:index_name為向量索引名,後面是要查詢的向量,n指定向量檢索返回的top結果數。
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["0.892704,0.783731&n=10"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量,n指定向量檢索返回的top結果數。
設定最低分閾值
HA3文法:
query=index_name:'0.1,0.2,0.98,0.6;0.3,0.4,0.98,0.6&n=10&sf=0.8'
註:index_name為向量索引名,後面是要查詢的向量,sf指定要過濾分數的閾值。
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["0.892704,0.783731&n=10&sf=0.8"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量,sf指定要過濾分數的閾值。
區分類目的查詢
HA3文法:
query=aitheta_index_name:'16#0.1,0.2,0.98,0.6;1512#0.3,0.4,0.98,0.6&n=200'
// query需要做urlencode
query=aitheta_index_name:'16%230.1%2c0.2%2c0.98%2c0.6%3b1512%230.3%2c0.4%2c0.98%2c0.6%26n%3d200'
註:區分類目的情況下,參數值中需要指定類目id以及要查詢的向量,類目id和向量之間使用'#'分隔(query中需要對'#'做URLEncode),多個類目之間使用逗號分隔,多個向量之間以分號分隔。
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["16%230.1%2c0.2%2c0.98%2c0.6%3b1512%230.3%2c0.4%2c0.98%2c0.6%26n%3d200"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量
註:dynamic_params內容需要做urlencode
註:區分類目的情況下,參數值中需要指定類目id以及要查詢的向量,類目id和向量之間使用'#'分隔(query中需要對'#'做URLEncode),多個類目之間使用逗號分隔,多個向量之間以分號分隔。
設定召回參數
HA3文法:
query=index_name:'0.1,0.2,0.98,0.6;0.3,0.4,0.98,0.6&n=10&sf=0.8&search_params={"proxima.qc.searcher.scan_ratio":0.001,"proxima.general.searcher.scan_count":10000}'
註:search_params指定向量召回參數,為json格式。proxima.qc.searcher.scan_ratio含有同上,proxima.general.searcher.scan_count意義同min_scan_doc_cnt
註:n,sf,search_params出現的順序不能變
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["0.892704,0.783731&n=10&sf=0.8&search_params={"proxima.qc.searcher.scan_ratio":0.001,"proxima.general.searcher.scan_count":10000}"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量,search_params指定向量召回參數,為json格式。proxima.qc.searcher.scan_ratio含有同上,proxima.general.searcher.scan_count意義同min_scan_doc_cnt
註:n,sf,search_params出現的順序不能變
查詢時按相似性排序
HA3文法:
query=index_name:'0.1,0.2,0.98,0.6;0.3,0.4,0.98,0.6...'&&kvpairs=first_formula:proxima_score(index_name)&&sort=+RANK
註:index_name為向量索引名,後面是要查詢的向量,kvpairs子句指定粗排公式為proxima_score(索引名),sort子句指定按相似性得分從小到大排序
SQL文法:
query=select proxima_score('index_name') as score,id from table_name where MATCHINDEX('index_name', ?) order by score asc limit 5&&kvpair=timeout:1000,iquan.plan.cache.enable:true;urlencode_data:false;iquan.plan.prepare.level:jni.post.optimize;dynamic_params:[["0.892704,0.783731"]]
註:index_name為向量索引名,kvpair中的dynamic_params是要查詢的向量,select中的proxima_score(索引名)函數用於擷取向量得分,通過order by 指定向量得分為排序依據,asc表示正序,desc 表示倒序