在 Langchain 中使用 RAPTOR 实现高级 RAG

本文介绍了如何在Langchain中利用RAPTOR技术实现高级的递归抽象处理,通过聚类和摘要创建分层树结构,用于长上下文的检索。文章详细阐述了RAPTOR的工作原理,以及在LLM应用技术栈中的具体实现,包括Langchain、Zephyr模型、嵌入模型和聚类算法。此外,还提供了代码实现步骤,包括安装库、获取模型参数、构建树和生成摘要。
摘要由CSDN通过智能技术生成

RAPTOR:树结构的索引和检索系统的递归抽象处理-CSDN博客 

原文地址:implementing-advanced-rag-in-langchain-using-raptor

2024 年 3 月 24 日

RAPTOR 简介

递归抽象处理树组织检索(RAPTOR)是种全新而强大的索引和检索技术,它全面适用于LLM。该方法采用自下而上的策略,通过聚类和汇总文本片段(块)来构建一个分层的树状结构。

RAPTOR 论文介绍了一种创新的文档索引和检索策略:

  • 首先,将一组初始文档(单个文档的文本块或者完整文档)视为树的“叶子”。
  • 这些叶子被嵌入并表示为向量,然后通过聚类算法进行分组。
  • 接着,这些聚类被提炼为更高层次(更抽象)的信息,这些信息跨越相似的文档进行整合。
  • 整个过程递归进行,形成了一棵从原始文档(叶子)到更抽象摘要的“树”。

假设我们有来自于庞大手册的8个文档块,我们并不只是简单地对这些块进行嵌入并直接进行检索,而是首先将它们转换成向量形式,接着对这些高维向量进行降维处理。这样做是因为生成包含所有维度的簇会带来极高的计算成本,例如,在使用OpenAI的嵌入模型时,维度高达1536,而在使用常见的开源小型嵌入模型时,维度为384。

完成降维后,我们应用聚类算法对这些低维向量进行分组。接下来,我们收集每个聚类中的所有文档块,并对每个聚类的上下文进行总结。这样生成的摘要不仅反映了嵌入和聚类的结果,而且我们还重复这一过程,直到达到模型的令牌限制(即上下文窗口的大小)。

简而言之,RAPTOR方法的核心思想可以概括为:

  • 聚类并总结相似的文档块。
  • 将相关信息从相关文档中提取到摘要中。
  • 为那些只需要少量上下文就能回答的问题提供支持。

LLM 应用技术栈

  1. Langchain
  2. llm :zephyr-7b-beta.Q4_K_M.gguf
  3. 嵌入模型 — thenlper/gte-small
  4. clustering 算法: GMM (Gaussian Mixture Model)

代码实现

安装所需的库

!pip install -U langchain umap-learn scikit-learn langchain_community tiktoken langchain-openai langchainhub chromadb
!CMAKE_ARGS="-DLLAMA_CUBLAS=on" FORCE_CMAKE=1 pip install -qU llama-cpp-python

import locale
def getpreferredencoding(do_setlocale = True):
  return "UTF-8"
locale.getpreferredencoding = getpreferredencoding

获取 Zephyr 模型参数文件 

!wget "https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/resolve/main/zephyr-7b-beta.Q4_K_M.gguf"

实例化 LLM

from langchain_community.llms import LlamaCpp
from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler
from langchain_core.prompts import PromptTemplate

# 放置在 GPU 上的层数,其余的将在 CPU 上进行,-1表示将所有层移至GPU。
n_gpu_layers = - 1  
# 介于 1 和 n_ctx 之间,考虑 GPU 中的 VRAM 量。
n_batch = 512  

# 回调支持 token-wise 流式处理
callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])

model = LlamaCpp(
    model_path="/content/zephyr-7b-beta.Q4_K_M.gguf",
    n_gpu_layers=n_gpu_layers,
    n_batch=n_batch,
    temperature=0.75,
    max_tokens=1000,
    top_p=1,
    n_ctx=35000,
    callback_manager=callback_manager,
    verbose=True,  # Verbose is required to pass to the callback manager
)

实例化嵌入模型

from langchain.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores.utils import DistanceStrategy

EMBEDDING_MODEL_NAME = "thenlper/gte-small"

embd = HuggingFaceEmbeddings(
    model_name=EMBEDDING_MODEL_NAME,
    multi_process=True,
    model_kwargs={"device": "cuda"},
    encode_kwargs={"normalize_embeddings": True},  # set True for cosine similarity
)

加载数据

使用LangChain的LCEL文档作为输入数据

import matplotlib.pyplot as plt
import tiktoken
from bs4 import BeautifulSoup as Soup
from langchain_community.document_loaders.recursive_url_loader import RecursiveUrlLoader

# 用于统计每个文本中 Token 数量的辅助函数
def num_tokens_from_string(string: str, encoding_name: str) -> int:
    """返回文本字符串中的令牌数量"""
    encoding = tiktoken.get_encoding(encoding_name)
    num_tokens = len(encoding.encode(string))
    return num_tokens

# LCEL 文档
url = "https://python.langchain.com/docs/expression_language/"
loader = RecursiveUrlLoader(
    url=url, max_depth=20, extractor=lambda x: Soup(x, "html.parser").text
)
docs = loader.load()

# LCEL w/ PydanticOutputParser (主要 LCEL 文档之外)
url = "https://python.langchain.com/docs/modules/model_io/output_parsers/quick_start"
loader = RecursiveUrlLoader(
    url=url, max_depth=1, extractor=lambda x: Soup(x, "html.parser&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值