文本语义分块、RAG 系统的分块难题:小型语言模型如何找到最佳断点?
转自jina最新的关于文本语义分块的分享和模型
之前我们聊过 RAG 里文档分块 (Chunking) 的挑战,也介绍了 迟分 (Late Chunking) 的概念,它可以在向量化的时候减少上下文信息的丢失。今天,我们来聊聊另一个难题:如何找到最佳的分块断点。
虽然迟分对边界位置不敏感,但也不代表我们可以随便乱切,毕竟可读性对人和大模型都很重要。所以我们现在的思路是:既然用了迟分,就不用太担心语义或上下文丢失的问题。边界好坏,迟分都能处理,因此文本块的可读性就成了关键。
基于这个想法,我们训练了三个小型语言模型 (SLM),专门用来切分长文档,同时保证语义连贯性,并且能够处理复杂的文档结构,比如代码、表格等等。它们分别是:
simple-qwen-0.5
,根据文档的结构元素进行切分,简单直接。https://huggingface.co/jinaai/text-seg-lm-qwen2-0.5btopic-qwen-0.5
:灵感来自思维链 (Chain-of-Thought) 推理,它会先识别文本中的主题,再根据主题进行切分。初步测试显示,它的切分结果非常符合人类的直觉。https://huggingface.co/jinaai/text-seg-lm-qwen2-0.5b-cot-topic-chunkingsummary-qwen-0.5
:不仅能切分文档,还能生成每个分块的摘要,在 RAG 应用中非常有用。https://huggingface.co/jinaai/text-seg-lm-qwen2-0.5b-summary-chunking
接下来,我们会聊聊我们为什么要开发这三个模型,它们各自的特点,以及它们和 Jina AI 的 Segmenter API 的效果对比。最后,还将分享我们学到的东西和对未来的一些想法。
传统分块存在的问题
**RAG 系统里,文档分块是核心问题。**文本块的质量好坏直接影响检索和生成效果,答案相关性、摘要质量都逃不掉它的影响。
传统的那些分块方法,像固定 token 长度、固定句子数量,或者高级点的用正则表达式,都忽略了语义边界。结果就是,碰上主题模糊的内容,分出来的块就支离破碎,即使后来用迟分生成带上下文的向量也救不回来。
因为 LLM 要想生成准确的答案,依赖的是连贯、结构良好的数据。要是分出来的文本块本身就没啥意义,LLM 理解上下文都费劲,更别说保证准确性了,最终影响整体性能。
所以,我们专门训练了小型语言模型来做分块,目标很明确:捕捉主题转换,保证文本块的连贯性,同时兼顾效率和通用性。
为什么要用小型语言模型?
那为什么要用小型语言模型 (Small Language Model, SLM) 来解决呢?
因为传统的分块技术在处理代码、表格、列表、公式这些复杂结构时容易翻车。它们通常只看 token 数量或结构规则,不理解语义,很难保证语义连贯内容的完整性。就容易导致代码片段被切得七零八落,上下文信息丢失,下游系统理解和检索都很抓瞎。
我们训练了专门的 SLM,就是想让它能够智能地识别并保留这些有意义的边界,保证相关元素不被拆散。这样 RAG 系统的检索质量提高了,摘要、问答等下游任务的效果也能更好了。相比传统那些死板的分块方法,SLM 的方案更灵活,也更具针对性。
一口气训练了 3 个小模型
我们训练了三个版本的 SLM:
simple-qwen-0.5
: 这是最简单的模型,主要根据文档的结构元素识别边界。它简单高效,适合基本的分块需求。topic-qwen-0.5
: 这个模型受到了思维链 (Chain-of-Thought) 推理的启发,它会先识别文本中的主题,比如“第二次世界大战的开始”,然后用这些主题来定义分块边界。它能保证每个文本块在主题上保持连贯,特别适合处理复杂的多主题文档。初步测试表明,它分块的效果很不错,很接近人类的直觉。summary-qwen-0.5
: 这个模型不仅能识别文本边界,还能给每个文本块生成摘要。在 RAG 应用里,文本块摘要很有用,尤其是在长文档问答这种任务上。当然,代价就是训练时需要更多的数据。
这三个模型都只返回文本块的头部,也就是每个文本块的截断版本。它们不生成完整的文本块,而是输出关键点或子主题。简单来说,因为它只提取关键点或子主题,这就相当于抓住了片段的核心意思,通过文本的语义转换,来更准确地识别边界,保证文本块的连贯性。
检索的时候,我们会根据这些“文本块头部”把文档文本切片,然后再根据切片结果重建完整的片段。相当于我们先用“文本块头部”做了个索引,需要的时候再根据索引找到对应的完整片段。这样既能保证检索的精准度,又能提高效率,避免处理过多的冗余信息。
数据集
我们使用了 wiki727k (https://github.com/koomri/text-segmentation