分块

RAG系统中的五种文档分块策略:原理详解-全面对比-最佳实践(固定大小分块、语义分块、递归分块、文档结构分块、LLM大模型分块) RAG系统中的文档分块策略直接影响检索效果和生成质量。本文详解五种分块方法:1)固定大小分块:简单高效但可能截断语义;2)语义分块:基于句子相似度保持语义连贯;3)递归分块:多层级处理复杂文档;4)文档结构分块:利用标题段落等结构化信息;5)LLM分块:利用大模型智能划分。每种策略都配有实现代码和优缺点分析,帮助开发者在实际项目中根据文档特性和应用场景选择合适的分块方法,优化RAG系统性能。 阅读详情

听闻分块大名已久,但仔细深究却是一个比较简单的思想~

大体思想:

分块就是把一段数分成几块来做

分块的操作一般是维护和查询,一个对于 [ l , r ] [l,r] [l,r]的操作,对于在该区间内的完整的块,我们直接维护整个块的信息;对于两侧不完整的部分,我们暴力修改每个点的信息。写分块的关键就是想好如何维护和查询。

一般情况下,当 S = N S=\sqrt{N} S=N ​时,时空复杂度最优。

解决问题:

分块可以处理很多区间问题,虽然复杂度要比树状数组和线段树要高,但是代码比较简短、思想直观形象。

具体实现

分块分块,首先自然需要分:

void build()
{
	dis=sqrt(n);                    //每个块的长度
	num=n/dis;                      //共有多少个块
	for (int i=1;i<=num;i++)        //给每一个块标记左右范围
	{
		l[i]=dis*(i-1)+1;
		r[i]=dis*i;
	}
	r[num]=n;                       //最后一个r dis*i有可能大于n故要改回n
	for (int i=1;i<=num;i++)
	{
		int ans=0;
		for (int j=l[i];j<=r[i];j++)
		{
			ans=max(ans,a[j]);      //具体题目具体分析,此题中要求维护区间最大值故记录区间最大值
			block[j]=i;             //记录没一个点属于哪一个块
		}
		maxx[i]=ans;
	}
}
}

相信这个是非常好理解的,接下来我们来看几个例题:

例题:

Problem1:HDU1754 I HATE IT

Problem Description

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

Input

本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N N N 和 M M M ( 0 < N < = 200000 , 0 < M < 5000 ) ( 0<N<=200000,0<M<5000 ) (0<N<=200000,0<M<5000),分别代表学生的数目和操作的数目。
学生ID编号分别从 1 1 1编到 N N N。
第二行包含 N N N个整数,代表这 N N N个学生的初始成绩,其中第 i i i个数代表ID为 i i i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取’Q’或’U’) ,和两个正整数A,B。
当C为’Q’的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为’U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

Output

对于每一次询问操作,在一行里面输出最高成绩。

题意总括:

维护一个序列支持查询最大值和单点修改

思路:

这题看起来是一个十分简单的线段树模板,不过既然我们在讲分块,就用分块来实现。

分块的思路是维护块中最大值,求区间最大值就是求区间内整块的最大值和左右两边零散的元素的最大值。

于是我们就有了代码:

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1000005;
int n,m,dis,num;
//dis表示每个块的长度,num表示块的数量
int a[maxn],l[maxn],r[maxn],maxx[maxn],block[maxn];
//a记录原数组,l记录每个块的最左边的位置,r记录每个块最右边的位置,maxx维护每个块的最大值,block表示每个点属于哪一个块

inline int read()
{
	int s=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9')
	{
		if (c=='-')
		{
			f=-1;
		}
		c=getchar();
	}
	while (c>='0'&&c<='9')
	{
		s=s*10+c-48;
		c=getchar();
	}
	return s*f;
}
void build()
{
	dis=sqrt(n);                    //每个块的长度
	num=n/dis;                      //共有多少个块
	for (int i=1;i<=num;i++)        //给每一个块标记左右范围
	{
		l[i]=dis*(i-1)+1;
		r[i]=dis*i;
	}
	r[num]=n;                       //最后一个r dis*i有可能大于n故要改回n
	for (int i=1;i<=num;i++)
	{
		int ans=0;
		for (int j=l[i];j<=r[i];j++)
		{
			ans=max(ans,a[j]);      //具体题目具体分析,此题中要求维护区间最大值故记录区间最大值
			block[j]=i;             //记录没一个点属于哪一个块
		}
		maxx[i]=ans;
	}
}
int query(int s,int t)
{
	int ans=0;
	if (block[s]==block[t])         //如果块是完整的(完全包含),其实和线段树挺像的
	{
		for (int i=s;i<=t;i++)
		{
			ans=max(ans,a[i]);
		}
	}
	else                            //如果块不完整,则对缺失部分进行遍历
	{
		for (int i=s;i<=r[block[s]];i++)
		{
			ans=max(ans,a[i]);
		}
		for (int i=block[s]+1;i<block[t];i++)
		{
			ans=max(ans,maxx[i]);
		}
		for (int i=l[block[t]];i<=t;i++)
		{
			ans=max(ans,a[i]);
		}
	}
	return ans;
}
void update(int x,int y)
{
	maxx[block[x]]=max(maxx[block[x]],y);
	a[x]=y;                         //更新的时候维护最大值数组要更新且原位置也要更新
}
int main()
{
	while (~scanf("%d%d",&n,&m))
	{
		for (int i=1;i<=n;i++)
		{
			a[i]=read();
		}
		build();
		while (m--)
		{
			char c;
			cin>>c;
			int x=read(),y=read();
			if (c=='Q')
			{
				printf("%d\n",query(x,y));
			}
			else
			{
				update(x,y);
			}
		}
	}
	return 0;
}

