1、RAG有哪几个步骤?
1.1、文本分块
第一个步骤是文本分块(chunking),这是一个重要的步骤,尤其在构建与处理文档的大型文本的时候。分块作为一种预处理技术,将长文档拆分成较小的文本块,这些文本块更适合于模型进行处理。
思考扩展
1、为什么要分块?
从以下四个方面来回答这个问题:
长文本处理的挑战:
语言模型(如BERT、GPT等)通常有输入长度限制。例如,GPT-3的最大输入长度在4096个token以内,如果文档过长,模型无法一次性处理所有内容。
文本信息在生成式模型中可能会被截断或被忽略,尤其当关键信息位于文档的后半部分时,单一长文本无法有效利用。
提高检索效果:
在RAG模型中,文档中的某些片段可能与用户查询高度相关,而其他片段则不相关。通过分块,检索模型可以更精确地找到最相关的文本块,而不是处理整个文档。
当一个长文档被分成多个块后,模型可以针对每个文本块单独计算相似度,更容易找到与查询最匹配的块,从而提升检索的准确性。
减少计算复杂度:
检索任务的计算复杂度与文本长度成正比。如果将文档分块,可以有效降低处理单个文本的计算复杂度,从而提高检索速度和生成效率。
分块后,模型可以并行处理多个文本块,这样整体的处理速度会更快。
增强模型的鲁棒性:
当文档被分块后,即使某些块的内容较为冗余或不相关,模型仍然能够依赖相关块生成高质量的回答。
分块还能避免单一文本块中包含过多无关信息,这有助于减少生成过程中不必要的信息干扰。
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、生成环节
关注待续........