ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

TransNormerLLM-7B 接入 LangChain 搭建知识库助手:自定义 LLM 类完整实战

TransNormerLLM-7B 接入 LangChain 搭建知识库助手:自定义 LLM 类完整实战 TransNormerLLM-7B 接入 LangChain 搭建知识库助手自定义 LLM 类完整实战【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm本篇技术指南以 Datawhale self-llm 仓库中 models/TransNormerLLM/02-TransNormerLLM-7B 接入langchain搭建知识库助手.md 为核心完整讲解如何将基于线性注意力架构的开源大模型 TransNormerLLM-7B 通过「自定义 LLM 类」的方式接入 LangChain 框架。读者按本指南操作后将掌握从云端 GPU 环境准备、ModelScope 模型下载到继承LLM基类、重写_call方法并直接以 LangChain 统一接口调用本地模型的完整链路为后续搭建知识库问答助手等 RAG 应用奠定模型接入基础。一、为什么要将 TransNormerLLM-7B 接入 LangChainTransNormerLLM 是基于线性注意力的 LLM在准确性和效率方面均优于传统的基于 softmax 注意力的模型官方在包含多达 1.4 万亿 token 的高质量语料库上进行训练并提供 385M、1B、7B 三个参数规模的开源版本。其架构在早期线性注意力模型 TransNormer 基础上升级了 LRPE 位置编码、闪电注意力加速、门控线性注意力GLA以及 SimpleRMSNormSRMSNorm归一化等机制这些技术细节可参见仓库内的 01-TransNormerLLM-7B FastApi 部署调用.md。LangChain 是目前最主流的大模型应用开发框架之一提供了链Chain、检索Retriever、工具调用等丰富的应用组件。要让 LangChain 生态中已有的组件直接驱动 TransNormerLLM-7B最优雅的方式是自定义一个 LLM 类只需从langchain.llms.base.LLM继承一个子类并重写构造函数与_call函数之后就可以以完全一致的方式调用 LangChain 的接口而无需考虑底层模型调用的差异。这正是知识库助手类应用的第一步——先把模型接入框架后续即可自由组合文档加载、向量检索、Prompt 模板等模块。二、环境准备云端 GPU 机器与依赖安装2.1 租赁 24G 显存 GPU 机器本教程建议在 AutoDL 平台租赁一块3090 / 4090 等 24G 显存的显卡机器创建实例时镜像选择PyTorch -- 2.0.0 -- 3.8 (ubuntu20.04) -- 11.8CUDA 11.3 以上版本均可如下图所示实例启动后打开服务器自带的 JupyterLab并从中打开终端Terminal后续的环境配置、模型下载与代码运行均在该终端中完成。这与仓库中 01-TransNormerLLM-7B FastApi 部署调用.md 和 03-TransNormerLLM-7B WebDemo.md 的环境前提保持一致。2.2 pip 换源并安装依赖包为了避免下载超时并加速安装先升级 pip 并把 pypi 源切换为清华镜像源# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple随后安装运行 TransNormerLLM-7B 及接入 LangChain 所需的依赖pip install modelscope1.11.0 pip install transformers4.37.0 accelerate tiktoken einops scipy transformers_stream_generator0.0.4 peft deepspeed pip install -U huggingface_hub pip install triton2.0.0 pip install einops pip install langchain其中几个关键依赖的作用值得说明transformers4.37.0代码中使用了tokenizer.apply_chat_template()接口与GenerationConfig.from_pretrained()这些 API 需要较新的 transformers 版本支持modelscope1.11.0用于从 ModelScope魔搭社区下载模型权重triton2.0.0TransNormerLLM 的自定义模型代码在推理加速路径上依赖 Triton需按指定版本安装transformers_stream_generator0.0.4配合流式生成使用langchain本教程接入框架的核心依赖代码将使用其langchain.llms.base.LLM基类。三、模型下载使用 ModelScope snapshot_download模型使用 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(OpenNLPLab/TransNormerLLM-7B, cache_dir/root/autodl-tmp, revisionmaster)保存后在终端执行python /root/autodl-tmp/model_download.py模型大小约 14 GB下载完成后权重会存放在/root/autodl-tmp/OpenNLPLab/TransNormerLLM-7B路径下这与 FastAPI 部署文档中记录的 12 GB 模型规模同属一个模型实际体积以下载结果为准后续所有加载代码都指向该路径。四、代码准备自定义 TransNormer_LLM 类为便捷构建 LLM 应用我们需要基于本地部署的 TransNormerLLM-7B 自定义一个 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 TransNormer_LLM(LLM): # 基于本地 TransNormer 自定义 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, trust_remote_codeTrue, use_fastFalse) self.model AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtypetorch.bfloat16, trust_remote_codeTrue, 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 TransNormer_LLM4.1 构造函数一次性加载本地模型构造函数在对象实例化的一开始就加载本地部署的 TransNormer 模型从而避免每一次调用都需要重新加载模型带来的时间开销。其中几个关键参数trust_remote_codeTrueTransNormerLLM-7B 在 HuggingFace/ModelScope 上发布时带有自定义模型代码包括线性注意力、SRMSNorm 等自定义算子与apply_chat_template模板必须允许执行远端代码use_fastFalse指定使用普通版而非 fast 版 tokenizer以兼容 TransNormerLLM 的 chat 模板加载torch_dtypetorch.bfloat16以 bfloat16 半精度加载模型显著降低显存占用这也是 24G 显存即可运行 7B 模型的关键device_mapauto由 accelerate 自动将模型各层分配到可用设备上GenerationConfig.from_pretrained(...)加载模型发布时附带的生成配置如温度、top_p、max_length 等保证生成行为与官方一致。4.2 _call 函数LLM 类的核心入口_call是LLM类的核心函数LangChain 会调用该函数来真正驱动底层模型。其内部执行了一条完整的对话式推理链路将用户prompt包装为 OpenAI 风格的消息结构messages [{role: user, content: prompt}]通过tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue)套用模型的 chat 模板生成模型输入文本add_generation_promptTrue表示追加生成提示符即模型开始回答的标志将文本编码为张量并搬运到 CUDA 设备.to(cuda)调用model.generate(..., max_new_tokens512)生成回答限制新增 token 数为 512通过output_ids[len(input_ids):]截掉输入部分的 token仅保留模型新生成的部分用batch_decode(..., skip_special_tokensTrue)解码为纯文本并返回。这一推理模式与仓库内 FastAPI 部署文档 中api.py的实现完全同构只是把面向 HTTP 请求的逻辑替换成了面向 LangChain 的_call接口可见该调用范式在仓库各部署方案中是一致且可复用的。4.3 _llm_type 属性_llm_type属性返回自定义 LLM 类型的标识字符串TransNormer_LLM这是LLM基类要求子类必须实现的接口用于标识 LLM 类型同时可在追踪与缓存等场景中区分不同模型实现。4.4 封装为 LLM.py在整体项目中上述代码被封装为LLM.py文件后续直接从该文件中引入自定义的 LLM 类即可。这一本地模型 自定义 LLM 类的模式在仓库中被多个模型复用例如 Qwen2 接入 LangChain、InternLM3 接入 LangChain、GLM-4 接入 LangChain 等文档均采用同一套自定义 LLM 类方案读者可以横向对照学习。五、调用测试像使用任何 LangChain 大模型一样使用封装完成后就可以像使用其他任何 LangChain 大模型一样使用 TransNormerLLM-7Bfrom LLM import TransNormer_LLM #注意此代码需要和 LLM.py在同路径下如果是写在Jupyter 中则不需要库导入 llm TransNormer_LLM(mode_name_or_path /root/autodl-tmp/OpenNLPLab/TransNormerLLM-7B) llm(你是谁)注意代码文件需与LLM.py处于同一路径下若在 Jupyter Notebook 中直接运行则无需库导入。执行后终端会先输出正在从本地加载模型...待权重加载完成后llm(你是谁)将直接返回模型生成的回答效果如下图所示由于TransNormer_LLM已完整实现LLM基类协议此后它可以被无缝传入 LangChain 的各类高层组件中——例如配合 Prompt 模板与输出解析器构建 Chain或作为 RetrievalQA 等知识库问答链的底层模型。这即为搭建知识库助手打通了最关键的一环模型接入层。后续如需让助手真正回答私有知识库中的内容可在此基础上进一步组合 LangChain 的文档加载器Document Loader、文本分割器Text Splitter、向量库Vector Store与检索器Retriever构建完整的检索增强生成RAG流水线。六、扩展阅读与相关资源TransNormerLLM-7B 在 self-llm 仓库中还有完整的配套实战文档建议按序阅读01-TransNormerLLM-7B FastApi 部署调用.md讲解 TransNormerLLM 架构改进LRPE 位置编码、SGLU 门控、SRMSNorm 归一化与 FastAPI 服务化部署其中api.py与本教程_call函数共享同一套apply_chat_templategenerate推理范式03-TransNormerLLM-7B WebDemo.md基于 Streamlit 构建网页聊天界面同样以AutoTokenizer/AutoModelForCausalLM加载本地模型04-TrasnNormerLLM-7B Lora 微调.md 与 04-TransNormerLLM-7B-chat-Lora.ipynb讲解如何用peft对模型进行 LoRA 高效微调微调后的模型同样可套用本文的自定义 LLM 类接入 LangChain仓库根目录下的数据集 dataset/huanhuan.json 可作为微调阶段构建指令集的示例数据。七、常见问题与注意事项显存不足7B 模型以 bfloat16 加载约需 14 GB 显存推理时建议使用 3090/4090 等 24G 显存机器若显存紧张可尝试调整max_new_tokens或引入量化方案参考仓库内其他模型的 4-bit 量化文档。trust_remote_code提示首次加载时 transformers 会询问是否允许运行自定义代码按y确认即可该机制是 TransNormerLLM 自定义算子与模板正常工作的前提。apply_chat_template依赖版本该接口要求transformers4.37.0若报模板相关错误请先检查 transformers 版本是否符合要求。自定义 LLM 类的接口演进本文代码基于 LangChain 经典接口langchain.llms.base.LLM在较新版本的 LangChain 中该基类仍可用但官方逐步推荐新的langchain_core.language_models.llms.LLM接口若未来遇到 import 报错可将导入路径切换为langchain_core下的对应模块重写的_call与_llm_type逻辑保持不变。模型调用路径一致性本文mode_name_or_path必须指向第 3 节snapshot_download实际下载的缓存目录/root/autodl-tmp/OpenNLPLab/TransNormerLLM-7B路径错误会直接导致加载失败。至此TransNormerLLM-7B 已成功接入 LangChain你可以像使用任何标准 LangChain 大模型一样对其进行调用、组合与二次开发为知识库助手等上层应用打下坚实基础。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进