Skip to content

Latest commit

 

History

History
170 lines (113 loc) · 10.7 KB

Asynchronous_Framwork_CN.md

File metadata and controls

170 lines (113 loc) · 10.7 KB

C++ Serving 异步模式

设计方案

一.同步网络线程

Paddle Serving 的网络框架层面是同步处理模式,即 bRPC 网络处理线程从系统内核拿到完整请求数据后( epoll 模式),在同一线程内完成业务处理,C++ Serving 默认使用同步模式。同步模式比较简单直接,适用于模型预测时间短,或单个 Request 请求批量较大的情况。

Server 端线程数 N = 模型预测引擎数 N = 同时处理 Request 请求数 N,超发的 Request 请求需要等待当前线程处理结束后才能得到响应和处理。

二.异步调度线程

为了提高计算芯片吞吐和计算资源利用率,C++ Serving 在调度层实现异步多线程并发合并请求,实现动态批量推理。异步模型主要适用于模型支持批量,单个 Request 请求的无批量或较小,单次预测时间较长的情况。

异步模式下,Server 端 N 个线程只负责接收 Request 请求,实际调用预测引擎是在异步框架的线程池中,异步框架的线程数可以由配置选项来指定。为了方便理解,我们假设每个 Request 请求批量均为1,此时异步框架会尽可能多得从请求池中取 n(n≤M)个 Request 并将其拼装为1个 Request(batch=n),调用1次预测引擎,得到1个 Response(batch = n),再将其对应拆分为 n 个 Response 作为返回结果。

三.动态批量

通常,异步框架合并多个请求的前提是所有请求的 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 不能直接合并。

从经验来看,当2个请求的同一个变量 shape 维度的数量相等时,通过 padding 补0的方式按最大 shape 值对齐即可。即 C 请求的 shape 补齐到 [1, 3, 960, 960],那么就可以与 A 和 B 请求合并了。Paddle Serving 框架实现了动态 Padding 功能补齐 shape。

当多个将要合并的请求中有一个 shape 值很大时,所有请求的 shape 都要按最大补齐,导致计算量成倍增长。Paddle Serving 设计了一套合并策略,满足任何一个条件均可合并:

  • 条件 1:绝对值差的字节数小于 1024 字节,评估补齐绝对长度
  • 条件 2:相似度的乘积大于 50%,评估相似度,评估补齐绝对值整体数据量比例

场景1:Shape-1 = [batch, 500, 500], Shape-2 = [batch, 400, 400]。此时,绝对值差 = 500*500 - 400*400 = 90000 字节,相对误差= (400/500) * (400/500) = 0.8*0.8 = 0.64,满足条件1,不满足条件2,触发动态 Padding。

场景2:Shape-1 = [batch, 1, 1], Shape-2 = [batch, 2, 2]。此时,绝对值差 = 2*2 - 1*1 = 3字节,相对误差 = (1/2) * (1/2) = 0.5*0.5 = 0.25,满足条件2,不满足条件1,触发动态 Padding。

场景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。

使用案例

一.开启同步模式

启动命令不使用 --runtime_thread_num--batch_infer_size 时,属于同步处理模式,未开启异步模式。--thread 16 表示启动16个同步网络处理线程。

python3 -m paddle_serving_server.serve --model uci_housing_model --thread 16 --port 9292 

二.开启异步模式

启动命令使用 --runtime_thread_num 2--batch_infer_size 32 开启异步模式,Serving 框架会启动2个异步线程,单次合并最大批量为32,自动开启动态 Padding。

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

性能测试

  • GPU:Tesla P4 7611 MiB
  • CUDA:cuda11.2-cudnn8-trt8
  • Python 版本:python3.7
  • 模型:ResNet_v2_50
  • 测试数据:构造全1输入,单client请求100次,shape 范围(1, 224 ± 50, 224 ± 50)

同步模式启动命令:

python3 -m paddle_serving_server.serve --model resnet_v2_50_imagenet_model --port 9393 --thread 8 --ir_optim --gpu_multi_stream --gpu_ids 1 --enable_prometheus --prometheus_port 1939

异步模式启动命令:

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

一.测试结果

使用异步模式,并开启动态批量后,并发测试不同 shape 数据时,吞吐性能大幅提升。

由于动态批量导致响应时长增长,经过测试,大多数场景下吞吐增量高于响应时长增长,尤其在高并发场景(client=70时),在响应时长增长 33% 情况下,吞吐增加 105%。

Client 1 5 10 20 30 40 50 70
QPS -2.08% -7.23% -1.89% 20.55% 23.02% 23.34% 46.41% 105.27%
响应时长 2.70% 7.09% 5.24% 13.34% 10.80% 43.60% 8.72% 33.89%

