Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
Serving
提交
d37a7279
S
Serving
项目概览
PaddlePaddle
/
Serving
大约 1 年 前同步成功
通知
185
Star
833
Fork
253
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
105
列表
看板
标记
里程碑
合并请求
10
Wiki
2
Wiki
分析
仓库
DevOps
项目成员
Pages
S
Serving
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
105
Issue
105
列表
看板
标记
里程碑
合并请求
10
合并请求
10
Pages
分析
分析
仓库分析
DevOps
Wiki
2
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d37a7279
编写于
11月 14, 2021
作者:
T
Thomas Young
提交者:
GitHub
11月 14, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1497 from HexToString/fix_doc_0.7.0
fix doc 2
上级
59dfd9e4
6e06208b
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
64 addition
and
5 deletion
+64
-5
doc/C++Serving/Introduction_CN.md
doc/C++Serving/Introduction_CN.md
+1
-1
doc/C++Serving/Performance_Tuning_CN.md
doc/C++Serving/Performance_Tuning_CN.md
+60
-1
examples/C++/PaddleDetection/ttfnet_darknet53_1x_coco/test_client.py
...+/PaddleDetection/ttfnet_darknet53_1x_coco/test_client.py
+3
-3
未找到文件。
doc/C++Serving/Introduction_CN.md
浏览文件 @
d37a7279
...
...
@@ -41,7 +41,7 @@ Server端的核心是一个由项目代码编译产生的名称为serving的二
<img
src=
'../images/syn_mode.png'
width =
"350"
height =
"300"
>
<p>
异步模型主要适用于模型支持多batch(最大batch数M可通过配置选项指定),单个Request请求的batch较小(batch << M),单次预测时间较长的情况。
异步模型下,Server端N个线程只负责接收Request请求,实际调用预测引擎是在异步框架的线程中,异步框架的线程数可以由配置选项来指定。为了方便理解,我们假设每个Request请求的batch均为1,此时异步框架会尽可能多得从请求池中取n(n≤M)个Request并将其拼装为1个Request(batch=n),调用1次预测引擎,得到1个Response(batch = n),再将其对应拆分为n个Response作为返回结果。
异步模型下,Server端N个线程只负责接收Request请求,实际调用预测引擎是在异步框架的线程
池
中,异步框架的线程数可以由配置选项来指定。为了方便理解,我们假设每个Request请求的batch均为1,此时异步框架会尽可能多得从请求池中取n(n≤M)个Request并将其拼装为1个Request(batch=n),调用1次预测引擎,得到1个Response(batch = n),再将其对应拆分为n个Response作为返回结果。
<p
align=
"center"
>
<img
src=
'../images/asyn_mode.png'
"
>
<p>
...
...
doc/C++Serving/Performance_Tuning_CN.md
浏览文件 @
d37a7279
待填写!
# C++ Serving性能分析与优化
# 1.背景知识介绍
1) 首先,应确保您知道C++ Serving常用的一些
[
功能特点
](
Introduction_CN.md
)
和
[
C++ Serving 参数配置和启动的详细说明
](
../SERVING_CONFIGURE_CN.md。
2) 关于C++ Serving框架本身的性能分析和介绍,请参考
[
C++ Serving框架性能测试
](
Frame_Performance_CN.md
)
。
3) 您需要对您使用的模型、机器环境、需要部署上线的业务有一些了解,例如,您使用CPU还是GPU进行预测;是否可以开启TRT进行加速;你的机器CPU是多少core的;您的业务包含几个模型;每个模型的输入和输出需要做些什么处理;您业务的最大线上流量是多少;您的模型支持的最大输入batch是多少等等.
# 2.Server线程数
首先,Server端线程数N并不是越大越好。众所周知,线程的切换涉及到用户空间和内核空间的切换,有一定的开销,当您的core数=1,而线程数为100000时,线程的频繁切换将带来不可忽视的性能开销。
在BRPC框架中,用户态协程worker数M >> 线程数N,用户态协程worker会工作在任意一个线程中,当RPC网络传输IO操作让出CPU资源时,BRPC会进行用户态协程worker的切换从而提高RPC框架的并发性。所以,极端情况下,若您的代码中除RPC通信外,没有阻塞线程的任何IO或网络操作,您的线程数完全可以 == 机器core数量,您不必担心N个线程都在进行RPC网络IO,而导致CPU利用率不高的问题。
Server端
<mark>
**线程数N**
</mark>
的设置需要结合三个因素来综合考虑:
## 2.1 最大并发请求量M
根据最大并发请求量来设置Server端线程数N,根据
[
C++ Serving框架性能测试
](
Frame_Performance_CN.md
)
中的数据来看,此时
<mark>
**线程数N应等于或略小于最大并发请求量M**
</mark>
,此时平均处理时延最小。
这也很容易理解,举个极端的例子,如果您每次只有1个请求,那此时Server端线程数设置1是最合理的,因为此时没有任何线程切换的开销。如果您设置线程数为任何大于1的数,必然就带来了线程切换的开销。
## 2.2 机器core数量C
根据机器core数量来设置Server端线程数N,众所周知,线程是CPU core调度执行的最小单元,若要在一个进程内充分使用所有的core,
<mark>
**线程数至少应该>=机器core数量C**
</mark>
,但具体线程数N/机器core数量C = ?需要您根据您的代码中网络、IO、内存和计算所占用的比例来决定,一般用户可以通过设置不同的线程数来测试CPU占用率来不断调整。
## 2.3 模型预测时间长短T
当您使用CPU进行预测时,预测阶段的计算是使用CPU完成的,此时,请参考前两者来进行设置线程数。
当您使用GPU进行预测时,情况有些不同,此时预测阶段的计算是由GPU完成的,此时CPU资源是空闲的,而预测操作是阻塞该线程的,类似于Sleep操作,此时若您的线程数==机器core数量,将没有其他可切换的线程从而导致必然有部分core是空闲的状态。具体来说,当模型预测时间较短时(<10ms),Server端线程数不宜过多(线程数=1~10倍core数量),否则线程切换带来的开销不可忽视。当模型预测时间较长时,Server端线程数应稍大一些(线程数=4~200倍core数量)。
# 3.异步模式
当
<mark>
**大部分用户的Request请求batch数<<模型最大支持的Batch数**
</mark>
时,采用异步模式的收益是明显的。
异步模型的原理是将模型预测阶段与RPC线程脱离,模型单独开辟一个线程数可指定的线程池,RPC收到Request后将请求数据放入模型的线程池中的Task队列中,线程池中的线程从Task中取出数据合并Batch后进行预测,从而提升QPS,更多详细的介绍见
[
C++Serving功能简介
](
Introduction_CN.md
)
,同步模式与异步模式的数据对比见
[
C++ Serving vs TensorFlow Serving 性能对比
](
Benchmark_CN.md
)
,在上述测试的条件下,异步模型比同步模式快百分50%。
异步模式的开启有以下两种方式。
## 3.1 Python命令辅助启动C++Server
`python3 -m paddle_serving_server.serve`
通过添加
`--runtime_thread_num 2`
指定该模型开启异步模式,其中2表示的是该模型异步线程池中的线程数为2,该数值默认值为0,此时表示不使用异步模式。
`--runtime_thread_num`
的具体数值设置根据模型、数据和显卡的可用显存来设置。
通过添加
`--batch_infer_size 32`
来设置模型最大允许Batch == 32 的输入,此参数只有在异步模型开启的状态下,才有效。
## 3.2 命令行+配置文件启动C++Server
此时通过修改
`model_toolkit.prototxt`
中的
`runtime_thread_num`
字段和
`batch_infer_size`
字段同样能达到上述效果。
# 4.多模型组合
当
<mark>
**您的业务中需要调用多个模型进行预测**
</mark>
时,如果您追求极致的性能,您可以考虑使用C++Serving
[
自定义OP
](
OP_CN.md
)
和
[
自定义DAG图
](
DAG_CN.md
)
的方式来实现上述需求。
## 4.1 优点
由于在一个服务中做模型的组合,节省了网络IO的时间和序列化反序列化的时间,尤其当数据量比较大时,收益十分明显(实测单次传输40MB数据时,RPC耗时为160-170ms)。
## 4.2 缺点
1) 需要使用C++去自定义OP和自定义DAG图去定义模型之间的组合关系。
2) 若多个模型之间需要前后处理,您也需要使用C++在OP之间去编写这部分代码。
3) 需要重新编译Server端代码。
## 4.3 示例
请参考
[
examples/C++/PaddleOCR/ocr/README_CN.md
](
../../examples/C++/PaddleOCR/ocr/README_CN.md
)
中
`C++ OCR Service服务章节`
和
[
Paddle Serving中的集成预测
](
Model_Ensemble_CN.md
)
中的例子。
examples/C++/PaddleDetection/ttfnet_darknet53_1x_coco/test_client.py
浏览文件 @
d37a7279
...
...
@@ -19,9 +19,9 @@ import cv2
preprocess
=
DetectionSequential
([
DetectionFile2Image
(),
DetectionResize
(
(
512
,
512
),
False
,
interpolation
=
cv2
.
INTER_LINEAR
),
DetectionNormalize
(
[
123.675
,
116.28
,
103.53
],
[
58.395
,
57.12
,
57.375
],
False
)
,
DetectionTranspose
((
2
,
0
,
1
))
(
512
,
512
),
False
,
interpolation
=
cv2
.
INTER_LINEAR
),
DetectionNormalize
([
123.675
,
116.28
,
103.53
],
[
58.395
,
57.12
,
57.375
]
,
False
),
DetectionTranspose
((
2
,
0
,
1
))
])
postprocess
=
RCNNPostprocess
(
"label_list.txt"
,
"output"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录