LLM之RAG理论(八)| 提高RAG性能的9种技术

34 篇文章 7 订阅

       2023年是迄今为止NLP发展最快的一年。这年,ChatGPT与许多其他大型语言模型层出不穷,包括开源的和闭源的。

​       与此同时,各个行业对个性化和全面运营的RAG的需求也在飙升,每个客户都渴望拥有自己的量身定制的解决方案。

本文将介绍9中提高RAG技术的方法:

1 — 🗃️ 提高索引数据的质量

       由于我们索引的数据决定了RAG答案的质量,因此在建立索引之前,需要对数据做很多预处理操作来保证数据质量非常关键。

下面是数据清洗的一些Tips:

  • 清除特殊字符、奇怪的编码、不必要的HTML标记来消除文本噪声(比如使用regex);
  • 找出与主要主题无关的文档异常值并将其删除(可以通过实现一些主题提取、降维技术和数据可视化来实现这一点);
  • 使用相似性度量删除冗余文档

2 — 🛠️ 优化索引结构

       在构建RAG时,块大小是一个关键参数,它决定了我们从矢量存储中检索的文档的长度。小的块大小可能会导致文档错过一些关键信息,而大的块大小则会引入不相关的噪声。

如何有效平衡块大小?

     可以通过在测试集上运行评估和计算度量来找到最佳块大小。LlamaIndex有一些有趣的功能可以做到这一点,可以参考[2]:

3 — 🏷️ 添加元数据

       将元数据与索引向量结合有助于提高搜索相关性。以下是元数据有用的一些场景:

  • 如果搜索项目并且以最近为标准,则可以对日期元数据进行排序;
  • 如果你搜索科学论文,并且事先知道你要寻找的信息总是位于特定的部分,比如实验部分,你可以将文章部分添加为每个区块的元数据,并对其进行过滤,以仅匹配实验。

4 — ↔️ 将输入查询与文档对齐

       LLM和RAG功能强大,因为它们提供了用自然语言表达查询的灵活性,从而降低了数据探索和更复杂任务的进入门槛。

       然而,有时,用户以几个单词或短句的形式制定的输入查询与索引文档之间会出现错位,索引文档通常以长句甚至段落的形式编写。

       让我们通过一个例子来理解这一点。

以下是一段关于发动机的内容(来源:ChatGPT)

The motor engine stands as an engineering marvel, propelling countless vehicles and machinery with its intricate design and mechanical prowess. At its core, a motor engine converts fuel into mechanical energy through a precisely orchestrated series 

of combustion events. This process involves the synchronized movement of pistons, a crankshaft, and a complex network of valves, all carefully calibrated to optimize efficiency and power output. Modern motor engines come in various types, such as internal combustion engines and electric motors, each with its

unique set of advantages and applications. The relentless pursuit of innovation continues to enhance motor engine technology, pushing the boundaries of performance, fuel efficiency, and environmental sustainability. Whether powering a car on the open road or driving industrial machinery, the motor engine 

remains a driving force behind the dynamic movement of our modern world.

       如果你提出一个简单的查询,比如“Can you tell how the motor engine works in a nutshell?”并计算其与段落的余弦相似性,你就会得到0.72的值。

       还不错,但我们能做得更好吗?

      要做到这一点,我们将不再通过嵌入来索引段落,而是通过嵌入它所回答的问题来索引段落。

让我们来考虑这段话所回答的三个问题。

  • What is the fundamental function of a motor engine?”,
  • How does a motor engine convert fuel into mechanical energy?”,
  • What are some key components involved in the operation of a motor engine, and how do they contribute to its efficiency?”

如果我们计算它们与输入查询的相似性,我们分别获得这些值。

0.864

0.841

0.845

这些值越高,表示输入查询与问题匹配得越精确。

       用他们回答的问题对块进行索引会稍微改变问题,但有助于解决对齐问题并提高搜索相关性:我们不优化与文档的相似性,而是优化与潜在问题的相似性。

