openPangu-7B-Diffusion-Base性能评测:超越主流模型的65.26平均分表现
Chonkie分块算法原理解析:语义分块与递归分块的技术内幕
Chonkie是一个轻量级、高效的文本分块库,专为RAG(检索增强生成)管道设计。在当今AI应用中,文本分块是处理长文档、构建知识库和优化检索性能的关键技术。本文将深入解析Chonkie中两种核心分块算法——语义分块(Semantic Chunking)和递归分块(Recursive Chunking)的技术原理与实现细节。
语义分块算法:基于语义相似度的智能分组
语义分块算法是Chonkie中最智能的分块策略之一,它通过计算文本中句子之间的语义相似度来确定最佳的分块边界。与传统的固定长度分块不同,语义分块能够根据内容主题自然划分文本,确保相关的内容被分到同一个块中。
核心技术原理
语义分块的核心思想是利用句子嵌入向量(embeddings)来计算句子之间的语义相似度。算法主要包含以下几个关键步骤:
- 句子分割:首先将文本分割成句子,使用标点符号(如句号、问号、感叹号)和换行符作为分隔符
- 嵌入计算:为每个句子生成嵌入向量,使用预训练的嵌入模型(如minishlab/potion-base-32M)
- 相似度分析:计算滑动窗口中句子与窗口整体内容的语义相似度
- 边界检测:使用Savitzky-Golay滤波器平滑相似度曲线,检测局部最小值作为分块边界
- 智能合并:通过skip-window机制合并语义相似的非连续内容块
算法实现细节
在Chonkie的语义分块器实现中(src/chonkie/chunker/semantic.py),有几个关键技术点值得关注:
相似度计算优化:算法采用窗口化交叉相似度计算,而不是简单的两两句子比较。这种方法能够更好地捕捉上下文关系,生成更连贯的分块结果。
# 核心相似度计算函数
def _get_similarity(self, sentences: list[Sentence]) -> list[float]:
window_embeddings = self._get_window_embeddings(sentences)
sentence_embeddings = self._get_sentence_embeddings(sentences)
similarities = [
float(self.embedding_model.similarity(w, s))
for w, s in zip(window_embeddings, sentence_embeddings)
]
return similarities
边界检测算法:使用Savitzky-Golay滤波器对相似度曲线进行平滑处理,然后检测局部最小值作为分块边界。这种方法能够有效减少噪声干扰,找到更自然的语义边界。
skip-window合并机制:当skip_window > 0时,算法会检查非连续的语义相似块并进行合并,这对于处理交替主题的文档特别有用。
图:Chonkie语义分块可视化效果,不同颜色代表不同的语义块
递归分块算法:层次化文本分割策略
递归分块是Chonkie中处理结构化文档的另一种强大策略。它通过多级分隔符层次结构,从粗粒度到细粒度逐步分割文本,特别适合处理具有明确层次结构的文档。
层次化分割原理
递归分块的核心是RecursiveRules对象,它定义了不同层次的分隔符规则。算法按照以下层次结构工作:
- 第一级分割:使用段落分隔符(如双换行符)分割文档
- 第二级分割:使用句子分隔符(如句号、问号)进一步分割
- 第三级分割:使用短语分隔符或按token数量分割
- 递归处理:对每个分割后的片段,如果仍然超过chunk_size限制,则进入下一级分割
规则系统设计
在src/chonkie/chunker/recursive.py中,递归分块器使用RecursiveRules对象来定义分割规则:
# 递归分割的核心逻辑
def _split_text(self, text: str, recursive_level: RecursiveLevel) -> list[str]:
if recursive_level.delimiters:
# 使用分隔符分割
include_mode = recursive_level.include_delim or "prev"
# ... 分割逻辑实现
elif recursive_level.whitespace:
# 使用空格分割
# ... 分割逻辑实现
else:
# 按token数量分割
encoded = self.tokenizer.encode(text)
token_splits = [
encoded[i : i + self.chunk_size] for i in range(0, len(encoded), self.chunk_size)
]
splits = list(self.tokenizer.decode_batch(token_splits))
return splits
智能合并策略
递归分块器还实现了智能合并机制,确保分割后的片段不会过小:
def _merge_splits(self, splits: list[str], token_counts: list[int]) -> tuple[list[str], list[int]]:
"""合并过小的分割片段"""
if not splits or not token_counts:
return [], []
# 使用chonkie-core的Rust实现进行高效合并
result = chonkie_core.merge_splits(splits, token_counts, self.chunk_size)
return result.merged, result.token_counts
两种算法的对比与应用场景
语义分块的适用场景
语义分块最适合以下场景:
- 主题连贯的文档:如技术文档、学术论文、新闻报道
- RAG系统优化:需要保持上下文完整性的检索任务
- 多主题长文档:需要智能识别主题边界的情况
- 对话式内容:保持对话连贯性的分块需求
递归分块的适用场景
递归分块最适合以下场景:
- 结构化文档:如Markdown、HTML、LaTeX文档
- 代码文件:具有明确语法结构的源代码
- 层次化内容:如书籍章节、法律文档、技术规范
- 多语言混合文档:需要不同语言特定规则的情况
性能优化与实现技巧
Rust核心加速
Chonkie在关键路径上使用了Rust实现(chonkie-core)来提升性能。这包括:
- SIMD加速的分割操作:利用现代CPU的SIMD指令集加速文本分割
- 零拷贝内存管理:减少Python与Rust之间的数据复制开销
- 并行处理支持:为大规模文档处理提供并行计算能力
内存效率优化
两种分块算法都采用了流式处理设计:
- 惰性计算:只在需要时计算嵌入向量
- 批量处理:对多个句子或文档进行批量嵌入计算
- 内存复用:重用中间计算结果,减少内存分配
实际应用示例
语义分块配置示例
from chonkie import SemanticChunker
# 配置语义分块器
chunker = SemanticChunker(
embedding_model="minishlab/potion-base-32M",
threshold=0.7, # 相似度阈值
chunk_size=512, # 最大token数
similarity_window=3, # 相似度计算窗口
skip_window=1, # 允许跳过1个不相似块进行合并
filter_window=5, # Savitzky-Golay滤波窗口
filter_polyorder=3, # 滤波器多项式阶数
min_sentences_per_chunk=2 # 最小句子数
)
递归分块配置示例
from chonkie import RecursiveChunker, RecursiveRules
# 创建自定义递归规则
rules = RecursiveRules([
{"delimiters": ["\n\n"], "include_delim": "prev"}, # 第一级:段落
{"delimiters": [". ", "! ", "? "], "include_delim": "prev"}, # 第二级:句子
{"whitespace": True} # 第三级:按空格分割
])
chunker = RecursiveChunker(
chunk_size=2048,
rules=rules,
min_characters_per_chunk=24
)
技术架构优势
模块化设计
Chonkie的分块器采用模块化设计,每个分块器都继承自BaseChunker基类,确保接口一致性。这种设计使得:
- 易于扩展:可以轻松添加新的分块算法
- 统一API:所有分块器都提供相同的接口
- 组合使用:可以链式组合不同的分块策略
可配置性
两种分块算法都提供了丰富的配置选项:
- 阈值调整:语义分块的相似度阈值可调
- 规则定制:递归分块的分隔符规则可完全自定义
- 性能调优:支持批量大小、并行度等性能参数调整
多语言支持
Chonkie内置对56种语言的支持,包括:
- 多语言分隔符:支持不同语言的句子边界识别
- 语言特定规则:为不同语言提供优化的分块策略
- Unicode兼容:完全支持Unicode字符集
总结
Chonkie的语义分块和递归分块算法代表了现代文本处理的两个重要方向:基于语义的智能分割和基于结构的层次化分割。这两种算法各有优势,可以满足不同场景下的分块需求。
语义分块通过深度理解文本内容,实现了真正意义上的"智能分块",特别适合需要保持语义连贯性的应用场景。而递归分块则通过层次化规则系统,为结构化文档提供了精确可控的分割策略。
在实际应用中,开发者可以根据文档类型、处理需求和性能要求,灵活选择或组合使用这两种算法。Chonkie的模块化设计和丰富的配置选项,使得分块策略的调优变得简单而高效。
通过深入理解这些算法的技术原理,开发者可以更好地利用Chonkie构建高效的文本处理管道,为RAG系统、文档分析、内容管理等应用提供强大的基础支持。
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐


所有评论(0)