|
今天,我们来看看一个竞赛的方案,之前有讲过EasyRAG,现在作者【来自北航,也是老刘说NLP社区的成员】专门写了个稿子,可以再次温习下。 历经4个月的时间,从初赛赛道第1,复赛赛道第2,到最后决赛获得季军,这一路我们团队收获了很多实践经验,也结识了不少业界的RAG研究者,受益匪浅。应组委会邀请,本文介绍一下我们EasyRAG方案的亮点和实验结果,欢迎感兴趣的朋友批评指正! 开源地址:https://github.com/BUAADreamer/EasyRAG 技术报告:https://github.com/BUAADreamer/EasyRAG/blob/master/assets/技术报告.pdf PPT:https://github.com/BUAADreamer/EasyRAG/blob/master/assets/PPT.pdf 论文链接:EasyRAG: Efficient Retrieval-Augmented Generation Framework for Automated Network Operations 挑战赛官网:https://competition.aiops-challenge.com/home/competition/1780211530478944282 0.概览先简要介绍背景,本次比赛题目是面向网络运维领域的私域知识问答,根据LLM的类型分为两个赛道,赛道一使用可以微调的Qwen2-7B,赛道二调用 GLM-4 API。我们选择了赛道二,模拟无法微调LLM的场景。 因此,我们的目标是如何在不微调任何模型的前提下,实现较为简洁的RAG,尽可能达到准确、高效和实用 
为了达成这一目标,我们基于llama-index[1],实现了一套包含查询改写、图像数据处理、分块策略、元数据利用、密集检索、稀疏检索、重排、排序融合、提示词优化、上下文压缩、部署的RAG框架,可以灵活地配置自己的RAG流程,方便地应用在自己的私域数据问答中。 
初赛RAG流程:块调优-两路稀疏/密集检索粗排-重排-rrf排序融合 
复赛RAG流程:块优化(图像信息和路径知识利用)-两路稀疏检索粗排-重排-答案迭代优化 
接下来我们将分别介绍我们在准确性,高效性和实用性方面的实践和实验结果,以飨读者 1.准确性数据处理流程# 原代码:https://github.com/run-llama/llama_index/blob/8f7cd3e1043da26514ac82fc732cd21bbb4bbe9c/llama-index-core/llama_index/core/node_parser/text/sentence.py#L155C5-L157C62 def split_text_metadata_aware(self, text: str, metadata_str: str) -> List[str]: metadata_len = len(self._tokenizer(metadata_str)) effective_chunk_size = self.chunk_size - metadata_len
# 我们的实现:https://github.com/BUAADreamer/EasyRAG/blob/893b3c272b2ce0d8c6cee80f02a171cccded9f96/src/easyrag/custom/splitter.py#L149 def split_text_metadata_aware(self, text: str, metadata_str: str) -> List[str]: metadata_len = len(self._tokenizer(metadata_str)) effective_chunk_size = self.chunk_size
# 分块实现:https://github.com/BUAADreamer/EasyRAG/blob/893b3c272b2ce0d8c6cee80f02a171cccded9f96/src/easyrag/custom/transformation.py#L67C1-L71C51 for node in nodes: node.metadata["file_abs_path"] = node.metadata['file_path'] file_path = node.metadata["file_path"].replace(self.data_path + "/", "") node.metadata["dir"] = file_path.split("/")[0] node.metadata["file_path"] = file_path 
RAG流程查询改写:我们尝试了关键词扩展和HyDE两种思路,但我们发现直接使用GLM4进行查询扩展会使得新查询词和私域文档偏差较大,因此在提交方案中没有采用,详情参见技术报告 两路稀疏检索粗排:基于BM25实现两路检索,除了常规的文档检索,我们还进行了知识路径检索。 密集检索粗排:基于LLM的embedding模型效果更佳 LLM Reranker 重排:基于LLM的Reranker效果更佳 多路排序融合:排序融合主要尝试了naive(去重合并)以及rrf(倒数排序融合)。我们发现重排融合相比粗排融合更有用 生成前融合:多组文档集合排序融合得到一组文档集合,输入LLM 生成后融合:每组文档集合分别输入LLM,将多个答案融合。我们尝试了直接拼接和取最长两种方式 粗排融合:复赛中我们直接将两路进行naive融合 重排融合:多路分别进行粗排-重排,得到多组文档集合
LLM 回答:简单问答提示词最佳 LLM 答案迭代优化:让模型逐步关注重要信息
缩写描述这里先对之后实验表中的一些缩写做出解释 

初赛实验结果这里列出我们初赛的提分路径,主要经历了3个阶段 单路粗排(0-2) 官方Baseline跑通(0==>57) bge-v1.5实验(57==>68) bm25实验(68==>69)
单路粗排-精排(3-16) 多路融合(17-21)

复赛实验结果由于复赛和初赛评价指标发生了变化,更看重事实正确性,因此稀疏检索粗排总体更加有效 这里列出我们复赛的提分路径,主要经历了5个阶段 流程探索(0-4) 路径知识利用(5-10) 粗排利用文件路径(91.5==>92.7) 重排利用知识路径(92.7==>93.1)
图像信息利用(11-12) 知识路径检索(13) 答案迭代优化(14-15)

2.高效性考虑到实际使用时对速度的要求,我们也实现了一些策略降低推理时延,以下为总的时间开销比较: 接下来分别讲解三个加速方案 高效稀疏检索
高效重排我们设计了层早退算法,将重排时间降低2s+ 
高效LLM推理我们设计了上下文压缩方法,将LLM推理时间降低1.5s+ 
3.实用性

网络运维问答案例
四大名著问答案例我们还使用四大名著语料[10]测试了框架能否支持通用的语料问答 
4.总结本次比赛我们以不微调任何模型作为自己的目标,并在此前提下,利用了各种先进模型搭建我们的pipeline,做了充分的消融实验,达到了比赛中先进的准确度,同时也做了一些高效性和实用性方面的尝试 这初步说明一个结论:对于垂直领域RAG,精心设计流程+挑选sota模型+流程调优在初期带来的收益可能要大于微调模型。不过我们相信,经过微调后的模型可以让我们的pipeline获得更好的效果。希望这个工作能对RAG社区做出一些贡献,欢迎各位大佬批评指正! 感谢组委会耐心细致的比赛组织,这次比赛大家的讨论氛围和体验都非常良好!感谢张老师和学长们对本次比赛的大力支持!最后再次推广下我们的框架EasyRAG,目前已经收获70+star;同时如果您对于此框架有好的想法,也欢迎提PR! |