RAG实战4-RAG过程中发生了什么?

这篇具有很好参考价值的文章主要介绍了RAG实战4-RAG过程中发生了什么?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

RAG实战4-RAG过程中发生了什么?

在RAG实战3中我们介绍了如何追踪哪些文档片段被用于检索增强生成,但我们仍不知道RAG过程中到底发生了什么,为什么大模型能够根据检索出的文档片段进行回复?本文将用一个简单的例子来解释前面的问题。

在阅读本文之前,请先阅读RAG实战3。

回答:为什么大模型能够根据检索出的文档片段进行回复?

先执行以下代码:

import logging
import sys
import torch
from llama_index.core import PromptTemplate, Settings, StorageContext, load_index_from_storage
from llama_index.core.callbacks import LlamaDebugHandler, CallbackManager
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.huggingface import HuggingFaceLLM

# 定义日志
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))


# 定义system prompt
SYSTEM_PROMPT = """You are a helpful AI assistant."""
query_wrapper_prompt = PromptTemplate(
    "[INST]<<SYS>>\n" + SYSTEM_PROMPT + "<</SYS>>\n\n{query_str}[/INST] "
)

# 使用llama-index创建本地大模型
llm = HuggingFaceLLM(
    context_window=4096,
    max_new_tokens=2048,
    generate_kwargs={"temperature": 0.0, "do_sample": False},
    query_wrapper_prompt=query_wrapper_prompt,
    tokenizer_name='/yldm0226/models/Qwen1.5-14B-Chat',
    model_name='/yldm0226/models/Qwen1.5-14B-Chat',
    device_map="auto",
    model_kwargs={"torch_dtype": torch.float16},
)
Settings.llm = llm

# 使用LlamaDebugHandler构建事件回溯器,以追踪LlamaIndex执行过程中发生的事件
llama_debug = LlamaDebugHandler(print_trace_on_end=True)
callback_manager = CallbackManager([llama_debug])
Settings.callback_manager = callback_manager

# 使用llama-index-embeddings-huggingface构建本地embedding模型
Settings.embed_model = HuggingFaceEmbedding(
    model_name="/yldm0226/RAG/BAAI/bge-base-zh-v1.5"
)

# 从存储文件中读取embedding向量和向量索引
storage_context = StorageContext.from_defaults(persist_dir="doc_emb")
index = load_index_from_storage(storage_context)
# 构建查询引擎
query_engine = index.as_query_engine(similarity_top_k=5)

# 查询获得答案
response = query_engine.query("不耐疲劳,口燥、咽干可能是哪些证候?")
print(response)

# get_llm_inputs_outputs返回每个LLM调用的开始/结束事件
event_pairs = llama_debug.get_llm_inputs_outputs()
# print(event_pairs[0][1].payload.keys())
print(event_pairs[0][1].payload["formatted_prompt"])

输出很长,我们一部分一部分来看。

首先找到类似下面的输出:

**********
Trace: query
    |_query ->  14.458354 seconds
      |_retrieve ->  0.845918 seconds
        |_embedding ->  0.71383 seconds
      |_synthesize ->  13.612246 seconds
        |_templating ->  2e-05 seconds
        |_llm ->  13.60905 seconds
**********

以上的输出记录了我们的query在程序过程中经历的阶段和所用的时间。整个过程分为两个阶段:抽取(retrieve)和合成(synthesize)。

合成阶段的templating步骤会将我们的query和抽取出来的文档片段组合成模板,构成新的query,然后调用LLM,得到最终的response。

所以,我们只要找到templating所构建的新query,就可以知道为什么大模型能够根据我们检索出来的文档进行回复了。

在输出中找到response下面的部分:

[INST]<<SYS>>
You are a helpful AI assistant.<</SYS>>

Context information is below.
---------------------
file_path: document/中医临床诊疗术语证候.txt