异步模式可有效提升服务吞吐性能。

二.测试数据

  1. 同步模式
client_num batch_size CPU_util_pre(%) 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) infer_count_total infer_cost_total(ms) infer_cost_avg(ms)
1 1 1.30 18.90 2066 71.56 22.938 100 43.594 23.516 78.118 78.323 133.544 4.4262 4.3596 7100.0000 1666392.70 41.1081
5 1 2.00 28.20 3668 92.57 33.630 500 148.673 39.531 373.231 396.306 419.088 15.0606 14.8676 7600.0000 1739372.7480 145.9601
10 1 1.90 29.80 4202 91.98 34.303 1000 291.512 76.728 613.963 632.736 1217.863 29.8004 29.1516 8600.0000 1974147.7420 234.7750
20 1 4.70 49.60 4736 92.63 34.359 2000 582.089 154.952 1239.115 1813.371 1858.128 59.7303 58.2093 12100.0000 2798459.6330 235.6248
30 1 5.70 65.70 4736 92.60 34.162 3000 878.164 231.121 2391.687 2442.744 2499.963 89.6546 87.8168 17600.0000 4100408.9560 236.6877
40 1 5.40 74.40 5270 92.44 34.090 4000 1173.373 306.244 3037.038 3070.198 3134.894 119.4162 117.3377 21600.0000 5048139.2170 236.9326
50 1 1.40 64.70 5270 92.37 34.031 5000 1469.250 384.327 3676.812 3784.330 4366.862 149.7041 146.9254 26600.0000 6236269.4230 237.6260
70 1 3.70 79.70 5270 91.89 33.976 7000 2060.246 533.439 5429.255 5552.704 5661.492 210.1008 206.0250 33600.0000 7905005.9940 238.3909
  1. 异步模式 - 未开启动态批量
client_num batch_size CPU_util_pre(%) 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) infer_count_total infer_cost_total(ms) infer_cost_avg(ms)
1 1 6.20 13.60 5170 71.11 22.894 100 43.677 23.992 78.285 78.788 123.542 4.4253 4.3679 3695.0000 745061.9120 40.6655
5 1 6.10 32.20 7306 89.54 33.532 500 149.109 43.906 376.889 401.999 422.753 15.1623 14.9113 4184.0000 816834.2250 146.7736
10 1 4.90 43.60 7306 91.55 38.136 1000 262.216 75.393 575.788 632.016 1247.775 27.1019 26.2220 5107.0000 1026490.3950 227.1464
20 1 5.70 39.60 7306 91.36 58.601 2000 341.287 145.774 646.824 994.748 1132.979 38.3915 34.1291 7461.0000 1555234.6260 229.9113
30 1 1.30 45.40 7484 91.10 69.008 3000 434.728 204.347 959.184 1092.181 1661.289 46.3822 43.4732 10289.0000 2269499.9730 249.4257
40 1 3.10 73.00 7562 91.83 80.956 4000 494.091 272.889 966.072 1310.011 1851.887 52.0609 49.4095 12102.0000 2678878.2010 225.8016
50 1 0.80 68.00 7522 91.10 83.018 5000 602.276 364.064 1058.261 1473.051 1671.025 72.9869 60.2280 14225.0000 3256628.2820 272.1385
70 1 6.10 78.40 7584 92.02 65.069 7000 1075.777 474.014 2411.296 2705.863 3409.085 111.6653 107.5781 17974.0000 4139377.4050 235.4626
  1. 异步模式 - 开启动态批量
client_num batch_size CPU_util_pre(%) 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) infer_count_total infer_cost_total(ms) infer_cost_avg(ms)
1 1 1.20 13.30 6048 70.07 22.417 100 44.606 24.486 78.365 78.707 139.349 4.5201 4.4608 1569.0000 462418.6390 41.7646
5 1 1.20 50.80 7116 87.37 31.106 500 160.740 42.506 414.903 458.841 481.112 16.3525 16.0743 2059.0000 539439.3300 157.1851
10 1 0.80 26.20 7264 88.74 37.417 1000 267.254 79.452 604.451 686.477 1345.528 27.9848 26.7258 2950.0000 752428.0570 239.0446
20 1 1.50 32.80 7264 89.52 70.641 2000 283.117 133.441 516.066 652.089 1274.957 33.0280 28.3121 4805.0000 1210814.5610 260.5873
30 1 0.90 59.10 7348 89.57 84.894 3000 353.380 217.385 613.587 757.829 1277.283 40.7093 35.3384 6924.0000 1817515.1710 276.3695
40 1 1.30 57.30 7356 89.30 99.853 4000 400.584 204.425 666.015 1031.186 1380.650 49.4807 40.0588 8104.0000 2200137.0060 324.2558
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