chatchat-space / Langchain-Chatchat

Langchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM, Qwen 与 Llama 等语言模型的 RAG 与 Agent 应用 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM, Qwen and Llama) RAG and Agent app with langchain
Apache License 2.0
31.81k stars 5.55k forks source link

文档输入每行多增加了个\n #2939

Closed qianma819 closed 8 months ago

qianma819 commented 8 months ago

原文档数据: 异常和中断的区别 在MIPS体系结构中,中断、自陷、系统调用以及其它打断程序正常执行流程的事件称为异常, 即异常包括中断,中断是一种特定类型的异常。 龙芯1c的异常分为四级

第一级: 各种情况下异常的总入口 调用的分词器是AliTextSplitter。在class AliTextSplitter增加log查看文档数据 class AliTextSplitter(CharacterTextSplitter): def init(self, pdf: bool = False, kwargs): super().init(kwargs) self.pdf = pdf

def split_text(self, text: str) -> List[str]:
    # use_document_segmentation参数指定是否用语义切分文档,此处采取的文档语义分割模型为达摩院开源的nlp_bert_document-segmentation_chinese-base,论文见https://arxiv.org/abs/2107.09278
    # 如果使用模型进行文档语义切分,那么需要安装modelscope[nlp]:pip install "modelscope[nlp]" -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html
    # 考虑到使用了三个模型,可能对于低配置gpu不太友好,因此这里将模型load进cpu计算,有需要的话可以替换device为自己的显卡id
    **print(text)**
    if self.pdf:
        text = re.sub(r"\n{3,}", r"\n", text)
        text = re.sub('\s', " ", text)
        text = re.sub("\n\n", "", text)

结果发现读取的数据跟原数据不一致: 异常和中断的区别

在MIPS体系结构中,中断、自陷、系统调用以及其它打断程序正常执行流程的事件称为异常,

即异常包括中断,中断是一种特定类型的异常。

龙芯1c的异常分为四级

第一级: 各种情况下异常的总入口。

第一行跟第二行中间增加了一个空行。原先的双空行也变成了一个空行。这个是哪地方做了特殊处理?

dosubot[bot] commented 8 months ago

🤖

@qianma819 你好呀,又见面了!希望你今天心情不错 😊

您的问题出现在SummaryAdapter类的_join_docs_drop_overlap方法中。

_join_docs方法使用类的_separator属性(设置为"\n\n")来连接文档,这就是在第一行和第二行之间添加了额外的换行符的地方。这是相关的代码:

def _join_docs(self, docs: List[str]) -> Optional[str]:
    text = self._separator.join(docs)
    text = text.strip()
    if text == "":
        return None
    else:
        return text

至于为什么双换行符被减少到单个换行符,这是在SummaryAdapter类的_drop_overlap方法中发生的。这个方法删除了连续文档之间的重叠部分。如果重叠恰好在换行符处,它将被删除,将双换行符减少到单个换行符。这是相关的代码:

