目的:使用AutoDL的深度学习环境,简单部署大模型
环境配置
考虑到部分同学配置环境可能会遇到一些问题,我们在AutoDL平台准备了LLaMA3-1的环境镜像,点击下方链接并直接创建Autodl示例即可。 CodeWithGPU | 能复现才是好算法
首先 pip
换源加速下载并安装依赖包
# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install fastapi==0.111.1 pip install uvicorn==0.30.3 pip install modelscope==1.16.1 pip install transformers==4.42.4 pip install accelerate==0.32.1
模型下载
模型下载社区有魔塔和huggingface(被墙,可能不能使用),所以同意使用魔塔社区的方式下载模型
新建 model_download.py
文件并在其中输入以下内容,粘贴代码后请及时保存文件,如下图所示。并运行 python model_download.py
执行下载,模型大小为 15GB,下载模型大概需要15 分钟。
import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os model_dir = snapshot_download('LLM-Research/Meta-Llama-3.1-8B-Instruct', cache_dir='/root/autodl-tmp', revision='master')
注意:如果模型下载失败,可以多试几次:运行
python model_download.py
核心代码
为便捷构建 LLM
应用,我们需要基于本地部署的 LLaMA3_1_LLM
,自定义一个 LLM
类,将 LLaMA3.1
接入到 LangChain
框架中。完成自定义 LLM
类之后,可以以完全一致的方式调用 LangChain
的接口,而无需考虑底层模型调用的不一致。
基于本地部署的 LLaMA3.1
自定义 LLM
类并不复杂,我们只需从 LangChain.llms.base.LLM
类继承一个子类,并重写构造函数与 _call
函数即可:
在当前路径新建一个 LLM.py
文件,并输入以下内容,粘贴代码后记得保存文件。
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 LLaMA3_1_LLM(LLM): # 基于本地 llama3.1 自定义 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_fast=False) self.model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtype=torch.bfloat16, device_map="auto") self.tokenizer.pad_token = self.tokenizer.eos_token print("完成本地模型的加载") def _call(self, prompt : str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any): messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": prompt} ] input_ids = self.tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True) model_inputs = self.tokenizer([input_ids], return_tensors="pt").to(self.model.device) generated_ids = self.model.generate(model_inputs.input_ids,max_new_tokens=512) 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_tokens=True)[0] return response @property def _llm_type(self) -> str: return "LLaMA3_1_LLM"
在上述类定义中,我们分别重写了构造函数和 _call
函数:对于构造函数,我们在对象实例化的一开始加载本地部署的 LLaMA3.1
模型,从而避免每一次调用都需要重新加载模型带来的时间过长;_call
函数是 LLM
类的核心函数,LangChain
会调用该函数来调用 LLM
,在该函数中,我们调用已实例化模型的 generate
方法,从而实现对模型的调用并返回调用结果。
在整体项目中,我们将上述代码封装为 LLM.py
,后续将直接从该文件中引入自定义的 LLM 类。
调用
然后就可以像使用任何其他的langchain大模型功能一样使用了。
注意:记得修改模型路径为你的路径哦~
from LLM import LLaMA3_1_LLM llm = LLaMA3_1_LLM(mode_name_or_path = "/root/autodl-tmp/LLM-Research/Meta-Llama-3.1-8B-Instruct") print(llm("你好呀"))
Langchain的缺点就是太繁琐了,导致token生成很慢
终止应用程序
Ctrl+c
可以结束api.py的API接口程序