如何在本地部署大模型并实现接口访问( Llama3、Qwen、DeepSeek等)

如何在本地部署大模型并实现接口访问( Llama3、Qwen、DeepSeek等)

  • 如何在本地部署大模型并实现接口访问( Llama3、Qwen、DeepSeek等)
    • 模型地址
    • 模型下载
    • 模型部署
      • 指定显卡运行
      • app.py
    • 运行环境
      • requirements
    • 调用接口
      • 代码调用
    • 结语

如何在本地部署大模型并实现接口访问( Llama3、Qwen、DeepSeek等)

本文详细介绍了如何在本地服务器上部署大模型(如DeepSeek、Llama3、Qwen等),并通过接口实现外部调用。首先,从HuggingFace或魔搭网站下载模型,使用git lfs和screen确保大文件完整下载;接着,使用FastAPI封装模型推理过程,支持多GPU运行并通过CUDA_VISIBLE_DEVICES指定显卡,提供完整的app.py代码实现模型加载和接口响应;然后,通过conda创建Python 3.10环境并安装依赖,使用nohup后台运行服务;最后,展示如何通过Postman或代码调用接口,发送请求并获取模型生成的文本。本文提供了从模型下载、部署到接口调用的完整流程,适合在本地服务器上运行大模型并实现高效的推理服务。

模型地址

在HuggingFace中搜索对应模型,并选择git clone
比如

git clone https://huggingface.co/deepseek-ai/DeepSeek-V2-Chat

huggingface网站可能会访问超时,因此可以选择国内的魔搭网站,同样登录网站后,搜索对应模型并下载

在这里插入图片描述

git clone https://www.modelscope.cn/deepseek-ai/DeepSeek-V2-Lite-Chat.git

模型下载

由于模型比较大,所以需要用git lfs install

如果是下载70B或者更大的模型,可能git clone还是会遗漏一些文件,所以推荐使用Screen在后台下载

创建conda环境后,使用conda install -c conda-forge screen安装screen

为 screen 会话指定一个名称,可以使用 -S 参数:

screen -S mysession

暂时离开当前 screen 会话(但保持会话在后台运行)

Ctrl + A,然后按 D

重新连接到之前创建的 screen 会话,可以使用以下命令:

screen -r mysession

screen相当于启动了一个新的终端,与其他的终端互不影响,其中的工作都在后台运行

在screen中运行 git clone命令即可

如果出现文件遗漏,可以使用sh脚本指定文件下载,比如指定三个文件进行下载的download_files.sh

#!/bin/bash# 目标 URL 和文件名的前缀
BASE_URL="https://www.modelscope.cn/models/LLM-Research/Llama-3.3-70B-Instruct/resolve/master"
FILES=("model-00028-of-00030.safetensors""model-00029-of-00030.safetensors""model-00030-of-00030.safetensors"
)# 循环下载文件
for FILE in "${FILES[@]}"; doecho "开始下载 $FILE ..."curl -O "$BASE_URL/$FILE"  # 使用 curl 下载文件if [ $? -eq 0 ]; thenecho "$FILE 下载成功"elseecho "$FILE 下载失败"fi
doneecho "所有文件下载完毕!"

在终端中运行脚本:

./download_files.sh
  • ./ 表示当前目录,确保系统知道从当前目录查找脚本。

模型部署

模型下载后,本地就有了完整的模型仓库

在这里插入图片描述
接下来就要进行模型的部署,采用fastapi进行模型部署,使用下列代码作为app.py

指定显卡运行

如果你有多张显卡,并且想指定使用第4和第5张GPU运行,可以在环境变量中设置仅4,5 GPU可见,此时第4变为0 第5变为1

if "DeepSeek" in MODEL_PATH_OR_NAME:os.environ['CUDA_VISIBLE_DEVICES'] = '4'
else:os.environ['CUDA_VISIBLE_DEVICES'] = '4,5'

然后加载模型时设置device_map="auto"

model = AutoModelForCausalLM.from_pretrained(MODEL_PATH_OR_NAME, torch_dtype=torch.float16, device_map="auto")

app.py

