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、生成环节

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

### 检索增强生成 RAG 技术原理 检索增强生成RAG)是一种融合了检索技术和生成模型的方法,旨在通过结合外部知识库中的信息来改进自然语言处理任务的效果。具体而言,在对特定查询时,系统会先利用检索模块从大量文档或其他形式的数据集中提取最相关的片段或条目;随后这些被选中的资料作为附加输入提供给生成组件,帮助其构建更加精准且富含背景支持的回答。 #### 工作流程概述 1. **检索阶段**:当接收到用户提出的请求后,RAG架构内的搜索引擎负责查找与之匹配度最高的若干候选答案来源。此过程可能涉及全文搜索、关键词定位或是更复杂的语义相似度计算等方式[^3]。 2. **生成阶段**:紧接着上述操作所得的结果会被传递至预训练的语言模型那里。此时后者不仅要理解原始问题本身所表达的意思,还需充分吸收由前者所提供的额外素材,并据此产出既贴合事实又具备良好流畅性的最终回复[^2]。 为了确保整个系统的高效运作以及输出质量,还需要特别关注以下几个方: - 对于检索部分来说,采用先进的算法设计至关重要。这包括但不限于考虑如何衡量不同文本间的关联程度、怎样快速锁定目标范围等问题。实践中往往倾向于运用诸如BM25、TF-IDF这样的经典方案或者是基于深度学习框架下的新兴手段如BERT等来进行优化配置[^4]。 - 针对生成环节,则强调要让模型学会有效整合多源异构的知识表示形式——即能够把来自结构化表格记录、半结构性网页内容乃至纯叙述性描述等各种类型的有用资讯无缝衔接到一起,从而实现高质量的对话交互体验[^1]。 ```python from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration tokenizer = RagTokenizer.from_pretrained("facebook/rag-token-nq") retriever = RagRetriever.from_pretrained("facebook/rag-token-nq", index_name="exact", use_dummy_dataset=True) model = RagSequenceForGeneration.from_pretrained("facebook/rag-token-nq") input_dict = tokenizer.prepare_seq2seq_batch( "What is the capital of France?", return_tensors="pt" ) outputs = model.generate(input_ids=input_dict["input_ids"], context_input_ids=retriever(contexts=["Paris"])) print(tokenizer.batch_decode(outputs, skip_special_tokens=True)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值