4.6.1.1
    津液不足证  syndrome/pattern of fluid and humor insufficiency
    津亏证
    因津液生成不足,或嗜食辛辣,蕴热化燥,邪热灼损津液所致。临床以口眼喉鼻及皮肤等干燥,大便干结,小便短少,舌质偏红而干,脉细数等为特征的证候。

4.6.1.

file_path: document/中医临床诊疗术语证候.txt

临床以口干、舌燥,频饮而不解其渴,食多、善饥,夜尿频多,逐渐消瘦,舌质红,舌苔薄黄或少,脉弦细或滑数,伴见皮肤干燥,四肢乏力,大便干结等为特征的证候。

4.6.3.2
    津亏热结证  syndrome/pattern of fluid depletion and heat binding
    液干热结证
    因津液亏虚,热邪内结所致。

file_path: document/中医临床诊疗术语证候.txt

临床以口眼喉鼻及皮肤等干燥,大便干结,小便短少,舌质偏红而干,脉细数等为特征的证候。

4.6.1.2
    津液亏涸证  syndrome/pattern of fluid and humor scantiness
    津液亏耗证
    津液干枯证
    因津液亏损,形体官窍失养所致。临床以口干、唇裂,鼻燥无涕,皮肤干瘪,目陷、螺瘪,甚则肌肤甲错,舌质红而少津,舌中裂,脉细或数,可伴见口渴、欲饮,干咳,目涩,大便干,小便少等为特征的证候。

file_path: document/中医临床诊疗术语证候.txt

临床以鼻咽干涩或痛,口唇燥干,舌质红,舌苔白或燥,脉浮或微数,伴见发热、无汗,头痛或肢节酸痛等为特征的证候。

3.6.3.2
    燥干清窍证  syndrome/pattern of dryness harassing the upper orifices
    因气候或环境干燥,津液耗损,清窍失濡所致。临床以口鼻、咽喉干燥,两眼干涩,少泪、少涕、少津、甚则衄血,舌质瘦小、舌苔干而少津,脉细等为特征的证候。

file_path: document/中医临床诊疗术语证候.txt

6.3.1
    津伤化燥证  syndrome/pattern of fluid damage transforming into dryness
    津伤燥热证
    因燥热内蕴,或内热化燥,伤津耗液所致。临床以口干、舌燥,频饮而不解其渴,食多、善饥,夜尿频多,逐渐消瘦,舌质红,舌苔薄黄或少,脉弦细或滑数,伴见皮肤干燥,四肢乏力,大便干结等为特征的证候。

4.6.3.
---------------------
Given the context information and not prior knowledge, answer the query.
Query: 不耐疲劳,口燥、咽干可能是哪些证候?
Answer: [/INST] 

上面这段很长的文本是由print(event_pairs[0][1].payload["formatted_prompt"])语句输出的,这段文本就是templating后的新query。

现在,我们就能回答为什么大模型能够根据检索出的文档片段进行回复这个问题了:我们的原始query由"不耐疲劳,口燥、咽干可能是哪些证候?"变成了上面这段很长的新query,由于我们给大模型提供了一些文档片段知识,并且要求大模型根据提供的先验知识回答我们的原始query,因此大模型能够根据检索出的文档片段进行回复。(这其实也就是RAG技术的本质了)

可以发现一个问题,新query中既有中文,也有英文,这是因为LlamaIndex是外国人做的,他们构建的模板都是英文的。LlamaIndex允许自定义查询流程,构建自己的中文模板,这里中英文混合也解决了我们的问题,因此不再赘述。

此外,event_pairs中其实还有很多对我们有用的信息,你可以通过输出或DEBUG的方式来寻找能够解决你自己问题的信息。比如,我注释掉的#print(event_pairs[0][1].payload.keys())就可以输出事件结束时所有相关的属性。

下面是模型的回复:

从提供的中医临床证候信息来看,口燥、咽干的症状可能与以下证候相关:

1. 津液不足证:由于津液生成不足或者体内燥热导致,表现为口眼喉鼻干燥,咽干是其中的一个症状。

