基于LangChain实现本地知识库问答问题总结

LangChain:我们不生产模型,我们只是大模型的搬运工。

基于LangChain实现本地知识库问答:

项目地址:

GitHub - chatchat-space/Langchain-Chatchat: Langchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM) QA app with langchainLangchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM) QA app with langchain - GitHub - chatchat-space/Langchain-Chatchat: Langchain-Chatchat(原Langchain-ChatGLM)基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM) QA app with langchainicon-default.png?t=N7T8https://github.com/chatchat-space/Langchain-Chatchat

流程如上图,知识库嵌入-->问题嵌入-->相似度计算-->提示文本-->回答

共涉及两个大模型,分别为文本嵌入模型大语言模型(LLM)。

文本嵌入模型作用:

1. 对知识库中的文件中的文本片段进行嵌入,存入知识向量库;

2. 对问题进行嵌入。

LLM作用:根据提示文本回答问题。

LangChain主打大模型间的调度,附带嵌入向量相似度计算,提示模板填充等功能;

下面总结下部署时遇到的一些小问题(v0.2.5):

1. 切换文本嵌入模型时报错。

官方提供了文本嵌入模型M3E的示例,但将其更换为BGE,初始化知识向量库时,弹出以下错误:

原因:断言出错,原向量库残留了一些模型信息,self.d对应M3E的嵌入维度768,但BGE的嵌入维度为1024,不能存库。

解决方案:删掉原来存储库所在目录或重命名即可,单纯在命令行添加--recreate-vs不起作用。

2. BGE加载代码存在问题。

./Langchain-Chatchat-0.2.5/server/knowledge_base/kb_cache/base.py中137行左右:

embeddings = HuggingFaceBgeEmbeddings(model_name=embedding_model_dict[model],
                                      model_kwargs={'device': device},
                                      query_instruction=query_instruction)

embeddding_model_dict未声明,改成下面即可:

embeddings = HuggingFaceBgeEmbeddings(model_name=get_model_path(model),
                                      model_kwargs={'device': device},
                                      query_instruction=query_instruction)

3. 使用百川13B大模型时,报错AttributeError: 'BaichuanTokenizer' object has no attribute 'sp_model'

需将baichuan-inc/Baichuan2-13B-Chat/tokenization_baichuan.py中的super()放至最后执行,如下:

self.vocab_file = vocab_file
self.add_bos_token = add_bos_token
self.add_eos_token = add_eos_token
self.sp_model = spm.SentencePieceProcessor(**self.sp_model_kwargs)
self.sp_model.Load(vocab_file)
super().__init__(
    bos_token=bos_token,
    eos_token=eos_token,
    unk_token=unk_token,
    pad_token=pad_token,
    add_bos_token=add_bos_token,
    add_eos_token=add_eos_token,
    sp_model_kwargs=self.sp_model_kwargs,
    clean_up_tokenization_spaces=clean_up_tokenization_spaces,
    **kwargs,
)

4. web运行时,出现KeyError: Caught exception: 'choices'

ERROR | root | KeyError: Caught exception: 'choices' 

可能是显存超了,减少匹配知识条数或减小kb_config.py中的CHUNK_SIZE等均可。

下面说一下在实际应用效果上的小问题:

1. 读取pdf时,不合宜的换行符'\n'会影响LLM对语义的理解。

例如,标题+'\n'+段落,LLM会因为'\n'认为标题和段落不存在关联,导致回答不准确。对于较为成熟的LLM(ChatGPT、文心等)并不会有太大影响,但对于ChatGLM是存在一定影响的。

解决方案:在构建知识向量库时,将全部'\n'替换为空格。替换代码所在目录:

./anaconda3/envs/LangChain/lib/python3.10/site-packages/langchain/text_splitter.py
若想在文本拆分前替换,将下面注释代码改为非注释代码即可,160行左右:

# texts.append(doc.page_content)
new_content = doc.page_content.replace('\n', ' ')
texts.append(new_content)

若想在文本拆分后替换,将下面注释代码改为非注释代码即可,150行左右:

# new_doc = Document(page_content=chunk, metadata=metadata)
new_chunk = chunk.replace('\n', ' ')
new_doc = Document(page_content=new_chunk, metadata=metadata)   
效果对比:

替换前(检索出了,但未能准确回答):

替换后(能够准确回答):

2. LLM存在一定随机性,问题相同,答复却不同。

对于相对困难的问题,回答差距较大,如下:

对于简单的问题,回答方式虽然不完全相同,但内容正确,如下:

解决方案:切换表现更好的LLM,百川2-13B表现较佳,但对算力设备要求较高,在算力一般(例如RTX 3090、2080ti)的设备上速度较慢。

3. 不适宜的文本、表格拆分对语义的影响严重。

尤其是表格数据被拦腰截断后,对于未含表头的数据则不可能被正确回答。

解决方案:替换文本分割方案,采用三方库docx读取.docx,能够单独读取表格,对于PDF和doc则需事先转为docx格式。

文本分割修改代码位置:~/Langchain-Chatchat-0.2.5/server/knowledge_base/utils.py中的KnowledgeFile.docs2texts()

文本分割函数 text_split_via_me() 内可包括文档的重新读取,代码太多就不贴细节了。

def docs2texts(
        self,
        docs: List[Document] = None,
        zh_title_enhance: bool = ZH_TITLE_ENHANCE,
        refresh: bool = False,
        chunk_size: int = CHUNK_SIZE,
        chunk_overlap: int = OVERLAP_SIZE,
        text_splitter: TextSplitter = None,
    ):
        docs = docs or self.file2docs(refresh=refresh)
        if not docs:
            return []

        # if self.ext not in [".csv"]:
        #     if text_splitter is None:
        #         text_splitter = make_text_splitter(splitter_name=self.text_splitter_name, chunk_size=chunk_size, chunk_overlap=chunk_overlap)
        #     if self.text_splitter_name == "MarkdownHeaderTextSplitter":
        #         docs = text_splitter.split_text(docs[0].page_content)
        #         for doc in docs:
        #             # 如果文档有元数据
        #             if doc.metadata:
        #                 doc.metadata["source"] = os.path.basename(self.filepath)
        #     else:
        #         docs = text_splitter.split_documents(docs)

        def text_split_via_me(docs):
            ...
            return ...
        docs = text_split_via_me(docs)

        print(f"文档切分示例:{docs[0]}")
        # if zh_title_enhance:
        #     docs = func_zh_title_enhance(docs)
        self.splited_docs = docs
        return self.splited_docs

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明) Chatgpt学习资料项目资料 用于实战ChatgptAI技术 源代码 供参考(代码+使用说明)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值