自学内容网 自学内容网

RAG(检索增强生成)面经(1)

1、RAG有哪几个步骤?

1.1、文本分块

第一个步骤是文本分块(chunking),这是一个重要的步骤,尤其在构建与处理文档的大型文本的时候。分块作为一种预处理技术,将长文档拆分成较小的文本块,这些文本块更适合于模型进行处理。

思考扩展

1、为什么要分块?

从以下四个方面来回答这个问题:

  • 长文本处理的挑战:

    1.  语言模型(如BERT、GPT等)通常有输入长度限制。例如,GPT-3的最大输入长度在4096个token以内,如果文档过长,模型无法一次性处理所有内容。

    2. 文本信息在生成式模型中可能会被截断或被忽略,尤其当关键信息位于文档的后半部分时,单一长文本无法有效利用。

  • 提高检索效果

    1. 在RAG模型中,文档中的某些片段可能与用户查询高度相关,而其他片段则不相关。通过分块,检索模型可以更精确地找到最相关的文本块,而不是处理整个文档。

    2. 当一个长文档被分成多个块后,模型可以针对每个文本块单独计算相似度,更容易找到与查询最匹配的块,从而提升检索的准确性。

  • 减少计算复杂度

    1. 检索任务的计算复杂度与文本长度成正比。如果将文档分块,可以有效降低处理单个文本的计算复杂度,从而提高检索速度和生成效率。

    2. 分块后,模型可以并行处理多个文本块,这样整体的处理速度会更快。

  • 增强模型的鲁棒性

    1. 当文档被分块后,即使某些块的内容较为冗余或不相关,模型仍然能够依赖相关块生成高质量的回答。

    2. 分块还能避免单一文本块中包含过多无关信息,这有助于减少生成过程中不必要的信息干扰。

2、分块的策略有哪些?

  • 按固定长度分块

          最简单的分块方法是按固定的token数量或句子数量进行分割。例如,将文档按每200个token进行切分,确保每个块的长度在模型的处理能力范围之内。这种方法简单直接,但可能会导致语义信息的中断,例如,某些句子或段落在块之间被截断,影响模型的理解。

  • 按自然语言结构分块

           一种更智能的分块方式是基于文档的自然语言结构,比如按段落、章节或主题进行分块。这种方法可以保持每个块的语义完整性,从而提升检索和生成的效果。这种方法通常需要先进行文本的自然语言处理(NLP)分析,例如通过段落分割器、主题检测器等工具。

  • 滑动窗口分块

           为了缓解固定长度分块带来的信息丢失问题,另一种常见的方法是使用滑动窗口。这意味着每个块之间会有一定的重叠区域,这样即使一个块被截断,重要的信息也可能会出现在相邻的块中。滑动窗口可以确保关键内容不会因为分块策略的限制而遗漏,尤其在上下文关联性很强的文档中,这种方法非常有用。

1.2、嵌入向量

第二步嵌入向量是关键的一步,直接影响模型的检索和生成效果。具体来说,使用编码模型将每个文本块转化为嵌入向量,这些向量用于表示文本块的语义信息。

思考扩展

1、为什么使用编码模型?

       编码模型通过将文本块转化为向量,使得查询和文本块可以在向量空间中比较其相似性。编码模型的作用是捕捉文本的语义信息,并将其表示为高维的向量表示,这些表示可以被用于快速、精确的相似度计算。

2、详细说说嵌入向量得流程

  • 文本分块后的预处理

        在将文档分成若干小块后,每个块需要被编码为向量,具体步骤如下:   

        1、Tokenization(分词):

        文本块首先通过分词器(如BERT分词器)将每个块拆分为一个个的token(子词单元)。分词的目的是将自然语言文本转化为模型能够理解的输入格式。例如,句子 "This is a cat" 会被拆解为 ["This", "is", "a", "cat"],并映射为对应的token ID(词汇表中的索引号)

         2、添加特殊token:

        通常还会在文本块的开始和结束位置加上特殊token,比如 [CLS] 表示开始,[SEP] 表示结束。这些token对BERT等模型非常重要,尤其是 [CLS] token 的嵌入向量往往用于表示整个文本块的语义。   

  • 使用编码模型生成嵌入向量

        1、输入到编码模型:

        分词后的文本块被输入到预训练的编码模型中,常用的模型包括BERT、RoBERTa等。每个token都会经过一系列的注意力机制、前馈神经网络等复杂的变换,最终得到每个token的上下文表示。

        2、获取块的向量表示:

        编码模型的输出是一个多维向量表示,通常是对于每个token生成一个向量。比如对于输入句子 "This is a cat",编码模型可能会输出形如 [768维度向量, 768维度向量, 768维度向量, 768维度向量] 这样的高维向量。

        在RAG的检索过程中,我们往往只使用 [CLS] token 的向量表示(这个向量是模型对整个文本块的语义总结),它可以表示整个文本块的语义。这个向量是一个固定长度的高维向量(如BERT的输出是768维)。

        3、归一化处理:

        为了便于向量之间的比较,通常会对向量进行归一化处理(例如将向量的长度标准化为1),这样可以使得不同向量之间的相似性计算更加稳定。

