故障排除性能问题

目录

以下是评估性能问题时需要检查的事项列表

  • 您是否启用了所有图优化?官方发布的软件包默认会启用所有优化,但从源代码构建时,请检查您的构建中是否已启用这些优化。
  • 您是否搜索过以前提交的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 维张量的两种不同的内存布局。

CNN 使用的大多数 TensorFlow 操作都支持 NHWC 和 NCHW 数据格式。TensorFlow 团队建议 NCHW 在 GPU 上更快,但在 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