news 2026/9/12 4:07:03

DeepSeek-7B-Chat 基于 FastAPI 的本地 API 部署与调用实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek-7B-Chat 基于 FastAPI 的本地 API 部署与调用实战指南

DeepSeek-7B-Chat 基于 FastAPI 的本地 API 部署与调用实战指南

【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm

导读

本文基于《开源大模型食用指南》(self-llm)项目中的 DeepSeek-7B-chat FastApi 部署文档,完整讲解如何在 Linux 云主机(以 AutoDL 为例)上从零搭建 DeepSeek-7B-Chat 的本地推理服务:包括环境准备、依赖安装、ModelScope 模型下载、FastAPI + Uvicorn 服务端编写,以及通过 curl 与 Python requests 发起 HTTP 请求的完整链路。读完本文,你将掌握一套可直接复制的"加载 HuggingFace 兼容权重 → 封装成 HTTP 接口 → 多端调用"的标准部署方案,并为后续接入 LangChain、搭建 Web Demo 或进行 LoRA 微调打好基础。

DeepSeek LLM 与 7B-Chat 模型简介

DeepSeek LLM 是由 DeepSeek 团队从零训练的高级语言模型,其中 DeepSeek-7B-Chat 由70 亿个参数组成,训练数据是一个包含2 万亿个英文和中文 token的庞大数据集。为了促进学术与工业研究,DeepSeek 面向研究社区开放了 DeepSeek LLM 7B/67B Base 与 7B/67B Chat 四个版本,本文聚焦 7B-Chat 对话版本在单卡 24G 显存(如 RTX 3090)环境下的 FastAPI 服务化部署。

从仓库后续文档可以印证该模型的更多特性:在 DeepSeek-7B-Chat Lora 微调文档 中,模型的对话格式采用如下模板(与官方仓库指令格式一致):

User: {messages[0]['content']} Assistant: {messages[1]['content']}<|end▁of▁sentence|>User: {messages[2]['content']} Assistant:

这一模板与本文 api.py 中使用的apply_chat_template能力相对应,理解该格式有助于排查部署后生成异常的边界情况。

环境准备:AutoDL 云主机与镜像选择

在 AutoDL 平台租用一台RTX 3090 等 24G 显存的显卡机器,创建实例时按以下路径选择镜像:

PyTorch → 2.0.0 → 3.8 (ubuntu20.04) → 11.8(CUDA 11.3 以上版本均可)。

实例创建并开机后,打开 JupyterLab,再打开其中的终端,后续的环境配置、模型下载与运行演示均在终端中完成。关于 AutoDL 的端口映射方法,可参考 AutoDL 开放端口文档:把 autodl 的 6006 端口映射到本地http://localhost:6006,即可在本地浏览器或脚本中访问云端 API。

安装运行依赖

在终端中依次执行以下命令,先升级 pip 并更换国内 PyPI 源以加速安装,再按固定版本安装依赖包:

# 升级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.104.1 pip install uvicorn==0.24.0.post1 pip install requests==2.25.1 pip install modelscope==1.9.5 pip install transformers==4.35.2 pip install streamlit==1.24.0 pip install sentencepiece==0.1.99 pip install accelerate==0.24.1 pip install transformers_stream_generator==0.0.4

各依赖的职责简要说明:

依赖包作用
fastapi提供 Web 框架,用于定义 HTTP 接口路由
uvicornASGI 服务器,负责承载并运行 FastAPI 应用
requests客户端调用库,用于本地验证 API 接口
modelscope模型下载工具,通过snapshot_download拉取权重
transformers加载模型、分词器并执行生成推理
sentencepieceDeepSeek 分词器底层依赖的分词实现
accelerate支持device_map="auto"实现多设备自动分配
transformers_stream_generator支持流式生成(后续 WebDemo 等场景会用到)