2. 津亏热结证:津液亏虚加上热邪内结,也可能出现口燥和咽干。

3. 津液亏涸证:严重的津液亏损可能导致口唇干燥、咽部干燥,伴随其他严重脱水症状。

4. 燥干清窍证:气候干燥或体质原因引起的津液缺乏,口鼻咽喉干燥也是其特征。

5. 津伤化燥证:燥热内蕴或内热化燥损伤津液,也会出现口燥、频饮但不解渴的现象。

因此,这些证候都有可能与不耐疲劳和口燥、咽干的症状相符合,需要结合其他临床表现来确定具体的证候类型。建议在中医诊断中由专业医生根据全人情况判断。

进阶尝试

接下来,我们尝试跟踪一下更复杂的RAG过程。

前面我们提到了抽取(retrieve)和合成(synthesize)两个阶段。

抽取(retrieve)阶段的retrievers模块规定了针对查询从知识库获取相关上下文的技术。我们之前使用的都是默认的方法,其实LlamaIndex官方为我们提供了一些其他常用的方法:

  • SimilarityPostprocessor: 使用similarity_cutoff设置阈值。移除低于某个相似度分数的节点。
  • KeywordNodePostprocessor: 使用required_keywords和exclude_keywords。根据关键字包含或排除过滤节点。
  • MetadataReplacementPostProcessor: 用其元数据中的数据替换节点内容。
  • LongContextReorder: 重新排序节点,这有利于需要大量顶级结果的情况,可以解决模型在扩展上下文中的困难。
  • SentenceEmbeddingOptimizer: 选择percentile_cutoff或threshold_cutoff作为相关性。基于嵌入删除不相关的句子。
  • CohereRerank: 使用coherence ReRank对节点重新排序,返回前N个结果。
  • SentenceTransformerRerank: 使用SentenceTransformer交叉编码器对节点重新排序,产生前N个节点。
  • LLMRerank: 使用LLM对节点重新排序,为每个节点提供相关性评分。
  • FixedRecencyPostprocessor: 返回按日期排序的节点。
  • EmbeddingRecencyPostprocessor: 按日期对节点进行排序,但也会根据嵌入相似度删除较旧的相似节点。
  • TimeWeightedPostprocessor: 对节点重新排序,偏向于最近未返回的信息。
  • PIINodePostprocessor(β): 可以利用本地LLM或NER模型删除个人身份信息。
  • PrevNextNodePostprocessor(β): 根据节点关系,按顺序检索在节点之前、之后或两者同时出现的节点。

合成(synthesize)阶段的响应合成器(response synthesizer)会引导LLM生成响应,将用户查询与检索到的文本块混合在一起。

假设有一堆文档。现在,你问了一个问题,并希望根据这些文档得到答案。响应合成器就像人一样,浏览文档,找到相关信息,并生成回复。

retrievers负责提取出相关的文本片段,我们已经讨论过了。而响应合成器负责将这些片段收集起来,并给出一个精心设计的答案。

LlamaIndex官方为我们提供了多种响应合成器:

  • Refine: 这种方法遍历每一段文本,一点一点地精炼答案。
  • Compact: 是Refine的精简版。它将文本集中在一起,因此需要处理的步骤更少。
  • Tree Summarize: 想象一下,把许多小的答案结合起来,再总结,直到你得到一个主要的答案。
  • Simple Summarize: 只是把文本片段剪短,然后给出一个快速的总结。
  • No Text: 这个问题不会给你答案,但会告诉你它会使用哪些文本。
  • Accumulate: 为每一篇文章找一堆小答案,然后把它们粘在一起。
  • Compact Accumulate: 是“Compact”和“Accumulate”的合成词。

此外,retriever和response synthesizer都支持自定义,在此不作讨论。

现在,让我们选择一种retriever和一种response synthesizer。retriever选择SimilarityPostprocessor,response synthesizer选择Refine

