正如我们之前的一篇博文 (opens new window)所探讨的,向量搜索相比传统的关键词匹配,在信息检索方面取得了显著的进展,采用了更加细致和具有上下文意识的方法。将文本转化为数值向量可以将搜索查询的上下文含义与数据对齐,从而提高搜索结果的相关性。
然而,向量搜索也存在挑战,最明显的是在文本到向量转换过程中可能丢失信息,因此需要采用其他方法来提高搜索准确性。
那么这些额外的方法是什么呢?
简要回答这个问题,使用向量搜索检索信息时,最重要的“额外方法”之一是实现一个两阶段检索系统。
让我们详细介绍一下如何使用MyScale实现两阶段检索方法的步骤指南,演示如何有效地将向量搜索和重新排序相结合,以优化信息检索系统的效率和效果。
# 什么是重新排序?
但首先,让我们定义一下重新排序,并考虑为什么它是两阶段检索过程的一部分。
简洁地说,重新排序是重新排列搜索结果,以增加向量搜索的上下文相关性。根据https://en.wiktionary.org/wiki/reranking (opens new window)的定义,它是“重新对某物进行排名或以不同的方式进行排名... [例如,]算法在达到最佳结果之前执行多次重新排序。”
重新排序通常使用交叉编码器模型 (opens new window)实现,通过提供一组更精细的结果来增强搜索结果。与初始的向量搜索不同,将文档总结为向量后再查询这些文档,重新排序将查询和文档一起处理,根据相关性精确地重新排序搜索结果。
然而,与其他事物一样,使用重新排序也存在挑战,最大的挑战是其高计算需求和在处理大型数据集时的不切实际性,这严重限制了其独立应用的潜力。
# 两阶段检索系统
为了解决这些挑战,开发了一个两阶段检索系统,将向量搜索和重新排序的优势结合起来,首先进行向量搜索以获取初始的广泛结果集,然后选择性地应用重新排序以提高准确性。
# MyScale的两阶段检索系统
MyScale的两阶段检索系统从对数据库进行向量搜索开始,选择一系列与搜索查询语义密切匹配的文档,将庞大的数据集高效地缩小为相关子集。
**接下来:**使用重新排序函数对这个子集进行精细化处理,根据相似性得分进行仔细排序,优先考虑精确性,尽可能地与用户意图接近,将最终结果集对齐。
为了简化这个两阶段检索系统,我们已经将这些重新排序函数 (opens new window)与MyScale集成在一起,通过简单的SQL查询即可访问。
注意:
这些函数利用了复杂的重新排序API,为用户提供了一个易于使用的界面,用于复杂的数据排序操作,将强大的搜索功能压缩成简洁高效的用户体验。
如下图所示,用户可以使用简单的命令启动这个两阶段检索机制,将向量搜索子查询与重新排序查询结合起来,返回前N个文档和提取最相关的K个文档。
这个系统的有效性在其性能指标中得到体现。使用OpenAI Embeddings (opens new window)进行分析,我们观察到检索准确性有了显著的提高。使用“bge-reranker-base”模型,命中率从0.854545提高到0.895455。平均倒数排名(MRR)也从0.640303提高到0.707652,这证明了该方法在获取相关搜索结果方面的熟练程度。这些改进凸显了将重新排序整合到信息检索过程中的价值。
注意:
我们在这个notebook (opens new window)中详细介绍了我们的评估方法和结果,遵循了LlamaIndex在这篇博文 (opens new window)中讨论的方法。
# 实施MyScale的两阶段检索系统
现在让我们通过一个实际的例子来更好地理解我们的两阶段检索系统,重点是改进抽象QA (opens new window)示例应用程序,具体细节在MyScale的文档中有详细说明。
注意:
唯一需要更改的是原始示例中的查询阶段 (opens new window),我们仍然使用相同的表和数据。
原始的抽象QA应用程序使用一个单独的检索器将问题转换为嵌入向量,然后执行搜索查询以找到前k个候选项。现在,如下面的SQL语句所示,使用MyScale的嵌入函数,这些步骤合并为一个单独的SQL命令。
SELECT summary,
distance(
summary_feature,
CohereEmbedText('what is the difference between bitcoin and traditional money?')
) AS dist
FROM default.myscale_llm_bitcoin_qa
WHERE article_rank < 500
ORDER BY dist LIMIT 10
这个SQL语句使用了一个自定义的嵌入函数——CohereEmbedText
,它使用Cohere的embed-english-light-v3.0模型 (opens new window)进行定义,代码片段如下所示。
CREATE FUNCTION CohereEmbedText ON CLUSTER '{cluster}'
AS (x) -> EmbedText(
x,
'Cohere',
'',
'YOUR_COHERE_API_KEY',
'{"model":"embed-english-light-v3.0", "input_type":"search_query"}')
为了进一步简化流程,我们引入了一个自定义的重新排序函数,如函数文档 (opens new window)中所述:
CREATE FUNCTION CohereRerank ON CLUSTER '{cluster}'
AS (x,y,z) -> Rerank(
x, y, z, 'Cohere', '', 'YOUR_COHERE_API_KEY', '');
有了这些函数,我们现在可以使用以下SQL语句实现两阶段检索系统:
SELECT
tupleElement(arrayElement, 2) AS summary,
tupleElement(arrayElement, 3) AS score
FROM (
SELECT arrayJoin(CohereRerank('what is the difference between bitcoin and traditional money?',
(SELECT groupArray(summary)
FROM (
SELECT summary, distance(summary_feature, CohereEmbedText('what is the difference between bitcoin and traditional money?')) as dist
FROM default.myscale_llm_bitcoin_qa
WHERE article_rank < 500
ORDER BY dist
LIMIT 50
)
), 10
)) AS arrayElement
)
这个SQL语句包括以下步骤来实现我们的两阶段检索系统:
- 将搜索结果从10个扩展到50个,以避免遗漏相关信息;
- 使用groupArray (opens new window)将前50个候选项分组为一个数组,用于重新排序;
- 使用
CohereRerank
函数根据相关性重新排序这些候选项,提取出最相关的10个摘要;最后 - 使用arrayJoin (opens new window)(用于将结果集展开为多行)和tupleElement (opens new window)(用于从结果行中提取指定的列)来结构化结果,以改善用户呈现。
# 结论
总之,MyScale的两阶段检索系统展示了现代搜索技术中简单和高效的力量。它表明,即使是向量搜索结合先进的重新排序函数这样复杂的过程,也可以通过一个简单的SQL查询无缝执行。这种方法不仅使复杂的检索过程对更广泛的用户可用,而且突显了MyScale提供强大而用户友好的数据搜索和分析工具的承诺。