开发基于大模型的RAG应用时,文本拆分是一个非常基础的功能。在拆分一个大文本时我们往往会要求拆分效率高并且拆分后的chunk语义完整,完整的语义对后面检索出精确的内容非常有意义。
semchunk 是一个快速、轻量且易于使用的 Python 库,用于将文本拆分为语义上有意义的块。我们切分文本数据时,可以自定义文本切分逻辑,可以使用 langchain 的 RecursiveCharacterTextSplitter,也可以使用semchunk 来切分文本。
semchunk的原理是:递归地拆分文本,直到所有生成的块都等于或小于指定的块大小。
- 使用语义上最有意义的分割器来分割文本;
- 递归地分割生成的块,直到产生一组等于或小于指定块大小的块;
- 将小于块大小的所有块合并在一起,直到达到块大小;
- 如果这样做不会使块超过块大小,则将所有非空白分割器重新附加到块的末尾(最后一个块除外),否则将非空白分割器添加为它们自己的块。
为了确保块尽可能具有语义意义, semchunk
按优先顺序使用以下分割器:
- 最大的换行符序列(
\n
)和/或回车符序列(\r
); - 最大的标签序列;
- 最大的空白字符序列(由正则表达式的
\s
字符类定义),或者,自版本 3.2.0 起,如果最大的空白字符序列只有一个字符,并且存在以任何语义上有意义的非空白字符开头的空白字符下面列出(按相同的优先级顺序),那么只有那些特定的空白字符; - 句子终止符(
.
、?
、!
和*
); - 子句分隔符(
;
,
(
、)
、[
、]
、“
、”
、'
、'
、'
、"
和 ``` ); - 句子中断词(
:
、—
和…
); - 单词连接符(
/
、\
、–
、&
和-
);以及 - 所有其他字符。
如果请求了重叠的块, semchunk
还会:
- 在内部将块大小减小到
min(overlap, chunk_size - overlap)
(对于相对重叠,overlap
计算为floor(chunk_size * overlap)
,对于绝对重叠,重叠计算为min(overlap, chunk_size - 1)
);并且 - 从第一个块开始合并每
floor(original_chunk_size / reduced_chunk_size)
个块,然后跳过floor((original_chunk_size - overlap) / reduced_chunk_size)
个块,直到到达最后一个块。
安装:
1 | pip install semchunk -i https://pypi.tuna.tsinghua.edu.cn/simple |
使用 chunkerify() 方法返回一个切分器实例,并用这个实例切分文本:
1 | import semchunk |
使用 chunk() 方法切分文本:
1 | import semchunk |
semchunk的github地址:https://github.com/isaacus-dev/semchunk