【RAG】RAG性能提升之路-RAPTOR:一种构建递归文档树的增强检索方法

news2025/2/26 7:07:56

背景

检索增强型语言模型(RALMs)在处理需要不断更新的知识和大量信息的文档时确实展现出了优势。然而,现有的方法在处理长篇文档时存在局限性,主要是因为它们通常只能检索较短的文本片段,这限制了对整体文档上下文的全面理解。在NLP中,长篇文档的检索和理解一直是一个挑战,因为传统检索方法往往难以有效处理长文档中的复杂结构和信息,可能导致检索结果不准确或遗漏关键信息。

为了解决这一问题,RAPTOR模型提出了一种创新的策略。它**通过递归地进行文本片段的向量化、聚类和摘要生成,构建了一个树状索引结构。**这种结构不仅捕捉了文档的高层次主题,还保留了低层次的细节,允许基于语义相似性而非仅仅是文本顺序对节点进行分组。这样的树状结构使得RAPTOR能够在不同的抽象层次上加载文档的上下文片段,从而有效地回答不同层次的问题。

方法

一、RAPTOR 树的构建

RAPTOR 树的构建是该模型的核心部分,通过递归的方式创建了一个多层次的树状结构,便于更好地理解和检索长文本信息。以下是 RAPTOR 树构建的步骤:

  1. 文本分块
    RAPTOR 首先将长文本分割成较短的、连续的文本块。每块文本的长度被限制在100个标记(tokens)以内。如果一个句子的标记数超过这个限制,它会完整地被移动到下一个文本块中,以保持语义的连贯性。

  2. 文本向量化
    使用SBERT(multi-qa-mpnet-base-cos-v1)对每个文本块进行embedding,生成文本的向量表示,这些嵌入向量将形成树结构的叶节点。

  3. 文本聚类
    通过文本聚类算法,将语义相似的文本块分组。RAPTOR 使用软聚类方法,允许文本块根据其语义相关性属于多个不同的聚类。聚类算法基于高斯混合模型(GMMs),并采用均匀流形近似和**投影(UMAP)**技术进行降维处理,以更好地捕捉文本数据的局部和全局结构。

    • 软聚类(Soft Clustering):与传统硬聚类不同,软聚类允许文本片段属于多个聚类,增加了灵活性。

    • 高斯混合模型(Gaussian Mixture Models, GMMs): 假设数据点是从多个高斯分布的混合中生成的。
      对于给定的文本向量 ( x ),其属于第 ( k ) 个高斯分布的概率表示为:
      P ( x ∣ k ) = N ( x ; μ k , Σ k ) P(x|k) = \mathcal{N}(x; \mu_k, \Sigma_k) P(xk)=N(x;μk,Σk)
      其中 N \mathcal{N} N 是多元高斯分布, μ k \mu_k μk是均值向量, Σ k \Sigma_k Σk 是协方差矩阵。
      整体概率分布是一个加权组合:
      P ( x ) = ∑ k = 1 K π k N ( x ; μ k , Σ k ) P(x) = \sum_{k=1}^{K} \pi_k \mathcal{N}(x; \mu_k, \Sigma_k) P(x)=k=1KπkN(x;μk,Σk)

      π k \pi_k πk表示第 k k k 个高斯分布的混合权重。

    • 降维处理(Dimensionality Reduction)
      由于向量嵌入的高维性,使用传统的距离度量可能在高维空间中表现不佳。采用 UMAP技术进行降维。

    • 层次聚类结构
      UMAP 中的最近邻参数 n 邻居决定了局部和全局结构的平衡。算法通过变化 n 邻居来创建层次聚类结构,首先识别全局聚类,然后在这些全局聚类内部执行局部聚类。

    • 模型选择(Model Selection)
      使用贝叶斯信息准则(Bayesian Information Criterion, BIC)来确定最优的聚类数量。

      • BIC 公式为:
        BIC = ln ⁡ ( N ) ⋅ k − 2 ln ⁡ ( L ^ ) \text{BIC} = \ln(N) \cdot k - 2 \ln(\hat{L}) BIC=ln(N)k2ln(L^)
        其中 N N N 是文本片段(或数据点)的数量, k k k 是模型参数的数量, L ^ \hat{L} L^ 是模型似然函数的最大值。

    小结:通过聚类算法,RAPTOR 能够有效地组织文本片段,形成具有不同层次的树状结构,从而在检索时能够提供更准确和全面的上下文信息。

  4. 文本摘要生成
    对于每个聚类,使用GPT-3.5生成该聚类的文本摘要。这些摘要随后被重新嵌入,形成树的上一层节点。

    GPT使用的文本摘要prompt如下:

  5. 递归构建
    上述过程(3 聚类和 4 摘要生成)递归地重复执行,直到无法进一步聚类或达到预设的层数限制,从而构建出一个从底向上的多层次树状结构。在这个结构中,父节点包含子节点的文本摘要,而子节点是原始文本块或下一级的摘要。

  1. 树的深度和广度
    • 树的深度取决于文本的复杂性和长度,以及聚类过程何时变得不可行。
    • 树的广度则取决于每个聚类中文本块的数量。

