作者:来自 Elastic Adam Demjen, Nick Chow
什么是语义重新排序?
语义重新排序(semantic reranking)是一种方法,它允许我们利用快速检索方法的速度和效率,同时在其上分层语义搜索。它还允许我们立即将语义搜索功能添加到现有的 Elasticsearch 安装中。
随着机器学习驱动的语义搜索的进步,我们拥有越来越多的工具可以从数百万个文档中快速找到匹配项。然而,就像为期末考试而临时抱佛脚一样,优化速度意味着要做出一些权衡,而这通常会以准确度的损失为代价。
为了抵消这一点,我们看到一些工具在梯度的另一端出现并变得越来越可用。虽然这些工具的速度要慢得多,但它们可以更准确地判断文档与查询的匹配程度。
解释一些关键术语:重新排序(reranking)是重新排序一组检索到的文档以提高搜索相关性的过程。在语义重新排序中,这是在重新排序机器学习模型的帮助下完成的,该模型计算输入查询和每个文档之间的相关性分数。
重新排序器通常对前 K 个结果(满足搜索查询的相关候选范围的缩小窗口)进行操作,因为对大量文档进行重新排序的成本极高。
为什么语义重新排序很重要?
语义重新排序(semantic reranking)对于搜索用户来说是一个重要的细化层,原因如下。
首先,用户对搜索的期望更高,正确的结果不在前十名或第一页,而是最佳答案(top answer)。这就像那个古老的搜索笑话 —— 隐藏秘密的最佳位置是搜索结果的第二页。不过,今天它的范围更窄了:任何低于前一、二或三名的结果都可能被丢弃。
这更适用于 RAG(retriieval augmented generation - 检索增强生成)—— 这些生成式 AI 用例需要紧密的上下文窗口。最佳文档可能是第 4 个结果,但如果你只输入前三名,你将无法获得正确答案,模型可能会产生幻觉。
最重要的是,生成式 AI 用例在有效截止(effective cutoff)时效果最佳。你可以定义一个最低分数或计数,直到该分数或计数结果被视为 “良好”,但如果没有一致的评分,这很难做到。
语义重新排序通过重新排序文档来解决这些问题,以便最相关的文档排在最前面。它提供可用、标准化和经过良好校准的分数,因此你可以衡量结果与查询的匹配程度。因此,你可以更可靠地获得更准确的顶级结果以提供给大型语言模型,并且如果前 K 个匹配项的分数大幅下降,你可以切断结果以防止出现幻觉。
那么我们如何进行重新排序?
Rerank inference 类型
Elastic 最近引入了推理端点和相关的 APIs。这一功能使我们可以使用某些服务,如内置或第三方的机器学习模型,来执行推理任务。支持的推理任务形式多样,例如 sparse_embedding 任务就是通过某个机器学习模型(如 ELSER)接收一些文本并生成一组加权术语,而 text_embedding 任务则是从输入中创建向量嵌入。
Elastic Serverless 以及即将发布的 8.14 版本新增了一种任务类型:rerank。在首次迭代中,rerank 支持与 Cohere 的 Rerank API 集成。这意味着你现在可以在 Elastic 中创建一个推理端点,提供你的 Cohere API 密钥,并享受开箱即用的语义重排序功能!
让我们通过一个示例来看一下实际操作,该示例取自 Cohere 博客。
假设你已经使用 Cohere Rerank v3 模型在 Elastic 中设置了你的 rerank 推理端点,我们可以传递一个查询和一个输入文本数组。正如我们所见,这些简短的段落都与 “capital” 一词有关,但不一定与作为政府所在地的含义相关,而查询正是寻找这一含义:
POST _inference/rerank/cohere-rerank-v3-model
{
"query": "What is the capital of the USA?",
"input": [
"Carson City is the capital city of the American state of Nevada. At the 2010 United States Census, Carson City had a population of 55,274.",
"Capital punishment (the death penalty) has existed in the United States since before the United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states.",
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean that are a political division controlled by the United States. Its capital is Saipan.",
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
"Charlotte Amalie is the capital and largest city of the United States Virgin Islands. It has about 20,000 people. The city is on the island of Saint Thomas.",
"North Dakota is a state in the United States. 672,591 people lived in North Dakota in the year 2010. The capital and seat of government is Bismarck."
]
}
重新排序任务通过分数和文档索引数组进行响应:
{
"rerank": [
{
"index": "3",
"relevance_score": "0.99838966"
},
{
"index": "1",
"relevance_score": "0.587174"
},
{
"index": "0",
"relevance_score": "0.061199225"
},
{
"index": "2",
"relevance_score": "0.032283258"
},
{
"index": "4",
"relevance_score": "0.015365342"
},
{
"index": "5",
"relevance_score": "0.0040072887"
}
]
}
最上面的条目告诉我们,相关性得分最高的 99.8% 是原始列表中的第 4 个文档(“index”:3,索引从零开始),又名 “Washington, D.C. ...”。其余文档在语义上与原始查询的相关性较低。
此重新排名推理步骤是优化搜索体验的重要拼图,现在我们准备将其放入拼图板中!
立即通过你的应用程序对搜索结果进行重新排序
利用语义重新排序功能的一种方法是在搜索应用程序中实现如下工作流程:
- 用户在你的应用程序的 UI 中输入查询。
- 搜索引擎组件检索与此查询匹配的一组文档。可以使用任何检索策略来完成此操作:词汇 (BM25)、向量搜索(例如 kNN)或结合两者的方法,例如 RRF。
- 应用程序获取前 K 个文档,从每个文档中提取我们要查询的文本字段,然后将此文本列表发送到重新排序推理端点,该端点配置为使用 Cohere。
- 推理端点将文档和查询传递给 Cohere。
- 结果是与每个分数匹配的分数和索引列表。你的应用程序获取这些分数,将它们分配给文档,并按此分数按降序重新排序。这有效地将语义上最相关的文档移到顶部。
- 如果在 RAG 中使用此流程为生成式 LLM 提供一些来源(例如总结答案),那么你可以放心,它将在正确的上下文中工作并提供答案。
这种方法效果很好,但涉及很多步骤、数据修改以及包含许多移动部件的复杂处理逻辑。我们可以简化它吗?
未来用检索器重新排序搜索结果
让我们花一点时间来讨论一下检索器(retrievers)。检索器(retriever)是一种新的抽象类型,在 _search API 中,不仅仅是一个简单的查询。它是一个用于端到端搜索流程的构建模块,用于获取命中结果并可能修改文档的得分和顺序。
检索器可以在流水线模式中使用,每个检索器单元在搜索过程中执行不同的任务。例如,我们可以配置一个第一阶段的检索器来获取文档,然后将结果传递给第二阶段的检索器,与其他结果结合,减少候选数量等等。作为最后一个阶段,检索器可以更新文档的相关性得分。
很快,我们将使用检索器增加新的重排序功能,第一个功能是文本相似性重排序检索器。这将通过调用重排序推理端点对前 K 个命中结果进行重排序。工作流程将简化为一个隐藏所有复杂性的单一 API 调用!
这就是前面描述的多阶段工作流程在单一检索器查询中的样子:
text_similarity_reranker 检索器配置了以下详细信息:
- 嵌套检索器
- Reranker 推理配置
- 其他控制,例如用于消除不相关匹配的最低分数截止值
以下是 text_similarity_reranker 查询的示例。让我们剖析一下,以更好地理解每个部分!
POST my-index/_search
{
"retriever": { // Retriever query
"text_similarity_reranker": { // Outermost retriever will perform reranking
"retriever": {
"standard": { // First-stage retriever is a standard Elasticsearch query
"query": {
"match": { // BM25 matching
"text": "What is the capital of the USA?"
}
}
}
},
"field": "text", // Document field to send to reranker
"window_size": 100, // Reranking will work on top K hits
"inference_id": "cohere-rerank-v3-model", // Inference endpoint
"inference_text": "What is the capital of the USA?",
"min_score": 0.6 // Minimum relevance score
}
}
}
请求将 retriever 查询定义为根属性。最外层的检索器将最后执行,在本例中为 text_similarity_reranker。它指定 standard 第一阶段检索器,负责获取一些文档。标准检索器接受 Elasticsearch query,在示例中为 BM25 match。
文本相似性重新排序器指向包含要进行语义重新排序的文本的 text 文档字段。前 100 个文档将被发送到我们已使用 Cohere 配置的 cohere-rerank-v3-model 重新排序推理端点进行重新排序。只有在重新排序过程中获得至少 60% 相关性分数的文档才会被返回。
响应的结构与 search 查询的结构完全相同。_score 属性是来自重新排序过程的语义相关性分数,_rank 指的是文档的排名顺序。
{
"took": 213,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.99838966,
"hits": [
{
"_index": "my-index",
"_id": "W7CDBo8BJDa_bRWhW1KH",
"_score": 0.99838966,
"_rank": 1,
"_source": {
"text": "Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district."
}
}
]
}
}
在即将发布的 Elastic 版本中,将很快提供使用检索器进行语义重新排序的功能。
结论
语义重新排名是一种非常强大的工具,可以提升搜索体验或 RAG 工具的性能。它可以用作直接推理调用、搜索体验上下文或作为检索器简化搜索流程的一部分。用户可以选择最适合其用例和上下文的工具集。
祝你重新排名愉快!😃
准备好自己尝试一下了吗?开始免费试用。
Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序!
原文:Semantic Reranking in Elasticsearch with Retrievers — Elastic Search Labs