Files
FastDeploy/llm/docs/FastDeploy_usage_tutorial.md
2024-11-21 07:31:59 +00:00

358 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 目录
- [部署环境准备](#部署环境准备)
- [基础环境](#基础环境)
- [准备部署镜像](#准备部署镜像)
- [准备模型](#准备模型)
- [创建容器](#创建容器)
- [启动服务](#启动服务)
- [配置参数](#配置参数)
- [启动服务](#启动服务)
- [服务状态查询](#服务状态查询)
- [服务测试](#服务测试)
- [Python 客户端](#Python-客户端)
- [HTTP调用](#HTTP调用)
- [OpenAI 客户端](#OpenAI-客户端)
- [返回示例](#返回示例)
- [基于dockerfile创建自己的镜像](#基于dockerfile创建自己的镜像)
- [模型配置参数介绍](#模型配置参数介绍)
- [请求参数介绍](#请求参数介绍)
## 部署环境准备
### 基础环境
目前 FastDeploy 仅支持在 Linux 系统下部署,部署之前请确保系统有正确的 GPU 环境。
- 安装 docker
请参考 [Install Docker Engine](https://docs.docker.com/engine/install/) 选择对应的 Linux 平台安装 docker 环境。
- 安装 NVIDIA Container Toolkit
请参考 [Installing the NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html#installing-the-nvidia-container-toolkit) 了解并安装 NVIDIA Container Toolkit。
NVIDIA Container Toolkit 安装成功后,参考 [Running a Sample Workload with Docker](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/sample-workload.html#running-a-sample-workload-with-docker) 测试 NVIDIA Container Toolkit 是否可以正常使用。
### 准备部署镜像
为了方便部署,我们提供了 cuda12.3 的镜像,可以直接拉取镜像,或者使用我们提供的 `Dockerfile` [构建自定义镜像](#基于dockerfile创建自己的镜像)
```
docker pull registry.baidubce.com/paddlepaddle/fastdeploy:llm-serving-cuda123-cudnn9-v1.2
```
### 准备模型
FastDeploy 为 PaddleNLP 静态图模型提供了高效的部署方案,模型静态图导出方案请参考:[LLaMA](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/llm/docs/predict/llama.md)、[Qwen](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/llm/docs/predict/qwen.md)、[Mixtral](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/llm/docs/predict/mixtral.md) ...
导出后的模型放在任意文件夹下,以 `/home/workspace/models_dir` 为例
```
cd /home/workspace/models_dir
# 导出的模型目录结构如下所示,理论上无缝支持 PaddleNLP 导出的静态图模型,无需修改模型目录结构
# /opt/output/Serving/models
# ├── config.json # 模型配置文件
# ├── xxxx.model # 词表模型文件
# ├── special_tokens_map.json # 词表配置文件
# ├── tokenizer_config.json # 词表配置文件
# ├── rank_mapping.csv # 多卡模型会有此文件,如为单卡模型,则无此文件(可选,仅在多卡部署模式下需要)
# └── rank_0 # 保存模型结构和权重文件的目录
# ├── model.pdiparams
# └── model.pdmodel
```
### 创建容器
创建容器之前,请检查 Docker 版本和 GPU 环境,确保 Docker 支持 `--gpus all` 参数。
将模型目录挂载到容器中,默认模型挂载地址为 `/models/`,服务启动时可通过 `MODEL_DIR` 环境变量自定义挂载地址。
```
docker run --gpus all \
--name fastdeploy_serving \
--privileged \
--cap-add=SYS_PTRACE \
--network=host \
--shm-size=5G \
-v /home/workspace/models_dir:/models/ \
-dit registry.baidubce.com/paddlepaddle/fastdeploy:llm-serving-cuda123-cudnn9-v1.2 bash
# 进入容器检查GPU环境和模型挂载是否正常
docker exec -it fastdeploy_serving /bin/bash
nvidia-smi
ls /models/
```
## 启动服务
### 配置参数
根据需求和硬件信息,配置以下环境变量
```
# 单/多卡推理配置。自行修改。
## 如果是单卡推理使用0卡设置如下环境变量。
export MP_NUM=1
export CUDA_VISIBLE_DEVICES=0
## 如果是多卡推理除了模型导出得满足2卡要求同时设置如下环境变量。
# export MP_NUM=2
# export CUDA_VISIBLE_DEVICES=0,1
# 如部署场景无流式Token返回需求可配置如下开关
# 服务将会将每个请求的所有生成Token一次性返回
# 降低服务逐个Token发送压力
# 默认关闭
# export DISABLE_STREAMING=1
# 配置数据服务。需要自行修改HTTP_PORT、GRPC_PORT、METRICS_PORT和INFER_QUEUE_PORT。(请事先检查端口可用)
export HTTP_PORT="8110" # 探活服务的http端口当前仅用于健康检查、探活
export GRPC_PORT="8811" # 模型推服务的grpc端口
export METRICS_PORT="8722" # 模型服务中监督指标的端口
export INFER_QUEUE_PORT="8813" # 模型服务内部使用的端口
export PUSH_MODE_HTTP_PORT="9965" # 服务请求HTTP端口号如不配置默认为-1即服务只支持GRPC协议
# MAX_SEQ_LEN: 服务会拒绝input token数量超过MAX_SEQ_LEN的请求并返回错误提示
# MAX_DEC_LEN: 服务会拒绝请求中max_dec_len/min_dec_len超过此参数的请求并返回错误提示
export MAX_SEQ_LEN=8192
export MAX_DEC_LEN=1024
export BATCH_SIZE="48" # 设置最大Batch Size模型可同时并发处理的最大输入数量不能高于128
export BLOCK_BS="5" # 缓存Block支持的最大Query Batch Size如果出现out of memeory 错误,尝试减少该数值
export BLOCK_RATIO="0.75" # 一般可以设置成 输入平均Token数/(输入+输出平均Token数)
export MAX_CACHED_TASK_NUM="128" # 服务缓存队列最大长度队列达到上限后会拒绝新的请求默认128
# 开启HTTP接口配置如下参数
export PUSH_MODE_HTTP_WORKERS="1" # HTTP服务进程数在 PUSH_MODE_HTTP_PORT 配置的情况下有效最高设置到8即可默认为1
```
更多请求参数请参考[模型配置参数介绍](#模型配置参数介绍)
### 启动服务
```
cd /opt/output/Serving
bash start_server.sh
# 重新启动服务前,需要停止服务,在/opt/output/Serving目录下执行 bash stop_server.sh
```
### 服务状态查询
```
# port为上面启动服务时候指定的HTTP_PORT
> 测试前请确保服务IP和端口正确
live接口 (服务是否能正常接收请求)
http://127.0.0.1:8110/v2/health/live
health接口模型是否准备好推理
http://127.0.0.1:8110/v2/health/ready
```
## 服务测试
### Python 客户端
```
from fastdeploy_client.chatbot import ChatBot
hostname = "127.0.0.1" # 服务部署的hostname
port = 8811 # 服务配置的GRPC_PORT
chatbot = ChatBot(hostname=hostname, port=port)
# 非流式接口
result = chatbot.generate("hello", topp=0.8, max_dec_len=128, timeout=120)
print(result)
# 流式接口
chatbot = ChatBot(hostname=hostname, port=port)
stream_result = chatbot.stream_generate("hello", max_dec_len=128, timeout=120)
for res in stream_result:
print(res)
```
### HTTP调用
提示HTTP调用接口使用变量 PUSH_MODE_HTTP_PORT 配置HTTP_PORT 仅用于探活接口使用!
```
import uuid
import json
import requests
push_mode_http_port = "9965" # 服务配置的PUSH_MODE_HTTP_PORT
url = f"http://127.0.0.1:{push_mode_http_port}/v1/chat/completions"
req_id = str(uuid.uuid1())
data_single = {
"text": "Hello, how are you?",
"req_id": req_id,
"max_dec_len": 64,
"stream": True,
}
# 逐token返回
res = requests.post(url, json=data_single, stream=True)
for line in res.iter_lines():
print(json.loads(line))
# 多轮对话
data_multi = {
"messages": [
{"role": "user", "content": "Hello, who are you"},
{"role": "system", "content": "I'm a helpful AI assistant."},
{"role": "user", "content": "List 3 countries and their capitals."},
],
"req_id": req_id,
"max_dec_len": 64,
"stream": True,
}
# 逐token返回
res = requests.post(url, json=data_multi, stream=True)
for line in res.iter_lines():
print(json.loads(line))
```
更多请求参数请参考[请求参数介绍](#请求参数介绍)
### 返回示例
```
如果stream为True流式返回
如果正常,返回{'token': xxx, 'is_end': xxx, 'send_idx': xxx, ..., 'error_msg': '', 'error_code': 0}
如果异常,返回{'error_msg': xxx, 'error_code': xxx}error_msg字段不为空error_code字段不为0
如果stream为False非流式返回
如果正常,返回{'tokens_all': xxx, ..., 'error_msg': '', 'error_code': 0}
如果异常,返回{'error_msg': xxx, 'error_code': xxx}error_msg字段不为空error_code字段不为0
```
### OpenAI 客户端
我们提供了 OpenAI 客户端的支持,使用方法如下:
提示:使用 OpenAI 客户端需要配置 `PUSH_MODE_HTTP_PORT`
```
import openai
push_mode_http_port = "9965" # 服务配置的PUSH_MODE_HTTP_PORT
client = openai.Client(base_url=f"http://127.0.0.1:{push_mode_http_port}/v1/chat/completions", api_key="EMPTY_API_KEY")
# 非流式返回
response = client.completions.create(
model="default",
prompt="Hello, how are you?",
max_tokens=50,
stream=False,
)
print(response)
print("\n")
# 流式返回
response = client.completions.create(
model="default",
prompt="Hello, how are you?",
max_tokens=100,
stream=True,
)
for chunk in response:
if chunk.choices[0] is not None:
print(chunk.choices[0].text, end='')
print("\n")
# Chat completion
# 非流式返回
response = client.chat.completions.create(
model="default",
messages=[
{"role": "user", "content": "Hello, who are you"},
{"role": "system", "content": "I'm a helpful AI assistant."},
{"role": "user", "content": "List 3 countries and their capitals."},
],
temperature=0,
max_tokens=64,
stream=False,
)
print(response)
print("\n")
# 流式返回
response = client.chat.completions.create(
model="default",
messages=[
{"role": "user", "content": "Hello, who are you"},
{"role": "system", "content": "I'm a helpful AI assistant."},
{"role": "user", "content": "List 3 countries and their capitals."},
],
temperature=0,
max_tokens=64,
stream=True,
)
for chunk in response:
if chunk.choices[0].delta is not None:
print(chunk.choices[0].delta.content, end='')
print("\n")
```
## 基于dockerfile创建自己的镜像
为了方便用户构建自定义服务我们提供了基于dockerfile创建自己的镜像的脚本。
```
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy/llm
docker build --network=host -f ./dockerfiles/Dockerfile_serving_cuda123_cudnn9 -t llm-serving-cu123-self .
```
创建自己的镜像后,可以基于该镜像[创建容器](#创建容器)
## 模型配置参数介绍
| 字段名 | 字段类型 | 说明 | 是否必填 | 默认值 | 备注 |
| :---: | :-----: | :---: | :---: | :-----: | :----: |
| MP_NUM | int | 模型并行度 | 否 | 8 | CUDA_VISIBLE_DEVICES 需配置对应卡数 |
| CUDA_VISIBLE_DEVICES | str | 使用 GPU 编号 | 否 | 0,1,2,3,4,5,6,7 | |
| HTTP_PORT | int | 探活服务的http端口 | 是 | 无 | 当前仅用于健康检查、探活 |
| GRPC_PORT | int | 模型推服务的grpc端口 | 是 | 无 | |
| METRICS_PORT | int | 模型服务中监督指标的端口 | 是 | 无 | |
| INFER_QUEUE_PORT | int | 模型服务内部使用的端口 | 否 | 56666 | |
| PUSH_MODE_HTTP_PORT | int | 服务请求HTTP端口号 | 否 | -1 | 如不配置服务只支持GRPC协议 |
| DISABLE_STREAMING | int | 是否使用流式返回 | 否 | 0 | |
| MAX_SEQ_LEN | int | 最大输入序列长度 | 否 | 8192 | 服务会拒绝input token数量超过MAX_SEQ_LEN的请求并返回错误提示 |
| MAX_DEC_LEN | int | 最大decoer序列长度 | 否 | 1024 | 服务会拒绝请求中max_dec_len/min_dec_len超过此参数的请求并返回错误提示 |
| BATCH_SIZE | int | 最大Batch Size | 否 | 50 | 模型可同时并发处理的最大输入数量不能高于128 |
| BLOCK_BS | int | 缓存Block支持的最大Query Batch Size | 否 | 50 | 如果出现out of memeory 错误,尝试减少该数值 |
| BLOCK_RATIO | float | | 否 | 0.75 | 建议配置 输入平均Token数/(输入+输出平均Token数) |
| MAX_CACHED_TASK_NUM | int | 服务缓存队列最大长度 | 否 | 128 | 队列达到上限后,会拒绝新的请求 |
| PUSH_MODE_HTTP_WORKERS | int | HTTP服务进程数 | 否 | 1 | 在 PUSH_MODE_HTTP_PORT 配置的情况下有效高并发下提高该数值建议最高配置为8 |
| USE_WARMUP | int | 是否进行 warmup | 否 | 0 | |
| USE_HF_TOKENIZER | int | 是否进行使用huggingface的词表 | 否 | 0 | |
| USE_CACHE_KV_INT8 | int | 是否将INT8配置为KV Cache的类型 | 否 | 0 | c8量化模型需要配置为1 |
| MODEL_DIR | str | 模型文件路径 | 否 | /models/ | |
| FD_MODEL_CONFIG_PATH | str | 模型config文件路径 | 否 | ${model_dir}/config.json | |
| DISTRIBUTED_CONFIG | str | 模型分布式配置文件路径 | 否 | ${model_dir}/rank_mapping.csv | |
## 请求参数介绍
| 字段名 | 字段类型 | 说明 | 是否必填 | 默认值 | 备注 |
| :---: | :-----: | :---: | :---: | :-----: | :----: |
| req_id | str | 请求ID用于标识一个请求。建议设置req_id保证其唯一性 | 否 | 随机id | 如果推理服务中同时有两个相同req_id的请求会返回req_id重复的错误信息 |
| text | str | 请求的文本 | 否 | 无 | text 和 messages 必须有一个 |
| messages | str | 多轮对话文本 | 否 | 无 | 多轮对话以list方式存储 |
| max_dec_len | int | 最大生成token的长度如果请求的文本token长度加上max_dec_len大于模型的max_seq_len会返回长度超限的错误信息 | 否 | max_seq_len减去文本token长度 | |
| min_dec_len | int | 最小生成token的长度最小是1 | 否 | 1 | |
| topp | float | 控制随机性参数数值越大则随机性越大范围是0~1 | 否 | 0.7 | |
| temperature | float | 控制随机性参数,数值越小随机性越大,需要大于 0 | 否 | 0.95 | |
| frequency_score | float | 频率分数 | 否 | 0 | |
| penalty_score | float | 惩罚分数 | 否 | 1 | |
| presence_score | float | 存在分数 | 否 | 0 | |
| stream | bool | 是否流式返回 | 否 | False | |
| return_all_tokens | bool | 是否一次性返回所有结果 | 否 | False | 与stream参数差异见表后备注 |
| timeout | int | 请求等待的超时时间,单位是秒 | 否 | 300 | |
| return_usage | bool | 是否返回输入、输出 token 数量 | 否 | False | |
* 在正确配置PUSH_MODE_HTTP_PORT字段下服务支持 GRPC 和 HTTP 两种请求服务
* stream 参数仅对 HTTP 请求生效
* return_all_tokens 参数对 GRPC 和 HTTP 请求均有效