本篇博客将介绍腾讯云 Elasticsearch service 新版本中对ELSER性能的激动人心的新增强功能!
我们在之前的文章中已经详细介绍了Elasticsearch中的词汇和语义搜索以及使用向量字段的文本相似性搜索。这些文章深入解释了向量搜索的工作原理。
我们也曾经讨论过如何通过优化ELSER v2来降低检索成本。尽管Elasticsearch对每个推理字段限制了512个词汇,ELSER仍然能够为多词查询生成大量的独特词汇。这导致了一个非常大的析取查询,并且会返回比单个关键词搜索更多的文档——实际上,产生大量结果的查询可能会匹配索引中的大多数或全部文档!
现在,让我们更详细地看一个使用ELSER v2的例子。通过推理API,我们可以查看短语“Is Pluto a planet?”的预测值。
POST /_ml/trained_models/.elser_model_2_linux-x86_64/_infer
{
"docs":[{"text_field": "is Pluto a planet?"}]
}
这将返回以下推理结果:
{
"inference_results": [
{
"predicted_value": {
"pluto": 3.014208,
"planet": 2.6253395,
"planets": 1.7399588,
...
"rocky": 0.0062791444
}
}
]
}
这些推理结果将作为输入送入文本扩展搜索。当我们运行一个文本扩展查询时,这些词汇最终会结合在一个大型的加权布尔查询中,例如:
{
"query": {
"bool": {
"should": [
{
"match": {
"pluto": {
"query": "pluto",
"boost": 3.014208
}
}
},
{
"match": {
"planet": {
"query": "planet",
"boost": 2.6253395
}
}
},
...
{
"match": {
"planets": {
"query": "rocky",
"boost": 0.0062791444
}
}
}
]
}
}
}
鉴于ELSER文本扩展产生的大量词汇,实现性能提升的最快速方法是减少进入最终布尔查询的词汇数量。这减少了Elasticsearch在执行搜索时的总工作量。我们可以通过识别文本扩展产生的非显著性词汇并将它们从最终查询中移除来实现这一点。
非显著性词汇可以定义为满足以下两个标准的词汇:
我们根据内部实验,使用ELSER v2开始了一些默认规则来识别非显著性词汇:
如果您使用的是ELSER以外的模型进行文本扩展,您可能需要调整这些值以获得最佳结果。
只有当词汇的频率阈值和权重阈值都显示出该词汇的非显著性时,该词汇才会被修剪。这让我们确保保留那些得分非常高或非常低频但可能得分不高的词汇。
我们使用MS Marco Passage Ranking基准测试对这些变化进行了基准测试。通过这个基准测试,我们观察到启用了上述默认值的词汇修剪,99%分位延迟提高了3-4倍!
一旦我们测量了真正的性能提升,我们就想验证相关性是否仍然合理。我们使用了一个小数据集对比MS Marco通道排名数据集。我们确实观察到在修剪词汇时对相关性有影响;然而,当我们在重新评分块中添加了被修剪的词汇时,相关性接近原始未修剪结果,并且延迟只增加了一个边际。
使用44个带有针对MS Marco Passage Ranking数据集的判断的样本查询:
Top K | Rescore Window Size | Avg rescored recall vs control | Control NDCG@K | Pruned NDCG@K | Rescored NDCG@K |
---|---|---|---|---|---|
10 | 10 | 0.956 | 0.653 | 0.657 | 0.657 |
10 | 100 | 1 | 0.653 | 0.657 | 0.653 |
10 | 1000 | 1 | 0.653 | 0.657 | 0.657 |
100 | 100 | 0.953 | 0.51 | 0.372 | 0.514 |
100 | 1000 | 1 | 0.51 | 0.372 | 0.51 |
现在,这只是其中一个数据集——但即便是在小规模上看到这样的结果也是令人鼓舞的!
修剪配置将在我们下一个版本中作为实验性功能推出。这是一个可选的、选择性加入的功能,所以如果您执行文本扩展查询时没有指定修剪,文本扩展查询的制定方式——以及性能——都不会发生变化。
我们在文本扩展查询文档中提供了如何使用新的修剪配置的一些示例。
这是一个带有修剪配置和重新评分的示例文本扩展查询:
GET my-index/_search
{
"query": {
"text_expansion": {
"ml.tokens": {
"model_id": ".elser_model_2",
"model_text": "Is pluto a planet?",
"pruning_config": {
"tokens_freq_ratio_threshold": 5,
"tokens_weight_threshold": 0.4,
"only_score_pruned_tokens": false
}
}
}
},
"rescore": {
"window_size": 100,
"query": {
"rescore_query": {
"text_expansion": {
"ml.tokens": {
"model_id": ".elser_model_2",
"model_text": "Is pluto a planet?",
"pruning_config": {
"tokens_freq_ratio_threshold": 5,
"tokens_weight_threshold": 0.4,
"only_score_pruned_tokens": true
}
}
}
}
}
}
}
请注意,重新评分查询将only_score_pruned_tokens设置为false,因此它只将原本被修剪的词汇重新加入到重新评分算法中。
我们还引入了一种新的加权词汇查询。
这种新查询类型主要有两个用例:
相同的用法:
GET my-index/_search
{
"query": {
"weighted_tokens": {
"query_expansion_field": {
"tokens": {
"pluto": 3.014208,
"planet": 2.6253395,
...
"rocky": 0.0062791444
},
"pruning_config": {
"tokens_freq_ratio_threshold": 5,
"tokens_weight_threshold": 0.4,
"only_score_pruned_tokens": false
}
}
}
},
"rescore": {
"window_size": 100,
"query": {
"rescore_query": {
"weighted_tokens": {
"query_expansion_field": {
"tokens": {
"pluto": 3.014208,
"planet": 2.6253395,
...
"rocky": 0.0062791444
},
"pruning_config": {
"tokens_freq_ratio_threshold": 5,
"tokens_weight_threshold": 0.4,
"only_score_pruned_tokens": true
}
}
}
}
}
}
}
这个功能作为技术预览功能在8.13.0版本中发布。您今天就可以在云端尝试它!别忘了访问我们的讨论论坛并告诉我们您的想法。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。