RAG系统检索的文档可能并不总是与用户的查询保持一致,这是一个常见的现象。当文档可能缺乏查询的完整答案或者包含冗余信息或包含不相关的细节,或者文档的顺序可能与用户的意图不一致时,就会经常出现这种情况。

本文将探讨三种有效的技术来增强基于rag的应用程序中的文档检索,通过结合这些技术,可以检索与用户查询密切匹配的更相关的文档,从而生成更好的答案。

查询扩展

查询扩展指的是一组重新表述原始查询的技术。

本文将讨论两种易于实现的流行方法。

1、使用生成的答案扩展查询

给定一个输入查询,首先让LLM提供一个假设答案(不管其正确性),然后将查询和生成的答案组合在一个提示中并发送给检索系统。

这种技术效果非常的好。这篇论文有详细的介绍:https://arxiv.org/abs/2212.10496

这个方法的思想是,我们希望检索看起来更像答案的文档,我们感兴趣的是它的结构和表述。所以可以将假设的答案视为帮助识别嵌入空间中相关邻域的模板。

下面是一个示例提示:

 You are a helpful expert financial research assistant.
 
 Provide an example answer to the given question, that might 
 be found in a document like an annual report.

2、通过包含多个相关问题扩展查询

第二种方法指示LLM生成与原始查询相关的N个问题,然后将它们(+原始查询)全部发送到检索系统。

这样可以从vectorstore中检索更多文档。但是其中一些将是重复的,所以需要执行后处理来删除它们。

这个方法的思想是扩展可能不完整或不明确的初始查询,合并成最终可能相关和互补最终结果。

下面是用来生成相关问题的提示:

 You are a helpful expert financial research assistant. 
 Your users are asking questions about an annual report.
 Suggest up to five additional related questions to help them 
 find the information they need, for the provided question.
 Suggest only short questions without compound sentences. 
 Suggest a variety of questions that cover different aspects of the topic.
 Make sure they are complete questions, and that they are related to 
 the original question.
 Output one question per line. Do not number the questions.

这种方法的缺点是最终会得到更多的文档,而这些文档可能会分散LLM的注意力,使其无法生成有用的答案。

所以就衍生出一个新的方法,重排序

重排序

该方法根据量化其与输入查询的相关性的分数对检索到的文档重新排序。

使用cross-encoder进行重新排序:

交叉编码器cross-encoder是一种深度神经网络,它将两个输入序列作为单个输入处理。允许模型直接比较和对比输入,以更综合和细致的方式理解它们的关系。

给定一个查询,用所有检索到的文档对其进行编码。然后按降序排序。得分高的认为是最相关的文件。

下面有一个简单的示例:

首先安装sentence-transformers

 pip install -U sentence-transformers

使用它加载cross-encoder模型:

 from sentence_transformers import CrossEncoder 
 cross_encoder = CrossEncoder("cross-encoder/ms-marco-MiniLM-L-6-v2")

这里我们选择ms-marco-MiniLM-L-6-v2,对于排序的性能度量可以参考SBERT选择更好的模型。

每对(查询,文档)打分:

 pairs = [[query, doc] for doc in retrieved_documents] 
 scores = cross_encoder.predict(pairs) 
 
 print("Scores:") for score in scores:     
 print(score)  
 
 # Scores: 
 # 0.98693466 
 # 2.644579 
 # -0.26802942 
 # -10.73159 
 # -7.7066045 
 # -5.6469955 
 # -4.297035 
 # -10.933233 
 # -7.0384283 
 # -7.3246956

重新整理文件:

 print("New Ordering:") 
 for o in np.argsort(scores)[::-1]:
     print(o+1)

重排序可以与查询扩展一起使用,在生成多个相关问题并检索相应文档(假设最终有M个文档)之后,对它们重新排序并选择最前面的K (K < M)。这样可以选择最重要的部分并且减小上下文的大小。

嵌入的适配器

