RAG的5种文本分块策略#Text Splitting

你是否曾经尝试将一段很长的文本输入ChatGPT,却被告知文本太长了?或者你是否试图让你的应用程序具有更好的长期记忆,但效果还不够好?

提高大语言模型性能的一个有效的策略是将大型数据分割成较小的部分。这个过程被称为分割或分块(Text Splitting)。 

c89300c1560a87542fc438b8ecf1700b.png

在这个教程中,介绍了文本分割的5种方法。我阅读后做了些精简,分享给大家,原文可以文末查看原链接。

Text Splitting

文本分割的方法

方法1:字符分割 - 简单的静态字符数据块

方法2:递归字符文本分割 - 基于分隔符列表的递归分块

方法3:特定文档分割 - 针对不同文档类型(PDF、Python、Markdown)的各种分块方法

方法4:语义分割 - 基于嵌入式遍历的分块

方法5:LLM 分割 - 使用类似代理系统的实验性文本分割方法。如果您的GPT成本接近于0.00美元,这种方法很好。

为了方便理解各种分割方式,可以通过下面这个可视化的网站,调整参数,体验文本分割的方法 ↓

a6a7e6cd42e2482317d049297f7d2281.png

可视化文本分割

chunkviz.up.railway.app

方法1:字符分割

字符分割是将文本分割的最基本形式。它是简单地将文本分割成N个字符大小的块,而不考虑其内容或形式。

优点:简单易行

缺点:非常刻板,不考虑文本的结构

需要了解的概念:

块大小 Chunk Size - 您希望在块中包含的字符数。50、100、100,000等。

块重叠 Chunk Overlap - 您希望连续块之间重叠的量。这是为了避免将单个上下文切割成多个部分。这将在块之间创建重复的数据。 

14af505de0f6cd1fd6aab1f991767687.png

方法2:递归字符文本分割

方法1的问题在于完全不考虑文档的结构。只是按照固定数量的字符进行分割。

递归字符文本分割器可以解决这个问题。通过它,我们将指定一系列分隔符来分割文档。例如 LangChain的默认分隔符:

"\n\n" - 换行

"\n" - 换行

" " - 空格

"" - 空字符

这是快速搭建应用程序时的首选。如果您不知道从哪个分割器开始,这是一个不错的首选。

672ee322c691d61cad434bafd8625d6d.png

方法3:特定文档分割

除了普通文本文件之外的其他文档类型。比如图片、PDF、代码片段等等。前两个方法对于这些情况并不适用,所以需要找到不同的策略。

Markdown、Python和JS的分割器基本上与递归字符分割器类似,只是使用不同的分隔符。例如 Markdown 分隔符:

\n#{1,6} - 标题

```\n -代码块

\n\\*\\*\\*+\n - Horizontal Lines

\n---+\n - Horizontal Lines

\n___+\n - Horizontal Lines

\n\n 换行

\n - 换行

" " - 空格

"" - 空字符

再比如 Python 分隔符:

\nclass -类

\ndef - 方法

\n\tdef - Indented functions

\n\n - 换行

\n - 换行

" " - 空格

"" - 空字符

方法4:语义分块

我们是否觉得为块大小设置一个全局常量很奇怪?我们的普通分块机制是否更奇怪,因为它们没有考虑实际内容?

嵌入表示了字符串的语义含义。它们本身并没有太多作用,但是当与其他文本的嵌入进行比较时,您可以开始推断块之间的关系。利用这个特性,探索使用嵌入来找到语义上相似的文本聚类。假设是语义上相似的块应该放在一起。

(此部分详见作者代码演示)

方法5:LLM 分块

我们是否可以命令LLM执行此任务?人类是如何进行分块的呢?我们会如何将文档分块成具有语义相似性的离散部分?

我会准备一张草稿纸或记事本。

我会从文章的顶部开始,假设第一部分将是一个块(因为我们还没有任何块)。

然后,我会继续阅读文章,评估新的句子或文章片段是否应该成为第一个块的一部分,如果不是,就创建一个新的块。

然后一直这样做,直到读完整篇文章。

ps:

是否要严格使用文档的原始文本,还是使用改写的形式。改写的方式,从原始文本中提取独立的陈述句。

例如: Greg went to the park. He likes walking 

['Greg went to the park.', 'Greg likes walking']


以上是5种不同的分割策略。欢迎入群交流 ↓

d1b90caacf80d1cf619ed01f9a7e73ae.jpeg

什么是RAG?私有化的wiki百科AI助手

原文:

https://github.com/FullStackRetrieval-com/RetrievalTutorials/blob/main/5_Levels_Of_Text_Splitting.ipynb

d20355b688736ae2e1992d856f6f9834.png

github.com/explodinggradients/ragas

评估工具推荐:

Ragas是一个帮助您评估检索增强生成(RAG)pipelines。Ragas提供基于最新研究的工具,用于评估LLM生成的文本,以帮助您了解RAG pipelines的情况。

  • 22
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,可以得知prompt+RAG的流程如下: 1. 首先,使用Retriever部分在知识库中检索出top-k个匹配的文档zi。 2. 然后,将query和k个文档拼接起来作为QA的prompt,送入seq2seq模型。 3. seq2seq模型生成回复y。 4. 如果需要进行Re-rank,可以使用LLM来rerank,给LLM写好prompt即可。 下面是一个简单的示例代码,演示如何使用prompt+RAG: ```python from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration # 初始化tokenizer、retriever和seq2seq模型 tokenizer = RagTokenizer.from_pretrained('facebook/rag-token-base') retriever = RagRetriever.from_pretrained('facebook/rag-token-base', index_name='exact', use_dummy_dataset=True) model = RagSequenceForGeneration.from_pretrained('facebook/rag-token-base') # 设置query和context query = "What is the capital of France?" context = "France is a country located in Western Europe. Paris, the capital city of France, is known for its romantic ambiance and iconic landmarks such as the Eiffel Tower." # 使用Retriever部分检索top-k个匹配的文档 retrieved_docs = retriever(query) # 将query和k个文档拼接起来作为QA的prompt input_dict = tokenizer.prepare_seq2seq_batch(query, retrieved_docs[:2], return_tensors='pt') generated = model.generate(input_ids=input_dict['input_ids'], attention_mask=input_dict['attention_mask']) # 输出生成的回复 generated_text = tokenizer.batch_decode(generated, skip_special_tokens=True)[0] print(generated_text) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值