import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
import torch
import torch.nn as nn
# Initialize FastAPI app
app = FastAPI()MODEL_PATH_OR_NAME = "/yourpath/DeepSeek-V2-Lite-Chat"# Set CUDA devices for visibility
if "DeepSeek" in MODEL_PATH_OR_NAME:os.environ['CUDA_VISIBLE_DEVICES'] = '4'
else:os.environ['CUDA_VISIBLE_DEVICES'] = '4,5'
device = torch.device('cuda:0')  # Using GPU 2# Declare global variables for model and tokenizer
model = None
tokenizer = None# Use startup and shutdown events for model loading and unloading
@app.on_event("startup")
async def startup():global model, tokenizerprint("Loading model and tokenizer...")if "DeepSeek" in MODEL_PATH_OR_NAME:tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH_OR_NAME, trust_remote_code=True)model = AutoModelForCausalLM.from_pretrained(MODEL_PATH_OR_NAME, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="auto").cuda()model.generation_config = GenerationConfig.from_pretrained(MODEL_PATH_OR_NAME)model.generation_config.pad_token_id = model.generation_config.eos_token_idelse:tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH_OR_NAME, use_fast=False)tokenizer.pad_token_id = tokenizer.eos_token_id  # 假设eos_token_id就是合适的填充词元标识model = AutoModelForCausalLM.from_pretrained(MODEL_PATH_OR_NAME, torch_dtype=torch.float16, device_map="auto")print("Model loaded successfully!")@app.on_event("shutdown")
async def shutdown():global model, tokenizerprint("Shutting down the model...")del modeldel tokenizer# Define request model using Pydantic
class ChatCompletionRequest(BaseModel):model: strmessages: listtemperature: float = 0max_tokens: int = 256top_p: float = 1stop: list = None  # Ensure stop is a list or None# Define response model
class ChatCompletionResponse(BaseModel):choices: list# Define the /generate route
@app.post("/generate", response_model=ChatCompletionResponse)
async def generate_response(request: ChatCompletionRequest):# Get user prompt (last message)prompt = request.messages[-1]["content"]print('INPUT :'+prompt+'\n')if "DeepSeek" in MODEL_PATH_OR_NAME:try:messages = [{"role": "user", "content": prompt}]input_tensor = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt")outputs = model.generate(input_tensor.to(device), max_new_tokens=100)result = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True)print('OUTPUT :'+result)return ChatCompletionResponse(choices=[{"message": {"role": "assistant", "content": result},"finish_reason": "stop"}])except Exception as e:raise HTTPException(status_code=500, detail=str(e))else:try:# Tokenize the input text (with padding and truncation to ensure consistency)input_ids = tokenizer.encode(prompt, return_tensors="pt").to(device)# Optionally, get eos_token_id for stopping criteriaeos_token_id = tokenizer.eos_token_id if tokenizer.eos_token_id else Noneattention_mask = torch.ones(input_ids.shape,dtype=torch.long,device=device)# Generate the response using the modeloutput = model.generate(input_ids,num_beams=1,  # Use greedy decodingnum_return_sequences=1,early_stopping=True,do_sample=False,max_length=(getattr(request, 'max_tokens', 50) + len(input_ids[0])),  # 默认 max_tokens=50top_p=getattr(request, 'top_p', 0.9),  # 默认 top_p=0.9temperature=getattr(request, 'temperature', 0.9),  # 默认 temperature=1.0repetition_penalty=getattr(request, 'repetition_penalty', 1.2),  # 默认 repetition_penalty=1.2eos_token_id=eos_token_id,  # Use eos_token_id for stoppingattention_mask=attention_mask,pad_token_id=eos_token_id)# Decode the generated text (skip special tokens)generated_text = tokenizer.decode(output[0], skip_special_tokens=True)# Strip the prompt (remove the input part from the output)output_tokens = output[0][len(input_ids[0]):]  # Remove input tokens from output tokensgenerated_text = tokenizer.decode(output_tokens, skip_special_tokens=True)print('OUTPUT:'+generated_text)# Return the generated text in the expected formatreturn ChatCompletionResponse(choices=[{"message": {"role": "assistant", "content": generated_text.strip()},"finish_reason": "stop"}])except Exception as e:raise HTTPException(status_code=500, detail=str(e))# Health check route
@app.get("/")
async def health_check():return {"status": "ok", "message": "Text Generation API is running!"}if __name__ == "__main__":import uvicornuvicorn.run("app:app", host="0.0.0.0", port=8890, reload=True)  # reload=True 用于开发时的热重载

运行环境

运行app.py前需要安装环境依赖

首先
conda 创建环境:

conda create -n llmapi python=3.10 -y
conda activate llmapi

安装以下依赖,保存为requirements,txt

requirements