这个方法利用用户检索文档相关性的反馈来训练一个新的适配器。

适配器是完全微调预训练模型的轻量级替代方案。一盘情况下适配器会插入到预训练模型层之间的小型前馈神经网络中,所以训练适配器的目标是更改嵌入查询,以便为特定任务生成更好的检索结果。

嵌入适配器是一个可以在嵌入阶段之后和检索之前插入的阶段。把它想象成一个对原始嵌入进行缩放的矩阵。

要训练适配器,需要执行以下步骤。

1、准备数据

这些数据可以手工标记或由LLM生成。数据必须包括元组(query, document)及其相应的标签(如果文档与查询相关,则为1,否则为-1)。

为了演示,我们将创建一个合成数据集,首先生成金融分析师在分析财务报告时可能会问的示例问题。

让我们使用LLM直接生成:

 import os
 import openai
 from openai import OpenAI
 
 from dotenv import load_dotenv, find_dotenv
 _ = load_dotenv(find_dotenv())
 openai.api_key = os.environ['OPENAI_API_KEY']
 
 PROMPT_DATASET = """
 You are a helpful expert financial research assistant. 
 You help users analyze financial statements to better understand companies.
 Suggest 10 to 15 short questions that are important to ask when analyzing 
 an annual report.
 Do not output any compound questions (questions with multiple sentences 
 or conjunctions).
 Output each question on a separate line divided by a newline.
 """
 
 def generate_queries(model="gpt-3.5-turbo"):
     messages = [
         {
             "role": "system",
             "content": PROMPT_DATASET,
         },
     ]
 
     response = openai_client.chat.completions.create(
         model=model,
         messages=messages,
     )
     content = response.choices[0].message.content
     content = content.split("\n")
     return content
 
 
 generated_queries = generate_queries()
 for query in generated_queries:
     print(query)
 
 # 1. What is the company's revenue growth rate over the past three years?
 # 2. What are the company's total assets and total liabilities?
 # 3. How much debt does the company have? Is it increasing or decreasing?
 # 4. What is the company's profit margin? Is it improving or declining?
 # 5. What are the company's cash flow from operations, investing, and financing activities?
 # 6. What are the company's major sources of revenue?
 # 7. Does the company have any pending litigation or legal issues?
 # 8. What is the company's market share compared to its competitors?
 # 9. How much cash does the company have on hand?
 # 10. Are there any major changes in the company's executive team or board of directors?
 # 11. What is the company's dividend history and policy?
 # 12. Are there any related party transactions?
 # 13. What are the company's major risks and uncertainties?
 # 14. What is the company's current ratio and quick ratio?
 # 15. How has the company's stock price performed over the past year?

然后,我们对每个生成的问题进行文档检索,得到了一个结果的合集

 results = chroma_collection.query(query_texts=generated_queries, n_results=10, include=['documents', 'embeddings'])
 retrieved_documents = results['documents']

然后需要评估每个问题与其相应文件的相关性。这里也使用LLM来完成这项任务:

 PROMPT_EVALUATION = """
 You are a helpful expert financial research assistant. 
 You help users analyze financial statements to better understand companies.
 For the given query, evaluate whether the following satement is relevant.
 Output only 'yes' or 'no'.
 """
 
 def evaluate_results(query, statement, model="gpt-3.5-turbo"):
     messages = [
     {
         "role": "system",
         "content": PROMPT_EVALUATION,
     },
     {
         "role": "user",
         "content": f"Query: {query}, Statement: {statement}"
     }
     ]
 
     response = openai_client.chat.completions.create(
         model=model,
         messages=messages,
         max_tokens=1
     )
     content = response.choices[0].message.content
     if content == "yes":
         return 1
     return -1