若网络访问 GitHub 受限,在需要安装 flash-attention 等额外依赖时,还可参考仓库中 DeepSeek-MoE-16b-chat FastApi 部署文档 的做法,先执行source /etc/network_turbo开启学术镜像加速(该方法同样适用于本文的 7B 模型场景)。pip/conda 换源的更多镜像选择可参考 pip、conda 换源文档。

通过 ModelScope 下载模型权重

使用 ModelScope 的snapshot_download函数下载模型,第一个参数为模型名称,cache_dir参数指定模型的下载路径。

/root/autodl-tmp路径下新建download.py文件并写入以下内容(保存后运行):

import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer from modelscope import GenerationConfig model_dir = snapshot_download('deepseek-ai/deepseek-llm-7b-chat', cache_dir='/root/autodl-tmp', revision='master')

执行下载:

python /root/autodl-tmp/download.py

模型大小约15 GB,下载耗时约10~20 分钟(取决于网络带宽)。下载完成后,权重会存放在/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat目录下,该路径将作为后续 api.py 中的模型加载路径。

编写 FastAPI 服务端代码(api.py)

/root/autodl-tmp路径下新建api.py文件,写入以下内容(代码包含详细注释):

from fastapi import FastAPI, Request from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig import uvicorn import json import datetime import torch # 设置设备参数 DEVICE = "cuda" # 使用CUDA DEVICE_ID = "0" # CUDA设备ID,如果未设置则为空 CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE # 组合CUDA设备信息 # 清理GPU内存函数 def torch_gc(): if torch.cuda.is_available(): # 检查是否可用CUDA with torch.cuda.device(CUDA_DEVICE): # 指定CUDA设备 torch.cuda.empty_cache() # 清空CUDA缓存 torch.cuda.ipc_collect() # 收集CUDA内存碎片 # 创建FastAPI应用 app = FastAPI() # 处理POST请求的端点 @app.post("/") async def create_item(request: Request): global model, tokenizer # 声明全局变量以便在函数内部使用模型和分词器 json_post_raw = await request.json() # 获取POST请求的JSON数据 json_post = json.dumps(json_post_raw) # 将JSON数据转换为字符串 json_post_list = json.loads(json_post) # 将字符串转换为Python对象 prompt = json_post_list.get('prompt') # 获取请求中的提示 max_length = json_post_list.get('max_length') # 获取请求中的最大长度 # 构建 messages 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(model.device), max_new_tokens=max_length) result = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True) now = datetime.datetime.now() # 获取当前时间 time = now.strftime("%Y-%m-%d %H:%M:%S") # 格式化时间为字符串 # 构建响应JSON answer = { "response": result, "status": 200, "time": time } # 构建日志信息 log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(result) + '"' print(log) # 打印日志 torch_gc() # 执行GPU内存清理 return answer # 返回响应 # 主函数入口 if __name__ == '__main__': mode_name_or_path = '/root/autodl-tmp/deepseek-ai/deepseek-llm-7b-chat' # 加载预训练的分词器和模型 tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, trust_remote_code=True,torch_dtype=torch.bfloat16, device_map="auto") model.generation_config = GenerationConfig.from_pretrained(mode_name_or_path) model.generation_config.pad_token_id = model.generation_config.eos_token_id model.eval() # 设置模型为评估模式 # 启动FastAPI应用 # 用6006端口可以将autodl的端口映射到本地,从而在本地使用api uvicorn.run(app, host='0.0.0.0', port=6006, workers=1) # 在指定端口和主机上启动应用

代码关键点逐段解析

1. 设备与显存管理

DEVICE = "cuda" DEVICE_ID = "0" CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE

将推理固定到 CUDA 设备 0。torch_gc()在每次请求结束后调用torch.cuda.empty_cache()清空缓存、torch.cuda.ipc_collect()回收显存碎片,避免长时运行导致显存膨胀——这是服务化部署中防止 OOM 的关键实践。

2. 请求解析与生成