代码如下所示:

import logging
import sys
import torch
from llama_index.core import PromptTemplate, Settings, SimpleDirectoryReader, \
    VectorStoreIndex, get_response_synthesizer
from llama_index.core.callbacks import LlamaDebugHandler, CallbackManager
from llama_index.core.indices.vector_store import VectorIndexRetriever
from llama_index.core.postprocessor import SimilarityPostprocessor
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.response_synthesizers import ResponseMode
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.huggingface import HuggingFaceLLM

# 定义日志
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

# 定义system prompt
SYSTEM_PROMPT = """You are a helpful AI assistant."""
query_wrapper_prompt = PromptTemplate(
    "[INST]<<SYS>>\n" + SYSTEM_PROMPT + "<</SYS>>\n\n{query_str}[/INST] "
)

# 使用llama-index创建本地大模型
llm = HuggingFaceLLM(
    context_window=4096,
    max_new_tokens=2048,
    generate_kwargs={"temperature": 0.0, "do_sample": False},
    query_wrapper_prompt=query_wrapper_prompt,
    tokenizer_name='/yldm0226/models/Qwen1.5-14B-Chat',
    model_name='/yldm0226/models/Qwen1.5-14B-Chat',
    device_map="auto",
    model_kwargs={"torch_dtype": torch.float16},
)
Settings.llm = llm

# 使用LlamaDebugHandler构建事件回溯器,以追踪LlamaIndex执行过程中发生的事件
llama_debug = LlamaDebugHandler(print_trace_on_end=True)
callback_manager = CallbackManager([llama_debug])
Settings.callback_manager = callback_manager

# 使用llama-index-embeddings-huggingface构建本地embedding模型
Settings.embed_model = HuggingFaceEmbedding(
    model_name="/yldm0226/RAG/BAAI/bge-base-zh-v1.5"
)

# 读取文档并构建索引
documents = SimpleDirectoryReader("document").load_data()
index = VectorStoreIndex.from_documents(documents)

# 构建retriever
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=5,
)

# 构建response synthesizer
response_synthesizer = get_response_synthesizer(
    response_mode=ResponseMode.REFINE
)

# 构建查询引擎
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=response_synthesizer,
    node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.6)],
)

# 查询获得答案
response = query_engine.query("不耐疲劳,口燥、咽干可能是哪些证候?")
print(response)

# get_llm_inputs_outputs返回每个LLM调用的开始/结束事件
event_pairs = llama_debug.get_llm_inputs_outputs()
print(event_pairs[0][1].payload["formatted_prompt"])

运行代码后,在输出中可以找到类似下面的内容:

**********
Trace: query
    |_query ->  33.425664 seconds
      |_synthesize ->  33.403238 seconds
        |_templating ->  2e-05 seconds
        |_llm ->  7.425154 seconds
        |_templating ->  2.5e-05 seconds
        |_llm ->  4.763223 seconds
        |_templating ->  2.4e-05 seconds
        |_llm ->  6.601226 seconds
        |_templating ->  2.2e-05 seconds
        |_llm ->  6.878335 seconds
        |_templating ->  2.2e-05 seconds
        |_llm ->  7.726241 seconds
**********

可以看出,我们将response synthesizer由默认的Compact替换为Refine之后,query在程序过程中经历的阶段发生了变化,REFINE模式会进行更多次的templating和LLM调用。

构建的新Query如下所示,这与之前是一样的:

[INST]<<SYS>>
You are a helpful AI assistant.<</SYS>>

Context information is below.
---------------------
file_path: document/中医临床诊疗术语证候.txt

临床以干咳、痰少,或痰中带血,口渴,鼻咽燥痛,声音嘶哑,肌肤枯燥,舌质红而干,舌苔少,脉虚数,伴见低热,神疲、乏力,语声低微,盗汗,大便干结等为特征的证候。