1.3、创建索引

        给文本块嵌入向量后创建索引的过程是实现高效检索的核心步骤。这个索引可以显著提高查询与文本块匹配的速度,使得在大规模语料库中快速检索与查询相关的内容成为可能。

思考扩展

1、为什么要创建索引

        文本块被嵌入到向量后,虽然可以通过向量相似度计算来找到最相关的块,但是在大规模数据集中(数百万甚至数十亿个文本块),逐个计算查询向量与每个文本块向量的相似性是非常耗时的。为了加速检索过程,必须对这些向量进行索引,从而在查询时高效地找到最相关的文本块。

        索引通过一些优化结构,比如倒排索引、树结构或近似最近邻搜索(ANN),可以在大规模数据中进行快速的查找。

2、创建索引得方法

        当你将文本块嵌入到向量后,可以选择使用向量数据库(如Milvus)或搜索引擎(如Elasticsearch with k-NN 插件)创建索引,以便于后续的相似性检索。可以去看看这两个工具中如何创建索引的。

        Milvus在处理超大规模数据集的嵌入和向量检索方面性能优异,而Elasticsearch则适合那些需要结合向量和全文检索的应用。

 1.4 创建Prompt

        当完成了文本块向量化并建立索引后,下一步就是基于用户的查询,通过查询检索得到的结果来构建一个针对大模型的Prompt(提示)。在基于检索的生成(Retrieval-Augmented Generation, RAG)系统中,这个Prompt会结合检索到的上下文,为大模型提供背景信息,从而生成更加相关和有针对性的响应。

思考扩展

1、怎么创建prompt呢?

  • 用户查询向量化

        当用户输入查询时,需要将这个查询使用同一个编码模型转化为向量,以便在向量数据库中查找与之最相似的文本块。

  • 基于用户查询向量进行向量检索

        使用向量数据库(如Milvus或Elasticsearch)进行相似性检索时,需要将用户查询的向量与数据库中的文本块向量进行相似度计算。通常使用余弦相似度或欧几里得距离等度量方法。

  • 构建Prompt:用户查询 + 检索到的文本块

        接下来,将用户的原始查询和检索到的相关文本块组合在一起,生成给大模型的Prompt。Prompt的设计需要同时包含用户的查询和上下文信息,以便模型能够更好地理解问题的背景。例如如下

用户提问: 请解释什么是量子计算。

已检索到的相关信息:
1. 量子计算是一种基于量子力学原理的计算方法,其利用了量子叠加和量子纠缠来进行并行计算。
2. 量子比特(qubits)是量子计算的基本单元,可以同时表示0和1的状态。
3. 量子计算的潜力在于解决经典计算机无法有效处理的复杂问题,比如密码学、分子模拟和优化问题。

请详细解释量子计算的原理和潜在应用。

2、如何优化Prompt?

        避免含糊不清的语言:使用清晰的动词来指示模型的行为,例如“解释”、“列出”、“总结”等。

        精确表述期望的输出格式:明确指定模型应该输出什么样的内容。比如要求模型以列表形式回答,或以简短段落方式回答。

        筛选最相关的内容:仅选择与用户查询最相关的文本块,而不是直接将所有检索结果拼接。

        控制上下文长度:上下文过长可能导致模型“迷失方向”或产生不必要的噪声。通过筛选减少无关或冗余的内容,有助于提升回答的质量和精确性。

        摘要检索到的文本:如果检索到的文本过长,你可以先对其进行摘要,将核心信息提取出来。

        剔除无关或重复内容:剔除那些对用户问题帮助不大的信息,或者去掉重复的部分。

 2、在实际项目中用过哪些优化的技巧?