现在就得到了我们的训练数据:每个元组将包含查询的嵌入、文档的嵌入和标签(1,-1)。

 retrieved_embeddings = results['embeddings']
 query_embeddings = embedding_function(generated_queries)
 
 adapter_query_embeddings = []
 adapter_doc_embeddings = []
 adapter_labels = []
 
 for q, query in enumerate(tqdm(generated_queries)):
     for d, document in enumerate(retrieved_documents[q]):
         adapter_query_embeddings.append(query_embeddings[q])
         adapter_doc_embeddings.append(retrieved_embeddings[q][d])
         adapter_labels.append(evaluate_results(query, document))

然后将它们放在Torch Dataset中作为训练集

 adapter_query_embeddings = torch.Tensor(np.array(adapter_query_embeddings))
 adapter_doc_embeddings = torch.Tensor(np.array(adapter_doc_embeddings))
 adapter_labels = torch.Tensor(np.expand_dims(np.array(adapter_labels),1))
 dataset = torch.utils.data.TensorDataset(adapter_query_embeddings, adapter_doc_embeddings, adapter_labels)

2、定义模型

我们定义了一个函数,它将查询嵌入、文档嵌入和适配器矩阵作为输入。该函数首先将查询嵌入与适配器矩阵相乘,并计算该结果与文档嵌入之间的余弦相似度。

 def model(query_embedding, document_embedding, adaptor_matrix):
     updated_query_embedding = torch.matmul(adaptor_matrix, query_embedding)
     return torch.cosine_similarity(updated_query_embedding, document_embedding, dim=0)

3、损失

我们的目标是最小化由前一个函数计算的余弦相似度。所以可以直接使用均方误差(MSE)

 def mse_loss(query_embedding, document_embedding, adaptor_matrix, label):
     return torch.nn.MSELoss()(model(query_embedding, document_embedding, adaptor_matrix), label)

4、训练过程

初始化适配器矩阵并训练它超过100次。

 # Initialize the adaptor matrix
 mat_size = len(adapter_query_embeddings[0])
 adapter_matrix = torch.randn(mat_size, mat_size, requires_grad=True)
 
 min_loss = float('inf')
 best_matrix = None
 for epoch in tqdm(range(100)):
     for query_embedding, document_embedding, label in dataset:
         loss = mse_loss(query_embedding, document_embedding, adapter_matrix, label)
         if loss < min_loss:
             min_loss = loss
             best_matrix = adapter_matrix.clone().detach().numpy()
         loss.backward()
         with torch.no_grad():
             adapter_matrix -= 0.01 * adapter_matrix.grad
             adapter_matrix.grad.zero_()

训练完成后,适配器可用于扩展原始嵌入并适应用户任务。

我们需要做的就是将原始的嵌入输出与适配器矩阵相乘,然后再将其输入到检索系统。

 test_vector = torch.ones((mat_size,1))
 scaled_vector = np.matmul(best_matrix, test_vector).numpy()
 
 test_vector.shape
 # torch.Size([384, 1])
 
 scaled_vector.shape
 # (384, 1)
 
 best_matrix.shape
 # (384, 384)

这样,我们检索系统后续使用的嵌入向量就是经过我们微调后的向量了,这相当于针对特定的任务进行优化

总结

我们介绍的这些检索技术有助于提高文档的相关性。但是这方面的研究还正在进行,还有很多其他方法例如,

利用真实反馈数据对嵌入模型进行微调;直接微调LLM以使其检索能力最大化(RA-DIT);探索更复杂的嵌入适配器使用深度神经网络而不是矩阵;深度和智能分块技术

这些技术我们也会在后面进行整理和介绍,感谢阅读。

https://avoid.overfit.cn/post/2f2d747462c44425be906b7c5611fe37

作者:Ahmed Besbes

相关文章

一张图读懂人工智能