accelerate==1.1.1
annotated-types==0.7.0
anyio==4.6.2.post1
certifi==2024.8.30
charset-normalizer==3.4.0
click==8.1.7
exceptiongroup==1.2.2
fastapi==0.115.5
filelock==3.16.1
fsspec==2024.10.0
gputil==1.4.0
h11==0.14.0
huggingface-hub==0.26.3
idna==3.10
jinja2==3.1.4
markupsafe==3.0.2
mpmath==1.3.0
# networkx==3.2.1
numpy==2.0.2
nvidia-cublas-cu12==12.4.5.8
nvidia-cuda-cupti-cu12==12.4.127
nvidia-cuda-nvrtc-cu12==12.4.127
nvidia-cuda-runtime-cu12==12.4.127
nvidia-cudnn-cu12==9.1.0.70
nvidia-cufft-cu12==11.2.1.3
nvidia-curand-cu12==10.3.5.147
nvidia-cusolver-cu12==11.6.1.9
nvidia-cusparse-cu12==12.3.1.170
nvidia-nccl-cu12==2.21.5
nvidia-nvjitlink-cu12==12.4.127
nvidia-nvtx-cu12==12.4.127
packaging==24.2
pillow==11.0.0
protobuf==5.29.0
psutil==6.1.0
pydantic==2.10.2
pydantic-core==2.27.1
pyyaml==6.0.2
regex==2024.11.6
requests==2.32.3
safetensors==0.4.5
sentencepiece==0.2.0
sniffio==1.3.1
starlette==0.41.3
sympy==1.13.1
tokenizers==0.20.3
torch==2.5.1
torchaudio==2.5.1
torchvision==0.20.1
tqdm==4.67.1
transformers==4.46.3
triton==3.1.0
typing-extensions==4.12.2
urllib3==2.2.3
uvicorn==0.32.1

运行下列命令安装:

pip install -r requirements,txt

然后运行下列命令启动app.py ,这个命令会在后台启动app.py,并且输出日志在app.log 文件内

nohup python app.py > app.log 2>&1 &

调用接口

查看日志模型是否成功启动:

在这里插入图片描述

然后使用Post请求对应接口

{"model": "deep seek", "messages": [{"role": "user", "content": "AI是什么意思?"}],"temperature": 0.9,"max_tokens": 100,"repetition_penalty": 1.2, "top_p": 0.9,"stop": ["\n"] }   

使用PostMan测试结果:

在这里插入图片描述

代码调用

 import requestsimport json# Define the FastAPI URLurl = "http://YourIPAddress:YourPort/generate"prompt = '你是什么模型?'# Define the request payload (data)data = {"model": "ModelName",  # Example model name (change according to your setup)"messages": [{'role': 'user', 'content': prompt}],"temperature": 0.7,"max_tokens": 100,"top_p": 1.0,"frequency_penalty": 0.0,"presence_penalty": 0.0,"stop": []  # Ensure 'stop' is an empty list}response = ''# Send a POST request to the FastAPI endpointresponse_data = requests.post(url, json=data)# Check the responseif response_data.status_code == 200:# print("Response received successfully:")# print(json.dumps(response.json(), indent=4))result = response_data.json()# 从响应中获取生成的文本response = str(result['choices'][0]['message']['content']).strip()else:print(f"Request failed with status code {response_data.status_code}")print(response_data.text)return response

结语

至此,大模型的本地部署和接口调用就介绍完了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/67243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库增量备份和全量备份

数据库增量备份和全量备份 1.修改配置 首先打开配置文件my.ini 添加以下配置 #log-bin"JSSM-20230617FY-bin" log-bin"mysql-bin"# Server Id. server-id1#指令指定写入二进制日志的事件格式 binlog_formatMIXED添加完之后对MySQL服务进行重启 重启之后…

用 Python 从零开始创建神经网络(十九):真实数据集

真实数据集 引言数据准备数据加载数据预处理数据洗牌批次(Batches)训练(Training)到目前为止的全部代码: 引言 在实践中,深度学习通常涉及庞大的数据集(通常以TB甚至更多为单位)&am…

[250110] React 19 深度探索:新特性、改进与最佳实践 | Caddy 2.9.0 发布

目录 React 19 深度探索:新特性、改进与最佳实践1 Actions API - 简化异步 UI 状态管理2 全新 Hooks 增强灵活性3 服务器组件 - 增强性能4 改进的 hydration5 增强的 Context API6 支持自定义元素7 迁移和最佳实践 Caddy 2.9.0 发布 React 19 深度探索:新…

Git 的基本概念

Git 是一种分布式版本控制系统,用于跟踪文件的修改历史和协同多人开发。 Git 的基本概念包括: 仓库(Repository):存储项目文件的地方。分支(Branch):用于同时进行多个任务或开发多…

使用 Debug 类的 Assert 方法查找 C# 中的错误

Debug类提供了几种用于调试代码的方法。其Assert方法采用布尔值,如果值为false则抛出异常。第二个参数给出异常应显示的错误消息。如果在调试器中运行时断言失败,您可以选择打开调试器到抛出异常的 Debug.Assert语句。 通常,您使用Debug.Ass…

