Qwen2-7B-Instruct 接入 LangChain 搭建知识库助手:从自定义 LLM 类到检索问答实战
Qwen2-7B-Instruct 接入 LangChain 搭建知识库助手从自定义 LLM 类到检索问答实战【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm导读本篇指南基于《开源大模型食用指南》self-llm 项目中 Qwen2 系列的 LangChain 接入教程讲解如何在 LinuxAutoDL环境下将本地部署的 Qwen2-7B-Instruct 模型封装为 LangChain 可用的自定义 LLM 类进而以统一接口构建检索增强问答RAG知识库助手。读完本文你将掌握 Qwen2 模型的下载与半精度加载、自定义 LLM 类的核心实现原理构造函数与_call重写、以及在 LangChain 中直接调用本地模型的方法并可结合仓库中已有的向量数据库与检索问答链示例搭建属于你自己的知识库助手。一、整体思路为什么要自定义 LLM 类接入 LangChainLangChain 提供了统一的 LLM 抽象层任何模型OpenAI API、本地 Transformers 模型等只要实现其LLM基类接口就能以完全一致的方式被上层 Chain、Agent、RetrievalQA 等组件调用而无需关心底层模型调用的差异。Qwen2-7B-Instruct 是阿里通义千问团队开源的第二代 Qwen 系列指令模型参数量约 70 亿具备较强的指令跟随与多轮对话能力。要将它接入 LangChain我们需要本地部署 Qwen2 模型下载 半精度加载继承langchain.llms.base.LLM重写构造函数与_call方法实例化自定义类像使用任何 LangChain LLM 一样调用。本项目的官方教程将这一过程完整记录在 models/Qwen2/02-Qwen2-7B-Instruct Langchain 接入.md 中下文将围绕该文档逐步展开并结合仓库中 Qwen-7B-Chat 接入 LangChain 搭建知识库助手 的完整示例源码进行纵深讲解。二、环境准备2.1 租用 GPU 服务器推荐在 AutoDL 平台租用一张 RTX 3090 等24G 显存的显卡机器。创建实例时镜像选择PyTorch → 2.1.0 → 3.10 (ubuntu20.04) → 12.1CUDA 11.3 以上版本均可。租用完成后打开服务器的 JupyterLab并在其中打开终端开始环境配置、模型下载与 demo 运行。环境提示考虑到部分同学配置环境可能遇到问题本项目在 AutoDL 平台准备了 Qwen2 的环境镜像适用于该仓库除 Qwen-GPTQ 和 vLLM 外的所有部署环境可通过codewithgpu.com/i/datawhalechina/self-llm/Qwen2一键创建实例说明见 models/Qwen2/01-Qwen2-7B-Instruct FastApi 部署调用.md。2.2 pip 换源与依赖安装在终端依次执行以下命令先升级 pip 并更换为清华 PyPI 源以加速安装再安装模型下载、推理与 LangChain 相关依赖# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install modelscope1.11.0 pip install langchain0.2.3 pip install transformers4.41.2 accelerate tiktoken einops scipy transformers_stream_generator0.0.4 peft deepspeed pip install -U huggingface_hub其中各依赖的作用如下依赖包作用modelscope从魔搭ModelScope平台下载模型权重langchainLangChain 框架本体提供 LLM 抽象、Chain、检索组件transformers4.41.2HuggingFace Transformers加载 Qwen2 模型与分词器accelerate支持device_mapauto自动分配设备加载大模型tiktoken/einops/scipyQwen2 推理所需的辅助库transformers_stream_generator流式生成支持peft/deepspeed后续 LoRA 微调与分布式训练所需本教程直接加载基座模型可不强制huggingface_hubHuggingFace Hub 客户端升级到最新三、模型下载使用 ModelScope 的snapshot_download函数下载模型。第一个参数为模型名称cache_dir为模型下载路径。在/root/autodl-tmp路径下新建model_download.py文件粘贴以下内容并保存import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os model_dir snapshot_download(qwen/Qwen2-7B-Instruct, cache_dir/root/autodl-tmp, revisionmaster)运行下载命令python /root/autodl-tmp/model_download.py模型大小约 14 GB网络良好时约 2 分钟即可完成。下载完成后模型权重位于/root/autodl-tmp/qwen/Qwen2-7B-Instruct这也是后文自定义 LLM 类与调用示例中使用的模型路径。说明ModelScope 会同步下载模型配置、分词器与 generation_config 等文件下载目录结构与 HuggingFace Hub 保持一致因此可直接被AutoTokenizer.from_pretrained/AutoModelForCausalLM.from_pretrained加载。四、自定义 LLM 类将 Qwen2 接入 LangChain为便捷构建 LLM 应用我们需要基于本地部署的 Qwen2自定义一个 LLM 类将 Qwen2 接入到 LangChain 框架中。完成自定义 LLM 类之后可以以完全一致的方式调用 LangChain 的接口而无需考虑底层模型调用的不一致。基于本地部署的 Qwen2 自定义 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, GenerationConfig, LlamaTokenizerFast import torch class Qwen2_LLM(LLM): # 基于本地 Qwen2 自定义 LLM 类 tokenizer: AutoTokenizer None model: AutoModelForCausalLM None def __init__(self, mode_name_or_path :str): super().__init__() print(正在从本地加载模型...) self.tokenizer AutoTokenizer.from_pretrained(mode_name_or_path, use_fastFalse) self.model AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtypetorch.bfloat16, device_mapauto) self.model.generation_config GenerationConfig.from_pretrained(mode_name_or_path) print(完成本地模型的加载) def _call(self, prompt : str, stop: Optional[List[str]] None, run_manager: Optional[CallbackManagerForLLMRun] None, **kwargs: Any): messages [{role: user, content: prompt }] input_ids self.tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) model_inputs self.tokenizer([input_ids], return_tensorspt).to(cuda) generated_ids self.model.generate(model_inputs.input_ids,max_new_tokens512) generated_ids [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response self.tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] return response property def _llm_type(self) - str: return Qwen2_LLM4.1 构造函数加载一次复用多次构造函数在对象实例化的一开始就完成模型加载从而避免每次调用都重新加载模型带来的时间开销AutoTokenizer.from_pretrained(mode_name_or_path, use_fastFalse)加载分词器。use_fastFalse使用慢速分词器避免与 Qwen2 的 chat template 处理产生兼容性问题AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtypetorch.bfloat16, device_mapauto)以bfloat16半精度加载模型device_mapauto让accelerate自动把模型权重分配到可用 GPU 显存中。对 7B 量级模型24G 显存的 3090 完全可以承载GenerationConfig.from_pretrained(mode_name_or_path)加载官方预设的生成配置如温度、top_p、repetition_penalty 等。这一构造函数中加载、后续直接复用的模式与本项目其他模型教程一脉相承。例如 models/Qwen/07-Qwen-7B-Chat 接入langchain搭建知识库助手/LLM.py 中QwenLM类的构造函数同样在实例化时通过AutoTokenizer.from_pretrained与AutoModelForCausalLM.from_pretrained完成加载并设置GenerationConfig。区别在于 Qwen-7B-Chat 时代还需要trust_remote_codeTrue加载自定义代码而 Qwen2 已原生支持不再需要该参数。4.2_call函数LangChain 与本地模型之间的桥梁_call是LLM类的核心函数LangChain 调用 LLM 时最终都会走到该方法。其中构造 messages将用户 prompt 包装为[{role: user, content: prompt}]的对话格式应用 chat templatetokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue)将对话格式转换为 Qwen2 的 Prompt Template 文本。Qwen2 采用的模板格式如下详见 models/Qwen2/05-Qwen2-7B-Instruct Lora 微调.md|im_start|system You are a helpful assistant.|im_end| |im_start|user 你是谁|im_end| |im_start|assistanttokenize 并送入 GPUself.tokenizer([input_ids], return_tensorspt).to(cuda)生成模型输入生成self.model.generate(model_inputs.input_ids, max_new_tokens512)控制最大新生成 token 数为 512截取新生成部分output_ids[len(input_ids):]将生成结果中与输入重叠的部分去掉只保留模型新生成的内容解码返回tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0]去除特殊 token 后得到纯文本回答。4.3_llm_type属性_llm_type是必须实现的只读属性用于标识 LLM 类型。LangChain 内部会用它进行类型判断与日志记录。这里返回Qwen2_LLM即可。4.4 封装为模块在整体项目中我们将上述代码封装为LLM.py后续直接从中导入自定义的 LLM 类。读者可将该文件放置在任意工作目录如/root/autodl-tmp/LLM.py并在同目录下运行调用脚本。仓库中已有类似封装范式可参考例如 models/Qwen/07-Qwen-7B-Chat 接入langchain搭建知识库助手/LLM.py、models/InternLM/06-InternLM接入LangChain搭建知识库助手/LLM.py、models/ChatGLM/05-ChatGLM3-6B接入LangChain搭建知识库助手/LLM.py 等各模型的_call实现略有差异有的调用model.chat有的走apply_chat_templategenerate这正是封装一层、统一接口的意义所在。五、调用验证封装完成后就可以像使用任何其他 LangChain 大模型功能一样使用了from LLM import Qwen2_LLM llm Qwen2_LLM(mode_name_or_path /root/autodl-tmp/qwen/Qwen2-7B-Instruct) print(llm(你是谁))终端输出如下加载进度条走完后返回模型回答由于Qwen2_LLM继承了LLM基类它天然支持llm.predict(...)、llm(...)等 LangChain 统一调用方式也可以直接传入RetrievalQA、ConversationChain等链式组件中使用。六、进阶搭建 Qwen2 知识库助手RAG自定义 LLM 类的价值在于上层应用无需感知底层模型差异。结合本项目 models/Qwen/07-Qwen-7B-Chat 接入langchain搭建知识库助手.md 的完整示例可将 Qwen2_LLM 无缝替换进检索问答链搭建基于本地知识库的 RAG 助手完整链路为文档加载 → 文本分块 → 向量化 → 向量库检索 → Prompt 拼接 → LLM 回答。6.1 构建向量数据库首先将知识库文档.md / .txt通过UnstructuredFileLoader/UnstructuredMarkdownLoader加载用RecursiveCharacterTextSplitter如chunk_size500, chunk_overlap150分块再以 HuggingFace 开源向量模型如paraphrase-multilingual-MiniLM-L12-v2可下载到/root/autodl-tmp/embedding_model经HuggingFaceEmbeddings向量化最后写入 Chroma 向量数据库并持久化from langchain.embeddings.huggingface import HuggingFaceEmbeddings from langchain.vectorstores import Chroma embeddings HuggingFaceEmbeddings(model_name/root/autodl-tmp/embedding_model) persist_directory data_base/vector_db/chroma vectordb Chroma.from_documents( documentssplit_docs, embeddingembeddings, persist_directorypersist_directory ) vectordb.persist()6.2 构建检索问答链加载持久化向量库实例化自定义 LLM并构造 Prompt Templatefrom langchain.vectorstores import Chroma from langchain.embeddings.huggingface import HuggingFaceEmbeddings from LLM import Qwen2_LLM from langchain.prompts import PromptTemplate embeddings HuggingFaceEmbeddings(model_name/root/autodl-tmp/embedding_model) vectordb Chroma(persist_directorydata_base/vector_db/chroma, embedding_functionembeddings) llm Qwen2_LLM(mode_name_or_path/root/autodl-tmp/qwen/Qwen2-7B-Instruct) template 使用以下上下文来回答最后的问题。如果你不知道答案就说你不知道不要试图编造答案。尽量使答案简明扼要。总是在回答的最后说“谢谢你的提问”。 {context} 问题: {question} 有用的回答: QA_CHAIN_PROMPT PromptTemplate(input_variables[context, question], templatetemplate) 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} )对比检索问答链与纯 LLM 的回答效果question 什么是Qwen2 result qa_chain({query: question}) print(检索问答链回答 question 的结果) print(result[result]) # 仅 LLM 回答效果 result_2 llm(question) print(大模型回答 question 的结果) print(result_2)可以看到使用检索问答链生成的答案更接近知识库中的内容这正是 RAG 的价值让模型基于给定的领域知识作答降低幻觉。该示例的完整实现可参见 models/Qwen/07-Qwen-7B-Chat 接入langchain搭建知识库助手.md 及其目录下的LLM.py、create_db.py、run_gradio.py。6.3 部署 Web Demo如需可视化交互可基于 Gradio 将问答链封装为load_chain()函数与Model_center类通过demo.launch()启动 Web 界面默认运行在 7860 端口。完整代码同样收录在 models/Qwen/07-Qwen-7B-Chat 接入langchain搭建知识库助手.md 中只需将其中QwenLM替换为本篇的Qwen2_LLM即可。七、常见问题与注意事项显存不足Qwen2-7B 以 bfloat16 加载约需 14–16 GB 显存若显存紧张可考虑 4-bit / 8-bit 量化加载如bitsandbytes或改用 vLLM 部署参见 models/Qwen2/04-Qwen2-7B-Instruct vLLM 部署调用.md。apply_chat_template依赖较新版本Qwen2 的 chat template 内置在 tokenizer 中需要transformers4.41.2请务必按本文版本安装不要使用过低版本。use_fastFalseQwen2 分词器加载时建议保持use_fastFalse避免与 chat template 兼容性问题。模型路径下载后的模型路径为/root/autodl-tmp/qwen/Qwen2-7B-Instruct自定义 LLM 类与调用脚本中的路径需与此保持一致。端口与外网访问若需在本地浏览器访问 Web Demo 或 API 服务需在 AutoDL 控制台配置端口映射具体方法参见 models/General-Setting/02-AutoDL开放端口.md。八、小结本篇基于 models/Qwen2/02-Qwen2-7B-Instruct Langchain 接入.md 完整复现了 Qwen2-7B-Instruct 接入 LangChain 的全流程环境准备GPU 实例与依赖安装→ 模型下载ModelScope snapshot_download→ 自定义Qwen2_LLM类构造函数加载 _call桥接→ 统一调用验证并延伸讲解了如何基于该自定义类搭建检索增强知识库助手。自定义 LLM 类是 LangChain 生态中连接私有本地模型与统一应用框架的关键一环。掌握这一模式后你可以将本项目 models 目录下的任何已支持模型Qwen、ChatGLM、InternLM、DeepSeek 等以相同方式接入 LangChain构建属于自己的知识库助手、Agent 等应用。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考