三、人工智能和多式联运 AI产品的发展趋势,以及语言模型的应急能力和广泛应用。视频探讨了人工智能和人类的优劣势,以及未来的发展方向。视频提出了一种积极的心态,认为人工智能可以成为我们的同事,帮助我们提高效率和能力。二、大型语言模型的训练过程和应用场景,包括文本到文本、图像到文本、语音转录等多个方面。同时也提到了不同模型的能力和成本。一、生成人工智能的概念和应用,以及如何使用大型语言模型进行聊天和创造原创内容。五、如何使用生成人工智能作为招聘公司的工具,以及如何有效地使用生成人工智能来制作有用结果的提示。

基于YOLOv8深度学习+Pyqt5的电动车头盔佩戴检测系统

该系统利用深度学习技术,通过训练YOLOv8模型来识别电动车骑行者是否佩戴头盔,并在检测到未佩戴头盔的情况下发出警报。因此,开发一种能够实时监测头盔佩戴情况的系统,对于提高骑行者的安全意识和减少交通事故具有重要作用。本文提出的基于YOLOv8的电动车头盔佩戴检测系统,能够有效地提高电动车骑行者的安全意识。YOLOv8是YOLO系列目标检测模型的最新版本,它在前代模型的基础上进行了优化,提高了检测速度和准确性。在不同的场景和光照条件下,模型均能稳定地识别出佩戴和未佩戴头盔的骑行者。wx供重浩:创享日记。

chatgpt的大致技术原理

在RLHF中,人类用户对模型生成的文本提供反馈(如打分或选择更喜欢的文本),然后模型根据这些反馈进行进一步的训练。预处理步骤包括分词(使用BPE算法将文本分解为更小的子单元,如单词或符号)、去除停用词(即那些对文本意义不大的词,如“的”、“了”等)以及其他可能的文本清洗工作。生成过程中,模型会考虑前文的上下文信息,以确保生成的文本是连贯和有意义的。通过收集大量的文本数据、建立深度学习模型、进行预训练和微调以及使用搜索算法和人类反馈强化学习等技术,ChatGPT能够生成高质量、连贯且有用的文本回复。

云计算与边缘计算:有什么区别?

云计算和边缘计算作为不同的计算范式,各自在特定场景中发挥着独特的作用。它们的区别体现在数据处理位置、延迟、可用性以及应用场景等方面。然而,随着数字化时代的发展,它们也逐渐形成了协同应用的趋势,充分发挥各自的优势,提供更灵活、高效的计算体系结构。未来,随着智能化、自动化和边缘计算的边界拓展,云计算和边缘计算将进一步推动数字化转型。同时,安全性、跨边缘计算标准和环境可持续性等问题也需要在未来的发展中得到更好的解决。

ChatGPT高效提问—prompt基础

​ 设计一个好的prompt对于获取理想的生成结果至关重要。通过选择合适的关键词、提供明确的上下文、设置特定的约束条件,可以引导模型生成符合预期的回复。例如,在对话中,可以使用明确的问题或陈述引导模型生成相关、具体的回答;在摘要生成中,可以提供需要摘要的文章段落作为prompt,以确保生成的摘要准确而精炼。

二维平面阵列波束赋形原理和Matlab仿真

阵面左下角天线位于坐标原点,将坐标原点阵元设为参考阵元,计算每个阵元相对于该参考阵元的入射波程差,从而来计算每个阵元接收的回波信号。实现波束赋形的最基本的方法是对各个天线阵元的信号进行适当延迟后相加,使目标方向的信号同相叠加得到增强,而其他方向均有不同程度的削弱,该方法通常用于模拟信号.根据上述理论推导可以仿真任意平面阵列的方向图,这里对两种典型的阵列(矩形平面阵列和圆形阵列)进行Matlab仿真,其余类型的阵列在此基础上修改即可。根据上述圆形阵列公式做仿真,得到下述的三维空间方向图。

人工智能与机器学习——开启智能时代的里程碑

