大模型RAG中二次重排序的重要性:为什么需要rerank
两阶段检索系统里,第一阶段的嵌入模型负责从海量数据中快速捞出一批候选文档。原理是把文档和查询都转成向量,然后算相似度。这玩意儿因为能把复杂的文本压缩成一个固定长度的向量,处理大规模数据时效率极高。但问题也出在这儿——压缩过程会丢掉不少上下文信息,导致它的准确率不如重新排序器。所以第二阶段就需要重新排序器上场,对这些候选文档进行精细排序。重新排序器通常基于更复杂的深度神经网络,能更好地理解文档和查询之间的上下文关联,提供更高的排序精度。
为什么要使用重新排序器?
既然嵌入模型已经能初步筛出结果,为什么还要多此一举?答案很简单——准确性。嵌入模型在转换文本时,不可避免会丢失信息,尤其是面对复杂查询和文档时,它根本抓不住两者之间的微妙差异。为啥?因为嵌入模型必须把文档的所有可能含义压缩成一个向量,这个向量只能表达一种通用的平均含义,没法针对某个具体的查询做出精准响应。
相比之下,重新排序器就能避免这种信息丢失。它直接处理查询和文档的原始信息,能更精细地分析文档内容跟查询之间的关联,从而给出更准的排序。关键是,重新排序器是在收到用户查询之后才运行的,所以它能结合查询的上下文做精准分析,而不是依赖嵌入模型那种平均化的向量表示。
Reranker与embedding模型的区别
虽然Reranker和Embedding模型都用在信息检索里,但它们的定位和功能完全不同。
Embedding模型主要负责初步筛选文档:把文本转成向量、算相似度,筛出一批可能相关的候选。它的优势是计算效率高,适合处理大规模数据集。而Reranker则负责对Embedding模型筛出来的候选文档做精细排序。Reranker基于更复杂的深度神经网络,能更好地理解文本的上下文和细微差异,排序精度更高。
打个比方:Embedding模型干的是“大海捞针,先捞出一把可能相关的”,Reranker干的则是“从这把里找出最相关的那几根,按顺序排好”。
Reranker能否直接用于检索?
理论上当然可以,但实际中很少这么干。因为Reranker的计算复杂度太高,直接对整个数据集排序,计算成本会爆表,实时性根本没法保证。所以常规做法是先让Embedding模型做快速筛选,把候选集缩小到合理范围,然后再用Reranker做精细排序。
代码示例:使用Reranker对候选文档重新排序
下面给一个简单的Reranker实现示例,基于阿里魔塔开源的gte,演示怎么对候选文档重新排序。
import torch
import torch.nn.functional as F
from modelscope import AutoModelForSequenceClassification, AutoTokenizer
# 初始化模型和分词器
model_name_or_path = "iic/gte_passage-ranking_multilingual-base"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
model = AutoModelForSequenceClassification.from_pretrained(model_name_or_path, trust_remote_code=True)
model.eval()
# 示例数据
query = "中国的首都在哪儿"
documents = [
"中国的首都在哪",
"北京。",
"上海是中国的一个主要城市。"
]
def reranker(query, documents):
with torch.no_grad():
# 创建 (query, document) 对
pairs = [[query, text] for text in documents]
# 对输入对进行分词
inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors='pt', max_length=8192)
# 通过模型计算得分
scores = model(**inputs, return_dict=True).logits.view(-1, ).float()
# 将得分转换为百分比形式的概率
probabilities = F.softmax(scores, dim=0) * 100
# 将文档与其对应的概率结合
ranked_results = list(zip(documents, probabilities.tolist()))
# 根据概率降序排序结果
ranked_results.sort(key=lambda x: x[1], reverse=True)
return ranked_results
# 运行 Reranker 并输出排序结果
ranked_documents = reranker(query, documents)
print(ranked_documents)
这段代码里,把结果输出为根据rerank计算的相似度百分比。3条数据大约跑了1.2秒,时间确实比较久。结果如下:
[('中国的首都在哪', 90.24225616455078), ('北京。', 6.394253730773926), ('上海是中国的一个主要城市。', 3.363481044769287)]
总结
把Embedding模型和Reranker结合,本质是在效率和准确性之间找平衡。Embedding模型负责快速筛出候选文档,Reranker则通过更细致的分析对这些文档做精准排序。虽然Reranker的计算开销高,但它在提升排序准确性上的作用不可忽视。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名