性能报告
本文主要列举torchpipe
的基础性能测试实验。triton inference server
是我们的主要参照物,然而我们的目的并非与其进行性能竞赛。 框架与框架之间的性能差异有时候很难进行直接的对比, 部分实验中我们采取了合理的非公平对比,用来帮助使用者理解两种框架的特点。
需要 服务性能的关键评价指标 章节作为铺垫。
测试机器情况参见尾注*.
本地函数 vs RPC
调用
torchpipe
以线程安全的本地调用为主要使用方式,并绑定pytorch
前端接口。这是他的一大特色。当与 triton
这些与RPC
强耦合*的框架进行性能对比时并不容易。为此,我们准备采取合理的不公平对比。虽然如此,我们尽可能合理地优化了测试流程,如将所有数据准备都在初始化时提前完成并重复利用。
在实验中我们发现,包含序列化/反序列化的大数据量的RPC调用中,triton和thrift有一定的性能差距。这使得我们很难直接对调度和计算部分进行对比。为此,我们采取对照的方式,首先测定纯粹RPC服务的性能作为对比基数。
当纯RPC服务的吞吐比纯粹计算后端服务的吞吐高一个量级的时候,可以认为RPC对于整个的服务的影响不大;否则,RPC部分可能产生显著的影响。
- 强耦合*:
triton
提供了C语言本地接口,然而并非面向用户的推荐方式。
Hello, World!
我们发送一条HelloWorld
讯息并寻求返回相同字符串。
经过测试,我们发现triton对于TYPE_STRING类型的处理并不友好,相同的数据,以TYPE_STRING格式发送以及以TYPE_UINT8格式发送,速度差异较为明显,所以以下实验,我们发送‘HelloWorld’的时候,均采用了triton推荐的UINT8类型进行发送,即将其转换为ASCII码对应的UINT8类型。
空载性能
这部分只作为速度的参照背景使用。 这部分的性能差距在实际业务中(计算密集型后端)影响并不大。
thrift采用了多线程模式, 以python
为客户端/服务端语言。
客户端1/计算后端实例1/超时时间0/max_batch1
python后端 | c++后端 | |
---|---|---|
torchpipie | QPS: 65227 | QPS: 70671 |
torchpipie+thrift | QPS: 10020 | QPS: 10444 |
thrift | QPS: 14890 | - |
triton-cli | QPS: 7342 | - |
相对于rpc框架本身数十万以上的并发要求, torchpipe
和 triton
本身的qps并不高。视觉领域的服务是计算密集型的,通常并不能算一种高并发
服务,实际单卡QPS一般在100-2000之间;以上实测空载性能上限满足要求。
多客户端加压
这部分只作为速度的参照背景使用。 这部分的性能差距在实际业务中(计算密集型后端)影响并不大。
客户端加压的情况下,差距缓解。
客户端10/计算后端实例1/超时时间0/max_batch1
python后端 | c++后端 | |
---|---|---|
torchpipie | QPS: 46655 | QPS: 55949 |
torchpipie-thrift | QPS: 13221 | QPS: 14977 |
thrift | QPS: 17262 | - |
triton-cli | QPS: 15039 | - |
凑batch过程自适应客户端数目
当流量不足以覆盖max_batch时,系统在等待凑batch的过程中,将以超时为代价。此节测试了这种情况下自适应客户端的情况。
本节使用torchpipie 和 triton 的python后端。
计算后端实例1/超时时间10ms/max_batch4
客户端数目 | torchpipe | triton |
---|---|---|
1 | TP50: 0.25 | TP50: 10.5 |
2 | TP50: 10.25 | TP50: 10.57 |
4 | TP50: 0.34 | TP50: 0.5 |
10 | TP50: 0.82 | TP50: 0.97 |
实验验证了torchpipie采取的保守的自适应策略,能在一定情况下,减少白白等待凑batch的时间。
max_batch=1时的凑batch效率
测试最大batchsize为1时的系统效率。理论上此时应该忽略掉凑batch过程。
本节使用torchpipie 和 triton 的python后端。
计算后端实例1/超时时间10ms/max_batch1
客户端数目 | torchpipie | triton |
---|---|---|
1 | TP50: 0.09 | TP50: 0.23 |
10 | TP50: 0.64 | TP50: 1.26 |
小结
python后端(cpu)并发性能
torchpipe
原生支持多线程模式,然而由于GIL锁的影响,此种模式对于python计算后端注定有比较大的缺陷;
类型 | 模式 | 备注 |
---|---|---|
GPU后端 | 多线程 | 多进程下需要虚拟化,存在共享显存传递的问题 |
不涉及GIL锁的CPU后端 | 可多线程 | - |
涉及GIL锁的CPU后端 | 多进程/RPC | 在python后端中使用multiprocessing/Joblib 库,或者桥接第三方RPC框架 |
以下表格验证了多进程模式处理GIL锁的有效性(后端进行了python的1-100000的累加操作):
客户端10/计算后端实例10/超时时间0/max_batch1
torchpipie(python后端) | triton | torchpipie-multiprocess |
---|---|---|
QPS: 233 | QPS: 814 | QPS: 872 |
纯cpu后端效率对比
本节测试jpg解码性能。输入数据为未解码的原始jpg图片,输出为大小为640x444x3的uint8的tensor.
在本节实验中,我们显式排除RPC框架本身带来的性能差距:客户端发送给我们Hello, world!
这一数据,我们在服务端自己准备jpg数据,调用
- python后端
- c++后端
cv2.imdecode(raw_jpg, cv2.IMREAD_COLOR)
cv::Mat imdecode(cv::InputArray buf, int flags)
解码,然后返回Hello, world!
到客户端。
客户端1/计算后端实例1/超时时间0/max_batch1
torchpipie-thrift(c++后端) | torchpipie-thrift(python后端) | torchpipie-thrift-multiprocess | triton-cli |
---|---|---|---|
QPS: 426 | QPS: 406 | QPS: - | QPS: 339 |
客户端10/计算后端实例10/超时时间0/max_batch1
torchpipie-thrift(c++后端) | torchpipie-thrift(python后端) | torchpipie-thrift-multiprocess | triton-cli |
---|---|---|---|
QPS: 1599 | QPS: 1334 | QPS: - | 1440 |
实验结果与预期相符:各种方式下的效率相近。最终,在十客户端下,
torchpipie-thrift(c++后端)
> triton-cli
> torchpipie-thrift(python后端)
.
resnet50
本节测试通常情况下,使用tensorrt处理resnet50模型的效率。 客户端输入为224x224x3的图片数据,输出为1x1000。 作为对照,我们补充了纯粹RPC效率的对比:此时服务端预先准备好数据,而不做任何计算。
基础测试
客户端1/计算后端实例1/超时时间0/max_batch1
torchpipie-thrift-rpc | triton-rpc | torchpipie-thrift | triton-cli | 备注 |
---|---|---|---|---|
QPS: 7519 | QPS: 1819 | QPS: 381 | QPS: 358 |
客户端10/计算后端实例10/超时时间0/max_batch1
torchpipie-thrift-rpc | triton-rpc | torchpipie-thrift | triton-cli | 备注 |
---|---|---|---|---|
QPS: 11938 | QPS: 3355 | QPS: 720 | QPS: 722 |
凑batch
客户端10/计算后端实例2/超时时间5/max_batch4
torchpipie-thrift | triton-cli | 备注 |
---|---|---|
QPS: 907 | QPS: 898 | - |
实际使用测试
实际使用中,triton经常需要以RPC调用服务端的方式串联多个节点/模型,而torchpipe的使用方式是本地调用,我们来看看两种方式下的性能对比情况。
基础测试
在如下的测试中,triton和torchpipe均只含有一个resnet18模型,模型均采用FP32的tensorrt加速,输入数据为shape:3x224x224的数据。
客户端1/计算后端实例1/超时时间0/max_batch1
torchpipie | triton-rpc | 备注 |
---|---|---|
QPS: 559 | QPS: 462 |
客户端10/计算后端实例1/超时时间0/max_batch1
torchpipie | triton-rpc | 备注 |
---|---|---|
QPS: 1303 | QPS: 907 |
与预期一致,torchpipe的本地调用方式在单卡情况下有一定的优势。