性能问题故障排除
目录
- 为什么即使 graph_optimization_level 设置为 ORT_ENABLE_ALL,模型图也没有优化?
- 为什么我的模型在 GPU 上运行比在 CPU 上慢?
- 我转换的 TensorFlow 模型很慢 - 为什么?
- 我看到高延迟差异。
- 我看到 Windows 上的 CPU 使用率很高
以下是评估性能问题时需要检查的事项列表
- 您是否启用了所有图优化?官方发布的软件包默认启用所有优化,但在从源代码构建时,请检查这些优化是否在您的构建中启用。
- 您是否搜索过之前提交的 GitHub 问题,看看您的问题是否之前讨论过?在提交新问题之前,请先执行此操作。
- 如果使用 CUDA 或 TensorRT,您是否安装了正确版本的依赖库? CUDA EP / TensorRT EP
为什么即使 graph_optimization_level 设置为 ORT_ENABLE_ALL,模型图也没有优化?
来自 IR_VERSION 4 的 ONNX 模型仅将出现在图形输入中的初始化器视为非常量。这可能会阻止一些图优化,例如常量折叠、运算符融合等。如果没有必要覆盖初始化器,请将初始化器移出图形输入,方法是使用最新的导出器/转换器重新生成模型,或使用工具 remove_initializer_from_input.py。
为什么我的模型在 GPU 上运行比在 CPU 上慢?
根据您使用的执行提供程序,它可能并不完全支持您模型中的所有运算符。回退到 CPU 运算可能会导致性能速度下降。此外,即使 CUDA 执行提供程序实现了某个运算,出于性能原因,它也可能不一定将该运算分配/放置到 CUDA EP。要查看 ORT 决定的放置位置,请打开详细日志记录并查看控制台输出。
我转换的 TensorFlow 模型很慢 - 为什么?
NCHW 和 NHWC 是 4-D 张量的两种不同内存布局。
CNN 使用的大多数 TensorFlow 操作都支持 NHWC 和 NCHW 数据格式。TensorFlow 团队建议,在 GPU 上,NCHW 更快,但在 CPU 上,NHWC 有时在 TensorFlow 中更快。但是,ONNX 仅支持 NCHW。因此,如果原始模型采用 NHWC 格式,则在转换模型时可能会添加额外的转置。 tensorflow-onnx 转换器确实删除了许多这些转置,但如果这没有充分帮助,请考虑以 NCHW 格式重新训练模型。
我看到高延迟差异。
在某些平台上,onnxruntime 在推理期间可能会表现出高延迟差异。这是由 onnxruntime 用于并行化线程池中任务的恒定成本模型引起的。对于每个任务,恒定成本模型将计算线程之间并行化的粒度,该粒度在任务执行结束之前保持不变。这种方法有时会导致负载不均衡,从而导致高延迟差异。为了缓解这种情况,onnxruntime 提供了一个动态成本模型,可以作为会话选项启用
sess_options.add_session_config_entry('session.dynamic_block_base', '4')
只要设置为正值,onnxruntime 线程池将以递减的粒度并行化内部任务。具体来说,假设线程池预期运行 N 次函数,启用动态成本模型后,池中的每个线程将声明
residual_of_N / (dynamic_block_base * num_of_threads)
只要它准备好运行。因此,在一段时间内,池中的线程可能更好地实现负载均衡,从而降低延迟差异。
由于相同的原因,动态成本模型也可能提高线程更容易被抢占的情况下的性能。根据我们的测试,到目前为止,dynamic_block_base 的最佳配置是 4,这在保持良好性能的同时降低了差异。
我看到 Windows 上的 CPU 使用率很高
据观察,对于拥有超过 64 个逻辑内核的机器,通过让线程池使用无锁任务队列(它利用自旋锁而不是互斥锁进行同步),可以显着降低 CPU 使用率。可以通过从源代码构建 onnxruntime 并使用以下标志来启用无锁任务队列
--use_lock_free_queue