MetaX-Tech Developer Forum
  • 沐曦开发者
search
Sign in

ddddys

  • Members
  • Joined 2025年7月4日
  • message 帖子
  • forum 主题
  • favorite 关注者
  • favorite_border Follows
  • person_outline 详细信息

ddddys has posted 1 message.

  • See post chevron_right
    ddddys
    Members
    langch智算n实现文本分割 教学相长 2025年7月4日 17:39
    1. CharacterTextSplitter按字符拆分

    它根据字符(默认为 "\n\n")进行拆分,并通过字符数来衡量块的长度。

    使用样例:
    加载word文档并分割:将字符分割CharacterTextSplitter作为text_splitter划分标准,可以划分docx文件:
    from langch智算n.document_loaders import UnstructuredFileLoader
    from langch智算n.text_splitter import CharacterTextSplitter
    loader = UnstructuredFileLoader('xxx/xx.docx', mode="elements")
    docs_all = loader.load() # 这里加载文档。
    text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0) # 换行划分\n\n
    docs = text_splitter.split_documents(docs_all)

    (注:chunk_overlap 是指拆分后的每个 块里包含几个上一个 块结尾的内容,主要作用是为了增加每个 块的上下文关联。比如,chunk_overlap=0时, 第一个 块为 12345,第二个为 6789;当 chunk_overlap=2 时,第一个 document 为 12345,第二个为 456789。chunk_size指块大小)

    1. 递归按照字符划分:RecursiveCharacterTextSplitter

    递归按字符切分,它由一个字符列表参数化。它按照优先级顺序依次尝试分割文本,若使用这些分隔符分割后 chunk 大小仍超出指定范围,则会进一步递归地选择其他分隔符进行分割,直至达到所需的 chunk 大小。默认列表是["\n\n", "\n", " ", ""]。这样做的效果是尽可能保持所有段落(然后句子,然后单词)在一起,因为它们在语义上通常是最相关的文本片段。

    使用样例:
    from langch智算n.text_splitter import RecursiveCharacterTextSplitter
    r_splitter = RecursiveCharacterTextSplitter(
    chunk_size=10,
    chunk_overlap=0,
    separators=["\n"]
    ) # 自定义切分
    test = """a\nbcefg\nhij\nk"""
    print(len(test))
    text = r_splitter.split_text(test) # test没进过加载器

    (解释:这里打印出来test长度为13,'\n'长度为1。我们自定义按照'\n'切分,但chunk_size很影响结果,优先以分割符为准,如果分割后的长度超过chunk_size没办法就不管他,但如果两块分割后的求和可以小于chunk_size则将它们合并,尽量保持语义的完整。比如:
    chunk_size=2时切分为['a', '\nbcefg', '\nhij', '\nk']
    chunk_size=5时切分为['a', '\nbcefg', '\nhij', '\nk']
    chunk_size=6时切分为['a', '\nbcefg', 'hij\nk'] -> 这里可以合并‘hij\nk’因为长度不超过chunk_size
    chunk_size=10时切分为['a\nbcefg', 'hij\nk']
    chunk_size=13时切分为['a\nbcefg\nhij\nk']
    这个好处就是尽量让分割后的能合并成不超过chunk_size的连续语句,如果希望段和段也要关联,则增大chunk_overlap。)

    1. SpacyTextSplitter(另有open智算 的embeding模型)

    基于语义进行分割,利用 Spacy 的语言模型来识别句子结构和语义边界,将文本分割成有意义的句子或短语作为 chunk。需要加载特定的语言模型来实现具体的功能,如加载英语模型 en_core_web_sm 或中文模型 zh_core_web_sm。

    使用样例:
    with open('../../../state_of_the_union.txt') as f:
    loader = f.read()
    from langch智算n.text_splitter import SpacyTextSplitter
    text_splitter = SpacyTextSplitter(
    pipeline="zh_core_web_sm",
    chunk_size=200,
    chunk_overlap=0,)# 有三种
    texts = text_splitter.split_text(loader)
    texts = text_splitter.split_documents(loader)
    texts = loader.load_and_split(text_splitter)

    (注:zh_core_web_sm 是 spacy 库中为中文提供的一个预训练模型,和 en_core_web_sm 类似,但针对中文进行了优化和训练,能够处理中文的分词、词性标注、命名实体识别等任务。
    en_core_web_sm是 spacy 库中为英语提供的一个预训练模型,是英语多任务 CNN,在 OntoNotes 上训练,大小为 11MB。它包含了基本的 NLP 工具,如分词、词性标注和命名实体识别等。)

    创建好分割器之后,根据输入的数据形式分为:
    如果经过非结构化数据类型UnstructuredFileLoader将文档加载成loader这种, 使用loader.load_and_split(text_splitter)或 text_splitter.split_documents(loader)
    如果是单纯的字符串string,使用text_splitter.split_text(text)
    stuff: 这种最简单粗暴,会把所有的 document 一次全部传给 llm 模型进行总结。如果document很多的话,势必会报超出最大 token 限制的错,所以总结文本的时候一般不会选中这个。
    map_reduce: 这个方式会先将每个 document 进行总结,最后将所有 document 总结出的结果再进行一次总结。
    refine: 这种方式会先总结第一个 document,然后在将第一个 document 总结出的内容和第二个 document 一起发给 llm 模型在进行总结,以此类推。这种方式的好处就是在总结后一个 document 的时候,会带着前一个的 document 进行总结,给需要总结的 document 添加了上下文,增加了总结内容的连贯性。
    这种一般不会用在总结的 ch智算n 上,而是会用在问答的 ch智算n 上,他其实是一种搜索答案的匹配方式。首先你要给出一个问题,他会根据问题给每个 document 计算一个这个 document 能回答这个问题的概率分数,然后找到分数最高的那个 document ,在通过把这个 document 转化为问题的 prompt 的一部分(问题+document)发送给 llm 模型,最后 llm 模型返回具体答案
    关于langch智算n的mapreduce策略的并行实现:

    Combine_docs方法中的Apply方法

    Apply方法中的generate方法

    Generate中的batch方法实现并行?

    用到了batch方法去并行地处理提示词,注意这里的base.py文件是runnable的,如下所示

    随后batch方法中调用到的self.invoke()方法是属于ch智算n 中实现的(是ch智算n继承了runnable类,runnable中的invoke方法是在ch智算n中实现的):

  • 沐曦开发者论坛
powered by misago