前面已经介绍过RAG中ReRanker的优化技巧和使用方法,我们趁中秋节假日这个机会,来对ReRanker进行一次全面的总结与梳理。
前面关于ReRanker的文章:
揭开RAG重排序(Rerankers)和两阶段检索(Two-Stage Retrieval)的神秘面纱
RAG优化神器:rerankers重新排名模型的终极方案,提供轻量级统一API
无论你是刚刚接触RAG,还是已经在项目中有所应用,这篇文章都将帮助你系统了解ReRanker的原理、常见实现方式及其在实际场景中的优化应用。希望这次总结能为你带来新的启发,助力你的技术提升。
重新排名是根据某些标准对项目列表重新排序的过程。在搜索上下文中,重新排名用于根据某些标准对搜索引擎返回的搜索结果进行重新排序。当搜索结果的初始排名不令人满意或者当用户提供了可用于改进搜索结果的排名的附加信息时,这可能很有用。
下面是几种常见的Reranker的实现方式,具体如下图片所示:
下面,我们通过LanceDB向量数据库来介绍上述Reranker的实现方式。LanceDB 是一个用于人工智能的开源矢量数据库,旨在存储、管理、查询和检索大规模多模式数据的嵌入。
LanceDB 的核心是用 Rust 编写的,并构建在Lance之上,Lance 是一种开源列式数据格式,专为高性能 ML 工作负载和快速随机访问而设计。
对于向量和 FTS 来说,使用重新排序器是可选的。然而,对于混合搜索,需要重新排序。要使用重新排序器,您需要创建重新排序器的实例并将其传递给查询构建器的ReRank方法。
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import CohereReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", data)
reranker = CohereReranker(api_key="your_api_key")
# Run vector search with a reranker
result = tbl.query("hello").rerank(reranker).to_list()
# Run FTS search with a reranker
result = tbl.query("hello", query_type="fts").rerank(reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text")
result = tbl.query("hello", query_type="hybrid").rerank(reranker).to_list()
一、Multi-vector reranking 多向量重排序
大多数重新排序器支持基于多个向量的重新排序。要基于多个向量重新排序,您可以将向量列表传递给rerank方法。以下是如何使用CrossEncoderReranker基于多个向量列进行重新排名的示例:
from lancedb.rerankers import CrossEncoderReranker
reranker = CrossEncoderReranker()
query = "hello"
res1 = table.search(query, vector_column_name="vector").limit(3)
res2 = table.search(query, vector_column_name="text_vector").limit(3)
res3 = table.search(query, vector_column_name="meta_vector").limit(3)
reranked = reranker.rerank_multivector([res1, res2, res3], deduplicate=True)
二、Cohere Reranker 一致性重排序器
支持的查询类型:混合、矢量、FTS(全文检索:Full-text Search)。
Cohere 是一家专注于企业人工智能的加拿大跨国科技公司,专门研究大型语言模型。
Cohere 由 Aidan Gomez、Ivan Zhu 和 Nick Frosst 于 2019 年创立,总部位于多伦多和旧金山,在帕洛阿尔托、伦敦和纽约市设有办事处。
原生的Cohere Rerank实现方式如下:
import cohere
co = cohere.Client(api_key="<YOUR API KEY>")
query = "What is the capital of the United States?"
docs = [
"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.",
"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.",
"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.",
"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. The President of the USA and many major national government offices are in the territory. This makes it the political center of the United States of America.",
"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 federal government (including the United States military) also uses capital punishment."]
results = co.rerank(model="rerank-english-v3.0", query=query, documents=docs, top_n=5, return_documents=True)
LanceDB中,通过将CohereReranker()传递给rerank()方法来使用此重新排序器。请注意,您需要设置COHERE_API_KEY环境变量或传递api_key参数才能使用此重新排序器。
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import CohereReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = CohereReranker(api_key="key")
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
三、Cross Encoder Reranker 交叉编码器重排序
在交叉编码器架构中,模型的输入始终由编码器联合处理的数据对(例如,两个句子或文档)组成。这使得模型能够更有效地捕获输入序列之间的交互和关系。编码器通常由多层神经网络单元组成,例如变压器或循环神经网络 (RNN),它们将输入序列中的信息编码为固定大小的表示。
此重新排序器使用句子转换器中的交叉编码器模型对搜索结果进行重新排序。您可以通过将CrossEncoderReranker()传递给rerank()方法来使用此重新排序器。
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import CrossEncoderReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = CrossEncoderReranker()
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
四、ColBERT Reranker ColBERT 重排序器
ColBERT(https://github.com/stanford-futuredata/ColBERT)是一种快速、准确的检索模型,可在数十毫秒内对大型文本集合进行基于 BERT 的可扩展搜索。尤其是最后一部分非常重要。
RAG 本身并不是一项快速技术。所有LLM调用都会引入延迟。由于再次重新排序需要调用重新排序模型,因此引入了额外的延迟。 ColBERT 是可用的最快的重新排名模型之一,可以减少这种摩擦点。
ColBERT 依赖于细粒度的上下文后期交互:它将每个段落编码为令牌级嵌入矩阵(如上图蓝色所示)。然后在搜索时,它将每个查询嵌入到另一个矩阵中(以绿色显示),并使用可扩展向量相似度 ( MaxSim ) 运算符有效地查找与查询上下文匹配的段落。
此重新排序器使用 ColBERT 模型对搜索结果进行重新排序。您可以通过将ColbertReranker()传递给rerank()方法来使用此重新排序器。
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import ColbertReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = ColbertReranker()
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
五、OpenAI Reranker OpenAI 重新排序器
此重新排序器使用 OpenAI 聊天模型对搜索结果进行重新排序。您可以通过将OpenAI()传递给rerank()方法来使用此重新排序器。
此重新排序器是实验性的。 OpenAI 没有专门的重新排名模型,因此我们使用聊天模型进行重新排名。
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import OpenaiReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = OpenaiReranker()
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
六、Linear Combination Reranker 线性组合重排序器
这是 LanceDB 混合搜索使用的默认重新排序器。它使用分数的线性组合来组合语义和全文搜索的结果。可以指定线性组合的权重。默认为0.7,即语义搜索权重为70%,全文搜索权重为30%。
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import LinearCombinationReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = LinearCombinationReranker()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
七、Jina Reranker 吉娜·重新排序
Jina 重新排序器 v2 ( jina-reranker-v2-base-multilingual )是一个基于变压器的模型,已针对文本重新排序任务进行了微调,文本重新排序任务是许多信息检索系统中的关键组成部分。它是一个交叉编码器模型,将查询和文档对作为输入,并输出指示文档与查询的相关性的分数。该模型在大型查询文档对数据集上进行训练,能够高精度地对多种语言的文档进行重新排名。
与最先进的 reranker 模型(包括之前发布的jina-reranker-v1-base-en相比, Jina Reranker v2模型在一系列针对文本检索、多语言能力、功能的基准测试中表现出了竞争力。调用感知和文本到 SQL 感知的重新排序以及代码检索任务。
此重新排序器使用Jina API 对搜索结果进行重新排序。您可以通过将JinaReranker()传递给rerank()方法来使用此重新排序器。请注意,您需要设置JINA_API_KEY环境变量或传递api_key参数才能使用此重新排序器。
import os
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import JinaReranker
os.environ['JINA_API_KEY'] = "jina_*"
embedder = get_registry().get("jina").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = JinaReranker(api_key="key")
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
八、AnswerDotAI Rerankers AnswerDotAI 重新排名
此集成允许使用answersdotai 的重新排名器对搜索结果重新排名。 Rerankers一个轻量级、低依赖性、统一的 API,可使用所有常见的重新排名和交叉编码器模型。
请阅读之前文章了解Rerankers的应用:RAG优化神器:rerankers重新排名模型的终极方案,提供轻量级统一API
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import AnswerdotaiRerankers
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = AnswerdotaiRerankers()
# Run vector search with a reranker
result = tbl.search("hello").rerank(reranker=reranker).to_list()
# Run FTS search with a reranker
result = tbl.search("hello", query_type="fts").rerank(reranker=reranker).to_list()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
九、Reciprocal Rank Fusion Reranker 倒数排名融合重排名器
前面的文章介绍过RRF的应用,感兴趣可以看一下这篇文章:RAG混合检索:掌握倒数秩融合RRF多维度提升检索结果评分的秘诀
倒数排名融合 (RRF) 是一种算法,用于评估多个先前排名结果的搜索分数,以生成统一的结果集。每当有两个或多个查询并行执行时,就会使用 RRF。每个查询都会生成一个排名结果集,并且 RRF 用于将排名合并并同质化为单个结果集,并在查询响应中返回。始终使用 RRF 的场景示例包括混合搜索和同时执行的多个向量查询。
参考论文:https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf
Lancedb使用倒数排名融合 (RRF) 是一种通过利用文档的位置/排名来评估搜索分数的算法,代码示例如下:
import numpy
import lancedb
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import RRFReranker
embedder = get_registry().get("sentence-transformers").create()
db = lancedb.connect("~/.lancedb")
class Schema(LanceModel):
text: str = embedder.SourceField()
vector: Vector(embedder.ndims()) = embedder.VectorField()
data = [
{"text": "hello world"},
{"text": "goodbye world"}
]
tbl = db.create_table("test", schema=Schema, mode="overwrite")
tbl.add(data)
reranker = RRFReranker()
# Run hybrid search with a reranker
tbl.create_fts_index("text", replace=True)
result = tbl.search("hello", query_type="hybrid").rerank(reranker=reranker).to_list()
以上便是多种Reranker在Lancedb中的应用,其实不局限在Lancedb,这些方法不依赖任何向量数据库,只要在RAG应用中,都可以使用。
以上便是多种 Reranker 在 Lancedb 中的应用介绍,实际上这些方法并不仅限于 Lancedb。
Reranker 的原理和实现方式并不依赖于任何特定的向量数据库,因而无论你使用的是哪种数据库或检索系统,在任何 RAG 应用场景中,都可以灵活地集成和使用这些优化技术。
希望通过这篇文章,大家能更好地理解并应用 Reranker,在各类 RAG 任务中实现更高效的检索与生成,进一步提升模型的表现。
参考资料:
https://lancedb.github.io/lancedb/reranking/cohere/
如果你对RAG优化和ReRanker实现感兴趣,欢迎扫码入群,和大家一起交流学习,共同进步!
如果进群二维码失效,也可以先关注我: