ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

self-llm 实战:Atom-7B-Chat 接入 LangChain 搭建知识库问答助手(RAG 全流程)

self-llm 实战:Atom-7B-Chat 接入 LangChain 搭建知识库问答助手(RAG 全流程) 大模型人工智能教程本地部署微调【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址https://gitcode.com/datawhalechina/self-llm点击查看免费下载本文是 Datawhale《开源大模型食用指南》self-llm 项目中Atom-7B-Chat 接入 LangChain 搭建知识库助手的完整实战指南以 03-Atom-7B-Chat 接入langchain搭建知识库助手.md 为核心骨架并结合该目录下配套的三个可运行脚本 creat_db.py、LLM.py、run_gradio.py 进行源码级展开。读完本文你将完整掌握一条可复用的本地大模型 私有知识库检索增强生成RAG落地路径从语料采集、文本分块、向量化与向量数据库持久化到将 Atom 封装为 LangChain 自定义 LLM、构建检索问答链最终基于 Gradio 部署成 Web 知识库助手。一、环境准备1.1 硬件与基础镜像本教程的运行环境以 AutoDL 云平台为示例租用一张 3090 等 24 GB 显存的 GPU 机器镜像选择PyTorch→2.0.0→3.8 (ubuntu20.04)→11.8。租用完成后打开 JupyterLab 并在其中打开终端进行环境配置、模型下载与 demo 运行。更多基础环境细节可参考同目录下的前置部署教程 01-Atom-7B-chat-WebDemo.md其中给出了transformers4.35.2、accelerate0.24.1、bitsandbytes0.41.2.post2、SentencePiece0.1.99等与 Atom-7B-chat 直接对话配套的基础依赖版本本教程的知识库搭建即建立在已完成 Atom-7B-chat 基础部署的前提之上。1.2 pip 换源与基础依赖安装首先升级 pip 并更换为国内 pypi 镜像源以加速依赖安装然后安装 Atom 模型推理所需的基础依赖# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install modelscope1.9.5 pip install transformers4.32.0 accelerate tiktoken einops scipy transformers_stream_generator0.0.4 peft deepspeed pip install -U huggingface_hub pip install -i https://test.pypi.org/simple/ bitsandbytes在此基础上再安装 LangChain 知识库问答链路所需的依赖包版本均已锁定以保证与本教程代码兼容pip install langchain0.0.292 pip install gradio4.4.0 pip install chromadb0.4.15 pip install sentence-transformers2.2.2 pip install unstructured0.10.30 pip install markdown3.3.7各依赖的角色如下langchain提供文档加载、文本分块、向量数据库封装与检索问答链gradio用于构建 Web 交互界面chromadb作为本地持久化向量数据库sentence-transformers负责加载词向量模型对文本块编码unstructured与markdown用于解析.md、.txt等非结构化文档。二、模型下载2.1 开源词向量模型下载文本向量化环节使用开源词向量模型sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2该模型对中文等多语言文本有良好的语义编码能力。在/root/autodl-tmp下新建download.py并写入以下内容然后运行python /root/autodl-tmp/download.pyimport os # 设置环境变量 os.environ[HF_ENDPOINT] https://hf-mirror.com # 下载模型 os.system(huggingface-cli download --resume-download sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 --local-dir /root/autodl-tmp/embedding_model)这里通过HF_ENDPOINT环境变量指定 HuggingFace 镜像站加速下载模型最终保存到本地路径/root/autodl-tmp/embedding_model后续HuggingFaceEmbeddings将直接读取该本地目录。2.2 Atom-7B-Chat 模型下载Atom 模型本体使用modelscope的snapshot_download函数下载第一个参数为模型名称参数cache_dir为模型的下载路径。同样在/root/autodl-tmp下新建download.py并运行import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os model_dir snapshot_download(FlagAlpha/Atom-7B-Chat, cache_dir/root/autodl-tmp, revisionmaster)模型大小约 13 GB下载大约需要 10~20 分钟下载完成后模型位于/root/autodl-tmp/FlagAlpha/Atom-7B-Chat。三、知识库建设知识库建设的核心目标是把语料转化为可检索的向量数据库流程为收集文件 → 加载为纯文本 → 文本分块 → 文本向量化 → 写入并持久化向量数据库。仓库配套脚本 creat_db.py 完整实现了该流程。3.1 语料来源与文件收集本教程选用以下两个开源仓库作为知识库来源Atom-7B-ChatModelScope 上的 FlagAlpha/Atom-7B-Chat 模型仓库Llama2-ChineseFlagAlpha 维护的中文 Llama2 相关开源仓库首先将开源仓库 clone 到本地AutoDL 环境可先开启学术资源加速再克隆# 进入到数据盘 cd /root/autodl-tmp # 打开学术资源加速 source /etc/network_turbo # clone 开源仓库作为语料来源 git clone Llama2-Chinese 仓库地址 # 关闭学术资源加速 unset http_proxy unset https_proxy为便于语料处理教程选取上述仓库中所有的.md、.txt文件作为示例语料。也可以将代码文件加入知识库但需要对代码文件格式做额外处理。第一步是定义get_files函数递归遍历指定文件夹收集所有满足后缀条件的文件绝对路径import os def get_files(dir_path): # argsdir_path目标文件夹路径 file_list [] for filepath, dirnames, filenames in os.walk(dir_path): # os.walk 函数将递归遍历指定文件夹 for filename in filenames: # 通过后缀名判断文件类型是否满足要求 if filename.endswith(.md): # 如果满足要求将其绝对路径加入到结果列表 file_list.append(os.path.join(filepath, filename)) elif filename.endswith(.txt): file_list.append(os.path.join(filepath, filename)) return file_list3.2 文本加载得到文件路径列表后使用 LangChain 的 FileLoader 系列对象加载目标文件得到解析后的纯文本对象。由于不同类型的文件需要对应的 Loader脚本根据后缀名分发到UnstructuredMarkdownLoader.md与UnstructuredFileLoader.txt并调用load()得到文本对象from tqdm import tqdm from langchain.document_loaders import UnstructuredFileLoader from langchain.document_loaders import UnstructuredMarkdownLoader def get_text(dir_path): # argsdir_path目标文件夹路径 # 首先调用上文定义的函数得到目标文件路径列表 file_lst get_files(dir_path) # docs 存放加载之后的纯文本对象 docs [] # 遍历所有目标文件 for one_file in tqdm(file_lst): file_type one_file.split(.)[-1] if file_type md: loader UnstructuredMarkdownLoader(one_file) elif file_type txt: loader UnstructuredFileLoader(one_file) else: # 如果是不符合条件的文件直接跳过 continue docs.extend(loader.load()) return docs3.3 文本分块直接对整个文档做向量化既不经济也不利于精准检索因此需要先对文本分块。LangChain 提供了多种文本分块工具此处使用字符串递归分割器RecursiveCharacterTextSplitter分块大小为 500块重叠长度为 150重叠部分用于缓解分块切断语义导致的信息丢失from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap150) split_docs text_splitter.split_documents(docs)3.4 向量化与向量数据库持久化使用开源词向量模型即 2.1 节下载的paraphrase-multilingual-MiniLM-L12-v2进行文本块向量化。LangChain 提供HuggingFaceEmbeddings接口直接加载 HuggingFace 开源模型from langchain.embeddings.huggingface import HuggingFaceEmbeddings embeddings HuggingFaceEmbeddings(model_name/root/autodl-tmp/embedding_model)向量数据库选用 Chroma。基于分块后的文档与向量化模型将语料加载到指定路径下的向量数据库并通过persist()持久化到磁盘后续可直接导入复用无需重复构建from langchain.vectorstores import Chroma # 定义持久化路径 persist_directory data_base/vector_db/chroma # 加载数据库 vectordb Chroma.from_documents( documentssplit_docs, embeddingembeddings, persist_directorypersist_directory # 允许我们将persist_directory目录保存到磁盘上 ) # 将加载的向量数据库持久化到磁盘上 vectordb.persist()3.5 整合为完整脚本将上述步骤整合即为 creat_db.py 的完整逻辑导入nltk并下载punkt分词器unstructured解析文本时依赖定义get_files/get_text两个函数指定目标文件夹tar_dir依次完成文本加载、分块、向量化与数据库构建。运行python creat_db.py即可在本地生成已持久化的向量数据库data_base/vector_db/chroma该数据库后续可直接加载使用。四、Atom 接入 LangChain为了让 LangChain 统一调度本地部署的 Atom 模型需要基于本地 Atom 自定义一个 LLM 类将模型接入 LangChain 框架。完成自定义后上层可以完全一致地调用 LangChain 接口而无需关心底层模型调用的差异。该部分代码即仓库中的 LLM.py。4.1 自定义 LLM 类设计从langchain.llms.base.LLM继承一个子类重写构造函数与_call函数即可from langchain.llms.base import LLM from typing import Any, List, Optional from langchain.callbacks.manager import CallbackManagerForLLMRun from transformers import AutoTokenizer, AutoModelForCausalLM import torch class Atom(LLM): # 基于本地 Atom 自定义 LLM 类 tokenizer : AutoTokenizer None model: AutoModelForCausalLM None def __init__(self, model_path :str): # model_path: Atom 模型路径 # 从本地初始化模型 super().__init__() print(正在从本地加载模型...) model_dir /root/autodl-tmp/FlagAlpha/Atom-7B-Chat self.tokenizer AutoTokenizer.from_pretrained(model_dir, trust_remote_codeTrue) self.model AutoModelForCausalLM.from_pretrained(model_dir, device_mapauto, trust_remote_codeTrue,torch_dtypetorch.float16,load_in_8bitTrue).eval() print(完成本地模型的加载) def _call(self, prompt: str, stop: Optional[List[str]] None, run_manager: Optional[CallbackManagerForLLMRun] None, **kwargs: Any): input_ids self.tokenizer([fsHuman: {prompt}\n/ssAssistant: ], return_tensorspt, add_special_tokensFalse).input_ids.to(cuda) generate_input { input_ids: input_ids, max_new_tokens: 512, do_sample: True, top_k: 50, top_p: 0.95, temperature: 0.3, repetition_penalty: 1.3, eos_token_id: self.tokenizer.eos_token_id, bos_token_id: self.tokenizer.bos_token_id, pad_token_id: self.tokenizer.pad_token_id } generate_ids self.model.generate(**generate_input) text self.tokenizer.decode(generate_ids[0]) return text property def _llm_type(self) - str: return Atom4.2 源码要点解析结合 LLM.py 的源码结构可以从三个层面理解该自定义类的设计构造函数__init__在对象实例化时一次性加载本地 Atom 模型与分词器避免每一次调用都重新加载模型导致耗时过长。加载时使用trust_remote_codeTrue信任 Atom 的自定义模型代码device_mapauto让模型自动分配到可用设备。需要说明的是教程正文为了降低显存占用额外传入了load_in_8bitTrue需要配合前面安装的bitsandbytes而仓库中的 LLM.py 采用 FP16 加载如果显存充足两种方式均可运行可按实际显存自行取舍。_call函数这是 LLM 类的核心函数LangChain 会调用它来调用 LLM。函数内部将用户提问组装为 Atom 的对话格式sHuman: {prompt}\n/ssAssistant:再调用model.generate完成推理并返回解码文本。生成参数中max_new_tokens512限制新生成 token 数temperature0.3与top_p0.95、top_k50控制采样的随机性与多样性repetition_penalty1.3抑制重复生成。_llm_type属性以只读属性的形式返回自定义 LLM 的类型标识Atom这是 LangChain 框架要求的接口之一。4.3 实例化与效果测试从LLM.py引入自定义类并实例化、直接预测from LLM import Atom llm Atom(model_path /root/autodl-tmp/FlagAlpha/Atom-7B-Chat) llm.predict(你是谁)从运行截图可以看到终端中先输出正在从本地加载模型…并完成 checkpoint 分片加载随后 Atom 以对话格式返回自我介绍说明自定义 LLM 类已可被 LangChain 正常调用。五、构建检索问答链LangChain 通过检索问答链对象RetrievalQA封装 RAG 全流程只需在初始化时填入已构建的向量数据库与自定义 LLMLangChain 便会自动完成基于提问检索 → 获取相关文档 → 拼接 Prompt → 交给 LLM 问答的完整链路。5.1 加载已构建的向量数据库通过Chroma与上文定义的词向量模型直接加载已持久化的数据库from langchain.vectorstores import Chroma from langchain.embeddings.huggingface import HuggingFaceEmbeddings import os # 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name/root/autodl-tmp/embedding_model) # 向量数据库持久化路径 persist_directory data_base/vector_db/chroma # 加载数据库 vectordb Chroma( persist_directorypersist_directory, embedding_functionembeddings )得到的vectordb对象可针对用户的 query 进行语义向量检索返回与提问相关的知识片段后续通过vectordb.as_retriever()作为问答链的检索器。5.2 Prompt Template 设计检索问答链还需要一个 Prompt Template。它本质上是带变量的字符串检索完成后 LangChain 会把相关文档片段填充进变量从而构造出带知识的 Prompt。基于PromptTemplate基类实例化from langchain.prompts import PromptTemplate # 我们所构造的 Prompt 模板 template 使用以下上下文来回答最后的问题。如果你不知道答案就说你不知道不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问”。 {context} 问题: {question} 有用的回答: # 调用 LangChain 的方法来实例化一个 Template 对象该对象包含了 context 和 question 两个变量在实际调用时这两个变量会被检索到的文档片段和用户提问填充 QA_CHAIN_PROMPT PromptTemplate(input_variables[context,question],templatetemplate)5.3 实例化检索问答链调用RetrievalQA.from_chain_type基于自定义 LLM、Prompt Template 和向量知识库构建基于 Atom 的检索问答链from langchain.chains import RetrievalQA qa_chain RetrievalQA.from_chain_type(llm,retrievervectordb.as_retriever(),return_source_documentsTrue,chain_type_kwargs{prompt:QA_CHAIN_PROMPT})其中return_source_documentsTrue会在结果中额外返回检索到的来源文档便于追溯答案依据。得到的qa_chain对象即实现了核心功能——基于 Atom 模型的专业知识库助手。5.4 检索增强与纯 LLM 的效果对比对比检索问答链与纯 LLM 的问答效果question 什么是Atom result qa_chain({query: question}) print(检索问答链回答 question 的结果) print(result[result]) # 仅 LLM 回答效果 result_2 llm(question) print(大模型回答 question 的结果) print(result_2)从运行截图可以清楚看到差异使用检索问答链生成的答案更接近知识库中的内容包含了模型的数据来源、优化点、参数规模等细节而纯 LLM 的回答则相对简短、缺乏知识库支撑。这正是 RAG 的价值——让模型基于给定知识作答降低幻觉风险。六、部署 WebDemo完成核心功能后基于 Gradio 框架将其部署为 Web 网页搭建小型 Demo 便于测试与使用。该部分对应仓库脚本 run_gradio.py。6.1 封装检索问答链加载函数将上文构建检索问答链的代码封装为load_chain函数在 Gradio 启动的第一时间调用后续直接复用该对象进行问答避免重复加载模型# 导入必要的库 import gradio as gr from langchain.vectorstores import Chroma from langchain.embeddings.huggingface import HuggingFaceEmbeddings import os from LLM import Atom from langchain.prompts import PromptTemplate def load_chain(): # 加载问答链 # 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name/root/autodl-tmp/embedding_model) # 向量数据库持久化路径 persist_directory data_base/vector_db/chroma # 加载数据库 vectordb Chroma( persist_directorypersist_directory, # 允许我们将persist_directory目录保存到磁盘上 embedding_functionembeddings ) llm Atom(model_path /root/autodl-tmp/FlagAlpha) template 使用以下上下文来回答最后的问题。如果你不知道答案就说你不知道不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问”。 {context} 问题: {question} 有用的回答: QA_CHAIN_PROMPT PromptTemplate(input_variables[context,question], templatetemplate) # 运行 chain from langchain.chains import RetrievalQA qa_chain RetrievalQA.from_chain_type(llm, retrievervectordb.as_retriever(), return_source_documentsTrue, chain_type_kwargs{prompt:QA_CHAIN_PROMPT}) return qa_chain6.2 封装问答中心类定义一个Model_center类负责加载并存储检索问答链并响应 Web 界面的问答动作。qa_chain_self_answer方法接收用户问题与聊天历史调用检索问答链作答并追加到历史中同时做了空输入防护与异常兜底异常信息会回显到界面输入框避免程序崩溃class Model_center(): 存储问答 Chain 的对象 def __init__(self): self.chain load_chain() def qa_chain_self_answer(self, question: str, chat_history: list []): 调用不带历史记录的问答链进行回答 if question None or len(question) 1: return , chat_history try: chat_history.append( (question, self.chain({query: question})[result])) return , chat_history except Exception as e: return e, chat_history def clear_history(self): self.chain.clear_history()6.3 构建 Gradio 界面按照 Gradio 的Blocks框架组织界面顶部展示标题主体为Chatbot聊天组件height450且支持复制按钮、Textbox文本输入框、Chat 提交按钮与 Clear console 清除按钮。按钮通过.click()绑定到Model_center的对应方法import gradio as gr model_center Model_center() block gr.Blocks() with block as demo: with gr.Row(equal_heightTrue): with gr.Column(scale15): gr.Markdown(h1centerAtom/center/h1 centerLlama2-chinese(教程来自DataWhale Self-LM团队)/center ) with gr.Row(): with gr.Column(scale4): chatbot gr.Chatbot(height450, show_copy_buttonTrue) # 创建一个文本框组件用于输入 prompt。 msg gr.Textbox(labelPrompt/问题) with gr.Row(): # 创建提交按钮。 db_wo_his_btn gr.Button(Chat) with gr.Row(): # 创建一个清除按钮用于清除聊天机器人组件的内容。 clear gr.ClearButton( components[chatbot], valueClear console) # 设置按钮的点击事件。当点击时调用上面定义的 qa_chain_self_answer 函数并传入用户的消息和聊天历史记录然后更新文本框和聊天机器人组件。 db_wo_his_btn.click(model_center.qa_chain_self_answer, inputs[msg, chatbot], outputs[msg, chatbot]) # 点击后清空后端存储的聊天记录 clear.click(model_center.clear_history) gr.Markdown(提醒br 1. 初始化数据库时间可能较长请耐心等待。 2. 使用中如果出现异常将会在文本输入框进行展示请不要惊慌。 br ) # threads to consume the request gr.close_all() # 启动新的 Gradio 应用设置分享功能为 True并使用环境变量 PORT1 指定服务器端口。 # demo.launch(shareTrue, server_portint(os.environ[PORT1])) # 直接启动 demo.launch()6.4 启动与访问将上述代码封装为run_gradio.py脚本后在终端直接运行python run_gradio.py即可在本地启动知识库助手的 Web Demo默认在 7860 端口运行。在 AutoDL 等远程服务器上可以通过平台的自定义服务配置端口映射将本地 7860 端口映射到本机即可在浏览器中访问从界面截图可以看到在输入框中提出请介绍一下 Atom这类问题时模型会结合知识库内容给出包含高效的中文词表自适应上下文扩展等细节的回答验证了整条 RAG 链路已完整打通。七、注意事项与工程要点基于仓库源码与教程正文的对照阅读以下几点值得实践者特别留意版本锁定是复现的前提本教程依赖的langchain0.0.292、chromadb0.4.15、gradio4.4.0等均为特定版本。例如vectordb.persist()的持久化写法与Chroma.from_documents的 API 形态都是该版本下的典型用法升级到更新版本后 API 可能有变化请以本教程锁定的版本组合运行。clear_history的实现取舍run_gradio.py 中Model_center.clear_history调用了self.chain.clear_history()但从 langchain 0.0.292 的 API 看RetrievalQA对象本身并不提供clear_history方法。如需后端清除对话记忆可改用ConversationRetrievalChain这类带记忆的会话型问答链或直接依靠前端ClearButton清空聊天组件。Prompt 模板的裁剪差异教程正文与仓库 run_gradio.py 中的 template 略有差异脚本版省略了使用以下上下文…的前缀提示语实际使用时可在脚本中自行补充系统提示语以引导模型基于上下文作答、避免编造答案。语料选择教程以.md/.txt文本作为示例语料代码类文件需要针对代码格式做额外处理如按代码块切分直接混入会降低检索质量。仓库内同类方案可横向参考从当前仓库结构看接入 LangChain 搭建知识库助手是多个模型目录下的通用范式例如 ChatGLM3-6B 接入 LangChain、Qwen-7B-Chat 接入 LangChain、InternLM 接入 LangChain 等读者可对比学习各模型在自定义 LLM 封装上的异同。至此一条完整的Atom-7B-Chat 本地部署 LangChain 知识库检索增强问答链路已经全部打通向量数据库负责知识检索自定义 LLM 类负责把 Atom 无缝接入 LangChain 生态RetrievalQA将两者编排为 RAG 问答链最后由 Gradio 呈现为可直接交互的 Web 知识库助手。将该范式替换语料与模型路径即可快速迁移到其他垂直领域构建属于自己的专业知识库问答系统。赞分享大模型人工智能教程本地部署微调【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址https://gitcode.com/datawhalechina/self-llm点击查看免费下载相关推荐self-llm 实战TransNormerLLM-7B 接入 LangChain 搭建知识库助手self llm 实战TransNormerLLM 7B 接入 LangChain 搭建知识库助手 本篇技术指南基于开源仓库《开源大模型食用指南》self教程大模型本地部署微调Atom-7B-Chat 接入 LangChain 搭建知识库助手从向量数据库构建到 RAG 问答与 Gradio 部署Atom 7B Chat 接入 LangChain 搭建知识库助手从向量数据库构建到 RAG 问答与 Gradio 部署 导读 本文是 Datawhale《开大模型人工智能教程本地部署微调Atom-7B-Chat 接入 LangChain 搭建知识库助手从向量库构建到 Gradio 部署的 RAG 实战Atom 7B Chat 接入 LangChain 搭建知识库助手从向量库构建到 Gradio 部署的 RAG 实战 本篇指南基于 self llm 仓库中《教程大模型本地部署微调创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表