文档的一些笔记:
性能调优小工具 ONNX GO Live Tool
这玩意儿有俩docker容器来实现支持,一个优化容器和一起模型转换容器。暂时具体不清楚原理,还没来得及看,后面试试。

什么执行单元(Execution Provider, EP)能够提供最好的性能表现
CPU版本的ONNX Runtime提供了完整的算子支持,因此只要编译过的模型基本都能成功运行。一个要注意的点是为了减少编译的二进制包能够足够小,算子只支持常见的数据类型,如果是一些非常见数据类型,请去提交PR。

CUDA版本的算子并不能完全支持,如果模型中有一部分不支持的算子,将会切换到CPU上去计算,这部分的数据切换是有比较大的性能影响。当然也可以contribute或者提交issue。

对于TRT和CUDA的区别,在同设备上TRT会比CUDA有着更好的性能表现,但是这个状况也局限于特定的模型以及算子是被TRT支持。

性能调优的一些建议

  • Shared arena based allocator

通过配置多个session中共享内存区域配置,可以减少内存消耗

  • 线程调控
  • 如果编译支持OpenMP,那么使用OpenMP的环境变量来控制预测线程数量。
  • 如果没有OpenMP支持,使用合适的ORT API来进行操控。
  • 当使用并行实行的时候inter op线程并不会受到OpenMP设置的影响,且总是应该使用ORT APIs来进行设置。
    默认CPU执行单元的相关设置(MLAS)
默认EP使用了很多旋钮来控制线程数量。举个例子:
import onnxruntime as rt

sess_options = rt.SessionOptions()

sess_options.intra_op_num_threads = 2
sess_options.execution_mode = rt.ExecutionMode.ORT_SEQUENTIAL
sess_options.graph_optimization_level = rt.GraphOptimizationLevel.ORT_ENABLE_ALL
  • Thread Count
  • ​sess_options.intra_op_num_threads = 2​​控制了运行模型时的线程数量。
  • Sequential vs Parallel Execution
  • ​sess_options.execution_mode = rt.ExecutionMode.ORT_SEQUENTIAL​​控制了计算图内部的算子是顺序计算还是并行计算,当一个模型含有多个分支的时候,设置为False会有比较大的性能提升。
  • 当​​sess_options.execution_mode = rt.ExecutionMode.ORT_PARALLEL​​时(即模型内计算图中的并行), 你可以设置 sess_options.inter_op_num_threads 来对并行计算的线程数量进行控制。这里注意是inter不是intra,和Thread Count里面的那个不一样。
  • ​sess_options.graph_optimization_level = rt.GraphOptimizationLevel.ORT_ENABLE_ALL​

图结构优化设置,分为三个​​level​​​,​​Basic​​​,​​Extend​​​和​​Layout Optimizations​​。默认所有的优化都是ENABLE。

MKL_DNN / nGraph执行单元

这俩玩意儿依赖openmp支持来实现并行化,对于这俩需要使用openmp的环境变量来进行性能调整。

  • OMP_NUM_THREADS=n
  • 控制线程池大小
  • OMP_WAIT_POLICY=PASSIVE / ACTIVE
  • 线程是否是thread spinning模式(线程调度的一种方式)。
  • PASSIVE 吞吐量模式,CPU只有在完成当前任务后被释放。当CPU使用率已经很高了,用这个模式。
  • ACTIVE 永远不会释放CPU,会以一个死循环的方式来检查下一个任务是否已经准备好。当你要低时延,用这个模式。