ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

使用 FastAPI 部署 DeepSeek-R1-Distill-Qwen-7B:从环境配置到 curl / requests 接口调用的完整实战指南

使用 FastAPI 部署 DeepSeek-R1-Distill-Qwen-7B:从环境配置到 curl / requests 接口调用的完整实战指南 使用 FastAPI 部署 DeepSeek-R1-Distill-Qwen-7B从环境配置到 curl / requests 接口调用的完整实战指南【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm本文是《开源大模型食用指南》中 DeepSeek-R1-Distill-Qwen 系列的第一篇部署教程完整讲解如何在 Linux CUDA 环境下用 FastAPI Uvicorn 将 DeepSeek-R1-Distill-Qwen-7B 包装成一个可直接对外提供服务的 HTTP 推理接口。读完本文你将掌握基于 ModelScope 的模型下载、带有思考过程think解析的服务端代码编写、服务启动与 AutoDL 端口映射以及使用 curl 和 Python requests 两种方式调用推理服务的完整技能。一、模型背景R1 系列的蒸馏成果DeepSeek-R1 系列模型通过大规模强化学习RL训练在推理能力上表现出色。其中 DeepSeek-R1-Zero 没有以监督微调SFT作为前置步骤虽然涌现出强大的推理行为但也面临无休止重复、可读性差、语言混合等问题DeepSeek 团队随后引入冷启动数据推出 DeepSeek-R1并开源了基于 Llama 和 Qwen 蒸馏得到的六个密集模型本教程使用的DeepSeek-R1-Distill-Qwen-7B正是其中之一详见本目录的 readme.md。与普通对话模型不同这类推理型模型在正式回答之前会先生成一段内部思考过程并包裹在think.../think标签中。这一特性直接决定了服务端代码的设计——我们需要额外处理思考内容与最终答案的分离这也是本文split_text函数存在的根本原因。二、环境准备本文基础环境如下---------------- ubuntu 22.04 python 3.12 cuda 12.1 pytorch 2.3.0 ----------------本文默认学习者已安装好以上 Pytorch(cuda) 环境如未安装请自行安装。2.1 pip 换源与依赖安装考虑到国内网络环境先升级 pip 并更换 pypi 源加速依赖安装换源的更多细节可参考仓库中的 01-pip、conda换源.md# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple随后按指定版本安装依赖包。版本号经过本仓库验证锁定版本有助于规避 FastAPI、Transformers 等库升级带来的接口变动pip install requests2.32.3 pip install fastapi0.115.8 pip install uvicorn0.34.0 pip install transformers4.48.2 pip install huggingface-hub0.28.1 pip install accelerate1.3.0 pip install modelscope1.22.3各依赖的作用依赖版本在本教程中的作用fastapi0.115.8构建 HTTP 服务端定义 POST 请求端点uvicorn0.34.0ASGI 服务器负责真正启动并监听端口transformers4.48.2加载模型与分词器、执行推理生成accelerate1.3.0支撑device_map设备自动分配modelscope1.22.3从 ModelScope 下载模型权重huggingface-hub0.28.1transformers 底层模型仓库管理依赖requests2.32.3后续用 Python 调用服务接口仓库还针对 AutoDL 平台准备了 DeepSeek-R1-Distill-Qwen 的环境镜像可直接一键创建实例省去手动配置环境的环节。三、模型下载使用modelscope中的snapshot_download函数下载模型第一个参数为模型名称参数cache_dir为模型的下载路径。新建model_download.py文件并输入以下内容from modelscope import snapshot_download model_dir snapshot_download(deepseek-ai/DeepSeek-R1-Distill-Qwen-7B, cache_dir/root/autodl-tmp, revisionmaster)保存后运行python model_download.py执行下载。注意记得修改cache_dir为你的模型下载路径且尽量使用绝对路径。关于模型下载仓库 03-模型下载.md 还介绍了 huggingface-cli、HF 镜像、git-lfs 等多种方式本教程以国内可稳定访问的 ModelScope 为主。下载完成后模型权重位于/root/autodl-tmp/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B后续代码中的model_name_or_path即指向该目录。四、FastAPI 服务端代码全解析新建api.py文件并输入以下内容代码带有详细注释from fastapi import FastAPI, Request from transformers import AutoTokenizer, AutoModelForCausalLM import uvicorn import json import datetime import torch import re # 设置设备参数 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内存碎片 # 文本分割函数 def split_text(text): pattern re.compile(rthink(.*?)/think(.*), re.DOTALL) # 定义正则表达式模式 match pattern.search(text) # 匹配 think思考过程/think回答 if match: # 如果匹配到思考过程 think_content match.group(1).strip() # 获取思考过程 answer_content match.group(2).strip() # 获取回答 else: think_content # 如果没有匹配到思考过程则设置为空字符串 answer_content text.strip() # 直接返回回答 return think_content, answer_content # 创建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) # 获取请求中的提示 messages [ {role: user, content: prompt} ] # 调用模型进行对话生成 input_ids tokenizer.apply_chat_template(messages,tokenizeFalse,add_generation_promptTrue) model_inputs tokenizer([input_ids], return_tensorspt).to(model.device) generated_ids model.generate(model_inputs.input_ids,max_new_tokens8192) # 思考需要输出更多的Token数设为8K generated_ids [ output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids) ] response tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] think_content, answer_content split_text(response) # 调用split_text函数分割思考过程和回答 now datetime.datetime.now() # 获取当前时间 time now.strftime(%Y-%m-%d %H:%M:%S) # 格式化时间为字符串 # 构建响应JSON answer { response: response, think: think_content, answer: answer_content, status: 200, time: time } # 构建日志信息 log f[{time}], prompt:\{prompt}\, response:\{repr(response)}\, think:\{think_content}\, answer:\{answer_content}\ print(log) # 打印日志 torch_gc() # 执行GPU内存清理 return answer # 返回响应 # 主函数入口 if __name__ __main__: # 加载预训练的分词器和模型 model_name_or_path /root/autodl-tmp/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B tokenizer AutoTokenizer.from_pretrained(model_name_or_path, use_fastFalse) model AutoModelForCausalLM.from_pretrained(model_name_or_path, device_mapCUDA_DEVICE, torch_dtypetorch.bfloat16) # 启动FastAPI应用 # 用6006端口可以将autodl的端口映射到本地从而在本地使用api uvicorn.run(app, host0.0.0.0, port6006, workers1) # 在指定端口和主机上启动应用注意记得修改model_name_or_path为你的模型下载路径。4.1 逐段解读关键设计设备与显存管理。DEVICE cuda、DEVICE_ID 0组合成CUDA_DEVICE cuda:0torch_gc()在每次请求结束后清空 CUDA 缓存并收集显存碎片避免长时服务因显存碎片累积导致 OOM。思考过程与答案分离split_text。正则rthink(.*?)/think(.*)配合re.DOTALL标志让.可以匹配换行符从而捕获多行的思考内容group(1)为思考过程group(2)为最终答案若模型输出中不含think标签例如请求被截断则思考内容置为空字符串、全文作为答案返回。同样的解析逻辑在姊妹教程 02-DeepSeek-R1-Distill-Qwen-7B Langchain 接入.md 中也被复用属于 R1 系列服务端开发的核心通用组件。对话模板与推理生成。tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue)将{role: user, content: prompt}结构按 Qwen 的聊天模板组装为模型输入add_generation_promptTrue会在末尾追加 assistant 起始标记引导模型开始生成。生成时max_new_tokens8192设为 8K——因为推理型模型的思考过程本身就会消耗大量 Token默认的 512/1024 会严重截断输出。响应结构与日志。接口返回response原始输出、think思考过程、answer最终答案、status、time五个字段同时服务端打印包含 prompt 与各部分输出的结构化日志便于排查问题。uvicorn.run(app, host0.0.0.0, port6006, workers1)监听所有网卡的 6006 端口便于后续端口映射。五、启动服务与端口映射在终端输入以下命令启动 api 服务python api.py模型加载完毕后终端出现 Uvicorn 启动成功信息说明服务已正常监听http://0.0.0.0:6006默认部署在 6006 端口。若你在 AutoDL 等云 GPU 平台上运行需要将远端 6006 端口映射到本地才能访问具体映射方法见仓库中的 02-AutoDL开放端口.md——只需在 AutoDL 控制台开通 6006 端口的对外映射即可在本地http://localhost:6006调用该 API。六、接口调用验证6.1 使用 curl 调用服务端通过 POST 方法接收 JSON 请求体字段为promptcurl -X POST http://127.0.0.1:6006 \ -H Content-Type: application/json \ -d {prompt: 请简要说明把大象放进冰箱分为几步}返回结果包含思考过程think与最终回答answerstatus为 200同时附有服务器时间戳6.2 使用 Python requests 调用也可以使用 python 中的requests库进行调用import requests import json def get_completion(prompt): headers {Content-Type: application/json} data {prompt: prompt} response requests.post(urlhttp://127.0.0.1:6006, headersheaders, datajson.dumps(data)) return response.json()[response] if __name__ __main__: print(get_completion(请简要说明把大象放进冰箱分为几步))得到的返回值如下所示{response: think\n好用户想要了解如何将大象放进冰箱。首先大象非常重通常超过几吨这远远超过了冰箱的容量。冰箱通常只有几立方英尺所以直接放进冰箱里是不可能的。首先需要考虑大象的体重和形状然后拆分大象比如分成几只小象再分装进冰箱。另外还需要考虑冰箱的容量是否足够是否有其他工具可以辅助装箱。最后确保大象安全安全措施很重要。这样一步步来就能解决大象放进冰箱的问题了。\n/think\n\n将大象放进冰箱需要分步骤进行具体如下\n\n1. **评估大象的重量和形状**大象通常非常重超过几吨而冰箱的容量通常只有几立方英尺因此直接将大象放进冰箱是不可能的。\n\n2. **拆分大象**将大象拆分为多个较小的部分比如分成几只小象或分多个箱子里装大象。这种分拆方法可以逐步将大象放进冰箱。\n\n3. **分装大象**将拆分后的大象部分逐一放入冰箱中逐步将大象装入冰箱确保大象安全。\n\n4. **检查冰箱容量**确保冰箱的容量足够容纳大象如果有其他工具可以辅助装箱可以考虑使用。\n\n5. **安全措施**确保大象在装箱过程中安全避免意外情况发生。\n\n通过以上步骤可以逐步将大象放进冰箱。, think: 好用户想要了解如何将大象放进冰箱。首先大象非常重通常超过几吨这远远超过了冰箱的容量。冰箱通常只有几立方英尺所以直接放进冰箱里是不可能的。首先需要考虑大象的体重和形状然后拆分大象比如分成几只小象再分装进冰箱。另外还需要考虑冰箱的容量是否足够是否有其他工具可以辅助装箱。最后确保大象安全安全措施很重要。这样一步步来就能解决大象放进冰箱的问题了。, answer: 将大象放进冰箱需要分步骤进行具体如下\n\n1. **评估大象的重量和形状**大象通常非常重超过几吨而冰箱的容量通常只有几立方英尺因此直接将大象放进冰箱是不可能的。\n\n2. **拆分大象**将大象拆分为多个较小的部分比如分成几只小象或分多个箱子里装大象。这种分拆方法可以逐步将大象放进冰箱。\n\n3. **分装大象**将拆分后的大象部分逐一放入冰箱中逐步将大象装入冰箱确保大象安全。\n\n4. **检查冰箱容量**确保冰箱的容量足够容纳大象如果有其他工具可以辅助装箱可以考虑使用。\n\n5. **安全措施**确保大象在装箱过程中安全避免意外情况发生。\n\n通过以上步骤可以逐步将大象放进冰箱。, status: 200, time: 2025-02-02 09:53:01}从返回结果可以清晰看到模型先在think中生成对问题的拆解与推理过程大象非常重……先考虑体重和形状……随后输出结构化的分步最终答案两部分由服务端的split_text自动分离到think与answer字段中七、推理型模型调用的进阶要点从源码和姊妹文档中可以总结出 R1 系列部署的几个关键经验输出 Token 预算要充足max_new_tokens建议设为 8K8192思考过程会先占用大量 Token设置过小会直接截断到思考部分导致answer为空。若业务对响应延迟敏感可适当调低但需接受回答质量下降。思考解析的正则鲁棒性split_text采用非贪婪匹配(.*?)能正确截取第一个/think之前的内容re.DOTALL保证多行思考内容不被截断。采样参数建议在仓库配套的 04-DeepSeek-R1-Distill-Qwen-7B vLLM 部署调用.md 中官方建议 temperature 设置在 0.5~0.7 区间推荐 0.6top_p 使用 0.95同时建议 prompt 以think\n结尾或在数学推理场景补充 Please reason step by step, and put your final answer within \boxed{}. 之类的引导语以更稳定地触发推理链。单进程部署workers1配合torch_gc()保证单卡显存下服务稳定若需高并发可参考同系列 vLLM 部署方案其通过 PagedAttention 管理 KV 缓存并支持连续批处理吞吐量显著更高。八、进阶继续接入 LangChain 或升级 vLLMFastAPI 方案解决的是如何把模型包装成可调用的 HTTP 服务在此基础上本仓库还提供了两条进阶路径02-DeepSeek-R1-Distill-Qwen-7B Langchain 接入.md继承langchain.llms.base.LLM自定义DeepSeek_R1_Distill_Qwen_LLM类将本地模型无缝接入 LangChain 生态构建 RAG 等上层应用04-DeepSeek-R1-Distill-Qwen-7B vLLM 部署调用.md使用 vLLM 搭建兼容 OpenAI API 协议的高吞吐服务支持/v1/completions与/v1/chat/completions并附有benchmark_throughput.py吞吐测试脚本仓库中 benchmark_throughput.py 对应的测试可在各模型目录中找到同类脚本。至此你已经完成了从模型下载、FastAPI 服务封装到双通道curl / requests调用的完整闭环可以基于该接口继续构建你自己的推理应用。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/GitHub_Trending/se/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表