5.4.1.5.1.1
    肺燥津伤证  syndrome/pattern of lung dryness with fluid damage
    肺燥津亏证
    因燥邪袭肺,津液亏虚,肺燥失润所致。临床以干咳、少痰,咽干,口燥,鼻燥,喉痒,舌质红,舌苔少津,脉浮细数等为特征的证候。

5.4.1.5.1.2
    肺燥伤阴证  syndrome/pattern of lung dryness damaging yin
    因肺热化燥,伤及阴津所致。临床以咳嗽,痰少或无,痰黄而黏,口干、咽燥,烦渴、多饮,小便短少,舌质红,舌苔焦黄,脉弦数,可伴见潮热、颧红等为特征的证候。

5.4.1.5.1.3
    肺燥阴虚证  syndrome/pattern of lung dryness with yin deficiency
    阴虚肺燥证
    因阴液亏虚,肺燥失润所致。临床以午后潮热,干咳、痰少,喉痒、鼻燥、少涕,咽干、烦渴,消瘦,舌质红,舌苔少,脉细数,伴见盗汗浸衣,心烦、失眠等为特征的证候。

5.4.1.5.2
    肺燥郁热证  syndrome/pattern of lung dryness with stagnated heat
    肺燥化热证
    因忧劳伤肺,郁热化燥,伤及肺津所致。临床以发热、烦渴,咳嗽、痰少而黏,胸胁灼痛,大便干结,小便短少,舌质红而干,舌苔薄黄,脉弦数等为特征的证候。

5.4.1.6
    肺经证  syndrome/pattern of lung meridian (vessel)
    泛指因各种原因致使肺经循行部位异常所引起的一类证候。

5.4.1.6.1
    肺经风热证  syndrome/pattern of wind and heat in the lung meridian
    因风热邪客肺经,或风热郁滞肤腠,外发于头面所致。
---------------------
Given the context information and not prior knowledge, answer the query.
Query: 不耐疲劳,口燥、咽干可能是哪些证候?
Answer: [/INST] 

另外,由于我们使用了SimilarityPostprocessor的retriever,并将相似度阈值设置为0.6,因此检索出的相似度小于0.6的文档片段会被摘除。

最后,我们看一下模型的回复:

从中医角度看,不耐疲劳、口燥、咽干的症状可能涉及多个证候,如燥邪犯肺证(4.6.3.3),由于燥气耗伤肺津;津亏热结证(4.6.3.2)或津枯肠结证(4.6.3.3),表现为体内津液亏损且伴有热象,导致口干、便秘等;肺胃阴虚证(5.6.4.4.2.2)和心肾阴虚(5.1.1.1.1),特别是心肾不交时,也会出现类似症状。此外,心系证中的心寒证(5.1.1.1)如心中寒证也可能表现出口干咽燥。具体诊断需根据临床表现、体质和相关检查结果来确定。

从上面的案例可以看出,我们可以自由组合不同的retriever和response synthesizer,以完成我们的需求。当LlamaIndex提供的

retriever和response synthesizer不能满足我们的需求的时候,我们还可以自定义retriever和response synthesizer,有兴趣的读者可以自行探索。文章来源地址https://www.toymoban.com/news/detail-837699.html