json_post_list = json_post_raw if isinstance(json_post_raw, dict) else json.loads(json_post)

json_post_list.get('prompt')json_post_list.get('max_length')分别读取用户提示与最大生成长度(两者均可缺省,max_length缺省时generate将使用模型默认的max_new_tokens)。

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(model.device), max_new_tokens=max_length) result = tokenizer.decode(outputs[0][input_tensor.shape[1]:], skip_special_tokens=True)

apply_chat_template会根据模型自带的 chat template 自动拼装出前文所述的User: ...\n\nAssistant:对话格式并追加生成提示符,return_tensors="pt"直接返回 PyTorch 张量;max_new_tokens=max_length控制新生成的 token 数量(而非输入 + 输出的总长度);解码时通过outputs[0][input_tensor.shape[1]:]切片去掉输入部分,只保留模型新生成的内容,skip_special_tokens=True剔除<|end▁of▁sentence|>等特殊 token。值得注意的是这里入参名是max_length,但实际语义对应 HF 的max_new_tokens

3. 响应与日志

响应统一封装为{"response": ..., "status": 200, "time": ...}三段式结构,并在服务端控制台打印[时间] prompt / response格式的访问日志,便于排查问题。

4. 模型加载与启动

tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="auto") model.generation_config = GenerationConfig.from_pretrained(mode_name_or_path) model.generation_config.pad_token_id = model.generation_config.eos_token_id model.eval()
  • trust_remote_code=True:DeepSeek 属于自定义架构(依赖远程代码文件),必须开启;
  • torch_dtype=torch.bfloat16:以半精度加载,显著降低显存占用(24G 单卡即可容纳 7B 模型);
  • device_map="auto":由 accelerate 自动将各层分配到可用设备;
  • model.generation_config.pad_token_id = model.generation_config.eos_token_id:将 pad token 设为 eos token,避免 batch 生成时 padding 干扰;
  • model.eval():切换为评估模式,关闭 dropout 等训练行为;
  • uvicorn.run(app, host='0.0.0.0', port=6006, workers=1):绑定所有网卡、监听 6006 端口,单 worker 运行(多 worker 会各自加载一份模型导致显存翻倍)。

启动 API 服务

在终端执行:

cd /root/autodl-tmp python api.py

当终端出现Loading checkpoint shards: 100%Application startup complete,并显示服务监听地址http://0.0.0.0:6006时,说明模型加载完毕、服务启动成功:

默认部署在6006 端口,通过POST 方法进行调用。配合 AutoDL 开放端口文档 将 6006 端口映射到本地后,即可在本地直接访问该 API。

调用 API 服务

方式一:使用 curl

curl -X POST "http://127.0.0.1:6006" \ -H 'Content-Type: application/json' \ -d '{"prompt": "你好"}'

方式二:使用 Python requests 库

import requests import json def get_completion(prompt): headers = {'Content-Type': 'application/json'} data = {"prompt": prompt} response = requests.post(url='http://127.0.0.1:6006', headers=headers, data=json.dumps(data)) return response.json()['response'] if __name__ == '__main__': print(get_completion('你好'))

返回结果格式

两种方式得到的返回值结构一致,示例:

{ 'response': '你好!有什么我可以帮助你的吗?', 'status': 200, 'time': '2023-12-01 17:06:10' }

其中response为模型生成文本,status为业务状态码,time为服务端处理时间戳。

关于 max_length 参数的实践建议

结合仓库中同系列模型 DeepSeek-MoE-16b-chat FastApi 部署文档 的实测经验:调用时建议显式携带max_length,例如{"prompt": "你好,你是谁?","max_length":100}——值过大容易爆显存,过小则回答输出不全。7B-Chat 在 24G 单卡环境下同样建议遵循"适度取值"原则,按实际显存余量在 64~256 之间调节。

部署后的能力延伸

