改进召回(Retrieval)和引入重排(Reranking)提升RAG架构下的LLM应用效果

改进召回(Retrieval)和引入重排(Reranking)提升RAG架构下的LLM应用效果

原创 ully AI工程化 2023-08-24 21:08

收录于合集

#LLM应用架构3个

#领域技术13个

动手点关注

干货不迷路

如前文LLM应用架构之检索增强(RAG)的缘起与架构介绍,RAG架构很好的解决了当前大模型Prompt learning过程中context window限制等问题,整体架构简明清晰,易于实现,得到了广泛的应用,但实际落地过程中有大量的实际问题需要改进优化。

<
<think>我们正在讨论如何在Cherry Studio中搭建RAG框架,并具体实现召回重排部分。根据用户需求,我们需要构建一个RAG(检索增强生成)系统,其中召回Retrieval重排(Re-ranking)是关键步骤。 首先,回顾RAG的基本流程: 1. 用户输入查询(query) 2. 召回:从知识库中检索与查询相关的文档片段(chunks) 3. 重排:对召回的结果进行重新排序,以提升最相关片段的位置 4. 将重排后的top-k个片段与查询一起输入到大语言模型(LLM)中生成答案 在Cherry Studio中搭建RAG框架,我们可以利用其提供的工具接口。Cherry Studio是一个面向AI应用开发的平台,提供了模型部署、API调用、数据处理等功能。 ### 召回Retrieval)实现 召回阶段的目标是从大量文档中快速找出与查询相关的候选文档片段。常用的方法有: - 关键词匹配(如BM25) - 向量相似度检索(使用嵌入模型将文本转换为向量,然后计算余弦相似度) 在Cherry Studio中,我们可以这样实现: 1. **文档预处理**:将文档分割成适当大小的片段(chunk)。参考引用中提到的策略,我们可以设置`chunk_size=800, overlap=50`,即每个片段800个字符,相邻片段重叠50个字符。 2. **构建索引**: - 如果使用向量检索,需要将每个片段通过嵌入模型(如`text-embedding-ada-002`)转换为向量,并存入向量数据库(如Milvus、Pinecone等)。 - 如果使用关键词检索,可以使用Elasticsearch等建立倒排索引。 3. **检索过程**: - 对于用户查询,同样转换为向量(或关键词)并在索引中搜索,返回最相似的top N个片段(例如N=100)。 示例代码(使用向量检索): ```python import cherry from cherry.models import EmbeddingModel # 初始化嵌入模型 embed_model = EmbeddingModel("text-embedding-ada-002") # 假设已经有一个向量数据库实例(这里用伪代码表示) vector_db = cherry.get_vector_db("my_rag_index") def retrieve(query, top_n=100): # 将查询转换为向量 query_embedding = embed_model.encode(query) # 从向量数据库中检索 results = vector_db.search(query_embedding, top_k=top_n) return results # 返回检索到的文档片段列表 ``` ### 重排(Re-ranking)实现 召回阶段返回的top N个片段可能包含不相关的结果,重排阶段的目标是利用更复杂的模型对候选片段进行精细排序。常用的重排模型有: - 交叉编码器(Cross-Encoder):计算查询每个片段的相关性分数,比向量检索更准确但计算量更大。 - 学习排序(Learning to Rank)模型:使用机器学习方法训练排序模型。 在Cherry Studio中实现重排: 1. **加载重排模型**:可以使用预训练的交叉编码器模型,如`cross-encoder/ms-marco-MiniLM-L-6-v2`。 2. **对召回结果重排**: - 将查询每个候选片段输入到重排模型,得到相关性分数。 - 根据分数对候选片段进行降序排序。 - 选择top k个片段(例如k=5)用于生成答案。 示例代码: ```python from cherry.models import RerankModel # 初始化重排模型 rerank_model = RerankModel("cross-encoder/ms-marco-MiniLM-L-6-v2") def rerank(query, retrieved_docs, top_k=5): # 准备输入:查询每个文档片段 pairs = [(query, doc) for doc in retrieved_docs] # 获取相关性分数 scores = rerank_model.predict(pairs) # 将分数与文档片段组合 scored_docs = list(zip(scores, retrieved_docs)) # 按分数降序排序 scored_docs.sort(key=lambda x: x[0], reverse=True) # 返回top_k个片段 return [doc for score, doc in scored_docs[:top_k]] ``` ### 整合召回重排召回重排整合到RAG流程中: ```python def rag_pipeline(query): # 召回 retrieved_docs = retrieve(query, top_n=100) # 重排 top_docs = rerank(query, retrieved_docs, top_k=5) # 将top_docsquery输入到LLM生成答案 context = "\n\n".join(top_docs) prompt = f"基于以下上下文,回答用户问题:\n{context}\n\n问题:{query}" response = cherry.llm.generate(prompt) return response ``` ### 性能优化与自主控制 参考引用[^1]提到的自主开发优势,在Cherry Studio中我们可以: - 定制检索流程:例如,在召回阶段可以结合关键词检索向量检索(混合检索),并设置冲突检测算法(如避免重复片段)。 - 动态调整文本分割策略:根据文档类型(如技术文档、法律文本)调整`chunk_size``overlap`。 - 轻量化运行:选择轻量级模型,如使用`MiniLM`作为嵌入模型重排模型,以减少内存占用。 ### 注意事项 - 嵌入模型重排模型的选择会影响效果性能,需根据实际需求权衡。 - 向量数据库的配置(如索引类型、相似度度量)也会影响召回效果。 - 重排阶段计算开销较大,可考虑只对召回的前N个结果进行重排以平衡延迟。 §§相关问题§§ 1. 在Cherry Studio中如何部署嵌入模型重排模型? 2. 如何评估RAG系统的召回准确率? 3. 除了交叉编码器,还有哪些重排方法? 4. 如何处理多源数据(如多个知识库)的RAG检索?</think>### Cherry Studio 搭建 RAG 框架:召回重排实现指南 #### 一、整体架构设计 在 Cherry Studio 中搭建 RAG 框架的核心流程: ```mermaid graph LR A[用户查询] --> B(召回模块) B --> C(重排模块) C --> D[LLM生成答案] D --> E[最终输出] ``` #### 二、召回模块实现 召回Retrieval)负责从知识库中快速筛选候选文档,关键实现步骤: 1. **文档预处理** - 使用动态文本分割策略(参考引用[^1]): ```python from langchain.text_splitter import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter( chunk_size=800, # 可调整 chunk_overlap=50, separators=["\n\n", "\n", "。", "?"] ) chunks = splitter.split_documents(docs) ``` 2. **向量化存储** - 在 Cherry Studio 使用内置向量数据库: ```python from cherry.studio import VectorDB # 初始化向量库 vector_db = VectorDB(model="text-embedding-ada-002") # 添加文档 for chunk in chunks: vector_db.add( text=chunk.content, metadata={"doc_id": chunk.id} ) ``` 3. **召回执行** - 混合检索策略示例: ```python def retrieve(query, top_k=50): # 1. 向量召回 vector_results = vector_db.search( query_text=query, top_k=top_k * 2 # 扩大召回) # 2. 关键词召回(可选) keyword_results = bm25_retriever.search(query, top_k=top_k) # 3. 结果合并去重 return merge_results(vector_results, keyword_results) ``` #### 三、重排模块实现 重排(Re-ranking)对召回结果精细化排序,提升相关性: 1. **交叉编码器重排** ```python from transformers import AutoModelForSequenceClassification, AutoTokenizer class Reranker: def __init__(self, model_name="cross-encoder/ms-marco-MiniLM-L-6-v2"): self.tokenizer = AutoTokenizer.from_pretrained(model_name) self.model = AutoModelForSequenceClassification.from_pretrained(model_name) def rerank(self, query, passages): # 构建query-passage对 pairs = [(query, p) for p in passages] # 计算相关性得分 inputs = self.tokenizer( pairs, padding=True, truncation=True, return_tensors="pt" ) scores = self.model(**inputs).logits # 按得分排序 ranked_indices = scores.argsort(descending=True) return [passages[i] for i in ranked_indices] ``` 2. **自定义规则增强** - 实现多源排序逻辑(参考引用[^1]): ```python def custom_rerank(query, passages): base_scores = reranker.rerank(query, passages) # 添加业务规则 for i, passage in enumerate(passages): if is_high_priority_source(passage.metadata["source"]): base_scores[i] *= 1.2 # 特定来源加权 if contains_key_terms(passage.text, ["紧急", "最新"]): base_scores[i] += 0.5 return sort_by_score(base_scores) ``` #### 四、系统集成 在 Cherry Studio 中组装完整流程: ```python from cherry.studio import LLMClient def rag_pipeline(query): # 1. 召回 candidates = retrieve(query, top_k=100) # 2. 重排 ranked_passages = custom_rerank(query, candidates)[:5] # 取Top5 # 3. 生成答案 context = "\n\n".join([p.text for p in ranked_passages]) prompt = f"基于以下上下文:\n{context}\n\n回答:{query}" llm = LLMClient(model="gpt-4-turbo") return llm.generate(prompt) ``` #### 五、性能优化建议 1. **召回优化** - 动态调整 `chunk_size`(技术文档用 1000,对话记录用 300) - 实现两级召回:先关键词粗筛,再向量精筛 2. **重排加速** - 使用蒸馏版交叉编码器(如 MiniLM) - 对低置信度结果并行处理 3. **内存控制** - 启用量化加载模型(最低 2GB 内存)[^1] - 使用 ONNX Runtime 加速推理 > **关键优势**:通过自主实现冲突检测算法与多源排序逻辑,可针对业务场景定制化优化,这是优于通用框架的核心竞争力[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

医疗AI强化曾小健

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值