基于 FastAPI 快速部署 BlueLM-7B-Chat 对话服务:环境配置、模型下载与 API 调用全流程
2026/9/19 23:49:22 网站建设 项目流程

基于 FastAPI 快速部署 BlueLM-7B-Chat 对话服务:环境配置、模型下载与 API 调用全流程

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

BlueLM-7B-Chat 是 vivo AI 全球研究院开源的 70 亿参数中文对话大模型,本教程完整梳理了在 Linux 云服务器上从零搭建其 FastAPI 推理服务的关键路径:环境准备、依赖安装、ModelScope 模型下载、推理服务代码实现,以及通过 curl 与 requests 完成接口调用验证的全过程。读完本文,你将具备独立部署一个可被外部程序调用的 BlueLM 对话 API 服务的能力,并理解服务端代码中设备管理、显存回收、对话模板拼接等实现细节。

1. BlueLM-7B-Chat 模型速览

BlueLM-7B 是由 vivo AI 全球研究院自主研发的大规模预训练语言模型,参数规模为 70 亿。该模型在 C-Eval 与 CMMLU 两大中文评测基准上均取得了领先结果,在同类尺寸的开源模型中具有较强的竞争力(此结论以模型发布时的评测结果为准)。本次发布共包含 7B 模型的 Base(基座)与 Chat(对齐)两个版本,并提供 32K 长上下文与 4bits 量化等多个变体,完整版本矩阵如下:

基座模型对齐模型
BlueLM-7B-BaseBlueLM-7B-Chat
BlueLM-7B-Base-32KBlueLM-7B-Chat-32K
BlueLM-7B-Chat-4bits

其中BlueLM-7B-Chat是面向对话场景的对齐模型,也是本文 FastAPI 部署教程的主角。本教程在 support_model.md 中登记为 Datawhale/self-llm 项目支持的开源模型之一,与其配套的还有 LangChain 接入、WebDemo 部署 与 LoRA 微调 等完整教程。

2. 部署方案总览

本方案的整体架构非常简洁:使用Transformers在 GPU 上加载 BlueLM-7B-Chat 模型权重,通过FastAPI编写一个接收 POST 请求的推理端点,再使用uvicorn将服务托管在 6006 端口。外部应用只需向该端口发送 JSON 请求(携带prompt等字段)即可获得模型的对话回复,从而把"模型推理"与"业务应用"解耦——API 服务可以作为知识库问答、智能客服、Agent 等上层应用统一的模型底座。

整个部署流程分为四步:

  1. 环境准备:在 AutoDL 等平台上租用 24G 显存的 GPU 机器,安装依赖包;
  2. 模型下载:使用 ModelScope API 将模型权重下载到本地磁盘;
  3. 代码准备:编写api.py推理服务脚本;
  4. 部署验证:启动服务并通过 curl / requests 调用接口。

3. 环境准备:GPU 实例与依赖安装

3.1 租用 GPU 实例

这里以 AutoDL 平台为例,租赁一台 3090 等 24G 显存的显卡机器。创建实例时,镜像选择PyTorch → 1.11.0 → 3.8 (ubuntu20.04) → 11.3,CUDA 版本在 11.3 以上均可满足要求:

实例创建完成后,打开 JupyterLab 自带的终端(也可以使用 VSCode SSH 远程连接服务器),后续的环境配置、模型下载与 demo 运行都在这个终端中完成。

3.2 pip 换源与依赖安装

为加快下载速度,先升级 pip 并将 pip 镜像源切换为清华源,随后安装部署所需的全部软件依赖:

# 升级pip python -m pip install --upgrade pip # 设置pip镜像源 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.11.0 pip install transformers==4.37.0 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

各依赖在部署链路中的作用如下:

依赖包版本作用
fastapi0.104.1构建异步 HTTP API 服务
uvicorn0.24.0.post1ASGI 服务器,托管 FastAPI 应用
requests2.25.1客户端调用 API 进行验证
modelscope1.11.0从 ModelScope 下载模型权重
transformers4.37.0加载与运行因果语言模型
streamlit1.24.0为后续 WebDemo 部署准备的 UI 框架
sentencepiece0.1.99模型分词器依赖的分词库
accelerate0.24.1支持device_map="auto"的设备自动分配
transformers_stream_generator0.0.4流式生成辅助库

4. 模型下载:使用 ModelScope API

国内网络环境下,通过 ModelScope 下载模型权重比 HuggingFace 更稳定。在/root/autodl-tmp目录下创建model_download.py文件:

from modelscope import snapshot_download model_dir = snapshot_download("vivo-ai/BlueLM-7B-Chat", cache_dir='/root/autodl-tmp', revision="master")

