文档中心>TI-ONE 训练平台>最佳实践>LLM 部署及推理>导入和部署自定义 LLM 大模型(用户自定义推理镜像)

导入和部署自定义 LLM 大模型(用户自定义推理镜像)

最近更新时间:2024-07-02 17:36:22

我的收藏

总览

本文以【Qwen2-7B-Instruct】模型为例,指导如何将自定义大模型导入到TI平台,并使用自定义推理镜像(vllm/openai:latest)部署大模型对话推理服务。

前置要求

申请 CFS

本文所涉及到的操作需要通过 CFS存储模型文件,详情请查看创建文件系统及挂载点

操作步骤

1. 上传模型文件到 CFS

登录腾讯云 TI-ONE 控制台训练工坊 > Notebook,单击新建,其中各字段的填写说明如下:
镜像:选择任意内置镜像即可。
计费模式:选择按量计费或包年包月均可,平台支持的计费规则请您查看计费概述
存储配置:选择 CFS 文件系统,路径默认为根目录/,用于指定保存用户自定义大模型位置。
其它设置:默认不需要填写。
说明:
本 Notebook 实例仅用于上传或下载大模型文件。


新建成功后启动 Notebook,单击 Notebook > Python3(ipykernel) 通过脚本下载所需模型;


您可在魔搭社区Hugging Face检索需要用到的大模型,通过社区中 Python 脚本自行下载模型并保存到 CFS 中,本文以【Qwen2-7B-Instruct】模型为例,下载代码如下:
!pip install modelscope

from modelscope import snapshot_download
#qwen/Qwen2-7B-Instruct为需要下载的模型名称,cache_dir为下载模型保存的地址,这里'./'表示将下载模型保存在CFS的根目录中
model_dir = snapshot_download('qwen/Qwen2-7B-Instruct', cache_dir='./')
说明:
指定下载模型的地址 cache_dir(例如path/to/local/dir)后,后续在线服务 CFS 中指定模型地址为 /path/to/local/dir/qwen/Qwen2-7B-Instruct。
复制上述下载脚本并更换需要下载的模型后,粘贴到新建的 ipynb 文件中,单击运行按钮即可开始下载模型;


此外您也可以在本地下载或微调后,通过 notebook 上传通道将模型文件保存至 CFS 中,上传接口如图所示:





2. 制作自定义镜像

我们准备使用 docker.io/vllm/vllm-openai:latest 镜像来部署服务,首先通过docker hub 文档查的镜像的启动 Entrypoint 命令为:
python3 -m vllm.entrypoints.openai.api_server
然后,我们再通过 vLLM 的官方 Docker部署文档查得推荐的 docker 部署命令为:
docker run --runtime nvidia --gpus all \\
-v ~/.cache/huggingface:/root/.cache/huggingface \\
--env "HUGGING_FACE_HUB_TOKEN=<secret>" \\
-p 8000:8000 \\
--ipc=host \\
vllm/vllm-openai:latest \\
--model mistralai/Mistral-7B-v0.1
通过上述两个文档我们可以总结出原生镜像是这样启动服务的:
1. 使用环境变量 HUGGING_FACE_HUB_TOKEN 指定的 token 从 Hugging Face上,下载 mistralai/Mistral-7B-v0.1 到 /root/.cache/huggingface 目录下。
2. 启动命令为 python3 -m vllm.entrypoints.openai.api_server --model mistralai/Mistral-7B-v0.1 。
3. http 服务会监听8000端口,等待请求。

TI-ONE 平台对自定义镜像有一些约束条件,可以参考使用自定义镜像发布在线服务开发指引
1. 推理在线服务端口限制为8501。
2. 服务必须以 HTTP 协议接受请求,并且只支持 POST 方法。
3. 使用 CFS、COS 作为模型来源时,平台默认将源路径下的模型文件(包括子目录),放在服务实例的/data/model目录下。因此自定义的代码及数据不能置于 /data/model目录,否则会被平台覆盖。

平台的约束条件与原生镜像的运行情况两项对比可以知道有两个困难:
1. 原生镜像监听在8000端口,而平台要求监听在8501端口。
2. 原生镜像在 /root/.cache/huggingface 下搜索模型,而平台只会将 CFS 上的模型挂在到 /data/model 目录下。
幸运的是,这两个困难都可以在页面上通过一些设置解决而无需重做镜像:
平台支持指定监听端口。
将启动命令修改为 python3 -m vllm.entrypoints.openai.api_server --model /data/model,可以直接使用 /data/model 下的模型。