5 — 🔍 混合检索

       虽然矢量搜索有助于检索给定查询的语义相关块,但它有时在匹配特定关键字方面缺乏准确性。

      想象一下,搜索数百万电子商务产品的矢量数据库,查询“Adidas ref XYZ sneakers white”,最热门的结果包括白色阿迪达斯运动鞋,但没有与确切的XYZ参考相匹配。

       这将是相当令人失望的。

       为了解决这个问题,混合检索是一种解决方案。该策略充分利用了矢量搜索和关键字搜索等不同检索技术的优势,并将它们智能地组合在一起。使用这种混合方法,您仍然可以匹配相关的关键字,同时保持对查询意图的控制。 混合搜索的案例,可以参考Pinecone的入门指南[3]

6 — 🔄 重新排序

       当您查询向量库时,前K个结果不一定以最相关的方式排序。假设它们都是相关的,但这些相关块中最相关的块可以是数字#5或#7,而不是#1或#2

       这就是ReRank的用武之地。重新排序已在各种框架中成功实现,包括LlamaIndex、LangChain和HayStack。

     例如,Diversity Ranker专注于基于文档多样性的重新排序,而LostInTheMiddleRanker则在上下文窗口的开头和结尾交替放置最佳文档。

7 — 🗜️ 提示压缩

       研究表明,检索到的上下文中的噪声会对RAG性能产生不利影响,更准确地说,是LLM生成的答案。可以在检索后应用后处理步骤来压缩不相关的上下文,突出显示重要段落,并减少整体上下文长度。

      Selective ContextLLMLingua使用小LLM来计算Prompt的互信息或困惑度,从而估计文本的重要性。

8 — 💡 HyDE

        当进行查询时,HyDE指示LLM生成一个假设答案。随后,无监督对比学习编码器(例如,Contriever)将文档转换为嵌入向量。

       该矢量用于精确定位语料库嵌入空间中的邻域,从而能够基于矢量相似性检索相似的真实文档。在第二步中,生成的文档被锚定到实际语料库,编码器的密集瓶颈有效地过滤掉了不正确的细节。

      实验表明,HyDE始终优于最先进的无监督密集检索器Contriever,并在各种任务(如网络搜索、QA和事实验证)和语言中表现出与微调检索器相当的稳健性能。

9 — ✒️ 查询重写和扩展

       当用户与RAG交互时,用户的查询格式不一定是很好的,也不能完全表达与向量库中的文档有效匹配的意图。

       为了解决这个问题,我们指示LLM在将该查询发送到RAG之前在后台重写该查询。这可以通过添加中间LLM调用来轻松实现,但也存在其他复杂的技术[4]。

参考文献:

[1] https://towardsdatascience.com/9-effective-techniques-to-boost-retrieval-augmented-generation-rag-systems-210ace375049

[2] https://blog.llamaindex.ai/evaluating-the-ideal-chunk-size-for-a-rag-system-using-llamaindex-6207e5d3fec5

[3] https://www.pinecone.io/learn/hybrid-search-intro/

[4] https://arxiv.org/abs/2305.03653

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
根据提供的引用内容,可以得知prompt+RAG的流程如下: 1. 首先,使用Retriever部分在知识库中检索出top-k个匹配的文档zi。 2. 然后,将query和k个文档拼接起来作为QA的prompt,送入seq2seq模型。 3. seq2seq模型生成回复y。 4. 如果需要进行Re-rank,可以使用LLM来rerank,给LLM写好prompt即可。 下面是一个简单的示例代码,演示如何使用prompt+RAG: ```python from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration # 初始化tokenizer、retriever和seq2seq模型 tokenizer = RagTokenizer.from_pretrained('facebook/rag-token-base') retriever = RagRetriever.from_pretrained('facebook/rag-token-base', index_name='exact', use_dummy_dataset=True) model = RagSequenceForGeneration.from_pretrained('facebook/rag-token-base') # 设置query和context query = "What is the capital of France?" context = "France is a country located in Western Europe. Paris, the capital city of France, is known for its romantic ambiance and iconic landmarks such as the Eiffel Tower." # 使用Retriever部分检索top-k个匹配的文档 retrieved_docs = retriever(query) # 将query和k个文档拼接起来作为QA的prompt input_dict = tokenizer.prepare_seq2seq_batch(query, retrieved_docs[:2], return_tensors='pt') generated = model.generate(input_ids=input_dict['input_ids'], attention_mask=input_dict['attention_mask']) # 输出生成的回复 generated_text = tokenizer.batch_decode(generated, skip_special_tokens=True)[0] print(generated_text) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wshzd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值