FastAPI 接口稳定运行后,可以自然地与仓库中的其他教程衔接,复用本文的模型加载与推理链路:

  • 接入 LangChain:参考 DeepSeek-7B-chat langchain 接入文档,从langchain.llms.base.LLM继承自定义DeepSeek_LLM类并重写_call方法,即可将本地模型无缝接入 LangChain 应用(其中同样使用了apply_chat_templatemax_new_tokens=100的生成配置);
  • 搭建 Web 对话界面:参考 DeepSeek-7B-chat WebDemo 部署文档,使用 Streamlit 包装同一套get_model()加载逻辑,并通过st.chat_message实现多轮对话界面;
  • 模型微调:如需针对业务数据微调,可参考 DeepSeek-7B-chat Lora 微调文档,其中包含指令集构建、LoraConfig参数(如r=8lora_alpha=32)与Trainer训练的完整流程。

常见问题与注意事项

  1. 显存不足:确认按 bfloat16 加载且未开启多 worker;调用时将max_length调小;若仍不足可考虑使用仓库中 4bits 量化 QLoRA 方案的思路(参见 DeepSeek-7B-chat 4bits 量化 Qlora 微调文档)压缩显存占用。
  2. 端口无法访问:确认云平台安全组/端口映射已开放 6006 端口;服务需监听0.0.0.0而非127.0.0.1,否则外部无法访问。
  3. 中文生成异常:DeepSeek 分词器基于 sentencepiece,请确保sentencepiece==0.1.99已正确安装;模型文件下载不完整时建议删除缓存目录重新snapshot_download
  4. max_length语义:接口入参实际对应max_new_tokens(新生成 token 上限),传入过大值可能导致超出上下文窗口而报错或输出截断。

至此,一个完整可用的 DeepSeek-7B-Chat HTTP 推理服务已部署完成,可直接被 curl、Python 脚本、LangChain 或其他服务集成调用。

【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调(全参数/Lora)、部署国内外开源大模型(LLM)/多模态大模型(MLLM)教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 4:04:33

PyTorch激活层实战指南:从源码、数值稳定性到工业部署避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 4:03:55

Splunk日志分析与安全运维实战指南

1. Splunk 是什么&#xff1f;从日志分析到安全运维的全能平台 第一次接触Splunk时&#xff0c;我正被海量服务器日志搞得焦头烂额。传统grep命令像在稻草堆里找针&#xff0c;直到同事扔给我一句"Splunk能让你像用Google一样搜日志"&#xff0c;这个比喻瞬间点燃了我…

作者头像 李华
网站建设 2026/9/12 4:03:49

从文本到CAD模型:text-to-cad技术原理与工程实践

1. 一个需求单引发的思考&#xff1a;text-to-cad到底戳中了谁很多人在聊text-to-cad时&#xff0c;都喜欢从"AI会不会取代设计师"这个角度切入&#xff0c;我觉得这不是重点。我自己的经历是&#xff0c;真正让人头疼的从来不是设计本身&#xff0c;而是"从需求…

作者头像 李华
网站建设 2026/9/12 4:03:26

滑动窗口最大值算法:单调队列原理与Go实现

1. 问题背景与核心挑战LeetCode 239题"滑动窗口最大值"是算法面试中的经典问题&#xff0c;主要考察对滑动窗口和单调队列的理解与应用。给定一个整数数组nums和一个整数k&#xff0c;我们需要找到每个长度为k的滑动窗口中的最大值&#xff0c;并返回这些最大值组成的…

作者头像 李华
网站建设 2026/9/12 4:03:05

双有源桥DAB Simulink闭环仿真建模与PI参数整定实战指南

做高频隔离型DCDC的同行应该都有这种感觉&#xff1a;双有源桥&#xff08;DAB&#xff09;看着就八个管子加一个变压器&#xff0c;原理图简单到让人放松警惕&#xff0c;真正自己搭Simulink模型做闭环控制的时候&#xff0c;问题一个接一个。最近这个月我已经帮三个人远程看D…

作者头像 李华