2.1、改进文本分块策略:

  • 块的大小控制:块太大可能导致不相关内容混入,块太小则可能无法提供足够上下文。一个常见的策略是每块包含 100-300 个字(或者 3-5 个句子),以确保上下文信息完整。
  • 基于语义的分割:不要简单地根据固定长度进行分块,使用语义分割技术(如自然段落或基于主题模型的分割)可以使每个块在语义上更加独立和完整。

2.2、改进向量化编码器

  • 使用预训练模型:选择适合你的领域的预训练模型(如BERT, RoBERTa,或者领域特定的模型如LegalBERT, BioBERT等),这些模型能够在特定领域更好地捕捉语义信息。
  • 微调(Fine-tuning)编码器:可以通过特定领域的训练数据对预训练模型进行微调,增强编码器对该领域语义的理解。微调的方式可以包括用领域数据进行有监督学习或对比学习。
  • 使用多种编码器:在某些复杂场景中,可以采用多个编码器分别编码不同的文本部分,例如长文本的标题、正文和结论部分分别编码,然后进行加权组合,提高召回的多样性和准确性

2.3、采用多路召回

        多路召回是一种组合式召回策略,采用多种不同的召回方式或算法,分别从不同角度去召回相关的文本或文档。这样可以弥补单一召回方式的不足,提升召回的全面性和覆盖率。以下是介绍几种常见的召回方式:

  • 稀疏召回:基于关键词的稀疏特征进行匹配,适合精确查询,常用于 BM25 等传统检索方式。
  • 语义召回:依赖于深度学习模型,通过向量相似度匹配语义相似的文本,适合处理模糊查询。
  • 字面召回:则完全基于字面的匹配,适合对特定词汇、术语或条文进行精确匹配的场景。        

3、RAG一般怎么做评估效果?

RAG做效果评估主要是针对检索和生成两个环节

3.1、检索环节

        在RAG模型(或其他检索-生成模型)的评估中,Mean Reciprocal Rank (MRR)、前k项命中率(Hits Rate)和NDCG(Normalized Discounted Cumulative Gain)是三种常用的评估指标,它们主要用于衡量检索阶段的表现。让我们逐一详细介绍这些指标,并结合实例解释。

1. Mean Reciprocal Rank (MRR)

MRR 衡量的是检索系统返回的第一个相关结果的位置,它的计算方式是找到第一个相关结果的排名,取其倒数,然后对所有查询的倒数进行平均。

举例:

假设有3个查询及其检索结果:

  • 查询1:第1个结果是相关的,排名为1。
  • 查询2:第3个结果是相关的,排名为3。
  • 查询3:第2个结果是相关的,排名为2。

那么对应的MRR计算如下:

 因此,MRR=0.611,表示系统的前几个结果中有比较高概率能返回相关文档。

2. 前k项命中率(Hits Rate)

Hits Rate@k 衡量的是在返回的前k个结果中是否存在至少一个相关结果。如果有,计为1,否则计为0。然后对所有查询的命中率取平均。

举例:

假设有3个查询,结果如下:

  • 查询1:前5个结果中有相关文档,命中。
  • 查询2:前5个结果中没有相关文档,未命中。
  • 查询3:前5个结果中有相关文档,命中。

那么,HitsRate@5的计算如下:

 因此,HitsRate@5 = 0.666,表示系统在返回的前5个结果中有较高概率能找到相关文档。

3. NDCG(Normalized Discounted Cumulative Gain)

NDCG 衡量的是检索结果的相关性和排名顺序,考虑到越早出现的相关结果对用户越有用。它通过归一化的**累积增益(Cumulative Gain, CG)**来衡量系统在不同位置返回相关结果的有效性。

举例:

假设某次查询的前3个结果的相关性分别为3、2和1,理想情况下的相关性也是3、2、1,那么我们计算DCG和NDCG。

在这个例子中,NDCG@3 = 1,表示系统检索结果的排序是最优的。

总结
  • MRR 更关注第一个相关结果的位置,适合需要快速找到答案的场景。
  • Hits Rate 则关注前k个返回结果中是否包含相关文档,适合衡量系统在给定返回数量内找到相关文档的能力。
  • NDCG 则进一步关注结果的排序和相关性,是衡量整体检索质量的综合性指标。

3.2、生成环节

关注待续........


原文地址:https://blog.csdn.net/m0_56569131/article/details/142961163

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!