人工智能是指使计算机系统表现出类似于人类智能的能力。其目标是实现机器具备感知、理解、学习、推理和决策等智能行为。人工智能的发展可以追溯到上世纪50年代,随着计算机技术和算法的不断进步,人工智能得以实现。机器学习是人工智能的一个重要分支,它通过让计算机从数据中学习和改进性能,而不需要明确的编程指令。机器学习可以分为监督学习、无监督学习和强化学习三种主要类型。

【GPU】深入理解GPU硬件架构及运行机制

GPU的基本底层构成,主要是以GPU计算核心 Cores,以及Memory以及控制单元,三大组成要素组成。Core是计算的基本单元,既可以用作简单的浮点运算,又可以做一些复杂的运算例如,tensor 或者ray tracing。多个core之间通讯的方式:在特定的应用场合多个core之间是不需要的通讯的,也就是各干各的(例如 图像缩放)。但是也有一些例子,多个core之间要相互通讯配合(例如上文谈到的数组求和问题),每个core之间都可以实现交互数据是非常昂贵的,

大数据深度学习卷积神经网络CNN:CNN结构、训练与优化一文全解

卷积神经网络是一种前馈神经网络,它的人工神经元可以响应周围单元的局部区域,从而能够识别视觉空间的部分结构特征。卷积层: 通过卷积操作检测图像的局部特征。激活函数: 引入非线性,增加模型的表达能力。池化层: 减少特征维度,增加模型的鲁棒性。全连接层: 在处理空间特征后,全连接层用于进行分类或回归。卷积神经网络的这些组件协同工作,使得CNN能够从原始像素中自动学习有意义的特征层次结构。随着深度增加,这些特征从基本形状和纹理逐渐抽象为复杂的对象和场景表现。

从虚拟到现实:数字孪生驱动智慧城市可持续发展

同时,我们也需要不断探索和创新数字孪生技术的应用场景和发展方向,为智慧城市的可持续发展提供更加全面和深入的支持。“方案365”2023年全新整理智慧城市、数字孪生、乡村振兴、智慧乡村、元宇宙、数据中台、智慧园区、智慧社区、智慧矿山、城市生命线、智慧水利、智慧应急、智慧校园、智慧工地、智慧农业、智慧文旅、智慧交通等300+行业全套解决方案。通过智能电表和能源管理系统,数字孪生技术可以实现对家庭、企业等各个层面的能源使用情况进行监测和优化,提高能源利用效率,推动城市的绿色发展。

如何使用人工智能优化 DevOps?

DevOps 和人工智能密不可分,影响着各种业务。DevOps 可以加快产品开发速度并简化现有部署的维护,而 AI 则可以改变整个系统的功能。DevOps团队可以依靠人工智能和机器学习来进行数据集成、测试、评估和发布系统。更重要的是,人工智能和机器学习可以以高效、快速、安全的方式改进 DevOps 驱动的流程。从开发人员实用性和业务支持的角度来看, 评估AI和ML在 DevOps 中的重要性对于企业来说是有益的。

人工智能有哪些领域?

像京东自主研发的无人仓采用大量智能物流机器人进行协同与配合,通过人工智能、深度学习、图像智能识别、大数据应用等技术,让工业机器人可以进行自主的判断和行为,完成各种复杂的任务,在商品分拣、运输、出库等环节实现自动化。人工智能在金融领域的应用主要有:智能获客、身份识别、大数据风控、智能投顾、智能客服、金融云等,该行业也是人工智能渗透最早、最全面的行业。目前,我国在ITS方面的应用主要是通过对交通中的车辆流量、行车速度进行采集和分析,可以对交通进行实施监控和调度,有效提高通行能力、简化交通管理、降低环境污染等。

使用LOTR合并检索提高RAG性能

为了解决LIM问题并提高检索性能,对RAG系统进行增强是非常重要的。通过设置不同的VectorStores并将它们与Merge retriver结合,以及使用LongContextReorder重新排列结果,可以减少LIM问题并使检索过程更高效。此外,在合并检索器中合并特定领域的嵌入也有着关键作用。这些步骤对于确保我们不会在检索文件的过程中遗漏重要细节至关重要。Lost in the Middle: How Language Models Use Long Contexts 论文。