接下来我们来看一下loj上的9个基础的分块题:

使用langchain实现五种分块策略:语义分块、父文档分块、递归分块、特殊格式、固定长度分块 这篇干货满满的指南会告诉你,五种常见分块的原理和实现: 固定长度分块 - 最简单粗暴,但经常把句子切得面目全非 递归智能分割 - 像削苹果一样,先按段落切,再按句子切,最后才按字符切 语义分块 - 这才是真正的黑科技!通过AI理解文本含义,在语义发生转折的地方精准分割 特别是语义分块,它能分析句子之间的相似度,自动找到最佳的分割点。就像有个超级聪明的助手,知道在哪里"换话题"最合适。 掌握了这些技巧,你的RAG系统检索准确率能提升30%以上!再也不用担心AI答不对问题了。 阅读详情

相关推荐

RAG专栏:分块策略

文档数据(Documents)经过解析后,通过分块技术将信息内容划分为适当大小的文档片段(chunks),从而使 RAG 系统能够高效处理和精准检索这些片段信息。分块的本质在于依据一定逻辑或语义原则,将较长文本拆解为更小的单元。分块策略有多种,各有侧重,选择适合特定场景的分块策略是提升 RAG 系统召回率的关键。

m0_37145844的博客 1359

区间维护(分块大法+卡常)

题目描述: 题目传送门 解题思路: 首先我们先忽略题目的标题(树状数组模板),我们来尝试一种新的算法——分块。 分块思想 分块是一种优美的暴力(by DFT)。他的核心思想在于将一个要维护的区间(长度为 nnn)分成又穷个 n\sqrt nn​ 个子区间来进行分别维护。每个子区间的长度都为 n\sqrt nn​,将我们所要查询的区间所覆盖的每个子区间的信息进行整合,就是我们要查询的区间的信息。 这样子将区间分块来处理有什么好处呢?因为它可以将对一个区间维护的复杂度均摊到每一个长度为 n\sqrt

.SAI.的博客 1171

RAG 常见分块策略全解析:一文了解7种分块方法【附代码】

然而,生成模型(如大型语言模型,LLM)的上下文窗口是有限的,这意味着它能够处理的输入文本长度是有限制的。如果检索到的文本块过大,超出了这个限制,就无法完整地输入到生成模型中,从而可能导致生成的响应不准确或不完整。通过将文档分块,可以确保每个块的大小都在生成模型的上下文窗口范围内,从而使模型能够有效地处理和生成高质量的响应。例如,在一个包含多个主题的长文档中,分块可以将不同主题的内容分割开来,使得检索系统能够针对特定主题进行更精确的检索。在检索增强生成(RAG)系统中,分块策略是决定系统性能的基石。

大F子的智能小课 1334

区间信息维护与查询【分块】 - 原理 分块详解

区间信息维护与查询【分块】 - 原理 分块详解

代码改变世界 767

【算法笔记】分块

之前一直不是很喜欢分块所以没学,现在看来分块这种暴力的艺术倒还是很适合我的… 分块——暴力的艺术 分块算法的思想是通过适当的划分,预处理一部分信息保存下来,用空间换取时间,达到时空平衡。 基本操作是,将一段序列,分成一定数量的块,每一块有一个长度,表示一段区间。对于区间操作,通过对完整块的整体操作和对不完整块的暴力操作而使复杂度尽可能的低 为了使得其有着最稳定的时间复杂度,我们经常将一个长度为 n 的序列分为 n\sqrt nn​ 个大小为 n\sqrt nn​ 的块,如果 n 不是完全平方数,则序列最右端

繁凡さん的博客 1680

05矩阵04——分块矩阵:常用的分块法、分块矩阵的运算

