知识库的创建(2) - make_text_splitter 生成文件分割器


前言

我们一起来详细解析 make_text_splitter 方法
在自然语言处理和文本分析中,文本分割是一项重要的任务,尤其是当处理大型文档或连续文本时。make_text_splitter 方法提供了一种灵活且可定制的方式,根据参数获取特定的文本分割器。本文将详细解析该方法的各个部分。

一、 方法定义和参数

def make_text_splitter(
        splitter_name: str = TEXT_SPLITTER_NAME,
        chunk_size: int = CHUNK_SIZE,
        chunk_overlap: int = OVERLAP_SIZE,
        llm_model: str = LLM_MODELS[0],
):
    """
    根据参数获取特定的分词器
    """

参数解析

  • splitter_name: 分割器的名称,默认为 TEXT_SPLITTER_NAME
  • chunk_size: 每个文本块的大小,默认为 CHUNK_SIZE
  • chunk_overlap: 文本块之间的重叠部分,默认为 OVERLAP_SIZE
  • llm_model: 使用的语言模型,默认为 LLM_MODELS[0]

该方法旨在根据给定的参数获取特定的文本分割器实例,以便后续对文本进行分割操作。

二、 分割器选择逻辑

splitter_name = splitter_name or "SpacyTextSplitter"
try:
    if splitter_name == "MarkdownHeaderTextSplitter":  # MarkdownHeaderTextSplitter特殊判定
        headers_to_split_on = text_splitter_dict[splitter_name]['headers_to_split_on']
        text_splitter = langchain.text_splitter.MarkdownHeaderTextSplitter(
            headers_to_split_on=headers_to_split_on)
    else:
        try:  ## 优先使用用户自定义的text_splitter
            text_splitter_module = importlib.import_module('text_splitter')
            TextSplitter = getattr(text_splitter_module, splitter_name)
        except:  ## 否则使用langchain的text_splitter
            text_splitter_module = importlib.import_module('langchain.text_splitter')
            TextSplitter = getattr(text_splitter_module, splitter_name)

步骤解析

  1. 默认分割器设置: 如果 splitter_name 未提供,默认使用 SpacyTextSplitter
  2. Markdown 特殊处理: 如果分割器名称是 MarkdownHeaderTextSplitter,则使用特定的头部信息进行分割。
  3. 加载自定义分割器: 尝试加载用户自定义的分割器模块。
  4. 加载默认分割器: 如果自定义分割器不可用,加载 langchain 库中的分割器。

三、 文本分割器的详细配置

        if text_splitter_dict[splitter_name]["source"] == "tiktoken":  ## 从tiktoken加载
            try:
                text_splitter = TextSplitter.from_tiktoken_encoder(
                    encoding_name=text_splitter_dict[splitter_name]["tokenizer_name_or_path"],
                    pipeline="zh_core_web_sm",
                    chunk_size=chunk_size,
                    chunk_overlap=chunk_overlap
                )
            except:
                text_splitter = TextSplitter.from_tiktoken_encoder(
                    encoding_name=text_splitter_dict[splitter_name]["tokenizer_name_or_path"],
                    chunk_size=chunk_size,
                    chunk_overlap=chunk_overlap
                )
        elif text_splitter_dict[splitter_name]["source"] == "huggingface":  ## 从huggingface加载
            if text_splitter_dict[splitter_name]["tokenizer_name_or_path"] == "":
                config = get_model_worker_config(llm_model)
                text_splitter_dict[splitter_name]["tokenizer_name_or_path"] = \
                    config.get("model_path")

            if text_splitter_dict[splitter_name]["tokenizer_name_or_path"] == "gpt2":
                from transformers import GPT2TokenizerFast
                from langchain.text_splitter import CharacterTextSplitter
                tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
            else:  ## 字符长度加载
                from transformers import AutoTokenizer
                tokenizer = AutoTokenizer.from_pretrained(
                    text_splitter_dict[splitter_name]["tokenizer_name_or_path"],
                    trust_remote_code=True)
            text_splitter = TextSplitter.from_huggingface_tokenizer(
                tokenizer=tokenizer,
                chunk_size=chunk_size,
                chunk_overlap=chunk_overlap
            )
        else:
            try:
                text_splitter = TextSplitter(
                    pipeline="zh_core_web_sm",
                    chunk_size=chunk_size,
                    chunk_overlap=chunk_overlap
                )
            except:
                text_splitter = TextSplitter(
                    chunk_size=chunk_size,
                    chunk_overlap=chunk_overlap
                )

步骤解析

  1. tiktoken 分割器: 根据 tiktoken 加载分割器,尝试使用 zh_core_web_sm 管道。
  2. Huggingface 分割器: 根据 Huggingface 模型加载分割器,如果未指定 tokenizer,使用 get_model_worker_config 获取模型路径。
  3. GPT2 分割器: 使用 GPT2 的分词器进行分割。
  4. 字符长度分割器: 使用 Huggingface 的 AutoTokenizer 进行字符长度分割。
  5. 默认处理: 如果以上配置均不可用,则使用默认分割器配置。

四、 异常处理和最终返回

    except Exception as e:
        print(e)
        text_splitter_module = importlib.import_module('langchain.text_splitter')
        TextSplitter = getattr(text_splitter_module, "RecursiveCharacterTextSplitter")
        text_splitter = TextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
        
    # If you use SpacyTextSplitter you can use GPU to do split likes Issue #1287
    # text_splitter._tokenizer.max_length = 37016792
    # text_splitter._tokenizer.prefer_gpu()
    return text_splitter

