1、安装,建议使用tar的形式,避免遇到一些依赖库找不到的问题。
2、Python图片预处理多进程不及多线程。
多进程CPU占用低,主要是预处理的时间过少,Python 进程分发任务开销对于我们的ms级应用不可忽视。
对比为batch=8,进程、线程为8,时间均为8张时间,循环1000次测试。
多线程,平均为8.5ms(每千次次变动7.5-9.5S,近乎100%占用);
多进程,平均为19ms(15-21ms);
无, 平均为40ms(每次变动范围30-55ms,20%-40%占用)。
3、预处理导致tensor RT和pytorch结果不一致问题:
1)输入图像数据错误。
tensor RT和pytorch均使用PIL库读取图像数据。
PIL是RGB格式HWC通道 0-255 int8类型,pytorch是RGB格式CHW通道 0-1浮点型,tensorRT为RGB格式CHW通道0-1浮点型。
Pytorch 通过torchvision.transforms.ToTensor方法将PIL从RGB格式HWC通道 0-255 int8类型转到RGB格式CHW通道 0-1浮点型。
tensorRT也需要这步操作,使用numpy在CPU上实现。
2)pytorch resize默认为BILINEAR,tensorRT官方例子使用ANTIALIAS。
3)鉴黄将归一化操作(去均值除方差)放在网络模型中在GPU上操作,TRT转换过程中pytorch到onnx这一步骤不支持原址运算。
TRT官方的例子这一步是通过使用numpy在cpu上实现。暂时也通过numpy在CPU上实现。也可以修改网络,不原址计算来实现在GPU上加速。
4、pytorch -> onnx ->TRT 失败(Pytorch - tensor RT自定义层处理),怎么办。
这种情况要么ONNX转换失败,要么ONNX可视化后会比较杂乱,一堆基础OP操作,可能某个OP失败,这种情况大多是使用的“自定义层”。
1)修改原始网络,替换TRT不支持的操作;
2)TRT支持,转换失败,使用TRT的OP搭建网络;
3)这个操作可拆解为TRT的几个OP;
4)使用TRT的plugin功能自己使用C++实现。
其中需要注意:
1)对于pytorch模型在提取网络中某个层的参数时,切记将对应的code放在 model.eval()后面。
因为如果某层包含自己的init函数,那么如果在eval方法前提取参数,很有可能此时的参数是随机数而不是训练完成的模型对应的参数。
2)、提取使用的方法:
使用print(net)打印对应模型的网络结构,使用
for i in net.state_dict():
print(i)
打印所有权重,找到对应的权重的键名,使用model.state_dict()[“键名"].cpu().data.numpy()获取对应键值。
其中net和键名有对应关系,一般以“.”为分割符。
3)修改网络返回值位置,使其短路输出可以parser的主干网络。
5、TRT5 建立engine时,batch size是其中一项超参数。
要求inference 时的batch size小于建立engine 时的batch size,两者相等时性能最优。
之前是仿照英伟达人员提供的例子使用numpy的copyto方法将image 数据传给TRT的host input参数,numpy要求前后矩阵大小一致,不适用该情况,仿照int8的例子,直接使用等号进行传递,会自动复制对应大小:TRT.h_input = imgs_np。
6、解决官方使用with管理context,线上无法释放资源问题。
主要理解Python with分别调用类的__enter__和__exit__方法来初始化和释放资源,手动调用这些方法即可。
with 的理解可以参考:python __enter__ 与 __exit__的作用,以及与 with 语句的关系 - 李皮筋 - 博客园
紧跟with后面的语句被求值后,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as后面的变量。当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。
with open("/tmp /foo.txt") as file:
data = file.read()
7、pytorch reshape 层报错
现在主要由Pytorch将自有框架中相关操作换成flatten。需要注意:
如果reshape后是二维[B, C x H x W],则使用flatten(1);
如果reshape后是三维[B, C, H x W],则使用flatten(2);
8、保证环境干净。
Python版的TRT在35上测试CPU占用3000%,而线上docker环境监控平台显示占用正常(1-4core);
Python版暴恐旗帜docker(mm detection)线上QPS远低于云主机;
总结:docker要干净,Python 各个依赖的版本要对应。
9、tensor是绑定硬件和软件,建议每次启动docker重新建立,设计好多实例情况下的tensor rt 建立engine的逻辑。
10、 关于半精度(fp16)和int8。
半精度几乎是不损失精度的,也不需要矫正数据去建立engine,但是需要特定的硬件支持-tensor core,因此:P40不支持半精度推理;v100和T4均支持半精度。
int 8 需要矫正数据来维持量化后精度,不需要特定硬件支持,P40和V100均支持int8。
11、截止20191212优选的资料:
1)官方资料:NVIDIA Documentation Center | NVIDIA Developer
2)综述资料:高性能深度学习支持引擎实战——TensorRT - 知乎
3)示例代码:如何使用TensorRT对训练好的PyTorch模型进行加速? - 知乎