二、树的检索

构建好的 RAPTOR 树可以在推理时用于检索。有两种检索策略:树遍历和折叠树。树遍历逐层检索树,而折叠树则将所有层展平为单层进行检索。


上图展示了树遍历折叠树检索机制的示意图。树遍历从树的根级别开始,根据与查询向量的余弦相似度检索顶层的 top-k (这里为 top-1) 节点。在每一层,它根据与查询向量的余弦相似度从上一层的 top-k 节点的子节点中检索 top-k 节点。这个过程一直重复,直到达到叶节点。最后,将所有选定节点的文本连接起来形成检索到的上下文。折叠树方法将整个树压缩成单一层,然后根据与查询向量的余弦相似度评估所有层的节点,直到达到设定阈值。

通过树检索信息的例子:

树遍历算法

  1. 初始化:从树的最底层(即叶子节点层)开始。
  2. 相似度计算:对于当前层中的每个节点,计算它与查询向量的余弦相似度。
  3. 选择Top-k节点:根据余弦相似度,选择每个层中与查询最相关的k个节点。
  4. 递归访问子节点:对于选定的节点,查看其子节点,并重复步骤2和3,直到达到树的根节点。
  5. 结果整合:将所有选定的节点文本进行拼接,形成检索到的上下文。
折叠树算法

  1. 树的扁平化:首先,将整个树结构扁平化为一个单一的节点集合,忽略节点之间的层级关系。
  2. 相似度计算:对于扁平化后的每个节点,计算它与查询向量的余弦相似度。
  3. 选择Top-k节点:根据余弦相似度,选择与查询最相关的k个节点。
  4. 限制Token数量:在添加节点到结果集中时,确保不超过模型输入限制的最大Token数量。
  5. 结果拼接:将选择的节点文本进行拼接,形成检索到的上下文。

小结:通过这种递归构建的树状结构,RAPTOR 能够将长篇文档分解成不同层次的摘要,从而在检索时提供更准确和全面的上下文信息,这对于处理需要综合多部分信息的复杂查询尤为重要。

实验

相关数据集实验

检索效率

RAPTOR 树构建成本与每个数据集的文档长度成线性比例。

对于最大长度为80,000个Tokens的文档,RAPTOR树的构建时间确实与文档长度成正比例关系。这意味着无论文档的实际内容如何,构建树所需的时间都会随着文档长度的增加而线性增加。
这种线性关系表明RAPTOR模型具有良好的可扩展性,能够高效地处理不同长度的文档。这一点非常重要,因为它确保了即使是较长的文档,RAPTOR也能够在合理的时间内完成索引结构的构建。

简易使用

设置LLM

import os
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

from raptor import RetrievalAugmentation

# Initialize with default configuration. For advanced configurations, check the documentation. [WIP]
RA = RetrievalAugmentation()

创建文档树

