问题: RAG中,有时,最合适的答案不一定排在检索的最前面
user_query = "how safe is llama 2"
search_results = vector_db.search(user_query, 5)for doc in search_results['documents'][0]:print(doc+"\n")response = bot.chat(user_query)
print("====回复====")
print(response)
方案:ReRank
- 检索时过召回一部分文本
- 通过一个排序模型对 query 和 document 重新打分排序
# !pip install sentence_transformers
from sentence_transformers import CrossEncoder# model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2', max_length=512) # 英文,模型较小
model = CrossEncoder('BAAI/bge-reranker-large', max_length=512) # 多语言,国产,模型较大user_query = "how safe is llama 2"
# user_query = "llama 2安全性如何"
scores = model.predict([(user_query, doc)for doc in search_results['documents'][0]])
# 按得分排序
sorted_list = sorted(zip(scores, search_results['documents'][0]), key=lambda x: x[0], reverse=True)
for score, doc in sorted_list:print(f"{score}\t{doc}\n")
0.918857753276825 In this work, we develop and release Llama 2, a family of pretrained and fine-tuned LLMs, Llama 2 and Llama 2-Chat, at scales up to 70B parameters. On the series of helpfulness and safety benchmarks we tested, Llama 2-Chat models generally perform better than existing open-source models.0.7791304588317871 We believe that the open release of LLMs, when done safely, will be a net benefit to society. Like all LLMs, Llama 2 is a new technology that carries potential risks with use (Bender et al., 2021b; Weidinger et al., 2021; Solaiman et al., 2023).0.47571462392807007 We provide a responsible use guide¶ and code examples‖ to facilitate the safe deployment of Llama 2 and Llama 2-Chat. More details of our responsible release strategy can be found in Section 5.3.0.47421783208847046 We also share novel observations we made during the development of Llama 2 and Llama 2-Chat, such as the emergence of tool usage and temporal organization of knowledge. Figure 3: Safety human evaluation results for Llama 2-Chat compared to other open-source and closed source models.0.16011707484722137 Additionally, these safety evaluations are performed using content standards that are likely to be biased towards the Llama 2-Chat models. We are releasing the following models to the general public for research and commercial use‡: 1.
1. ReRank 的核心作用
在 RAG(检索增强生成)系统中,ReRank 用于优化初步检索结果,解决传统向量检索的两大痛点:
- 语义模糊性:向量检索可能返回语义相关但细节不匹配的文档。
- 精度天花板:仅依赖向量相似度无法捕捉复杂的语义关联。
示例场景:
当用户查询 "how safe is llama 2"
时,向量检索可能返回包含 "llama 2 model architecture"
或 "safety guidelines for AI"
的文档,而 ReRank 会进一步识别与 "safety"
直接相关的内容。
2. 代码解析
(1) 安装依赖与导入库
# !pip install sentence_transformers
from sentence_transformers import CrossEncoder
sentence_transformers
:提供预训练模型和工具,用于文本向量化、排序等任务。CrossEncoder
:交叉编码器模型,同时处理查询和文档,计算相关性得分。
(2) 加载 ReRank 模型
# 英文小模型(适合快速实验)
# model = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2', max_length=512)# 多语言大模型(中文优化,精度高)
model = CrossEncoder('BAAI/bge-reranker-large', max_length=512)
- 模型选择:
cross-encoder/ms-marco-MiniLM-L-6-v2
: 轻量级英文模型,适合低资源场景。BAAI/bge-reranker-large
: 北京智源研究院的中英多语言模型,支持更长文本和复杂语义。
(3) 定义查询与待排序文档
user_query = "how safe is llama 2"
# user_query = "llama 2安全性如何"# 假设 search_results 是初步检索结果
search_results = {'documents': [["Llama 2 introduced safety fine-tuning to reduce harmful outputs.","The model architecture of Llama 2 uses a transformer-based design.","Safety in AI involves rigorous testing and ethical guidelines."]]
}
(4) 计算相关性得分并排序
# 生成 (query, doc) 对
pairs = [(user_query, doc) for doc in search_results['documents'][0]]# 计算得分
scores = model.predict(pairs)# 按得分从高到低排序
sorted_list = sorted(zip(scores, search_results['documents'][0]),key=lambda x: x[0],reverse=True
)# 输出结果
for score, doc in sorted_list:print(f"{score:.4f}\t{doc}\n")
输出示例:
0.8762 Llama 2 introduced safety fine-tuning to reduce harmful outputs.0.2345 The model architecture of Llama 2 uses a transformer-based design.0.1287 Safety in AI involves rigorous testing and ethical guidelines.
3. 关键技术:交叉编码器 vs 双编码器
特性 | 双编码器 (Bi-Encoder) | 交叉编码器 (Cross-Encoder) |
---|---|---|
工作原理 | 分别编码查询和文档,计算余弦相似度 | 同时编码查询和文档,直接计算相关性得分 |
速度 | 快(适合大规模检索) | 慢(适合对少量候选文档重排序) |
精度 | 较低(独立编码损失细节) | 较高(联合编码捕捉细粒度交互) |
典型应用 | 初步检索(如向量数据库) | 精细化排序(如 ReRank) |
4. 如何选择 ReRank 模型?
模型名称 | 语言支持 | 精度 | 速度 | 适用场景 |
---|---|---|---|---|
cross-encoder/ms-marco-MiniLM-L-6-v2 | 英文 | 中 | 快 | 英文简单查询,资源受限环境 |
BAAI/bge-reranker-large | 中英多语言 | 高 | 慢 | 复杂查询、多语言混合、高精度需求 |
5. 实际应用中的优化建议
-
分块策略:
- 文档分块时保留上下文(如使用
sliding window
或overlap
),避免关键信息被截断。
- 文档分块时保留上下文(如使用
-
截断文本:
- 根据模型
max_length
(如 512 token)截断输入,优先保留头部和尾部关键信息。
- 根据模型
-
混合排序:
- 将向量检索得分与 ReRank 得分加权融合,平衡精度与效率:
final_score = 0.7 * rerank_score + 0.3 * retrieval_score
- 将向量检索得分与 ReRank 得分加权融合,平衡精度与效率:
-
异步处理:
- 在高并发场景下,将 ReRank 部署为独立服务,避免阻塞主流程。
6. 完整流程示例
# 1. 初步检索(向量数据库)
from vector_db import search # 假设的向量数据库接口
search_results = search(user_query, top_k=50)# 2. 重新排序
pairs = [(user_query, doc) for doc in search_results['documents']]
scores = model.predict(pairs)
reranked_docs = [doc for _, doc in sorted(zip(scores, search_results['documents']), reverse=True)]# 3. 截断 Top-K 文档输入大模型
context = "\n".join(reranked_docs[:5])
prompt = f"基于以下上下文回答:{context}\n\n问题:{user_query}"
response = llm.generate(prompt)
总结
通过 ReRank 技术,RAG 系统的答案精度可提升 20-30%(尤其在复杂查询场景)。通过 BAAI/bge-reranker-large
模型实现精细化排序,核心步骤包括:
- 加载交叉编码器模型。
- 对初步检索结果生成
(query, doc)
对。 - 计算相关性得分并排序。
在实际应用中,需权衡 精度、延迟、成本,选择适合的模型和分块策略。
一些 Rerank 的 API 服务
- Cohere Rerank:支持多语言
- Jina Rerank:目前只支持英文