3. 创建在线服务

通过腾讯云 TI 平台的模型服务 > 在线服务,单击新建服务来启动推理服务,以下是服务实例配置的指引。
模型来源:选择 CFS
选择模型:指定申请的 CFS,模型路径为 CFS 中下载或上传的模型路径,此处为【/qwen/Qwen2-7B-Instruct】。
运行环境:选择【自定义 / 镜像地址】,并填入镜像地址 docker.io/vllm/vllm-openai:latest。
算力规格:根据实际的模型大小或拥有的资源情况选择,大模型推理时需要的机器资源与模型的参数量相关,推荐按如下规则配置推理服务资源。
模型参数量
GPU 卡类型和数量
6 ~ 8B
L20 * 1 / A10 * 1 / A100 * 1 / V100 * 1
12 ~ 14B
L20 * 1 / A10 * 2 / A100 * 1 / V100 * 2
65 ~ 72B
L20 * 8 / A100 * 8
高级设置 > 端口】:修改为8000。
高级设置 > 启动命令】:填入 python3 -m vllm.entrypoints.openai.api_server --model /data/model --served-model-name Qwen2-7B-Instruct --max-model-len=2048。这里指定 --max-model-len=2048 是因为 Qwen2-7B-Instruct 模型的最大长度为 128K,防止 vLLM 初始化 KV 缓存时消耗资源过大。

在线服务创建实例配置如下:







4. 接口服务调用

可通过服务调用 Tab 页中的接口信息 > 调用方式(在线测试)进行访问,接口的调用地址为【${SERVER_URL}/v1/completions】,请求体的格式:
{
"model": "Qwen2-7B-Instruct",
"prompt": "你好",
"max_tokens": 50,
"temperature": 0
}
字段 content 为具体的消息内容。


公网访问地址可从在线服务实例服务调用中获取,API调用示例如下:
# 公网访问地址
SERVER_URL = https://ms-gp6rjk2jj-**********.gw.ap-shanghai.ti.tencentcs.com/ms-gp6rjk2j

# 非流式调用
curl -H "content-type: application/json" ${SERVER_URL}/v1/completions -d '{"model":"Qwen2-7B-Instruct","prompt":"你好","max_tokens":50,"temperature":0}'
# 流式调用
curl -H "content-type: application/json" ${SERVER_URL}/v1/completions -d '{"model":"Qwen2-7B-Instruct","prompt":"你好","max_tokens":50,"temperature":0, "stream": true}'
非流式返回结果:
{"id":"cmpl-f2bec3ca2ded4b518fb8e73dc3461202","object":"text_completion","created":1719890717,"model":"Qwen2-7B-Instruct","choices":[{"index":0,"text":",我最近感觉很焦虑,有什么方法可以缓解吗?\\n你好!焦虑是一种常见的情绪反应,但可以通过一些方法来缓解。你可以尝试深呼吸、冥想、运动、听音乐、与朋友聊天等方式来放松自己。同时","logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":1,"total_tokens":51,"completion_tokens":50}}
流式返回结果:
data: {"id":"cmpl-3a575c7fd0204234afc51e195ee06596","created":1719890729,"model":"Qwen2-7B-Instruct","choices":[{"index":0,"text":",","logprobs":null,"finish_reason":null,"stop_reason":null}]}

data: {"id":"cmpl-3a575c7fd0204234afc51e195ee06596","created":1719890729,"model":"Qwen2-7B-Instruct","choices":[{"index":0,"text":"我","logprobs":null,"finish_reason":null,"stop_reason":null}]}

...此处忽略中间结果...

data: {"id":"cmpl-3a575c7fd0204234afc51e195ee06596","created":1719890729,"model":"Qwen2-7B-Instruct","choices":[{"index":0,"text":"。","logprobs":null,"finish_reason":null,"stop_reason":null}]}

data: {"id":"cmpl-3a575c7fd0204234afc51e195ee06596","created":1719890729,"model":"Qwen2-7B-Instruct","choices":[{"index":0,"text":"同时","logprobs":null,"finish_reason":"length","stop_reason":null}]}

data: [DONE]
更多的调用参考可以参考 vLLM的官方文档