执行该脚本后,模型会以vivo-ai/BlueLM-7B-Chat为子目录保存在/root/autodl-tmp下。后续加载模型时使用的本地路径即为/root/autodl-tmp/vivo-ai/BlueLM-7B-Chat(LangChain 接入教程中正是使用该路径直接加载本地模型,参见 02-BlueLM-7B-Chat langchain 接入.md)。

5. 编写 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 = f"[|Human|]:{prompt}[|AI|]:" # 构建输入 inputs = tokenizer(messages, return_tensors="pt") inputs = inputs.to("cuda:0") # 通过模型获得输出 outputs = model.generate(**inputs, max_new_tokens=max_length) result = tokenizer.decode(outputs.cpu()[0], 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="vivo-ai/BlueLM-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='127.0.0.1', port=6006, workers=1) # 在指定端口和主机上启动应用

下面拆解这段代码中的关键技术点。

5.1 设备参数与 GPU 显存清理

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

通过DEVICE/DEVICE_ID两个变量组合出cuda:0的设备标识,方便在单卡环境下统一管理设备。

torch_gc()函数用于在每次请求处理完成后释放 GPU 缓存:

def torch_gc(): if torch.cuda.is_available(): with torch.cuda.device(CUDA_DEVICE): torch.cuda.empty_cache() # 清空CUDA缓存 torch.cuda.ipc_collect() # 收集CUDA内存碎片

empty_cache()释放 PyTorch 缓存分配器持有的未使用显存,ipc_collect()收集进程间通信产生的内存碎片。在长驻服务场景下,每次推理后调用torch_gc()可有效避免显存碎片累积导致的 OOM 问题。

5.2 POST 端点:请求解析与响应构建

@app.post("/") async def create_item(request: Request): global model, tokenizer json_post_raw = await request.json() json_post = json.dumps(json_post_raw) json_post_list = json.loads(json_post) prompt = json_post_list.get('prompt') max_length = json_post_list.get('max_length')

端点声明为async def,通过await request.json()异步读取请求体。这里先序列化再反序列化的写法是为了确保从请求中拿到的是标准的 Python 对象,随后从中取出prompt(用户提示语)与max_length(生成长度上限)两个字段。

注意:代码中max_length实际被传给model.generate(..., max_new_tokens=max_length),即它控制的是新生成token 的数量上限而非输入+输出的总长度。调用方可以依据此语义设定合适的值,避免生成过长或过短的回复。

5.3 BlueLM 对话模板的拼接

messages = f"[|Human|]:{prompt}[|AI|]:"

这是 BlueLM 系列模型区别于其他模型的关键细节:BlueLM 的对话模板只有[|Human|][|AI|]两个角色标记,构造输入时必须遵循[|Human|]:<用户输入>[|AI|]:的格式。这一点在仓库中得到了多处印证:

  • LangChain 接入教程自定义 LLM 类的_call方法中同样拼接了f"[|Human|]:{prompt}[|AI|]:"(参见 02-BlueLM-7B-Chat langchain 接入.md);
  • WebDemo 教程的build_prompt函数通过res += f"[|Human|]:{query}[|AI|]:{response}</s>"来组织多轮对话历史(参见 03-BlueLM-7B-Chat WebDemo 部署.md);
  • LoRA 微调教程将数据格式化为"[|Human|]:解释什么是人工智能。\n[|AI|]:"作为模型输入,并明确指出"BlueLM 只有[|Human|][|AI|]两个角色,所以数据格式就是这样的"(参见 04-BlueLM-7B-Chat Lora 微调.md)。

因此,任何调用 BlueLM 服务的上层应用都必须按此模板组织输入,否则模型的回复质量会明显下降。

5.4 推理与响应

inputs = tokenizer(messages, return_tensors="pt") inputs = inputs.to("cuda:0") outputs = model.generate(**inputs, max_new_tokens=max_length) result = tokenizer.decode(outputs.cpu()[0], skip_special_tokens=True)

分词器将模板文本编码为张量并送入 GPU,model.generate执行自回归生成,最后将输出张量移回 CPU 并解码为文本(skip_special_tokens=True会去掉[|Human|][|AI|]等特殊标记,仅保留模型生成的回复内容)。

响应统一封装为三个字段:

字段类型含义
responsestring模型生成的对话回复
statusint状态码,固定 200 表示成功
timestring服务器处理请求的时间戳,格式YYYY-MM-DD HH:MM:SS

每次请求还会在服务端打印一条包含时间、prompt 与 response 的日志,便于排查问题。

5.5 模型加载与服务启动