五、步骤解析

  1. 异常处理: 捕获并打印异常,如果上述加载方式失败,使用 RecursiveCharacterTextSplitter 作为默认备选方案。
  2. 返回分割器实例: 返回配置好的文本分割器实例。

六、设计模式

make_text_splitter 方法主要使用了设计模式中的 工厂模式(Factory Method)

1. 工厂模式概述

工厂模式是一种创建型设计模式,它提供了一种创建对象的接口,而不是明确指定具体类。工厂方法将实例化对象的过程延迟到子类或函数实现,使得代码更加灵活和可扩展。

2. 如何体现工厂模式

make_text_splitter 方法通过参数(如 splitter_namechunk_sizechunk_overlapllm_model)来决定具体创建哪种文本分割器实例。这种模式提供了一种统一的接口,用于创建不同类型的文本分割器,而不需要在客户端代码中显式地实例化具体的分割器类。

3. 具体分析

1) 接口统一:
- make_text_splitter 方法提供了一个统一的接口,通过传递不同的参数来创建不同的文本分割器实例。

2) 延迟实例化:
- 文本分割器的实例化过程被延迟到方法内部,根据传入的 splitter_name 动态决定具体的分割器类型。

3) 灵活性和扩展性:
- 通过使用 try...except 结构和动态导入模块,该方法可以根据实际需求加载用户自定义的分割器模块或默认的分割器模块。这使得代码更加灵活,并且易于扩展新的分割器类型。

4) 异常处理:
- 在实例化过程中,如果某些分割器的创建失败,该方法能够捕获异常并提供一个默认的分割器作为备选方案,保证了系统的鲁棒性。

5. 工厂模式的优点

1) 代码复用: 提供了统一的对象创建接口,避免了重复的实例化代码。
2) 扩展性: 可以通过修改或增加参数来扩展新的分割器类型,而不需要修改客户端代码。
3) 解耦: 客户端代码与具体的分割器实现解耦,客户端只需要知道如何使用接口,而不需要了解具体的实现细节。

通过上述分析可以看出,make_text_splitter 方法很好地体现了工厂模式的特点,使得文本分割器的创建过程更加灵活、可扩展和易于维护。

总结

make_text_splitter 方法提供了一种灵活的方式,根据参数动态加载和配置文本分割器。它通过多种方式尝试加载指定的分割器,并处理各种特殊情况和异常,确保最终能够返回一个有效的分割器实例。这种设计极大地提高了文本分割的适应性和鲁棒性,使其能够应对不同的文本分割需求和场景。

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 文件分割是一种软件工具,用于将较大的文件分割成多个较小的文件。这种工具通常被用于将大文件分割成若干个部分,以方便在传输、备份或存储时使用。 文件分割的使用方法通常很简单,只需要将待分割文件从软件界面上拖放到指定位置,然后按照设定的参数进行切割即可。用户可以根据需要进行设置,如文件分割数目、每个文件的大小等。 文件分割具有灵活性和便捷性,可以节省空间和时间。它可以让用户更加方便地备份和存储大文件,降低了传输大文件的风险和成本。同时,文件分割也能够避免因为文件过大而导致系统崩溃或运行缓慢的问题。 总之,文件分割是一种实用的工具,可以有效地优化文件管理和传输,提高工作效率和数据安全性。 ### 回答2: 文件分割file-splitter指的是一种软件工具,它可以将单个大文件分割成若干个较小的文件,方便进行传输、备份、存储和处理等应用。同时,该工具也可以对分割后的文件进行合并操作,恢复原始文件文件分割的使用非常简单,用户只需要选择需要分割文件,设置分割的大小或数量,即可完成分割操作。分割后的文件具有独立性,可以远程传输、储存和处理,不会对原始文件产生影响。在一些网络传输场景中,大文件可能会被网络中断或者过于繁忙等原因导致传输失败。使用文件分割,可以将文件分割成若干小文件,这样即使遇到网络中断或过于繁忙等问题,只需重新传输失败的文件分割部分,而不需要重新传输整个大文件,节约时间和带宽。 除了网络传输场景,文件分割在备份和存储场景中也有着广泛的应用。备份一个大文件比备份若干个小文件更容易和更高效。而对于存储场景,如果硬盘空间不足,可以将一个大文件分割成若干个小文件存储在多个硬盘上,这样既不占用大量空间,又可以防止因硬盘故障而造成文件的丢失。 总之,文件分割在数据传输、备份和存储方面都有着广泛的应用,极大地方便了我们的数据处理和管理。 ### 回答3: 文件分割(file-splitter)是一种可以将一个大文件分割成多个小文件的工具软件。使用文件分割可以在不改变数据内容的情况下,将文件分割为多个小文件,方便传输、存储和备份。 文件分割的主要功能是将大文件切割成指定大小的若干个小文件,同时还可以设置文件分割的数量和文件名格式。这样,用户就可以将大文件分割成若干个小文件,在传输或存储文件时更加方便。同时,文件分割还支持对分割后的文件进行合并操作,将多个小文件合并成一个大文件文件分割具有以下优点:一是文件分割后可以方便地进行存储和传输,且更加安全可靠;二是文件分割后的小文件可以更快地传输,也可以防止因网络传输中断而导致整个文件传输失败的情况发生;三是文件分割具有较高的灵活性,用户可以根据自己的需要制定文件分割的大小和数量,同时也可以进行合并操作,满足了用户的不同需求。 总之,文件分割是一款非常实用的工具软件,可以方便地将大文件分割成若干个小文件,更加便于存储、传输和备份。同时,文件分割还具有灵活性高、操作简便等优点,非常适合各种用户使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值