提交 883ed94e 编写于 作者: T TeslaZhao

Update doc

上级 775e913e
# 保存用于 Serving 部署的模型参数
- [背景介绍](#1)
- [功能设计](#2)
- [功能使用](#3)
- [PYTHON 命令执行](#3.1)
- [代码引入执行](#3.2)
- [Serving 部署](#4)
- [服务端部署示例](#4.1)
- [客户端部署示例](#4.2)
<a name="1"></a>
## 背景介绍
模型参数信息保存在模型文件中,为什么还要保存用于 Paddle Serving 部署的模型参数呢,原因有3个:
1. 服务化场景分为客户端和服务端,服务端加载模型,而在客户端没有模型信息,但需要在客户端需实现数据拼装和类型转换。
2. 模型升级过程中 `feed vars``fetch vars` 的名称变化会导致代码升级,通过增加一个 `alias_name` 字段映射名称,代码无需升级。
3. 部署 `Web` 服务,并使用 `URL` 方式访问时,请求信息中缺少类型和维度信息,在服务端推理前需要进行转换。
<a name="2"></a>
## 功能设计
飞桨训推一体框架中,从动态图模型训练到静态图推理部署,一体化流程如下所示
......@@ -65,6 +80,7 @@ feed 与 fetch 变量的类型列表如下:
| complex64 | 10
| complex128 | 11 |
<a name="3"></a>
## 功能使用
......@@ -84,6 +100,7 @@ Paddle 推理模型有3种形式,每种形式的读模型的方式都不同,
| `model_filename` | str | None | 存储需要转换的模型Inference Program结构的文件名称。如果设置为None,则使用 `__model__` 作为默认的文件名 |
| `params_filename` | str | None | 存储需要转换的模型所有参数的文件名称。当且仅当所有模型参数被保>存在一个单独的二进制文件中,它才需要被指定。如果模型参数是存储在各自分离的文件中,设置它的值为None |
<a name="3.1"></a>
**一.PYTHON 命令执行**
......@@ -99,6 +116,7 @@ python3 -m paddle_serving_client.convert --dirname ./your_inference_model_dir
python3 -m paddle_serving_client.convert --dirname . --model_filename dygraph_model.pdmodel --params_filename dygraph_model.pdiparams --serving_server serving_server --serving_client serving_client
```
<a name="3.2"></a>
**二.代码引入执行**
......@@ -108,10 +126,14 @@ import paddle_serving_client.io as serving_io
serving_io.inference_model_to_serving(dirname, serving_server="serving_server", serving_client="serving_client", model_filename=None, params_filename=None)
```
<a name="4"></a>
## Serving 部署
生成完的模型可直接用于服务化推理,服务端使用和客户端使用。
**一.服务端使用**
<a name="4.1"></a>
**一.服务端部署示例**
示例一:C++ Serving 启动服务
```
......@@ -140,7 +162,9 @@ op:
device_type: 0
```
**二.客户端使用**
<a name="4.2"></a>
**二.客户端部署示例**
通过 `client` 对象的 `load_client_config` 接口加载模型配置信息
```
......
# C++ Serving 异步模式
- [设计方案](#1)
- [网络同步线程](#1.1)
- [异步调度线程](#1.2)
- [动态批量](#1.3)
- [使用案例](#2)
- [开启同步模式](#2.1)
- [开启异步模式](#2.2)
- [性能测试](#3)
- [测试数据](#3.1)
- [测试结论](#3.2)
<a name="1"></a>
## 设计方案
<a name="1.1"></a>
**一.同步网络线程**
Paddle Serving 的网络框架层面是同步处理模式,即 bRPC 网络处理线程从系统内核拿到完整请求数据后( epoll 模式),在同一线程内完成业务处理,C++ Serving 默认使用同步模式。同步模式比较简单直接,适用于模型预测时间短,或单个 Request 请求批量较大的情况。
......@@ -12,6 +27,8 @@ Paddle Serving 的网络框架层面是同步处理模式,即 bRPC 网络处
Server 端线程数 N = 模型预测引擎数 N = 同时处理 Request 请求数 N,超发的 Request 请求需要等待当前线程处理结束后才能得到响应和处理。
<a name="1.2"></a>
**二.异步调度线程**
为了提高计算芯片吞吐和计算资源利用率,C++ Serving 在调度层实现异步多线程并发合并请求,实现动态批量推理。异步模型主要适用于模型支持批量,单个 Request 请求的无批量或较小,单次预测时间较长的情况。
......@@ -22,6 +39,8 @@ Server 端线程数 N = 模型预测引擎数 N = 同时处理 Request 请求数
异步模式下,Server 端 N 个线程只负责接收 Request 请求,实际调用预测引擎是在异步框架的线程池中,异步框架的线程数可以由配置选项来指定。为了方便理解,我们假设每个 Request 请求批量均为1,此时异步框架会尽可能多得从请求池中取 n(n≤M)个 Request 并将其拼装为1个 Request(batch=n),调用1次预测引擎,得到1个 Response(batch = n),再将其对应拆分为 n 个 Response 作为返回结果。
<a name="1.3"></a>
**三.动态批量**
通常,异步框架合并多个请求的前提是所有请求的 `feed var` 的维度除 batch 维度外必须是相同的。例如,以 OCR 文字识别案例中检测模型为例,A 请求的 `x` 变量的 shape 是 [1, 3, 960, 960],B 请求的 `x` 变量的 shape 是 [2, 3, 960, 960],虽然第一个维度值不相同,但第一个维度属于 `batch` 维度,因此,请求 A 和 请求 B 可以合并。C 请求的 `x` 变量的 shape 是 [1, 3, 640, 480],由于除了 `batch` 维度外还有2个维度值不同,A 和 C 不能直接合并。
......@@ -39,16 +58,21 @@ Server 端线程数 N = 模型预测引擎数 N = 同时处理 Request 请求数
场景3:`Shape-1 = [batch, 3, 320, 320], Shape-2 = [batch, 3, 960, 960]`。此时,`绝对值差 = 3*960*960 - 3*320*320 = 2457600`字节,`相对误差 = (3/3) * (320/960) * (320/960) = 0.3*0.3 = 0.09`,条件1和条件2均不满足,未触发动态 Padding。
<a name="2"></a>
## 使用案例
**一.不开启异步模式**
<a name="2.1"></a>
**一.开启同步模式**
启动命令不使用 `--runtime_thread_num``--batch_infer_size` 时,属于同步处理模式,未开启异步模式。`--thread 16` 表示启动16个同步网络处理线程。
```
python3 -m paddle_serving_server.serve --model uci_housing_model --thread 16 --port 9292
```
<a name="2.2"></a>
**二.开启异步模式**
启动命令使用 `--runtime_thread_num 4``--batch_infer_size 32` 开启异步模式,Serving 框架会启动8个异步线程,单次合并最大批量为32,自动开启动态 Padding。
......@@ -56,9 +80,9 @@ python3 -m paddle_serving_server.serve --model uci_housing_model --thread 16 --p
python3 -m paddle_serving_server.serve --model uci_housing_model --thread 16 --port 9292 --runtime_thread_num 4 --batch_infer_size 32 --ir_optim --gpu_multi_stream --gpu_ids 0
```
## 测试数据
<a name="3"></a>
**一.测试环境**
## 性能测试
GPU:Tesla P4 7611 MiB
Cuda:cuda11.2-cudnn8-trt8
......@@ -76,7 +100,9 @@ python3 -m paddle_serving_server.serve --model resnet_v2_50_imagenet_model --por
python3 -m paddle_serving_server.serve --model resnet_v2_50_imagenet_model --port 9393 --thread 64 --runtime_thread_num 8 --ir_optim --gpu_multi_stream --gpu_ids 1 --enable_prometheus --prometheus_port 19393
```
**二.测试数据**
<a name="3.1"></a>
**一.测试数据**
1. 同步模式
......@@ -121,8 +147,9 @@ python3 -m paddle_serving_server.serve --model resnet_v2_50_imagenet_model --por
|50 |1 |1.50 |50.60 |7578 |89.04 |121.545 |5000 |411.364 |331.118 |605.809 |874.543 |1285.650 |48.2343 |41.1369 |9350.0000 |2568777.6400 |295.8593|
|70 |1 |3.80 |83.20 |7602 |89.59 |133.568 |7000 |524.073 |382.653 |799.463 |1202.179 |1576.809 |57.2885 |52.4077 |10761.0000 |3013600.9670 |315.2540|
<a name="3.2"></a>
**.测试结论**
**.测试结论**
使用异步模式,并开启动态批量后,并发测试不同 shape 数据时,吞吐性能大幅提升。
<div align=center>
......
# C++ Serving 通讯协议
- [网络框架](#0)
- [Tensor](#1)
- [1.1 构建 FLOAT32 Tensor](#1.1)
- [1.2 构建 STRING Tensor](#1.2)
- [Request](#2)
- [2.1 构建 Protobuf Request](#2.1)
- [2.2 构建 Json Request](#2.2)
- [Response](#3)
- [3.1 读取 Response 数据](#3.1)
<a name="0"></a>
## 网络框架
C++ Serving 基于 [bRPC](https://github.com/apache/incubator-brpc) 网络框架构建服务,支持 bRPC、gRPC 和 RESTful 协议请求。不限于开发语言和框架,甚至 `curl` 方式,只要按照上述协议封装数据并发送,Server 就能够接收、处理和返回结果。
对于支持的各种协议我们提供了部分的 Client SDK 示例供用户参考和使用,用户也可以根据自己的需求去开发新的 Client SDK,也欢迎用户添加其他语言/协议(例如 GRPC-Go、GRPC-C++ HTTP2-Go、HTTP2-Java 等)Client SDK 到我们的仓库供其他开发者借鉴和参考。
......@@ -15,9 +29,7 @@ C++ Serving 基于 [bRPC](https://github.com/apache/incubator-brpc) 网络框架
C++ Serving 请求和应答的数据格式为 protobuf,重要的结构有以下3个:
- Tensor
- Request
- Response
<a name="1"></a>
## Tensor
......@@ -110,6 +122,8 @@ Tensor 结构中重要成员 `elem_type`、`shape`、`lod` 和 `name/alias_name`
|11|COMPLEX128
|20|STRING|
<a name="1.1"></a>
**一.构建 FLOAT32 Tensor**
创建 Tensor 对象,通过 `mutable_float_data::Resize()` 设置 FLOAT32 类型数据长度,通过 memcpy 函数拷贝数据。
......@@ -135,6 +149,8 @@ tensor->mutable_float_data()->Resize(total_number, 0);
memcpy(tensor->mutable_float_data()->mutable_data(), float_datadata(), total_number * sizeof(float));
```
<a name="1.2"></a>
**二.构建 STRING Tensor**
创建 Tensor 对象,通过 `set_tensor_content` 设置 string 类型数据。
......@@ -154,6 +170,8 @@ tensor->set_alias_name(alias_name);
tensor->set_tensor_content(string_data);
```
<a name="2"></a>
## Request
......@@ -174,6 +192,8 @@ message Request {
当使用 bRPC 或 gRPC 进行请求时,使用 protobuf 或 Json 格式请求数据。
<a name="2.1"></a>
**一.构建 Protobuf Request**
创建 Request 对象,通过 `add_tensor` 接口来设置 Tensor。
......@@ -187,6 +207,7 @@ for (auto &name : fetch_name) {
Tensor *tensor = req.add_tensor();
...
```
<a name="2.2"></a>
**二.构建 Json Request**
......@@ -196,6 +217,8 @@ Tensor *tensor = req.add_tensor();
{"tensor":[{"float_data":[0.0137,-0.1136,0.2553,-0.0692,0.0582,-0.0727,-0.1583,-0.0584,0.6283,0.4919,0.1856,0.0795,-0.0332],"elem_type":1,"name":"x","alias_name":"x","shape":[1,13]}],"fetch_var_names":["price"],"log_id":0}
```
<a name="3"></a>
## Response
Response 为服务端返回给客户端的结果,包含了 Tensor 数据、错误码、错误信息等。定义如下:
......@@ -231,6 +254,8 @@ Response 结构中核心成员:
|-5002|"Paddle Serving Array Overflow Error."|
|-5100|"Paddle Serving Op Inference Error."|
<a name="3.1"></a>
**一.读取 Response 数据**
读取 Response 对象中 Tensor 数据示例如下
......
# C++ Serving ABTest
- [功能设计](#1)
- [使用案例](#2)
- [1.1 安装 Paddle Serving Wheels](#2.1)
- [1.2 下载多个模型并保存模型参数](#2.2)
- [1.3 启动 A,B,C 3个服务](#2.3)
- [1.4 客户端注册 A,B,C 服务端地址](#2.4)
- [1.5 启动客户端并验证结果](#2.5)
ABTest 是一种功能测试方案,一般是为同一个产品目标制定多种方案,让一部分用户使用 A 方案,另一部分用户使用 B 或 C 方案,根据测试效果,如点击率、转化率等来评价方案的优劣。
模型服务化部署框架中,ABTest 属于一个重要的基础功能,为模型迭代升级提供实验环境。Paddle Serving 的 PYTHON SDK 中实现 ABTest 功能,为用户提供简单易用功能测试环境。
<a name="1"></a>
## 功能设计
Paddle Serving 的 ABTest 功能是基于 PYTHON SDK 和 多个服务端构成。每个服务端加载不同模型,在客户端上注册多个服务端地址和访问比例,最终确定访问。
......@@ -12,6 +22,7 @@ Paddle Serving 的 ABTest 功能是基于 PYTHON SDK 和 多个服务端构成
<img src='images/6-5_Cpp_ABTest_CN_1.png' height = "400" align="middle"/>
</div
<a name="2"></a>
## 使用案例
......@@ -20,9 +31,10 @@ Paddle Serving 的 ABTest 功能是基于 PYTHON SDK 和 多个服务端构成
1. 安装 Paddle Serving Wheels
2. 下载多个模型并保存模型参数
3. 启动 A,B,C 3个服务
4. 客户端注册 A,B,C 服务端地址
4. 客户端注册 A,B,C 服务端地址
5. 启动客户端并验证结果
<a name="2.1"></a>
**一.安装 Paddle Serving Wheels**
......@@ -32,6 +44,8 @@ Paddle Serving 的 ABTest 功能是基于 PYTHON SDK 和 多个服务端构成
pip3 install paddle-serving-client==0.8.3 -i https://pypi.tuna.tsinghua.edu.cn/simple
```
<a name="2.2"></a>
**二.下载多个模型并保存模型参数**
本示例已提供了一键下载脚本 `sh get_data.sh`,下载 `bow``cnn``lstm` 3种不同方式训练的模型。
......@@ -108,6 +122,8 @@ fetch_var {
}
```
<a name="2.3"></a>
**三.启动 A,B,C 3个服务**
后台启动 `bow``cnn``lstm` 模型服务:
......@@ -123,6 +139,8 @@ python3 -m paddle_serving_server.serve --model imdb_cnn_model/ --port 9298 >/de
python3 -m paddle_serving_server.serve --model imdb_lstm_model/ --port 9299 >/dev/null 2>&1 &
```
<a name="2.4"></a>
**四.客户端注册 A,B,C 服务端地址**
使用 `paddle_serving_client``Client::add_variant(self, tag, cluster, variant_weight)` 接口注册服务标签、服务地址和权重。框架会将所有权重求和后计算每个服务的比例。本示例中,bow 服务的权重是10,cnn 服务的权重是30, lstm的权重是60,每次请求分别请求到3个服务的比例是10%、30%和60%。
......@@ -142,6 +160,7 @@ client.connect()
```
如要在结果中打印请求到了哪个服务,在 `client.predict(feed, fetch, batch, need_variant_tag, logid)` 中设置 `need_variant_tag=True`
<a name="2.5"></a>
**五.启动客户端并验证结果**
......
# Python Pipeline 框架设计
- [目标](#1)
- [框架设计](#2)
- [2.1 网络层设计](#2.1)
- [2.2 图执行引擎层](#2.2)
- [2.3 服务日志](#2.3)
- [2.4 错误信息](#2.4)
- [自定义信息](#3)
- [3.1 自定义 Web 服务 URL](#3.1)
- [3.2 自定义服务输入和输出结构](#3.2)
- [3.3 自定义服务并发和模型配置](#3.3)
- [3.4 自定义推理过程](#3.4)
- [3.5 自定义业务错误类型](#3.5)
<a name="1"></a>
## 目标
为了解决多个深度学习模型组合的复杂问题,Paddle Serving 团队设计了一个通用端到端多模型组合框架,其核心特点包括:
1. 通用性:框架既要满足通用模型的输入类型,又要满足模型组合的复杂拓扑关系。
......@@ -7,6 +24,7 @@
3. 高可用性:高可用的架构依赖每个服务的健壮性,服务状态可查询、异常可监控和管理是必备条件。
4. 易于开发与调试:使用 Python 语言开发可大幅提升研发效率,运行的错误信息准确帮助开发者快速定位问题。
<a name="2"></a>
## 框架设计
Python Pipeline 框架分为网络服务层和图执行引擎2部分,网络服务层处理多种网络协议请求和通用输入参数问题,图执行引擎层解决复杂拓扑关系。如下图所示
......@@ -15,6 +33,8 @@ Python Pipeline 框架分为网络服务层和图执行引擎2部分,网络服
<img src='../images/pipeline_serving-image1.png' height = "250" align="middle"/>
</div>
<a name="2.1"></a>
**一.网络服务层**
网络服务层包括了 gRPC-gateway 和 gRPC Server。gPRC gateway 接收 HTTP 请求,打包成 proto 格式后转发给 gRPC Server,一套处理程序可同时处理 HTTP、gRPC 2种类型请求。
......@@ -69,6 +89,7 @@ rpc_port: 9988
http_port: 18089
```
<a name="2.2"></a>
**二.图执行引擎层**
......@@ -137,6 +158,7 @@ Channel的设计原则:
<img src='../images/pipeline_serving-image3.png' height = "500" align="middle"/>
</div>
<a name="2.3"></a>
**三.服务日志**
......@@ -209,6 +231,8 @@ Pipeline 的日志模块在 `logger.py` 中定义,使用了 `logging.handlers.
```
<a name="2.4"></a>
**四. 错误信息**
框架提供的错误信息如下所示, 完整信息在 `error_catch.py``CustomExceptionCode` 类中定义。
......@@ -246,6 +270,7 @@ class CustomExceptionCode(enum.Enum):
UNKNOW = 10000
```
<a name="3"></a>
## 自定义信息
......@@ -256,8 +281,9 @@ class CustomExceptionCode(enum.Enum):
- 自定义推理过程
- 自定义业务错误类型
<a name="3.1"></a>
1. 自定义 Web 服务 URL
**一.自定义 Web 服务 URL**
在 Web 服务中自定义服务名称是常见操作,尤其是将已有服务迁移到新框架。URL 中核心字段包括 `ip``port``name``method`,根据最新部署的环境信息设置前2个字段,重点介绍如何设置 `name``method`,框架提供默认的 `methon``prediciton`,如 `http://127.0.0.1:9999/ocr/prediction`
......@@ -296,8 +322,9 @@ service PipelineService {
}
};
```
<a name="3.2"></a>
2. 自定义服务输入和输出结构
**二.自定义服务输入和输出结构**
输入和输出结构包括 proto 中 Request 和 Response 结构,以及 Op 前后处理返回。
......@@ -307,10 +334,15 @@ service PipelineService {
修改后,需要[重新编译]()
3. 自定义服务并发和模型配置
<a name="3.3"></a>
**三.自定义服务并发和模型配置**
完整的配置信息可参考[配置信息]()
4. 自定义推理过程
<a name="3.4"></a>
**四.自定义推理过程**
推理 Op 为开发者提供3个外部函数接口:
......@@ -435,8 +467,9 @@ class ResponseOp(Op):
return resp
```
<a name="3.5"></a>
5. 自定义业务错误类型
**五.自定义业务错误类型**
用户可根据业务场景自定义错误码,继承 ProductErrCode,在 Op 的 preprocess 或 postprocess 中返回列表中返回,下一阶段处理会根据自定义错误码跳过后置OP处理。
```python
......
......@@ -2,18 +2,27 @@
从设计上,Python Pipeline 框架实现轻量级的服务化部署,提供了丰富的核心功能,既能满足服务基本使用,又能满足特性需求。
- 安装与环境检查
- 服务启动与关闭
- 本地与远程推理
- 批量推理
- 单机多卡推理
- 多种计算芯片上推理
- TensorRT 推理加速
- MKLDNN 推理加速
- 低精度推理
- 复杂图结构 DAG 跳过某个 Op 运行
- [安装与环境检查](#1)
- [服务启动与关闭](#2)
- [本地与远程推理](#3)
- [批量推理](#4)
- [4.1 客户端打包批量数据](#4.1)
- [4.2 服务端合并多个请求动态合并批量](#4.2)
- [4.3 Mini-Batch](#4.3)
- [单机多卡推理](#5)
- [多种计算芯片上推理](#6)
- [TensorRT 推理加速](#7)
- [MKLDNN 推理加速](#8)
- [低精度推理](#9)
- [9.1 CPU 低精度推理](#9.1)
- [9.2 GPU 和 TensorRT 低精度推理](#9.2)
- [9.3 性能测试](#9.3)
- [复杂图结构 DAG 跳过某个 Op 运行](#10)
<a name="1"></a>
## 安装与环境检查
在运行 Python Pipeline 服务前,确保当前环境下可部署且通过[安装指南](./2-0_Index_CN.md)已完成安装。其次,`v0.8.0`及以上版本提供了环境检查功能,检验环境是否安装正确。
输入以下命令,进入环境检查程序。
......@@ -78,6 +87,8 @@ shutil.Error: Destination path '/home/work/Pipeline_test_cpu/PipelineServingLogs
```
<a name="2"></a>
## 服务启动与关闭
服务启动需要三类文件,PYTHON 程序、模型文件和配置文件。以[Python Pipeline 快速部署案例](./3-2_QuickStart_Pipeline_OCR_CN.md)为例,
......@@ -125,6 +136,8 @@ python3 -m paddle_serving_server.serve stop # 触发 SIGINT 信号
python3 -m paddle_serving_server.serve kill # 触发 SIGKILL 信号,强制关闭
```
<a name="3"></a>
## 本地与远程推理
本地推理是指在服务所在机器环境下开启多进程推理,而远程推理是指本地服务请求远程 C++ Serving 推理服务。
......@@ -184,6 +197,8 @@ op:
fetch_list: ["prediction"]
```
<a name="4"></a>
## 批量推理
Pipeline 支持批量推理,通过增大 batch size 可以提高 GPU 利用率。Python Pipeline 支持3种 batch 形式以及适用的场景如下:
......@@ -191,12 +206,15 @@ Pipeline 支持批量推理,通过增大 batch size 可以提高 GPU 利用率
- 场景2:服务端合并多个请求动态合并批量(Server auto-batching)
- 场景3:拆分一个大批量的推理请求为多个小批量推理请求(Server mini-batch)
<a name="4.1"></a>
**一.客户端打包批量数据**
当输入数据是 numpy 类型,如shape 为[4, 3, 512, 512]的 numpy 数据,即4张图片,可直接作为输入数据。
当输入数据的 shape 不同时,需要按最大的shape的尺寸 Padding 对齐后发送给服务端
<a name="4.2"></a>
**二.服务端合并多个请求动态合并批量**
有助于提升吞吐和计算资源的利用率,当多个请求的 shape 尺寸不相同时,不支持合并。当前有2种合并策略,分别是:
......@@ -248,6 +266,8 @@ op:
```
<a name="4.3"></a>
**三.Mini-Batch**
拆分一个批量数据推理请求成为多个小块推理:会降低批量数据 Padding 对齐的大小,从而提升速度。可参考 [OCR 示例](),核心思路是拆分数据成多个小批量,放入 list 对象 feed_list 并返回
......@@ -310,6 +330,8 @@ def preprocess(self, input_dicts, data_id, log_id):
return feed_list, False, None, ""
```
<a name="5"></a>
## 单机多卡推理
单机多卡推理与 `config.yml` 中配置4个参数关系紧密,`is_thread_op``concurrency``device_type``devices`,必须在进程模型和 GPU 模式,每张卡上可分配多个进程,即 M 个 Op 进程与 N 个 GPU 卡绑定。
......@@ -346,6 +368,8 @@ op:
对于更灵活的进程与 GPU 卡绑定方式,会持续开发。
<a name="6"></a>
## 多种计算芯片上推理
除了支持 CPU、GPU 芯片推理之外,Python Pipeline 还支持在多种计算硬件上推理。根据 `config.yml` 中的 `device_type``devices`来设置推理硬件和加速库如下:
......@@ -371,6 +395,7 @@ devices: "0"
ir_optim: True
```
<a name="7"></a>
## TensorRT 推理加速
......@@ -405,6 +430,7 @@ op:
#开启 ir_optim
ir_optim: True
```
<a name="8"></a>
## MKL-DNN 推理加速
......@@ -439,6 +465,7 @@ op:
#开启 MKLDNN
use_mkldnn: True
```
<a name="9"></a>
## 低精度推理
......@@ -446,7 +473,9 @@ Pipeline Serving支持低精度推理,CPU、GPU和TensoRT支持的精度类型
低精度推理需要有量化模型,配合`config.yml`配置一起使用,以[低精度示例]() 为例
**一.CPU 低精度推理配置**
<a name="9.1"></a>
**一.CPU 低精度推理**
通过设置,`device_type``devices` 字段使用 CPU 推理,通过调整`precision``thread_num``use_mkldnn`参数选择低精度和性能调优。
......@@ -484,6 +513,8 @@ op:
use_mkldnn: True
```
<a name="9.2"></a>
**二.GPU 和 TensorRT 低精度推理**
通过设置`device_type``devices` 字段使用原生 GPU 或 TensorRT 推理,通过调整`precision``ir_optim``use_calib`参数选择低精度和性能调优,如开启 TensorRT,必须一同开启`ir_optim``use_calib`仅配合 int8 使用。
......@@ -521,6 +552,8 @@ op:
ir_optim: True
```
<a name="9.3"></a>
**三.性能测试**
测试环境如下:
......@@ -547,6 +580,8 @@ CPU 推理性能较好的配置是
<img src='../images/low_precision_profile.png' height = "600" align="middle"/>
</div
<a name="10"></a>
## 复杂图结构 DAG 跳过某个 Op 运行
此应用场景一般在 Op 前后处理中有 if 条件判断时,不满足条件时,跳过后面处理。实际做法是在跳过此 Op 的 process 阶段,只要在 preprocess 做好判断,跳过 process 阶段,在和 postprocess 后直接返回即可。
......
# Python Pipeline 优化指南
- [优化响应时长](#1)
- [1.1 分析响应时长](#1.1)
- [Pipeline Trace Tool](#1.1.1)
- [Pipeline Profile Tool](#1.1.2)
- [1.2 优化思路](#1.2)
- [优化服务吞吐](#2)
- [2.1 分析吞吐瓶颈](#2.1)
- [2.2 优化思路](#2.2)
- [增加 Op 并发](#2.2.1)
- [动态批量](#2.2.2)
- [CPU 与 GPU 处理分离](#2.2.3)
通常,服务的性能优化是基于耗时分析,首先要掌握服务运行的各阶段耗时信息,从中找到耗时最长的性能瓶颈再做针对性优化。对于模型推理服务化不仅要关注耗时,由于 GPU 芯片昂贵,更要关注服务吞吐,从而提升 GPU 利用率实现降本增效。因此,模型推理服务化可总结为:
- 优化响应时长
- 优化服务吞吐
经过分析和调优后,各个阶段实现整体服务的性能最优。
<a name="1"></a>
## 优化响应时长
首先,优化响应时长的主要思路首先要掌握各阶段耗时,并分析出性能瓶颈或者耗时占比较高的阶段,再针对性能瓶颈做专项优化。
......@@ -14,7 +29,13 @@ Paddle Serving 提供2种耗时分析工具,`Pipeline Trace Tool` 和 `Pipelin
- Pipeline Trace Tool : 统计服务端所有进程各个阶段的平均耗时,包括每个 `Op``Channel`,用于定量分析。
- Pipeline Profile Tool : 是可视化 Trace View 工具,生成多进程并发效果图,用定性和定量分析执行和并发效果。
**一.Pipeline Trace Tool**
<a name="1.1"></a>
**一.耗时分析**
<a name="1.1.1"></a>
1.Pipeline Trace Tool
`Pipeline Trace Tool` 统计每个 `Op``Channel` 中各阶段的处理耗时,
......@@ -59,8 +80,9 @@ dag:
chl1(In: ['uci'], Out: ['@DAGExecutor']) size[0/0] # uci Op 与 框架 ResponseOp 之间 Channel 中堆积的请求数。此值较大,说明下游 ReponseOp 消费能力不足。
==================== TRACER ======================
```
<a name="1.1.2"></a>
**二.Pipeline Profile Tool**
2.Pipeline Profile Tool
```
dag:
......@@ -101,8 +123,9 @@ python3.7 trace.py
通过图示中并发请求的处理流程可观测到推理阶段的流水线状态,以及多个请求在推理阶段的`间隔`信息,进行优化。
<a name="1.2"></a>
**三. 降低响应时长优化思路**
**二.降低响应时长优化思路**
根据 `Pipeline Trace Tool` 输出结果在不同阶段耗时长的问题,常见场景的优化方法如下:
- Op 推理阶段(midp) 耗时长:
......@@ -126,8 +149,14 @@ python3.7 trace.py
此外,还有一些优化思路,如将 CPU 处理较慢的过程转换到 GPU 上处理等,客户端与服务端传输较大数据时,可使用共享内存方式传递内存或显存地址等。
<a name="2"></a>
## 优化服务吞吐
<a name="2.1"></a>
**一.分析吞吐瓶颈**
服务的吞吐量受到多种多因素条件制约,如 Op 处理时长、传输数据耗时、并发数和 DAG 图结构等,可以将这些因素进一步拆解,当传输数据不是极端庞大的时候,最重要因素是流水线中`最慢 Op 的处理时长和并发数`
```
Op 处理时长:
......@@ -142,10 +171,15 @@ service_avg_cost = ∑op_concurrency 【关键路径】
批量预测平均耗时:
avg_batch_cost = (N * pre + mid + post) / N
```
<a name="2.2"></a>
**二.优化思路**
优化吞吐的主要方法是 `增大 Op 并发数``自动批量``CPU 与 GPU 处理分离`
**一.增加 Op 并发数**
<a name="2.2.1"></a>
1.增加 Op 并发**
调整 Op 的并发数量通过设置 `is_thread_op: False` 进程类型 Op 和 `uci` Op 的 `concurrency` 字段
```
......@@ -159,11 +193,15 @@ op:
```
Op 的进程数量不是越大越好,受到机器 CPU 核数、内存和显存大小的限制,推荐设置 Op 的并发数不超过系统 CPU 核数。
**二.自动批量**
<a name="2.2.2"></a>
2.动态批量
动态批量是增加吞吐的有一种方法,开启方式可参考[Python Pipeline 核心功能](./7-2_Python_Pipeline_Senior_CN.md#批量推理)
自动配量是增加吞吐的有一种方法,开启方式可参考[Python Pipeline 核心功能](./7-2_Python_Pipeline_Senior_CN.md#批量推理)
<a name="2.2.3"></a>
**三.CPU 与 GPU 处理分离**
3.CPU 与 GPU 处理分离
`CV` 模型中,对图片或视频的前后处理成为主要瓶颈时,可考虑此方案,即将前后处理过程独立成一个 Op 并独立设置并发度。
......
本次提测的Serving版本,支持GPU预测,希望以此任务为例,对Paddle Serving支持GPU预测的性能给出测试数据。
# Python Pipeline 性能测试
- [测试环境](#1)
- [性能指标](#2)
<a name="1"></a>
## 测试环境
测试环境如下表所示:
| | GPU | 显存 | CPU | 内存 |
|----------|---------|----------|----------------------------------------------|------|
| Serving端 | 4x Tesla P4-8GB | 7611MiB | Intel(R) Xeon(R) Gold 5117 CPU @ 2.00GHz 48核 | 216G |
......@@ -10,6 +16,8 @@
使用单卡GPU,未开启TensorRT。
模型:ResNet_v2_50
<a name="2"></a>
## 性能指标
|model_name |thread_num |batch_size |CPU_util(%) |GPU_memory(mb) |GPU_util(%) |qps(samples/s) |total count |mean(ms) |median(ms) |80 percent(ms) |90 percent(ms) |99 percent(ms) |total cost(s) |each cost(s)|
......
......@@ -3,6 +3,5 @@ Kubernetes 集群部署
服务部署经历从物理机、虚拟机、容器化、云原生4个阶段。云原生,提供集装箱组合模式的乐高生态,Docker、Kubernetes 已称为云原生时代基础设施,推动应用程序大发展。Kubernetes 的可扩展性和分布式架构一直是人工智能和机器学习的绝佳选择,随着解决方案不断成熟,推动机器学习大规模工程落地。
本章节介绍 Kubernetes 上集群化部署 Paddle Serving 方案以及企业级安全网关部署案例。
- [Kubernetes 集群部署方案]()
- [Kubernetes 集群部署方案](./9-1_Kubernetes_CN.md)
- [Kubernetes 安全网关部署案例]()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册