【AI】人工智能复兴的推进器之神经网络

神经网络是一种模仿生物神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。神经网络由大量节点(或神经元)相互关联构成,每两个节点间的连接都代表一个对于通过该连接信号的加权值,称之为权重,这可以看作人工神经元的记忆。网络的输出则依网络的连接方式,权重值和激励函数的不同而不同。而网络自身通常都是对自然界某种算法或者函数的逼近,也可能是对一种逻辑策略的表达。此外,根据网络的结构和运行方式,神经网络可以分为前馈神经网络和反馈神经网络。

目标检测与测距算法在极端天气下的应用

在现代社会中,极端天气条件对人们的生活和工作带来了很大的挑战。对于一些特定领域,如交通运输、安全监控等,准确的目标检测与测距算法在极端天气下尤为重要。本文将分点概述极端天气下目标检测与测距算法的关键问题及解决办法。

AI时代架构设计新模式

本书是一本旨在帮助架构师在人工智能时代展翅高飞的实用指南。全书以ChatGPT为核心工具,揭示了人工智能技术对架构师的角色和职责进行颠覆和重塑的关键点。本书通过共计 13 章的系统内容,深入探讨AI技术在架构设计中的应用,以及AI对传统架构师工作方式的影响。通过学习,读者将了解如何利用ChatGPT这一强大的智能辅助工具,提升架构师的工作效率和创造力。本书的读者主要是架构师及相关从业人员。

深度解析 PyTorch Autograd:从原理到实践

本文深入探讨了 PyTorch 中 Autograd 的核心原理和功能。从基本概念、Tensor 与 Autograd 的交互,到计算图的构建和管理,再到反向传播和梯度计算的细节,最后涵盖了 Autograd 的高级特性。

AIGC实战——WGAN(Wasserstein GAN)

在本节中,我们学习了如何使用 Wasserstein 损失函数以解决经典 GAN 训练过程中的模式坍塌和梯度消失等问题,使得 GAN 的训练更加可预测和可靠。WGAN-GP 通过在损失函数中添加一个令梯度范数指向 1 的项,为训练过程施加 1-Lipschitz 约束。

ChatGPT的常识

ChatGPT不仅可以提供高效的服务,还可以通过模拟人类对话和表情,提高人机交互的趣味性和友好性。其次,ChatGPT可以实现个性化服务,根据用户的个性化需求和反馈不断优化和改进。用户在与ChatGPT进行交互的过程中,ChatGPT可以对用户的个性化需求进行识别和记录,从而实现个性化的服务。ChatGPT的设计理念是建立一个可以持续学习和更新的聊天机器人,可以不断地根据用户的反馈和互动进行优化和改进。同时,ChatGPT还具有很强的适应性和灵活性,可以应对不同场景和话题的要求。

人工智能时代:AIGC的横空出世

AIGC是一种新的人工智能技术,即人工智能生成内容。它是一种基于机器学习和自然语言处理的技术,能够自动产生文本、图像、音频等多种类型的内容。

【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)

脑肿瘤是一种致命的疾病,没有MRI技术,无法可靠地检测到。为了为MRI图像的形态学操作铺平道路,我们首先使用各向异性扩散滤波器对图像进行滤波,以降低像素之间的对比度。然后,我们调整图像大小,并手动将其转换为黑白图像,通过阈值处理来初步筛选出肿瘤可能存在的区域。这个项目的更大目标是建立一个包含从不同角度拍摄的特定人类MRI图像中的肿瘤2D图像数据的数据库,并通过对这些图像进行分析来确定肿瘤的精确3D位置。尽管这个模拟程序在大多数情况下可以给出准确的结果,但对于过小的肿瘤或具有中空结构的肿瘤,它可能无法执行。
返回
顶部