with open('sample.txt', 'r') as file:
    text = file.read()
RA.add_documents(text)

进行问答

question = "How did Cinderella reach her happy ending?"
answer = RA.answer_question(question=question)
print("Answer: ", answer)

保存文档树

SAVE_PATH = "demo/cinderella"
RA.save(SAVE_PATH)

加载文档树问答

RA = RetrievalAugmentation(tree=SAVE_PATH)
answer = RA.answer_question(question=question)

总结

综上所述,RAPTOR模型通过其递归抽象处理方法,有效地解决了现有方法在长篇文档检索中的局限。通过构建树状索引结构,RAPTOR不仅提升了对长篇文档的理解,还增强了检索的准确性和效率,为处理知识密集型任务提供了新的可能。

参考文献

  • paper:RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL,https://arxiv.org/pdf/2401.18059
  • code:https://github.com/parthsarthi03/raptor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1823785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝牙资讯|苹果iOS 18增加对AirPods Pro 2自适应音频的更多控制

苹果 iOS 18 系统将为 AirPods Pro 2 用户带来一项实用功能 —— 更精细的“自适应音频”控制。AirPods Pro 2 的“自适应音频”功能包含自适应降噪、个性化音量和对话增强等特性,可以根据周围环境自动调节声音和降噪效果。 当更新至最新测试版固件的 AirPods Pro 2…

24年法考报名照片千万别乱拍,否则卡审

法考报名照片每年都有很多被卡审😭 常见的问题是 ①照片比例不对,无法上传,人像比例要求非常严格 ②照片像素错误,不能直接拿大图压缩图片,需要做出413*626像素的法考证件照 ③照片文件偏大,照片要求40-100…

【LeetCode刷题】前缀和解决问题:560.和为k的子数组

【LeetCode刷题】Day 16 题目1:560.和为k的子数组思路分析:思路1:前缀和 哈希表 题目1:560.和为k的子数组 思路分析: 问题1:怎样找到数组所有子数组? 方式一:暴力枚举出来&#x…

CSS实现经典打字小游戏《生死时速》

🌻 前言 CSS 中有这样一个模块:Motion Path 运动模块,它可以使元素按照自定义的路径进行移动。本文将为你讲解这个模块属性的使用,并且利用它实现我小时候电脑课经常玩的一个打字游戏:金山打字的《生死时速》。 &…

Kettle 传参(参数)的使用

Kettle 传参的符号是 ? 。 一、给表改名,并在名称后面加上日期 1、表输入获取名称参数 我这是通过SQL来获取 SELECT concat("score","_",DATE_FORMAT(sysdate(),%Y%m%d%H%i)) aa FROM dual2、执行SQL语句 使用SQL脚本组件 想要获得参数&a…

win10 3389,win10操作系统如何修改3389端口

在Windows 10操作系统中,3389端口是远程桌面服务(Remote Desktop Protocol, RDP)的默认侦听端口。出于安全考虑,许多用户和管理员会选择修改这个默认端口号,以减少潜在的攻击面。下面将详细介绍如何修改Windows 10中的…

工作随机:oracle集群下的vip intermediate,failed over处理

文章目录 前言一、问题排查二、恢复db2使用1.确认db2 vip状态2.恢复db2 的vip3.检查监听: 前言 在对数据库进行巡检发现,集群中一个节点的备份没有执行,未生成当天的任何日志,查询/var/spool/oracle 信息发现提示:no …

会声会影封面图怎么设置 会声会影渲染封面如何固定 会声会影视频剪辑软件制作教程

使用会声会影剪辑完成过后,通常我们需要给我们的视频设置封面,渲染封面又需要进行固定。本文将围绕会声会影封面图怎么设置和会声会影渲染封面如何固定来进行介绍。 一、会声会影封面图怎么设置 会声会影不能随意自定义设置封面,默认情况下…

镭速如何做到数据同步文件及文件夹的ACL属性?

