RAGLAB:又来一个RAG框架,还是模块化的
1. 背景
检索增强生成(RAG)借助外部知识来缓解幻觉问题,保障实时知识更新。然而,大家在研究 RAG 算法时面临两大主要问题:
• 一方面,许多已发表的成果要么并非开源,要么难以搭建环境,大家不得不耗费大量时间从零开始研发新算法。
• 另一方面,新的 RAG 算法纷纷涌现,比如 ITER-RETGEN、RRR、Self-Ask、Active RAG、Self-RAG 等等。然而,这些 RAG 算法在基本组件和评估方法上并不统一,导致大家难以准确评估改进效果。
虽然现在也有很多新的开发框架支持RAG算法,比如:LlamaIndex、LangChain、Haystack、FastRAG、RALLE、LocalRQA、AutoRAG 和 FlashRAG。
• LlamaIndex、LangChain 和 Haystack 过度封装,内部运作机制缺乏透明度。
• FastRAG 和 RALLE 提供了轻量且透明的框架,使用户能够运用核心组件组装自己的 RAG 系统。
• AutoRAG 提供了全面的指标,为定制数据挑选最优的 RAG 系统。
• LocalRAG 提供了丰富的模型训练算法和评估方法。
• FlashRAG 通过重现大量现有算法解决了这一问题。然而,FlashRAG 缺少训练功能,并且在推理时无法正确对齐生成器,导致各种算法之间的比较有失公平。
为了填补这一空缺,作者推出了 RAGLAB,一个面向研究人员的 RAG 工具包,用于对现有 RAG 算法进行公平比较,并简化新算法的开发流程。
2. RAGLAB
RAGLAB 的整体架构如上图所示。
2.1 类和概念
2.1.1 检索器
RAGLAB 整合了两个高性能的基于 BERT 的模型,即 Contriever 和 ColBERT。而且,RAGLAB 统一了不同检索器类的查询接口,方便用户在各种检索器之间无缝切换。
在评估阶段,研究人员需要并行对多个 RAG 算法进行基准测试。为了避免反复加载和查询检索器模型及知识数据库会耗费大量时间,RAGLAB 设计了检索器服务器和客户端架构,实现对检索器的高并发访问。
此外,RAGLAB 还实现了检索缓存机制。会存储初始查询的结果及其检索到的知识。所以,当使用相同输入进行查询时,检索器会直接返回缓存结果,无需重新计算。
基于 RAGLAB,用户只需加载一次检索器模型和知识数据库,就能在多个并行评估实验中实现延迟小于 0.1 秒的检索服务。
2.1.2 语料库
外部知识数据库对 RAG 系统的性能有重大影响。
RAGLAB 提供了两个版本的预处理维基百科语料库:第一个版本基于 DPR 项目开源的 2018 年维基百科数据;第二个版本利用 FactScore 开源的 2023 年维基百科数据。
RAGLAB 还基于维基百科 2018 和 2023 语料库为 ColBERT 和 Contriever 模型预先构建了索引和嵌入。另外,RAGLAB 开源了所有处理脚本,方便研究人员直接下载预处理的维基百科语料库及其相应的索引和嵌入。
2.1.3 生成器
生成器是 RAG 系统的核心组件。集成了 Huggingface Transformers 和 VLLM,使得 RAGLAB 能够兼容众多开源模型,同时提供稳定高效的推理性能。
RAGLAB 还融入了量化和LoRA功能,让用户即便在计算资源有限的情况下,也能使用 70B 或更大的模型作为生成器。
此外,考虑到用户可能需要在单个 RAG 算法中同时加载多个生成器,开发了一个 GPU 管理模块。该模块能让用户通过参数配置在指定的 GPU 上精准分配多个生成器。
除了开源模型,生成器模块包含OpenaiModel,支持像 OpenAI 这样的闭源大型语言模型。未来的发展会将支持扩展到包括 Claude、Gemini 和 Azure 在内的其他闭源大型语言模型。
2.1.4 指令实验室
指令对大型语言模型生成的输出质量影响显著。然而,在诸如 LlamaIndex 和 LangChain 等框架中,许多关键指令缺乏透明度,被封装在架构的底层。这种封装不方便修改提示词指令。
为解决这些问题,RAGLAB 设计了指令实验室模块,其中包括三个关键组件:系统指令、任务指令和算法指令。允许用户从 3 个指令池中高效导入和组合所需的提示。此外,用户可以在配置设置中调整参数,便于使用不同指令进行对比实验。
2.1.5 训练器
RAGLAB 集成了 Accelerate 和 DeepSpeed 库,以提供全面且高效的微调能力。此外,训练器模块支持LoRA和QLoRA技术,使用户能够在计算资源有限的情况下微调70B或更大的模型。
2.1.6 数据集和指标
如上表,RAGLAB 收集了 10 个被广泛使用的测试数据集,涵盖 5 个不同的任务。
RAGLAB 提供了 3 个经典指标和 2 个高级指标。
经典指标包括准确性、精确匹配和 F1 分数。
高级指标包括 Factscore 和 ALCE。
• FactScore 是一种评估长文本生成的事实准确性的高级指标。
• ALCE 则作为评估 RAG 系统的引用准确性和召回率的基准。ALCE 还整合了其他指标,包括 ROUGE-L、MAUVE、str-em 和 str-hit。
2.2 架构和开发指南
RAGLAB 重现了六种已发表的 RAG 算法,分别是 Naive RAG、RRR、ITER-RETGEN、Self-ASK、Active RAG 和 Self-RAG。这些算法有诸多相似之处,每个高级的 RAG 算法本质上都是对 Naive RAG 的改进。
RAGALB 的设计理念源自 HuggingFace Transformer 库。用户只需从 Transformer 库中定义他们的模型,然后就能使用generate()方法进行推理。
RAGALB 将每个 RAG 算法实现为一个不同的类。每个算法类中的两个关键方法是init()和infer()。init()方法用于设置参数和加载生成器,而infer()方法实现算法的推理过程。
基于这个设计框架,用户可以通过几个简单步骤开发新算法,如上图所示:
(1)定义一个继承自NaiveRAG的NewMethod()类。(2)通过重写init()方法为新算法添加必要的参数和组件。(3)通过重写infer()方法,利用框架提供的组件实现新算法的推理逻辑。
继承自 NaiveRAG 的算法可以复用inference()方法和所有实用函数。值得注意的是,inference()方法已经提供了自动评估和交互功能。这种设计让研究人员能够专注于设计infer()方法来开发新算法。
2.3 示例脚本
RAGLAB 提供了一个用户友好的界面,允许用户仅用 5 行代码重现 RAG 算法以进行交互或评估。
如上图所示,展示了一个在交互和评估模式下重现 Self-RAG 算法的示例脚本。
实现过程如下:
• (1)get_config()函数从 YAML 文件读取参数并定义 args 对象。
• (2)根据 args 参数定义SelfRag_Reproduction类,为 Self-RAG 算法做好所有设置。
• (3)调用第 9 行的inference()方法进入交互模式。
• (4)再次调用第 12 行的inference()方法进入评估模式。
3. 局限性
• 鉴于计算资源有限,RAGLAB 当下仅涵盖 6 种算法和 10 个被广泛运用的基准。然而,仍有必要纳入更多算法和数据集。
• 不同的检索器模型和外部知识数据库对 RAG 算法的性能有着显著影响。由于计算资源受限,仅处理了 2018 年和 2023 年的维基百科。
• 当下的研究主要聚焦于提升算法的性能,缺少对资源消耗和推理延迟的全面评估。目前,RAGLAB 仅包含 3 个经典指标和 2 个高级指标。
本文转载自大语言模型论文跟踪,作者:HuggingAGI