到了这里,关于RAG实战4-RAG过程中发生了什么?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RAG实战 7 - 使用llama_index实现多模态RAG

    转载自:LLM之RAG实战(七)| 使用llama_index实现多模态RAG https://mp.weixin.qq.com/s/FVF09cEO5nUipcL9R8ydXQ OpenAI开发日上最令人兴奋的发布之一是GPT-4V API(https://platform.openai.com/docs/guides/vision)的发布。GPT-4V是一个多模态模型,可以接收文本/图像,并可以输出文本响应。最近还有一些其他

    2024年01月17日
    浏览(36)
  • 什么是RAG技术

    RAG(Retrieval-Augmented Generation)技术是一种结合检索和生成功能的自然语言处理(NLP)技术。它通过从大型外部数据库中检索与输入问题相关的信息,来辅助生成模型回答问题。RAG技术的核心思想是将传统的检索技术与现代的自然语言生成技术相结合,以提高文本生成的准确性

    2024年04月27日
    浏览(29)
  • RAG实战5-自定义prompt

    在阅读本文之前,先阅读RAG实战4。在RAG实战4中我们分析了LlamaIndex中RAG的执行过程,同时留下了一个尚待解决的问题:LlamaIndex中提供的prompt template都是英文的,该如何使用中文的prompt template呢? 直接看以下代码: 先看 print(list(prompts_dict.keys())) 这行代码的输出: 这表明我们使

    2024年03月11日
    浏览(37)
  • Elasticsearch:什么是检索增强生成 - RAG?

    在人工智能的动态格局中,检索增强生成(Retrieval Augmented Generation - RAG)已经成为游戏规则的改变者,彻底改变了我们生成文本和与文本交互的方式。 RAG 使用大型语言模型 (LLMs) 等工具将信息检索的能力与自然语言生成无缝结合起来,为内容创建提供了一种变革性的方法。

    2024年02月08日
    浏览(38)
  • Elasticsearch:什么是检索增强生成 (RAG)?

    检索增强生成 (RAG) 是一种利用来自私有或专有数据源的信息来补充文本生成的技术。 它将旨在搜索大型数据集或知识库的检索模型与大型语言模型 (LLM) 等生成模型相结合,后者获取该信息并生成可读的文本响应。 检索增强生成可以通过添加来自其他数据源的上下文并通过培

    2024年02月04日
    浏览(41)
  • LLM之RAG实战(十六)| 使用Llama-2、PgVector和LlamaIndex构建LLM Rag Pipeline

           近年来,大型语言模型(LLM)取得了显著的进步,然而大模型缺点之一是幻觉问题,即“一本正经的胡说八道”。其中RAG(Retrieval Augmented Generation,检索增强生成)是解决幻觉比较有效的方法。本文,我们将深入研究使用 transformer库 、 Llama-2模型 、 PgVector数据库 和

    2024年01月21日
    浏览(46)
  • LLM之RAG实战(八)| 使用Neo4j和LlamaIndex实现多模态RAG

           人工智能和大型语言模型领域正在迅速发展。一年前,没有人使用LLM来提高生产力。时至今日,很难想象我们大多数人或多或少都在使用LLM提供服务,从个人助手到文生图场景。由于大量的研究和兴趣,LLM每天都在变得越来越好、越来越聪明。不仅如此,他们的理解

    2024年02月02日
    浏览(47)
  • 如何看待测试过程中的漏测发生

    漏测,相信对于每个测试同学而言,都是“谈虎变色”的事,但是实际工作中,我们稍有不谨慎便会和它来一次“亲密接触”。那么,现在我们一起来聊聊测试中的漏测。 一方面,会让他人对你的技术、业务能力产生怀疑,而且发生多次后,甚至会质疑你存在的价值; 另一

    2024年02月12日
    浏览(36)
  • RAG实战2-如何使用LlamaIndex存储和读取向量

    本文是检索增强生成(Retrieval-augmented Generation,RAG)实战1-基于LlamaIndex构建第一个RAG应用的续集,在阅读本文之前请先阅读前篇。 在前篇中,我们介绍了如何使用LlamaIndex构建一个非常简单的RAG应用,初步了解了LlamaIndex构建RAG应用的大体流程。在运行前篇的程序时,我们会发现两

    2024年03月09日
    浏览(51)
  • TS版LangChain实战:基于文档的增强检索(RAG)

    LangChain是一个以 LLM (大语言模型)模型为核心的开发框架,LangChain的主要特性: 可以连接多种数据源,比如网页链接、本地PDF文件、向量数据库等 允许语言模型与其环境交互 封装了Model I/O(输入/输出)、Retrieval(检索器)、Memory(记忆)、Agents(决策和调度)等核心组件

    2024年02月05日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包