数据文件同步时,除了要同步文件的内容,还要对文件的属性做同步。权限属性作为一个重要的文件属性,是属性同步的重中之重,控制着不同用户与用户组对文件和文件夹的访问权限。不同的操作系统有着自己不同的权限控制机制,…

python通过selenium实现自动登录及轻松过滑块验证、点选验证码(2024-06-14)

一、chromedriver配置环境搭建 请确保下载的驱动程序与你的Chrome浏览器版本匹配,以确保正常运行。 1、Chrome版本号 chrome的地址栏输入chrome://version,自然就得到125.0.6422.142 版本 125.0.6422.142(正式版本) (…

使用powershell筛选AD域控不能自主更改的用户并变更

# 查询“用户不能更改密码”为勾选状态的所有域用户,将域账户、姓名、勾选状态作为结果保存到C:\result\result.csvGet-ADUser -Filter * -Properties CannotChangePassword | Where-Object { $_.CannotChangePassword -eq $true } | Select SamAccountName, Name, …

LabVIEW超导体临界电流与磁场变化检测系统

一、项目背景 某高校物理实验室需要开发一套检测系统,用于研究超导体在不同条件下的临界电流和磁场变化情况。该系统需满足实验教学和科研的双重需求,提供高精度的数据采集和处理功能。 二、系统设计与实现 1. 硬件配置 高精度电流传感器:…

实例化游戏物体的实例(生成游戏物体)

一、实例1:实例化 1、准备工作:制备预制体,命名。如Circle 2、Create Empty,名字自取。如:CirclePrefab 3、给CirclePrefab添加Test.cs public GameObject CirclePrefab; // 预制体变量,用于存储Circle预…

Golang免杀-编码加密-Xor(GG)

go语言环境搭建 Golang学习日志 ━━ 下载及安装_golang下载-CSDN博客 go run xxx.go go build xxx.go 首先,cs.msf生成比特流数据. 放入xor,py脚本中进行xor加密. xor.py def xor(shellcode, key):new_shellcode ""key_len len(key)# 对shellcode的每一位进行…

有监督学习——线性回归

1. 线性模型 有监督学习是通过已知的样本产生预测模型的学习方法,任何有监督学习模型都可被想象成一个函数: 其中,\(x_1,x_2,x_3…x_n\)是模型的n维的特征值,\(y\)是要预测的目标值/分类,当\(y\)是可枚举的类型时&…

【leetcode--字母异位词分组】

class Solution:def groupAnagrams(self, strs: List[str]) -> List[List[str]]:np collections.defaultdict(list)for st in strs:name "".join(sorted(st))np[name].append(st)return list(np.values()) collections.defaultdict(list)创建字典类型&#xff…

给你一个扫码支付的二维码,如何写测试用例?

前言 面试的时候,经常会临场出题:给你一个xxx, 如何测试, 或者说如何写测试用例?xxx可以是圆珠笔,水杯,电梯等生活中常见的场景。 那么给你一个支付的二维码,如何写测试用例呢? 二维码扫码支…

Vue路由守卫的使用

示例如下:(第一张图)当你点击车1的时候你写了路由守卫就点不开出现无权访问 (第二张图,就是可以访问后的图)有路由守卫点不开的情况下当你在本地存储中写了你在路由守卫中写的东西就可以进入了 你需要在r…

材料科学SCI期刊,中科院3区,IF=3.8,专业性强

一、期刊名称 Materials Today Communications 二、期刊简介概况 期刊类型:SCI 学科领域:材料科学 影响因子:3.8 中科院分区:3区 三、期刊征稿范围 《今日材料通讯》是一本范围广泛、多学科、快速出版的期刊,专注…

【docker】Dockerfile制作基础镜像 python 底层镜像制作 | 打包所有的requirement依赖

一、Dockerfile思想 我们正常的对一个项目进行打包 docker image 通常是在CI工具编译时进行对依赖的安装,比如golang的go get、python的pip install、node的npm install 等等 好处:我们更新了依赖可以动态的再编译时进行一个对依赖的更新 坏处&#xf…