💖💖感谢各位观看这篇文章,💖💖点赞💖💖、收藏💖💖、你的支持是我前进的动力!💖💖 💖💖感谢你的阅读💖,专栏文章💖持续更新!💖关注不迷路!!💖

炫云云 5370

java 反射

public ContinuousPresenceMode ModeStr2Mode(String modestr){ if ("null".equals(modestr) || modestr == null) { return ContinuousPresenceMode.CP_None; } //modestr 参数的形式是3_1,24_1 String modl

YRZHLL的专栏 730

【pprof】简要学习教程

基本介绍 pprof 是在做性能优化前的性能分析工具。 安装: go get -u github.com/google/pprof 分析工具 go tool pprof 是命令行指令,用于分析 Profiling 数据,源数据可以是 http 地址,也可以是已经 dump 下当 profile 文件;查看模式可以命令行交互模式,也可以是浏览器模式(-http 参数)。 两种应用 服务型应用 _ "net/http/pprof" 包,专用于采集 web 服务 运行数据的分析。即在运行的服务中通过 API .

码农印象 883

字符串之模式匹配

/*** @description: 获取模式串在主字符串中的所有首字母出现索引位置(递归版)* @author: cutefrog(injection.mail@gmail.com)* @parameter: $mainstr 主字符串* @parameter: $modestr 模式串* @parameter: $mainpos 主字符串起始索引* @parameter: $modepos 模式串起始索引* @parameter: $matcheds 匹配到的索引数组* @parameter: $lim

457

永磁同步电机ADRC控制策略优化:从理论到Simulink仿真实践

本文深入探讨了永磁同步电机自抗扰控制(ADRC)策略的优化与实践。针对传统PID在动态响应、抗扰及噪声抑制方面的不足,详细解析了ADRC三大核心组件——跟踪微分器(TD)、扩张状态观测器(ESO)与非线性状态误差反馈(NLSEF)的工作原理。通过手把手的Simulink仿真教程,展示了从算法编写、模型搭建到参数整定的完整流程,并进阶实现了位置-速度双环ADRC协同控制,为高性能电机伺服系统设计提供了从理论到实践的清晰指南。

root9的博客 412

史上最全的Logisim运算器实验教程(基于华中科技大学计算机组成原理实验)

本博客是实现了Logisim的运算器设计,有具体的运算器设计的思路和运算器设计的电路,适合一步一步的按照思路做。

qq_62325622的博客 4万+

树状数组维护区间最大值

C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants

Accepted ALL lve 1595

快速上手springboot+vue的前后端分离项目

使用webStorm新建项目后,把 .lock文件删除后项目运行才不报错,配置文件 vue.config.js 中加入 lintOnSave: false 关闭eslint语法检测。在多层嵌套的父子组件之间传递状态已经十分麻烦,而Vue更是没有为兄弟组件提供直接共享数据的办法。基于这个问题,许多框架提供了解决方案——使用全局的状态管理器,将所有分散的共享数据交由状态管理器保管,Vue也不例外。其中一种解决CORS 的方法, 在springboot项目中跨域的方法或类加上@CrossOrigin注解。

m0_61950264的博客 1905

【数论】整除分块(数论分块)

整除分块(数论分块)的介绍,包括复杂度分析,分块边界计算,一般模板,例题及详解

Wmiracle的博客 1万+

[模型部署]-[LLM]昇腾部署Qwen3-Coder-30B-A3B-Instruct

摘要:本文介绍了在Ascend NPU上部署Qwen3-Coder-30B-A3B-Instruct大模型的实践过程。通过vLLM-Ascend框架,详细说明了环境准备(CANN 8.1、PyTorch-NPU 2.5.1等)、模型下载、容器启动及服务部署步骤,包括vLLM服务的启动参数配置和接口测试方法。测试结果显示在当前2卡910B3配置下性能表现仅为8token/s(1并发),并指出流式调用时存在无法输出usage信息的问题。该方案为Ascend平台私有化部署大模型推理服务提供了参考实现。

1671

第4章-上下文管理-对话历史记忆系统与窗口优化-《Agentic AI 智能体应用开发》

当上下文窗口接近极限时,需要对已有内容进行压缩。压缩不是简单的截断——你需要保留核心语义,去除冗余。# Python: 对话摘要压缩# 使用 Haiku 做摘要任务,成本最低"""将一段对话历史压缩为摘要"""system="你是一个对话摘要专家。请生成简洁但有信息量的摘要。",f"'用户'

AI天才研究院 246

详解RAG五种分块策略(二)固定大小分块、语义分块、递归分块、基于文档结构的分块、基于LLM的分块

这种分块适用于文档有清晰的结构,但很多时候,一个文档的结构会比想象中复杂,此外,很多时候文档章节内容大小不一,很容易超过块的大小限制,需要结合递归拆分再进行合并处理。语义分块(Semantic Chunking),根据句子、段落、主题等有语义内涵的单位对文档进行分段创建嵌入,如果第一个段的嵌入与第二个段的嵌入具有较高的余弦相似度,则这两个段形成一个块。在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

Androiddddd的博客 1478

波士顿房价预测分析----以线性回归LinearRegression为例

波士顿房价数据集包括506个样本,每个样本包括13个特征变量和该地区的平均房价,房价显然和多个特征变量相关,先选择一元线性回归与多个特征建立线性方程,观察模型预测的好坏,再选择多元线性回归进行房价预测。13个特征变量缩写含义CRIM城镇人均犯罪率ZN住宅用地所占比例INDUS城镇中非住宅用地所占比例CHAS虚拟变量,用于回归分析NOX环保指数RM每栋住宅的房间数AGE1940 年以前建成的自住单位的比例DIS距离 5 个波士顿的就业中心的加权距离RAD。

我走的每一步都算数 842

大模型RAG中的分块策略(一)什么是分块?分块技术及其策略

分块涉及将文本划分为可管理的单元或“块”,以实现高效处理。这种分割对于语义搜索、信息检索和生成式 AI 应用等任务至关重要。每个块都保留上下文和语义完整性,以确保结果连贯。

Androiddddd的博客 1861

【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能

在探讨计算机性能优化的旅程中,我们常常被引导去关注算法的复杂度、代码的优化,或是更高效的数据结构。然而,有一个经常被忽视的角色在幕后默默地影响着程序的运行效率——那就是缓存(Cache)。正如哲学家亨利·戴维·梭罗在《瓦尔登湖》中所说:“细节是造成美丽的源泉”,在软件开发的世界里,对缓存的理解和优化,就是那些决定程序性能优雅与否的细节。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 3735

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

算法 | 分块查找

算法 | 分块查找 1. 简介 分块查找也称为索引顺序表查找。分块查找就是将顺序表(主表)分成若干个子表,然后为每个子表建立一个索引表,利用索引在其中一个子表中查找。 两部分: 索引表:存储顺序表的每个子表的开始索引和最大值。 顺序表:主表所有数据存放的位置。 1.1. 条件 子表内可以是无序的,但是子表之前面的子表中每个元素必须小于后面子表中的每个元素。 1.2. 分块 纯个人的一些理解,欢迎一起沟通交流 1.2.1. 前言 我第一次看分块查找时也十分纠结应该怎么分块每个子表数据应该多长,什么

yimtcode 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

RAG文本分块

不论是向量化模型还是大语言模型,都存在输入长度的限制。对于超过限制的文本,模型会进行截断,造成语义缺失。分块可以确保每个文本片段都在模型的处理范围内,避免重要信息的丢失。

ngadminq的博客 3011

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【实操实录】深入探讨了RAG系统中的文本分块策略,固定长度、递归字符分块、用文档结构的Markdown/HTML分块、基于语义和主题的高级分块、小-大分块等混合策略、chunk_size设置

本文摘要:文章深入探讨了RAG系统中的文本分块策略,指出分块质量直接影响系统性能。介绍了几种主要分块方法:1)固定长度和递归字符分块等基础策略;2)利用文档结构的Markdown/HTML分块;3)基于语义和主题的高级分块;4)小-大分块等混合策略。强调应根据文档特性选择策略:从递归分块开始,检查结构化特征,在精度不足时尝试语义分块,对复杂文档采用混合策略。文章提供了Python代码示例,并指出合理的chunk_size和chunk_overlap设置对平衡信息完整性与检索精度至关重要。

2402_87515571的博客 1884

RAG分块方法 从固定大小到自然语言处理分块——深入研究文本分块技术

rag分块方法

ECNU_sei_mfj的博客 2889

LLM之RAG实战(三十八)| RAG分块策略之语义分块

这意味着,虽然块的大小不会完全相同,但它们仍然具有相似的大小,并可以利用固定大小块和重叠的优点。:该方法不像上述两种方法一样,它不会使用一定数量的字符或递归过程,而是基于文档的逻辑部分(如段落或小节)来生成对齐的块。我们可以看到,语义分块和Naive分块的结果几乎相同,只是Naive分块对答案的真实表示更好,与语义分块的0.88分相比,得分为0.95。语义分块包括获取文档中每个句子的嵌入,比较所有句子的相似性,然后将嵌入最相似的句子分组在一起。这里的假设是,我们可以使用单个句子的嵌入来生成更有意义的块。

wshzd的博客 7381
上一篇: 二分图的最大团问题
下一篇: [LGOJ]P3033 [USACO11NOV]Cow Steeplechase G
Modestr-E·X·L
博客等级 码龄7年 5粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值