一个轻量级的统一 API,用于各种重排序模型。由 @bclavie 作为 answer.ai 成员开发。
欢迎使用 rerankers!我们的目标是为用户提供一个简单的 API 来使用任何重排序模型。
更长的发布历史可以在本 README 的发布历史部分找到。
pydantic 和 tqdm 依赖,因此 rerankers 现在默认无依赖,避免了任何 Pydantic v1/v2 的问题!rerankers 迈向多模态,支持了第一个 MonoVLMRanker 模型,MonoQwen2-VL-v0.1!!以及许多质量改进修复。rerankers?重排序器是任何检索架构的重要组成部分,但它们通常也比流程的其他部分更不为人知。
有时,甚至很难知道该使用哪一个。每个问题都不同,适用于场景 X 的最佳模型不一定与场景 Y 的相同。
此外,新的重排序方法不断涌现:例如,使用 LLMs 重排序文档的 RankGPT 去年才出现,并在零样本基准测试中取得了非常有希望的结果。
所有不同的重排序方法往往都在自己的库中实现,文档水平参差不齐。这导致了更高的入门门槛。新用户需要在多种不熟悉的输入/输出格式之间切换,每种格式都有自己的特点!
rerankers 旨在通过为所有流行的重排序器提供一个简单的 API 来解决这个问题,无论其架构如何。
rerankers 力求做到:
- 🪶 轻量级。它只附带最必要的依赖项。
- 📖 易于理解。只需学习少数几个调用,即可使用所有提供的重排序模型。
- 🔗 易于集成。它应该只需几行代码就能融入几乎所有现有的流程!
- 💪 易于扩展。任何新的重排序模型都可以用很少的代码库知识添加。你只需要一个带有 rank() 函数的新类,将(查询,[文档])输入映射到 RankedResults 输出。
- 🐛 易于调试。这是一个测试版,可能存在一些问题,但代码库的设计使得大多数问题应该易于追踪和尽快修复。
安装非常简单。核心包不附带任何依赖项,以避免与您当前环境发生冲突。
然后,您可以根据需要仅安装要尝试的模型所需的依赖项:
# 仅核心包,需要其他依赖项已安装
pip install rerankers
# 所有基于 transformers 的方法(cross-encoders, t5, colbert)
pip install "rerankers[transformers]"
# RankGPT
pip install "rerankers[gpt]"
# 基于 API 的重排序器(Cohere, Jina, MixedBread, Pinecone, Isaacus)
pip install "rerankers[api]"
# FlashRank 重排序器(ONNX 优化,在 CPU 上非常快)
pip install "rerankers[flashrank]"
# RankLLM 重排序器(更好的 RankGPT + 支持本地模型,如 RankZephyr 和 RankVicuna)
# 注意:RankLLM 仅支持 Python 3.10+!在 Python 3.9 上无法工作。
pip install "rerankers[rankllm]"
# 支持多模态重排序器,如 MonoQwen2-VL 和其他 MonoVLM 模型,这些模型需要 flash-attention, peft, accelerate 和最新版本的 `transformers`
pip install "rerankers[monovlm]"
# 支持 LLM-Layerwise 重排序器(需要安装 flash-attention)
pip install "rerankers[llmlayerwise]"
# 以上所有
pip install "rerankers[all]"
无论架构如何,只需一行代码即可加载任何支持的重排序器:
from rerankers import Reranker
# 默认 cross-encoder。您可以指定 'lang' 参数来加载多语言版本!
ranker = Reranker('cross-encoder')
# 特定的 cross-encoder
ranker = Reranker('mixedbread-ai/mxbai-rerank-large-v1', model_type='cross-encoder')
# 默认 FlashRank。您可以指定 'lang' 参数来加载多语言版本!
ranker = Reranker('flashrank')
# 特定的 flashrank 模型。
ranker = Reranker('ce-esci-MiniLM-L12-v2', model_type='flashrank')
# 默认 T5 Seq2Seq 重排序器
ranker = Reranker("t5")
# 特定的 T5 Seq2Seq 重排序器
ranker = Reranker("unicamp-dl/InRanker-base", model_type = "t5")
# API (Cohere)
ranker = Reranker("cohere", lang='en' (或 'other'), api_key = API_KEY)
# 自定义 Cohere 模型?没问题!
ranker = Reranker("my_model_name", api_provider = "cohere", api_key = API_KEY)
# API (Pinecone)
ranker = Reranker("pinecone", api_key = API_KEY)
# API (Jina)
ranker = Reranker("jina", api_key = API_KEY)
# API (Isaacus)
ranker = Reranker("isaacus", api_key = API_KEY)
# RankGPT4-turbo
ranker = Reranker("rankgpt", api_key = API_KEY)
# RankGPT3-turbo
ranker = Reranker("rankgpt3", api_key = API_KEY)
# 使用其他 LLM 提供商的 RankGPT
ranker = Reranker("MY_LLM_NAME" (查看 litellm 文档), model_type = "rankgpt", api_key = API_KEY)
# 默认 GPT (GPT-4o) 的 RankLLM
ranker = Reranker("rankllm", api_key = API_KEY)
# 指定 GPT 模型的 RankLLM
ranker = Reranker('gpt-4-turbo', model_type="rankllm", api_key = API_KEY)
# ColBERTv2 重排序器
ranker = Reranker("colbert")
# LLM Layerwise 重排序器
ranker = Reranker('llm-layerwise')
# ... 或者一个非默认的 colbert 模型:
ranker = Reranker(model_name_or_path, model_type = "colbert")
rerankers 总是会根据名称尝试推断您要使用的模型,但如果可以的话,传递一个 model_type 参数总是更安全的!
然后,无论加载了哪个重排序器,都可以使用加载的模型根据查询对文档进行排序:
> results = ranker.rank(query="I love you", docs=["I hate you", "I really like you"], doc_ids=[0,1])
> results
RankedResults(results=[Result(document=Document(text='I really like you', doc_id=1), score=-2.453125, rank=1), Result(document=Document(text='I hate you', doc_id=0), score=-4.14453125, rank=2)], query='I love you', has_scores=True)
您不需要传递 doc_ids!如果没有提供,它们将自动生成为与文档在 docs 中索引对应的整数。
您也可以自由传递元数据,它将与文档一起存储。在结果对象中也可以访问它:
> results = ranker.rank(query="I love you", docs=["I hate you", "I really like you"], doc_ids=[0,1], metadata=[{'source': 'twitter'}, {'source': 'reddit'}])
> results
RankedResults(results=[Result(document=Document(text='I really like you', doc_id=1, metadata={'source': 'twitter'}), score=-2.453125, rank=1), Result(document=Document(text='I hate you', doc_id=0, metadata={'source': 'reddit'}), score=-4.14453125, rank=2)], query='I love you', has_scores=True)
如果您希望代码更清晰,也可以直接自己构造 Document 对象,然后传递它们。在这种情况下,您不需要传递单独的 doc_ids 和 metadata:
> from rerankers import Document
> docs = [Document(text="I really like you", doc_id=0, metadata={'source': 'twitter'}), Document(text="I hate you", doc_id=1, metadata={'source': 'reddit'})]
> results = ranker.rank(query="I love you", docs=docs)
> results
RankedResults(results=[Result(document=Document(text='I really like you', doc_id=0, metadata={'source': 'twitter'}), score=-2.453125, rank=1), Result(document=Document(text='I hate you', doc_id=1, metadata={'source': 'reddit'}), score=-4.14453125, rank=2)], query='I love you', has_scores=True)
您也可以使用 rank_async,它本质上只是一个将 rank() 包装成协程的包装器。结果将是相同的:
> results = await ranker.rank_async(query="I love you", docs=["I hate you", "I really like you"], doc_ids=[0,1])
> results
RankedResults(results=[Result(document=Document(text='I really like you', doc_id=1, metadata={'source': 'twitter'}), score=-2.453125, rank=1), Result(document=Document(text='I hate you', doc_id=0, metadata={'source': 'reddit'}), score=-4.14453125, rank=2)], query='I love you', has_scores=True)
所有重排序器都将返回一个 RankedResults 对象,这是一个包含 Result 对象列表和一些其他有用信息(如原始查询)的 Python 对象。您可以通过运行 top_k() 从中检索前 k 个结果:
> results.top_k(1)
[Result(Document(doc_id=1, text='I really like you', metadata={}), score=0.26170814, rank=1)]
Result 对象在访问它们存储的文档时是透明的,因为 Document 对象只是作为一种存储 ID 和元数据的简便方式而存在。如果您想访问给定结果的文本或元数据,可以直接将其作为属性访问:
> results.top_k(1)[0].text
'I really like you'
这就是快速入门需要了解的全部内容!查看概览笔记本以获取有关 API 和不同模型的更多信息,或查看 langchain 示例以了解如何将其集成到您的 langchain 流程中。
图例:
- ✅ 已支持
- 🟠 已实现,但功能不完整
- 📍 暂不支持但计划未来支持
- ⭐ 同上,但重要。
- ❌ 不支持且目前无计划
模型:
- ✅ 任何标准的 SentenceTransformer 或 Transformers cross-encoder
- ✅ RankGPT(可通过原始 RankGPT 实现和改进的 RankLLM 实现获得)
- ✅ 基于 T5 的点式排序器(InRanker, MonoT5...)
- ✅ 基于 LLM 的点式排序器(BAAI/bge-reranker-v2.5-gemma2-lightweight 等...)
- ✅ Cohere、Jina、Voyage、MixedBread、Pinecone 和 Isaacus API 重排序器
- ✅ FlashRank 重排序器(ONNX 优化模型,在 CPU 上非常快)
- ✅ 基于 ColBERT 的重排序器 - 最初并非为重新排序设计的模型,但在某些情况下表现相当出色。实现轻量级,仅基于 transformers。
- 🟠⭐ RankLLM/RankZephyr:通过包装 rank-llm 库 支持!对 RankZephyr/RankVicuna 的支持未经测试,但 RankLLM + GPT 模型完全有效!
- ✅ 🆕 v0.6.0: MonoVLMRanker,采用 MonoT5 方法并使用 VLM 后端的多模态图像重排序器。
- 📍 LiT5
功能:
- ✅ 元数据支持!
- ✅ 重排序
- ✅ 一致性笔记本,确保任何给定模型实现在 scifact 上的性能与文献匹配(RankGPT 除外,其结果更难复现)。
- ✅ ONNX 运行时支持 --> 通过 FlashRank 提供 -- 符合本库的理念,当 @PrithivirajDamodaran 在做出色的工作时,我们不会重复造轮子!
- 📍 在 Python >=3.10 上训练(通过与其他库交互)
- ❌(📍也许?) 直接通过 rerankers 训练
如果 rerankers 对您的学术工作有所帮助,请随时引用以下工作!
@misc{clavié2024rerankers,
title={rerankers: A Lightweight Python Library to Unify Ranking Methods},
author={Benjamin Clavié},
year={2024},
eprint={2408.17344},
archivePrefix={arXiv},
primaryClass={cs.IR},
url={https://arxiv.org/abs/2408.17344},
}
.top_k() 来获取排序后的结果!BGE 系列层式 LLM 重排序器,基于 Gemma 和 MiniCPM。这些与 RankGPT 不同,因为它们不是列表式的:这些模型被重新用作 "cross-encoders",并输出 logit 分数。Document 对象,由 @bclavie 和 Anmol6 联合工作提供。此对象是透明的,但现在支持与每个文档一起存储的 metadata。许多小的质量改进更改(RankedResults 可以直接迭代...)