Ubuntu服务器提示:检测到存在恶意文件,补救思路

1. 确定文件类型 可以使用file命令来检查该文件的类型,这有助于判断它是否真的是一个恶意文件 file /path/to/the/file 2. 检查文件内容 使用strings命令查看文件内容,看是否有可疑的命令或脚本: strings /path/to/the/file 3. 扫描系统…

webrtc自适应分辨率的设置

DegradationPreference 是一个枚举类,用于在视频编码或实时通信(如 WebRTC)中指定系统资源不足时如何处理质量下降的策略。以下是该枚举类的中文解释: enum class DegradationPreference {// 禁用:不根据资源过载信号…

United States of America三种表示

"United States of America", "United States", 和 "America" 都表示美国,但它们的使用场景和背景略有不同。以下是关于为什么这些名称可以合在一起表示美国的详细解释: 1. "United States of America" 全称&a…

时序数据库TDengine 3.3.5.0 发布:高并发支持与增量备份功能引领新升级

近日,TDengine 3.3.5.0 版本正式发布,带来了多项重磅更新与优化,从功能拓展到性能提升,再到用户体验进行了全面改进。本次更新围绕用户核心需求展开,涵盖了开发工具、数据管理、安全性、可视化等多个层面,为…

Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Qt绘图基础 QPainter概述 基本工作流程 绘图事件系统 paintEvent事件 重绘机制 文字绘制技术 基本文字绘制 ​编辑 高级文字效果 基本图形绘制 线条绘制 ​编辑 形状绘制 …

《计算机网络》课后探研题书面报告_网际校验和算法

网际校验和算法 摘 要 本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等&a…

浅谈计算机网络02 | SDN控制平面

计算机网络控制平面 一、现代计算机网络控制平面概述1.1 与数据平面、管理平面的关系1.2 控制平面的发展历程 二、控制平面的关键技术剖析2.1 网络层协议2.1.1 OSPF协议2.1.2 BGP协议 2.2 SDN控制平面技术2.2.1 SDN架构与原理2.2.2 OpenFlow协议2.2.3 SDN控制器 一、现代计算机…

51_Lua面向对象编程

面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构。像C++、Java、Objective-C、Smalltalk、C#、Ruby等编程语言都支持面向对象编程。 1.面向对象编程特性 面向对象编程是一种编程范式,它使用“对象”来设计软件。对象是数据和行为的封装单元…

《重生到现代之从零开始的C++生活》—— 入门基础语法

命名空间 创建 namespace name {int a;char b; }命名空间是干什么的呢? 已知我们读取变量都是先读取局部变量,再读取全局变量,但是如果碰到一些起名重合的时候会报错,我们只能换变量名 那么有没有方法能让其不报错,让他们合法…

SpringBoot整合Easy-es

一.什么是Easy-Es Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,在 RestHighLevelClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称…

网络层协议-----IP协议

目录 1.认识IP地址 2.IP地址的分类 3.子网划分 4.公网IP和私网IP 5.IP协议 6.如何解决IP地址不够用 1.认识IP地址 IP 地址(Internet Protocol Address)是指互联网协议地址。 它是分配给连接到互联网的设备(如计算机、服务器、智能手机…

我国无人机新增实名登记110.3 万架,累计完成飞行2666万小时

据央视新闻从中国民航局了解到,2024 年我国全年新增通航企业 145 家、通用机场 26 个,颁发无人驾驶航空器型号合格证 6 个、新增实名登记无人机 110.3 万架,无人机运营单位总数超过 2 万家,累计完成无人机飞行 2666 万小时&#x…

MySQL主从:如何处理“Got Fatal Error 1236”或 MY-013114 错误(percona译文)

错误的 GTID 如今,典型的复制设置使用 GTID 模式,完整的错误消息可能如下所示: mysql > show replica status\G *************************** 1. row ***************************Replica_IO_Running: NoReplica_SQL_Running: YesLast_I…

【Linux】正则表达式

正则表达式是一种可供Linux工具过滤文本的自定义模板,Linux工具(如sed、gawk)会在读取数据时使用正则表达式对数据进行模式匹配。 正则表达式使用元字符来描述数据流中的一个或多个字符。它是由正则表达式引擎实现的。正则表达式引擎是一种底…

数据平台浅理解

定义 数据平台架构是指用于收集、存储、处理和分析数据的一系列组件、技术和流程的整体架构设计。它就像是一个复杂的数据生态系统的蓝图,旨在高效地管理数据从产生源头到产生价值的整个生命周期。 主要层次 数据源层 这是数据的起点,包含各种类型的数据…