def _drop_overlap(self, docs: List[DocumentWithVSId]) -> List[str]:
    merge_docs = []
    pre_doc = None
    for doc in docs:
        if len(merge_docs) == 0:
            pre_doc = doc.page_content
            merge_docs.append(doc.page_content)
            continue
        for i in range(len(pre_doc), self._OVERLAP_SIZE // 2 - 2 * len(self._separator), -1):
            pre_doc = pre_doc[1:]
            if doc.page_content[:len(pre_doc)] == pre_doc:
                merge_docs.append(doc.page_content[len(pre_doc):])
                break
        pre_doc = doc.page_content
    return merge_docs

源代码:

关于AliTextSplitter类的作用以及它如何与Langchain-Chatchat代码库的其余部分交互的问题,AliTextSplitter类是CharacterTextSplitter的子类,用于将文本分割成段落。它特别设计用来处理PDF的文本,如其构造函数中的pdf参数所示。

split_text方法是这个类的主要功能。它接收一个文本字符串作为输入,并返回一个分段的文本列表。如果pdf参数设置为True,它会对文本进行一些预处理,以删除过多的换行符和空格。

split_text方法使用modelscope.pipelines包中的一个文档分割模型来执行实际的文本分割。使用的模型是damo/nlp_bert_document-segmentation_chinese-base,这是一个用于文档分割的中文语言模型。模型被加载到CPU中进行计算,但如果需要,可以更改为GPU。

分割的文本然后被分割成一个句子列表,这些句子由方法返回。

在与Langchain-Chatchat代码库的其余部分的交互方面,AliTextSplitter类将在需要文本分割的地方使用,例如在将文本输入到语言模型进行问题回答或其他NLP任务的预处理步骤中。 源代码:

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

qianma819 commented 8 months ago

@dosu-bot 我增加了打印,发现增加一个doc文件到知识库,并没有进入def _join_docs这个类。这是什么情况?还在哪地方处理了?

dosubot[bot] commented 8 months ago

🤖

关于您提到的文档输入每行多增加了个\n的问题,这是由于在处理文档内容时,代码中有一行 context = "\n".join([doc.page_content for doc in docs])。这行代码将docs列表中每个文档的页面内容用换行符连接起来。这通常是为了在合并多个文本文档时保持可读性和结构。

至于添加doc文件到知识库并没有触发_join_docs方法的问题,这是因为提供的上下文中并没有引用或使用_join_docs方法。提供的代码是处理知识库聊天功能的knowledge_base_chat函数,它并不处理向知识库添加新文档的功能。_join_docs方法可能是另一个未在提供的上下文中包含的模块或函数的一部分。因此,如果没有关于_join_docs方法的额外上下文或信息,就无法提供一个确定的答案,解释为什么在向知识库添加doc文件时没有触发它。

关于AliTextSplitter类的问题,这个类是CharacterTextSplitter的子类,它的目的是将输入文本分割成一个句子或段落的列表。这在自然语言处理任务中非常有用,因为需要将输入文档分解成更小、易于管理的片段进行进一步处理。

AliTextSplitter类在其split_text方法中与输入文档交互。如果pdf属性设置为True,它首先对输入文本进行一些预处理,以删除过多的换行符和空格。

然后,它使用modelscope.pipelines包中的文档分割模型将文本分割成段落。使用的模型是'damo/nlp_bert_document-segmentation_chinese-base',这是达摩院开发的用于文档分割的中文语言模型。模型加载到CPU进行计算,但如果需要,可以更改为GPU。

split_text方法返回输入文本的句子或段落列表。

在Langchain-Chatchat仓库中,向知识库添加新文档的具体过程包括以下步骤:

  1. 创建ESKBService类的实例,将知识库的名称作为参数传递。例如,esKBService = ESKBService("test")

  2. ESKBService实例上调用add_doc方法,将KnowledgeFile对象作为参数传递。KnowledgeFile对象应包含文档的文件名和知识库的名称。例如,esKBService.add_doc(KnowledgeFile(filename="README.md", knowledge_base_name="test"))

add_doc方法在内部调用_load_es方法将文档写入Elasticsearch。然后,它通过在索引中搜索文档来检查文档是否成功写入。如果找到文档,它返回包含文档id和元数据的字典列表。如果找不到文档,它会引发ValueError

希望这些信息能帮助您解决问题。如果您有任何其他问题或需要进一步的澄清,请随时提问。

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

qianma819 commented 8 months ago

@dosu-bot 关于您提到的文档输入每行多增加了个\n的问题,这是由于在处理文档内容时,代码中有一行 context = "\n".join([doc.page_content for doc in docs])。这行代码将docs列表中每个文档的页面内容用换行符连接起来。这通常是为了在合并多个文本文档时保持可读性和结构。

》》你这个回答的不对吧。你这个是knowledge_base_chat类里面的代码,我咨询的是文档增加到知识库里增加的"\n"

dosubot[bot] commented 8 months ago

🤖

关于您提到的文档输入每行多增加了个"\n"的问题,这可能是由于在处理文档内容时,代码中有一行 context = "\n".join([doc.page_content for doc in docs])。这行代码将docs列表中每个文档的页面内容用换行符连接起来。这通常是为了在合并多个文本文档时保持可读性和结构。这可能是导致您看到的额外换行符的原因。

至于您提到的_join_docs,在提供的上下文中并没有提到这个类或函数,所以我无法根据给定的上下文提供原因。如果您能提供更多的信息,例如_join_docs在代码中的位置,我可能能提供更多的帮助。

关于AliTextSplitter类,这个类是CharacterTextSplitter的子类,用于将输入文本分割成一个句子列表。这是通过使用一个文档分割模型来完成的,具体来说是达摩院的nlp_bert_document-segmentation_chinese-base模型。这个类的目的是为了在Langchain-Chatchat应用中进一步处理文本。

split_text方法是这个类的主要方法。它接收一个文本字符串作为输入,并返回一个句子列表。如果pdf属性设置为True,该方法首先对文本进行一些预处理,以删除过多的换行符和空格。

然后,它使用modelscope.pipelines模块的pipeline函数来加载文档分割模型。模型被加载到CPU进行计算,但如果需要,可以更改为GPU。然后使用模型将输入文本分割成句子,这些句子以列表的形式返回。

与被添加到知识库的文档的交互是,AliTextSplitter类可能用于将文档分割成句子,然后可以单独将这些句子添加到知识库。这使得知识库能以更结构化和可搜索的格式存储文档。

如果您有更多的问题或需要进一步的澄清,请随时提问。

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.