向量索引介绍
向量召回是指将商品或者内容等以向量的形式表达,并建立向量索引库,索引库上支持输入一个或多个用户或商品向量来根据向量距离召回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 表示倒序