大模型之RAG:如何做好文档切分,长上下文是否替代了RAG?

我们对RAG有了基本的认识,也了解了下他的原理与发展。

Tips

  1. 果然不能让自己太忙,太忙挤占了学习成长空间。

  2. 大模型发展越来越快,按说新生技术是不能间隔这么久的,先机都被别人占了。希望也有一些和我一样最近没来得及学习的人。

目前主流大模型支持的上下文长度越来越长,Kimi支持200万字的上下文。在此背景下,也出现了一个新的声音:长上下文是否替代了RAG?

基础永远是基石

不管如何变化,我们扎马步的功夫还是不能抛弃。本文我们会介绍,从0搭建一个自己的RAG,需要哪些步骤,重点介绍第一步,如何做好文档切分。

RAG系统搭建的基本流程

  1. 准备对应的垂域资料

  2. 文档的读取解析,进行文档切分(本文重点介绍切分策略与方法)

  3. 将分割好的文本灌入检索引擎(向量数据库)

  4. 封装检索接口

  5. 构建流程:Query -> 检索 -> Prompt -> LLM -> 回复

形成如下的应用场景:

在这里插入图片描述

文档切分

文档切分方法

一、基于规则的切分方法

根据预定义的规则和标准进行文本切分,往往缺乏灵活性和对复杂语义的深入理解,如:

  • 基于字符分块 : 据固定字符数目以及特定的字符进行切分。

  • **固定大小分块:**指定每个块的固定令牌数,通常会有一些重叠,以保持语义连贯性。

  • **基于token的分块:**根据固定的token数进行切分,每个令牌代表一个词或语素,通常使用与目标语言模型相同的分词器。

  • **内容感知分块:**使用 NLTK ,spaCy 等这工具来实现基于内容的切分,比如利用句子分割、识别段落、标题和标点符号。

  • **根据规则递归分块:**递归分块首先尝试按照一定的标准(如段落或标题)分割文本,如果分割后的文本块仍然过大,就会在这些块上重复进行分割过程,直到所有块的大小都符合要求。这种方法适用于需要将长文本细分为较小片段的场景,同时尽量保持每个块的独立性和完整性。

  • **针对特定数据的分块:**这些方法尊重内容的结构和格式元素,确保语义连贯性。例如,Markdown文本可以根据标题、列表和代码块等元素进行分块,而LaTeX文本可以根据章节、小节和公式等逻辑单元进行分块。

二、基于语义聚类的切分方法

基于嵌入的语义分块本质上是通过一个滑动窗口(combined_sentence )来计算相似度。那些相邻并且满足阈值的句子会被归为一个分块。如LlamaIndex中的SemanticSplitterNodeParser方法,其主要步骤如下:

  1. 文本嵌入:首先,文本被输入到一个嵌入模型中(如OpenAI的Embedding Model),该模型将文本中的每个句子或段落转换成高维空间中的向量。这些向量代表了文本的语义特征。

  2. 语义分析:利用这些嵌入向量,可以通过计算向量之间的相似度来评估句子或段落之间的语义关系。如通过余弦相似度等度量,来确定哪些文本部分在内容上是相似的。

  3. **分块决策:**基于预设的相似度阈值或其他标准,这些语义相近的文本段落被分组为一个块(chunk)。这个过程通常涉及到确定“断点”,即在哪里开始新的分块,以确保每个分块在语义上尽可能的独立和完整。

三、基于机器学习模型的方法

利用自然语言模型,如BERT和其他Transformer模型,这些方法通过学习文本中的语言模式来预测最合适的分块点。

这些模型通常被训练来识别文本中的结构和语义断点,能够自动适应各种语言和文本类型。

  • Naive BERT

    使用BERT模型的下一句预测(NSP)功能来判断两个句子之间是否存在直接的连续关系。这种方法通过分析相邻句子的语义关系来确定分块点。

  • Cross Segment Attention[6]

    采用跨片段的注意力机制来分析文本,如通过BERT和双向LSTM结合的方式,来更细致地理解和划分文本。这种方法不仅考虑单个句子,还考虑其周围的上下文,以确定分割点。

  • SeqModel[7]

    在[6]的基础上提出了进一步的改进,即 SeqModel。SeqModel 利用 BERT 同时编码多个句子,在进行句子向量计算之前,建模了更长上下文内的依赖关系。然后,它预测每个句子之后是否会发生文本分割。此外,这个模型采用了自适应性滑动窗口方法来提高推理速度,同时不牺牲准确性。

四、基于代理的切分方法

