ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

在 self-llm 中使用 FastAPI 部署 Qwen1.5-7B-Chat:从环境配置、模型下载到 API 调用的完整实战

在 self-llm 中使用 FastAPI 部署 Qwen1.5-7B-Chat:从环境配置、模型下载到 API 调用的完整实战 在 self-llm 中使用 FastAPI 部署 Qwen1.5-7B-Chat从环境配置、模型下载到 API 调用的完整实战【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm本文是基于《开源大模型食用指南》Datawhale / self-llm 仓库中 models/Qwen1.5/01-Qwen1.5-7B-Chat FastApi 部署调用.md 编写的实战教程目标是帮助读者在 LinuxUbuntu CUDA 环境下用 FastAPI Uvicorn 将 Qwen1.5-7B-Chat 封装为可被任意 HTTP 客户端调用的本地大模型推理服务。读完本文后你将掌握 pip 换源安装依赖、通过 ModelScope 下载模型权重、编写并启动 api.py 服务端代码以及使用 curl 和 Python requests 完成 API 调用验证的完整技能链路。Qwen1.5 系列与 FastAPI 部署方案概览Qwen1.5 是阿里云通义千问团队发布的大语言模型系列Qwen1.5-7B-Chat 是该系列中 70 亿参数规模的对话模型版本具备中英文对话、代码理解等能力因其权重相对适中、对单卡部署友好是社区中学习 LLM 本地部署与二次开发的常见选择。在 Datawhale / self-llm 仓库中Qwen1.5 系列教程覆盖了从部署到微调的完整链路见 support_model.md本文Qwen1.5-7B-Chat 的 FastAPI 部署调用HTTP API 化02-Qwen1.5-7B-Chat 接入 langchain 搭建知识库助手基于本地模型自定义 LangChain LLM 类03-Qwen1.5-7B-Chat WebDemoGradio 交互式 Web 界面04-Qwen1.5-7B-chat Lora 微调 与 08-Qwen1.5-7B-chat LoRA 微调接入实验管理LoRA 参数高效微调07-Qwen1.5-7B-Chat vLLM 推理部署调用高吞吐 vLLM 推理服务。FastAPI 是当前 Python 生态中主流的异步 Web 框架配合 UvicornASGI 服务器可以非常轻量地把本地加载好的 HuggingFace Transformers 模型包装成 RESTful API。相比 WebDemo 页面API 化部署的优势在于调用方与模型解耦前后端分离可以被 curl、requests、LangChain、企业内部系统等任意客户端复用是后续搭建知识库助手等上层应用的基础形态。环境准备基础环境与依赖安装基础环境要求本文部署基于以下已验证的基础环境---------------- ubuntu 22.04 python 3.12 cuda 12.1 pytorch 2.3.0 ----------------本文默认学习者已安装好以上 PyTorch(CUDA) 环境如未安装请自行安装。Qwen1.5-7B-Chat 在 bf16 精度下推理约需 16GB 左右显存建议使用显存不小于 24GB 的显卡如 RTX 3090/4090 或 AutoDL 上的同类实例。pip 换源加速国内网络环境下直接使用官方 PyPI 源下载依赖往往较慢先在终端执行以下命令完成 pip 升级与清华源切换# 升级pip python -m pip install --upgrade pip # 更换 pypi 源加速库的安装 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simplepip config set global.index-url会把镜像源写入全局配置此后所有pip install均默认从该源拉取。若希望了解其他镜像源如教育网 CERNET 镜像的配置方式可参考仓库中的 models/General-Setting/01-pip、conda换源.md。安装依赖包逐个安装本项目所需的依赖版本已锁定以保证兼容性pip install fastapi0.111.1 pip install uvicorn0.30.3 pip install modelscope1.16.1 pip install transformers4.43.2 pip install accelerate0.32.1各依赖的作用fastapi提供声明式路由与请求解析的 Web 框架用于定义 POST 推理接口uvicorn运行 FastAPI 应用的 ASGI 服务器负责监听端口、处理并发请求modelscope阿里达摩院模型库 Python SDK本文用它下载 Qwen1.5-7B-Chat 权重国内访问速度快无需代理transformersHuggingFace Transformers 库负责加载模型与分词器、执行推理accelerate为device_mapauto等设备自动分配能力提供支撑使模型可自动加载到 GPU或在显存不足时部分落到 CPU。考虑到部分同学配置环境可能会遇到一些问题仓库作者在 AutoDL 平台准备了 Qwen1.5 的环境镜像该镜像适用于该仓库除 Qwen-GPTQ 和 vllm 外的所有部署环境可直接基于该镜像创建实例省去环境配置过程。同时仓库提供了一份 AutoDL 开放端口的说明文档 models/General-Setting/02-AutoDL开放端口.md本文部署阶段会用到端口映射能力。模型下载使用 ModelScope 拉取 Qwen1.5-7B-Chat使用modelscope中的snapshot_download函数下载模型。参数说明第一个参数模型名称qwen/Qwen1.5-7B-Chat即 ModelScope 上的模型仓库标识cache_dir自定义的模型下载路径必须为绝对路径revision模型仓库分支版本master代表主分支也是一般模型上传的默认分支。先切换到存放模型的目录cd /root/autodl-tmp然后新建名为model_download.py的 Python 文件输入以下内容并保存# model_download.py from modelscope import snapshot_download model_dir snapshot_download(qwen/Qwen1.5-7B-Chat, cache_dir/root/autodl-tmp, revisionmaster)在终端中执行python model_download.py下载完成后模型权重会存放在/root/autodl-tmp/qwen/Qwen1.5-7B-Chat目录下snapshot_download会在cache_dir下按模型名自动创建子目录。注意该模型权重文件比较大7B 参数、bf16 精度约 15GB需要耐心等待一段时间直到模型下载完成。注意记得修改cache_dir为你的模型下载路径。若你的环境更习惯使用 HuggingFace仓库的 models/General-Setting/03-模型下载.md 还介绍了huggingface-cli、hf-mirror镜像、git-lfs、OpenXlab 等多种模型下载方式可结合网络情况灵活选用。编写 API 服务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) # 获取请求中的提示 messages [ {role: system, content: You are a helpful assistant.}, {role: user, content: prompt} ] # 调用模型进行对话生成 input_ids tokenizer.apply_chat_template(messages,tokenizeFalse,add_generation_promptTrue) model_inputs tokenizer([input_ids], return_tensorspt).to(cuda) generated_ids 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 tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0] now datetime.datetime.now() # 获取当前时间 time now.strftime(%Y-%m-%d %H:%M:%S) # 格式化时间为字符串 # 构建响应JSON answer { response: response, status: 200, time: time } # 构建日志信息 log [ time ] , prompt: prompt , response: repr(response) print(log) # 打印日志 torch_gc() # 执行GPU内存清理 return answer # 返回响应 # 主函数入口 if __name__ __main__: # 加载预训练的分词器和模型 model_name_or_path /root/autodl-tmp/qwen/Qwen1.5-7B-Chat tokenizer AutoTokenizer.from_pretrained(model_name_or_path, use_fastFalse) model AutoModelForCausalLM.from_pretrained(model_name_or_path, device_mapauto, torch_dtypetorch.bfloat16) # 启动FastAPI应用 # 用6006端口可以将autodl的端口映射到本地从而在本地使用api uvicorn.run(app, host0.0.0.0, port6006, workers1) # 在指定端口和主机上启动应用关键代码逻辑拆解1. 设备与显存管理第 814 行DEVICE cuda DEVICE_ID 0 CUDA_DEVICE f{DEVICE}:{DEVICE_ID} if DEVICE_ID else DEVICE通过DEVICE/DEVICE_ID两个变量组合出形如cuda:0的目标设备字符串。如果你的机器有多张卡修改DEVICE_ID即可指定使用哪一块 GPU。2.torch_gc()显存回收第 1622 行def torch_gc(): if torch.cuda.is_available(): with torch.cuda.device(CUDA_DEVICE): torch.cuda.empty_cache() torch.cuda.ipc_collect()每次请求结束后调用empty_cache()释放 PyTorch 缓存中未使用的显存块ipc_collect()回收跨进程IPC的显存碎片。长期运行的 API 服务中频繁的请求会产生显存碎片定期回收可避免显存占用持续膨胀这是保证服务长稳运行的重要细节。3. POST 端点与请求解析第 2432 行端点路径为/使用async def异步处理函数。await request.json()获取请求体 JSON经json.dumps→json.loads的标准往返后取出prompt字段。这里将请求 JSON 转为字符串再转回 Python 对象可以规避部分客户端直接json.loads可能遇到的类型兼容问题是一种稳妥的做法。4. Chat 模板应用第 3442 行messages [ {role: system, content: You are a helpful assistant.}, {role: user, content: prompt} ] input_ids tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue)Qwen1.5-Chat 系列采用 ChatML 风格的对话模板需要把消息列表渲染成|im_start|system\n...|im_end|\n|im_start|user\n...|im_end|\n|im_start|assistant\n这样的模板字符串。apply_chat_template自动完成这一渲染tokenizeFalse先不分词只得到模板字符串add_generation_promptTrue在末尾追加 assistant 角色起始标记提示模型开始作答。5. 生成与解码第 4450 行model_inputs tokenizer([input_ids], return_tensorspt).to(cuda) generated_ids 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 tokenizer.batch_decode(generated_ids, skip_special_tokensTrue)[0]max_new_tokens512限制新生成的 token 数上限不含输入部分防止长对话时无限制生成耗尽显存生成完成后通过切片去掉输入部分的 token id只保留新生成的部分batch_decode(..., skip_special_tokensTrue)把 token id 还原为文本并剔除|im_end|、|im_start|等特殊标记得到最终回复。如需进一步控制生成行为温度、top_p、重复惩罚等可在model.generate中补充temperature、top_p、repetition_penalty等参数或加载GenerationConfig进行统一配置。6. 响应结构与日志第 5263 行返回的 JSON 包含三个字段字段含义response模型生成的回复文本status固定 200表示请求成功time服务器处理该请求的时间戳格式%Y-%m-%d %H:%M:%S同时在服务端控制台打印一条包含时间、prompt、response 的日志便于追踪每次调用。7. 模型加载与启动第 6675 行model_name_or_path /root/autodl-tmp/qwen/Qwen1.5-7B-Chat tokenizer AutoTokenizer.from_pretrained(model_name_or_path, use_fastFalse) model AutoModelForCausalLM.from_pretrained(model_name_or_path, device_mapauto, torch_dtypetorch.bfloat16) uvicorn.run(app, host0.0.0.0, port6006, workers1)use_fastFalse使用慢速分词器兼容性更稳避免个别特殊 token 在 fast 分词器中处理不一致device_mapauto由 accelerate 自动把模型各层分配到可用设备显存充足时全量上 GPUtorch_dtypetorch.bfloat16以 bf16 半精度加载权重相比 fp32 可节省近一半显存同时数值稳定性优于 fp16是现代大模型推理的标准精度选择host0.0.0.0监听所有网卡使服务可被外部访问port6006为服务端口workers1单进程运行模型驻留单个进程内存中。关于 6006 端口在 AutoDL 平台6006 端口可以映射到本地浏览器访问从而在本地调用 API这也是选择该端口号的原因。启动服务与验证启动 API 服务在终端输入以下命令启动 API 服务cd /root/autodl-tmp python api.py模型加载需要数分钟首次会进行权重分片加载当终端出现类似以下信息说明服务启动成功从上图可见关键日志依次为Loading checkpoint shards: 100%权重分片加载完成、Started server process服务器进程启动、Application startup complete.应用启动完成以及Uvicorn running on http://0.0.0.0:6006Uvicorn 正在 6006 端口监听按CTRLC可退出。使用 curl 调用服务默认部署在 6006 端口通过 POST 方法调用可使用 curlcurl -X POST http://127.0.0.1:6006 \ -H Content-Type: application/json \ -d {prompt: 你好}若在本地机器通过 AutoDL 端口映射访问将127.0.0.1:6006替换为映射后的本地地址即可。使用 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:你好有什么我可以帮助你的吗,status:200,time:2024-02-05 18:08:19}从上图可以看到客户端代码通过 POST 请求向http://127.0.0.1:6006发送{prompt: 你好}服务端返回了模型的中文回复你好很高兴为您服务。有什么我可以帮助您的吗证明整个模型加载 → HTTP 服务 → 推理 → JSON 响应链路已完全打通。响应字段解读客户端通过response.json()[response]即可拿到模型生成的文本无需关心底层推理细节。响应中status字段可用来判断请求是否成功time字段记录了服务处理时间便于日志统计与链路追踪。从仓库视角看 API 化的后续扩展将 Qwen1.5-7B-Chat 通过 FastAPI 暴露为 HTTP 接口后即可像调用任何远程 LLM 服务一样去构建上层应用。Datawhale / self-llm 仓库中提供了多个基于此能力或同类本地部署能力的进阶方向接入 LangChain 搭建知识库助手参考 models/Qwen1.5/02-Qwen1.5-7B-Chat 接入langchain搭建知识库助手.md。该文档展示了如何从LangChain.llms.base.LLM继承并重写_call函数将本地 Qwen1.5 封装成 LangChain 可用的 LLM 类从而复用向量检索、文档问答等全套知识库组件Gradio WebDemo 交互界面参考 models/Qwen1.5/03-Qwen1.5-7B-Chat WebDemo.md将同样的模型加载与对话逻辑包装成可视化聊天页面适合演示与人工评测vLLM 高吞吐推理当单机 API 服务的吞吐无法满足需求时参考 models/Qwen1.5/07-Qwen1.5-7B-Chat vLLM 推理部署调用.md。vLLM 通过 PagedAttention 管理 KV 缓存并支持连续批处理吞吐更高且提供兼容 OpenAI 格式的 API 服务LoRA 微调后再部署参考 models/Qwen1.5/04-Qwen1.5-7B-chat Lora 微调.md 与 models/Qwen1.5/08-Qwen1.5-7B-chat LoRA微调接入实验管理.md对模型完成领域适配后可将本文AutoModelForCausalLM.from_pretrained加载路径替换为微调后权重即可把定制能力以同样的 API 形态对外服务。可以推断本文介绍的api.py是仓库中 FastAPI 部署系列如 Qwen、ChatGLM、Atom 等模型目录下的同类文档的标准范式FastAPI Request解析 →apply_chat_template构造对话 →model.generate生成 → 统一 JSON 响应 torch_gc()回收显存。掌握了这一范式迁移到其他 Qwen 系列或其他支持 Transformers 加载的模型上只需替换模型名称与模板调用部署逻辑几乎可以复用。常见问题与注意事项cache_dir未生效模型下载路径必须为绝对路径且最终权重目录为cache_dir下的qwen/Qwen1.5-7B-Chatapi.py中model_name_or_path需与该实际路径保持一致下载耗时过长7B 模型权重约 15GB属正常现象可使用revision指定特定分支或在网络较好的环境使用仓库 models/General-Setting/03-模型下载.md 中介绍的镜像方式加速启动时报显存不足OOM确认torch_dtypetorch.bfloat16已生效且机器显存不小于约 16GB多卡机器可检查DEVICE_ID与device_mapauto的分配结果本地无法访问 6006 端口确认服务监听的是0.0.0.0而非127.0.0.1在 AutoDL 等云平台上还需要配置端口映射具体操作见 models/General-Setting/02-AutoDL开放端口.md并发请求支持本文示例以workers1单进程部署模型常驻内存、请求串行处理适合个人学习与低并发场景若需承载更高并发可升级为 vLLM 方案见 models/Qwen1.5/07-Qwen1.5-7B-Chat vLLM 推理部署调用.md而非简单调大 workers 数量多 worker 会导致模型在多个进程中重复加载、成倍占用显存返回结果含特殊标记若解码结果中出现|im_start|、|im_end|等标记说明skip_special_tokensTrue未生效或模板渲染异常检查apply_chat_template的调用参数即可。至此你已经完成了 Qwen1.5-7B-Chat 的 FastAPI 化部署可以像调用云端 API 一样在任意项目中复用本地大模型的推理能力并在此基础上继续探索仓库中的 LangChain 知识库助手、LoRA 微调等进阶玩法。【免费下载链接】self-llm《开源大模型食用指南》针对中国宝宝量身打造的基于Linux环境快速微调全参数/Lora、部署国内外开源大模型LLM/多模态大模型MLLM教程项目地址: https://gitcode.com/datawhalechina/self-llm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表