mode_name_or_path="vivo-ai/BlueLM-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() uvicorn.run(app, host='127.0.0.1', port=6006, workers=1)

几个要点值得展开:

  • trust_remote_code=True:BlueLM 需要加载其自定义的模型与分词器代码,必须开启该参数,否则会因缺少本地自定义类而报错;
  • torch_dtype=torch.bfloat16:以 BF16 半精度加载权重,7B 模型的权重占用约 14GB 显存,加上推理时的激活值开销,24G 显存的 3090 可以平稳运行;
  • device_map="auto":借助 accelerate 自动将模型各层分配到可用设备上,简化单卡部署的代码;
  • model.generation_config.pad_token_id = model.generation_config.eos_token_id:将 pad token 设置为 eos token,避免生成时出现 pad 相关告警或行为异常;
  • model.eval():切换到评估模式,关闭 Dropout 等训练期行为,保证推理结果稳定可复现;
  • uvicorn.run(..., host='127.0.0.1', port=6006, workers=1):服务监听本机 6006 端口,workers 固定为 1——多个 worker 进程会各自重复加载一份模型权重,24G 显存无法容纳,这一点在部署时务必保持默认;
  • 6006 端口的特殊意义:在 AutoDL 平台,6006 端口可以被映射到本地,从而在本地浏览器或程序中直接访问服务器上的 API 服务。

6. 启动服务与调用验证

6.1 启动服务

在 bash 终端中运行以下命令:

cd /root/autodl-tmp python api.py

终端出现以下输出即表示服务启动成功,模型权重加载完成并已监听 6006 端口:

日志中的关键信息包括:

  • Loading checkpoint shards: 100%:模型权重分片全部加载完成;
  • Application startup complete.:FastAPI 应用初始化完成;
  • Uvicorn running on http://127.0.0.1:6006:服务已运行在 6006 端口。

6.2 使用 curl 调用

默认服务端口为 6006,通过 POST 方法进行调用。新建一个终端输入:

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

6.3 使用 Python requests 调用

也可以使用 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":"2024-03-20 12:09:29"}

在 Jupyter Notebook 中执行上述调用代码,模型成功返回了自然流畅的中文回复,验证了服务的可用性:

至此,一个可复用的 BlueLM-7B-Chat 对话 API 服务就完成了部署。任何语言编写的程序都可以通过 HTTP POST 请求与之交互。

7. 关键实现细节与最佳实践

7.1 多轮对话的扩展思路

FastAPI 示例中每次请求只携带单条 prompt,属于单轮对话。若要在服务端支持多轮对话,可参考仓库中 WebDemo 的build_prompt实现(03-BlueLM-7B-Chat WebDemo 部署.md),用<s></s>组织历史轮次:

res = "" for query, response in messages: # messages 为 (用户query, AI回复) 的历史列表 res += f"[|Human|]:{query}[|AI|]:{response}</s>" res += f"[|Human|]:{prompt}[|AI|]:"

将此逻辑移植到api.py的 POST 端点中,即可让 API 具备多轮上下文理解能力。

7.2 显存管理

服务长驻运行后,显存碎片会随请求次数增多而累积。示例代码在每次请求末尾调用torch_gc(),这是维持服务长期稳定运行的关键习惯。若并发量增大,还应考虑在应用层增加请求排队或并发控制,避免多个请求同时触发显存峰值。

7.3 参数命名与调用约定

max_length在服务端被映射为max_new_tokens,调用方应理解其语义为"新生成 token 的上限"。响应结构固定为response / status / time三字段,客户端解析时以response字段为准。

8. 延伸:仓库中 BlueLM 的完整学习路径

本文实现的 FastAPI 服务是 BlueLM 部署链路的"第一站"。Datawhale/self-llm 仓库还围绕 BlueLM-7B-Chat 提供了完整的进阶教程(均登记于 support_model.md):

教程内容应用场景
02-BlueLM-7B-Chat langchain 接入.md继承LangChain.llms.base.LLM自定义BlueLM将本地模型接入 LangChain 应用框架
03-BlueLM-7B-Chat WebDemo 部署.md基于 Streamlit 构建带多轮对话历史的聊天界面面向用户的交互式 Web 演示
04-BlueLM-7B-Chat Lora 微调.md基于 transformers + peft 对模型进行 LoRA 高效微调打造领域专属的定制化对话模型

建议的学习顺序是:先按本文完成 FastAPI 部署并跑通接口调用,再根据实际需求选择 LangChain 集成(构建知识库问答等应用)或 LoRA 微调(打造私域模型)。三者可以组合使用:微调产出的新权重替换模型路径后重新启动服务,即可将定制能力通过 API 对外提供。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询