通过将文本分解为独立的命题或信息单元,并根据这些单元的语义相关性进行聚类和组织。通常依赖于先进的自然语言处理技术来提取和评估文本中的关键信息,然后基于这些信息创建结构化的数据块。其步骤如下:

  1. 理解文本:首先,大型语言模型(LLM)需要理解整个文本。就像一个人在阅读文章时,理解每一个段落、句子和词汇的意义一样。

  2. 生成命题: 然后,模型将文本分解为命题。命题是文本中的独立观点或信息片段,每个命题都包含一个完整的思想或陈述。例如,如果原文是一篇关于历史事件的文章,一个命题可能是“XX年发生了YY事件”。

  3. 命题评估:接下来,模型(代理)会评估每个命题的相关性和上下文。它会考虑这个命题与文本中其他内容的关联程度。比如模型可能会问:“这个命题是否与我已经划分出的其他信息块有逻辑上的联系?”

  4. 创建或分配块: 基于评估结果,模型决定将命题放入现有的信息块中,还是为其创建一个新的块。如果一个命题与现有块紧密相关,它就会被添加到那个块中。如果它是一个全新的观点或信息片段,就会创建一个新的块。

  5. 迭代和优化: 模型会不断评估和调整,直到文本被有效地分割成一系列有意义的、相互关联的信息块。

在使用(RAG)处理长文本数据时,合理的文本切割策略是提高模型性能和效率的关键。

文档切分实践-pdf文档的分割

今天我们基于特定文档类型的分割,使用pdfminer库(PDFMiner 是一个用于解析PDF文档的Python库。

它可以从PDF文件中提取文本和数据,包括文本内容、字体信息、页面布局、表格、图片以及文档元数据):

安装pdfminer库

pip install pdfminer.six

引用相关的包

from pdfminer.high_level import extract_pages``from pdfminer.layout import LTTextContainer

pdf解析方法

def extract_text_from_pdf(filename, page_numbers=None, min_line_length=1):`    `'''从 PDF 文件中(按指定页码)提取文字'''`    `paragraphs = []`    `buffer = ''`    `full_text = ''`    `# 提取全部文本`    `for i, page_layout in enumerate(extract_pages(filename)):`        `# 如果指定了页码范围,跳过范围外的页`        `if page_numbers is not None and i not in page_numbers:`            `continue`        `for element in page_layout:`            `if isinstance(element, LTTextContainer):`                `full_text += element.get_text() + '\n'`    `# 按空行分隔,将文本重新组织成段落`    `lines = full_text.split('\n')`    `for text in lines:`        `if len(text) >= min_line_length:`            `buffer += (' ' + text) if not text.endswith('-') else text.strip('-')`        `elif buffer:`            `paragraphs.append(buffer)`            `buffer = ''`    `if buffer:`        `paragraphs.append(buffer)`    `return paragraphs

调用与输出

paragraphs = extract_text_from_pdf("doc\demo.pdf", min_line_length=10)``   ``for para in paragraphs[:50]:`    `print(para + "\n")

文本分割的粒度

文本切割策略主要依赖于两个参数:chunksize(块大小)和overlap(重叠)。正确配置这些参数可以显著影响模型的输出质量和处理速度。

#  按一定粒度,部分重叠式的切割文本,使上下文更完整``def split_text(paragraphs, chunk_size=300, overlap_size=100):`    `'''按指定 chunk_size 和 overlap_size 交叠割文本'''`    `# 英文句子分割`    `# sentences = [s.strip() for p in paragraphs for s in sent_tokenize(p)]`    `# 中文句子分割`    `sentences = [s.strip() for p in paragraphs for s in re.split('(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s', p)]`    `chunks = []`    `i = 0`    `while i < len(sentences):`        `chunk = sentences[i]`        `overlap = ''`        `prev_len = 0`        `prev = i - 1`        `# 向前计算重叠部分`        `while prev >= 0 and len(sentences[prev])+len(overlap) <= overlap_size:`            `overlap = sentences[prev] + ' ' + overlap`            `prev -= 1`        `chunk = overlap+chunk`        `next = i + 1`        `# 向后计算当前chunk`        `while next < len(sentences) and len(sentences[next])+len(chunk) <= chunk_size:`            `chunk = chunk + ' ' + sentences[next]`            `next += 1`        `chunks.append(chunk)`        `i = next`    `return chunks``   ``chunks = split_text(paragraphs, 300, 100)

我的需求

等我把市面主流的java面试资料都喂给了LLM,远程面试八股文这关,是不是可以放个麦克风在电脑边,面试官边讲,LLM边给我输出,反正chatgpt-o,文字、语音、图片等等多模态都可以,哈哈。

有了需求,下一篇我们就准备把解析的pdf资料灌入检索引擎。

长上下文是否替代了RAG?

长上下文窗口的好处

  1. **提高理解和连贯性:**长上下文窗口允许模型在生成回答时,参考更多的背景信息,这使得模型能够更好地理解复杂的查询上下文,从而生成更加相关和连贯的回答

  2. 复杂任务处理能力:有些任务,如撰写文章、编程、数据分析等,需要对大量信息进行处理和引用。长上下文窗口使模型能够处理这类复杂任务提供更加深入和准确的输出

  3. 提升用户体验:用户在与模型交互时,往往希望模型能够记住并利用整个对话历史中的信息。长上下文窗口可以使模型在整个会话过程中保持信息的连续性,提供更加个性化和满意的用户体验。

