
快速准确的文本语义分块Python库
semchunk是一个高效的Python文本分块库,能将文本分割成语义连贯的片段。与同类库相比,它在语义准确性和处理速度方面都有显著提升。该库采用先进的分块算法,兼容多种分词器和token计数工具,可处理单条或批量文本,并支持多进程加速。semchunk适用于大规模文本处理和各类自然语言分析任务。
<a href="https://pypi.org/project/semchunk/" alt="PyPI 版本"><img src="https://img.shields.io/pypi/v/semchunk"></a> <a href="https://github.com/umarbutler/semchunk/actions/workflows/ci.yml" alt="构建状态"><img src="https://img.shields.io/github/actions/workflow/status/umarbutler/semchunk/ci.yml?branch=main"></a> <a href="https://app.codecov.io/gh/umarbutler/semchunk" alt="代码覆盖率"><img src="https://img.shields.io/codecov/c/github/umarbutler/semchunk"></a> <a href="https://pypistats.org/packages/semchunk" alt="下载量"><img src="https://img.shields.io/pypi/dm/semchunk"></a>
semchunk是一个快速轻量的Python库,用于将文本分割成语义有意义的块。
由于其复杂而高效的分块算法,semchunk在语义准确性上比langchain.text_splitter.RecursiveCharacterTextSplitter更优(参见工作原理🔍),同时也比semantic-text-splitter快90%以上(参见基准测试📊)。
可以使用pip安装semchunk:
pip install semchunk
以下代码片段演示了如何使用semchunk对文本进行分块:
import semchunk from transformers import AutoTokenizer # `transformers`和`tiktoken`都不是必需的, import tiktoken # 这里仅用于演示目的。 chunk_size = 2 # 这里使用较小的块大小仅用于演示。请注意, # 除非使用自定义token计数器,否则`semchunk`不会考虑特殊token, # 所以你可能需要将块大小减去tokenizer添加的特殊token数量。 text = 'The quick brown fox jumps over the lazy dog.' # 如下所示,`semchunk.chunkerify`接受所有OpenAI模型名称、OpenAI `tiktoken`编码和 # Hugging Face模型(按此优先顺序),以及具有`encode()`方法的自定义tokenizer #(如`tiktoken`、`transformers`和`tokenizers`的tokenizer),最后是任何能接受文本 # 并返回其token数量的函数。 chunker = semchunk.chunkerify('umarbutler/emubert', chunk_size) or \ semchunk.chunkerify('gpt-4', chunk_size) or \ semchunk.chunkerify('cl100k_base', chunk_size) or \ semchunk.chunkerify(AutoTokenizer.from_pretrained('umarbutler/emubert'), chunk_size) or \ semchunk.chunkerify(tiktoken.encoding_for_model('gpt-4'), chunk_size) or \ semchunk.chunkerify(lambda text: len(text.split()), chunk_size) # 生成的`chunker`可以处理单个文本或文本列表,分别返回块列表或块列表的列表。 assert chunker(text) == ['The quick', 'brown', 'fox', 'jumps', 'over the', 'lazy', 'dog.'] assert chunker([text], progress = True) == [['The quick', 'brown', 'fox', 'jumps', 'over the', 'lazy', 'dog.']] # 如果你有大量文本需要分块,且速度是一个考虑因素,你也可以通过将`processes`设置为大于1的数值来启用多进程。 assert chunker([text], processes = 2) == [['The quick', 'brown', 'fox', 'jumps', 'over the', 'lazy', 'dog.']]
def chunkerify( tokenizer_or_token_counter: str | tiktoken.Encoding | transformers.PreTrainedTokenizer | \ tokenizers.Tokenizer | Callable[[str], int], chunk_size: int = None, max_token_chars: int = None, memoize: bool = True, ) -> Callable[[str | Sequence[str], bool, bool], list[str] | list[list[str]]]:
chunkerify()构建一个分块器,将一个或多个文本分割成由指定tokenizer或token计数器确定大小的语义有意义的块。
tokenizer_or_token_counter可以是:tiktoken或transformers tokenizer的名称(优先考虑前者);具有encode属性的tokenizer(例如tiktoken、transformers或tokenizers的tokenizer);或返回输入token数量的token计数器。
chunk_size是一个块可能包含的最大令牌数。它默认为None,在这种情况下,它将被设置为与分词器的model_max_length属性相同的值(减去尝试对空字符串进行分词返回的令牌数),如果可能的话;否则将引发ValueError。
max_token_chars是一个令牌可能包含的最大字符数。它用于显著加快长输入的令牌计数。它默认为None,在这种情况下,要么不使用它,要么如果可能,将其设置为分词器词汇表中最长令牌的字符数,由token_byte_values或get_vocab方法确定。
memoize标志是否对令牌计数器进行记忆化。它默认为True。
此函数返回一个分块器,它接受单个文本或一系列文本,如果提供了单个文本,则返回最多chunk_size个令牌长的块列表,去除用于分割文本的任何空白;如果提供了多个文本,则返回块的列表列表,每个内部列表对应于所提供输入文本之一的块。
生成的分块器可以传递一个processes参数,指定在对多个文本进行分块时要使用的进程数。
还可以传递一个progress参数,如果设置为True并且传递了多个文本,将显示一个进度条。
从技术上讲,分块器将是semchunk.Chunker类的一个实例,以协助类型提示,尽管这应该不会影响其使用方式。
def chunk( text: str, chunk_size: int, token_counter: Callable, memoize: bool = True, ) -> list[str]
chunk()函数将文本分割成语义上有意义的块,大小由提供的令 牌计数器确定。
text是要分块的文本。
chunk_size是一个块可能包含的最大令牌数。
token_counter是一个可调用对象,它接受一个字符串并返回其中的令牌数。
memoize标志是否对令牌计数器进行记忆化。它默认为True。
此函数返回最多chunk_size个令牌长的块列表,去除用于分割文本的任何空白。
semchunk通过递归分割文本,直到所有结果块等于或小于指定的块大小。具体而言,它:
为确保块在语义上尽可能有意义,semchunk按以下优先顺序使用以下分割器:
\n)和/或回车符(\r)序列;\s字符类定义);.、?、!和*);;、,、(、)、[、]、"、"、'、'、'、"和`);:、—和…);/、\、–、&和-);