RAG的不可替代性

虽然很多模型能处理更长的上下文窗口,但它们无法取代RAG,因为处理复杂RAG任务仍然需要更好的系统才能投入生产。

长上下文窗口允许RAG系统在检索精度较低的情况下仍然进行有意义的处理,从而促进了RAG生产的简化,提升了RAG应用的效能。

零基础如何学习AI大模型

领取方式在文末

为什么要学习大模型?

学习大模型课程的重要性在于它能够极大地促进个人在人工智能领域的专业发展。大模型技术,如自然语言处理和图像识别,正在推动着人工智能的新发展阶段。通过学习大模型课程,可以掌握设计和实现基于大模型的应用系统所需的基本原理和技术,从而提升自己在数据处理、分析和决策制定方面的能力。此外,大模型技术在多个行业中的应用日益增加,掌握这一技术将有助于提高就业竞争力,并为未来的创新创业提供坚实的基础。

大模型典型应用场景

AI+教育:智能教学助手和自动评分系统使个性化教育成为可能。通过AI分析学生的学习数据,提供量身定制的学习方案,提高学习效果。
AI+医疗:智能诊断系统和个性化医疗方案让医疗服务更加精准高效。AI可以分析医学影像,辅助医生进行早期诊断,同时根据患者数据制定个性化治疗方案。
AI+金融:智能投顾和风险管理系统帮助投资者做出更明智的决策,并实时监控金融市场,识别潜在风险。
AI+制造:智能制造和自动化工厂提高了生产效率和质量。通过AI技术,工厂可以实现设备预测性维护,减少停机时间。

这些案例表明,学习大模型课程不仅能够提升个人技能,还能为企业带来实际效益,推动行业创新发展。

学习资料领取

如果你对大模型感兴趣,可以看看我整合并且整理成了一份AI大模型资料包,需要的小伙伴文末免费领取哦,无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发

在这里插入图片描述

部分资料展示

一、 AI大模型学习路线图

整个学习分为7个阶段
在这里插入图片描述
请添加图片描述

二、AI大模型实战案例

涵盖AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,皆可用。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、视频和书籍PDF合集

从入门到进阶这里都有,跟着老师学习事半功倍。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

四、LLM面试题

在这里插入图片描述
在这里插入图片描述

五、AI产品经理面试题

在这里插入图片描述

如果二维码失效,可以点击下方链接,一样的哦
【CSDN大礼包】最新AI大模型资源包,这里全都有!无偿分享!!!

😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~
在这里插入图片描述

### Ollama RAG技术文档和实现细节 #### 关键概念和技术背景 RAG(Retrieval-Augmented Generation)是一种增强型生成方法,通过引入外部知识库来提升大型语言模型的能力[^2]。这种机制允许模型在处理特定领域问题时能够访问最新的、结构化的数据资源。 #### 架构概述 针对基于Ollama框架构建的RAG系统,整体架构可以划分为离线处理流程与在线服务两大部分: - 数据读取:从各种源获取原始资料。 - 文档拆分:将收集到的信息按照一定规则分割成更小单元以便管理和索引。 - 向量化:利用编码器转换文本片段为数值向量表示形式。 - 数据存储:保存经过预处理后的特征向量至高效检索数据库中。 - **在线部分** 用户发起请求后触发一系列操作: - 数据检索(召回):依据输入查询匹配最相似的历史记录或知识点。 - Prompt拼装:组合上下文信息形成完整的提示语句供下游组件解析。 - LLM生成:调用大模型完成最终响应内容创作过程[^3]。 #### 实现要点 为了使上述设计思路付诸实践并达到预期效果,在具体实施过程中需关注以下几个方面: - **优化文档切分策略**:合理规划文件划分标准直接影响后期搜索效率及质量[^1]。 - 提升查询召回性能:确保能快速定位关联度最高的参考资料集合。 - 整合多模态信息源:除了纯文字材料之外还可以考虑图像、音频等多种媒体类型的融合应用。 - 加强安全防护措施:防止敏感信息泄露的同时保障整个系统的稳定运行。 ```python import ollama_rag_library as olr def process_document(document_path): """Process a single document through the pipeline.""" doc = olr.read_data(document_path) chunks = olr.split_into_chunks(doc, method='optimized') vectors = olr.encode_texts(chunks) return olr.store_vectors(vectors) def retrieve_and_respond(query_string): """Retrieve relevant documents and generate response using an LLM.""" results = olr.search_index(query_string)[:5] context = " ".join([result['text'] for result in results]) prompt = f"Given this context:\n{context}\nAnswer the following question: {query_string}" answer = llm.generate(prompt=prompt).strip() return {"answer": answer} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值