故障排除性能问题
目录
- 为什么即使将 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 维张量的两种不同的内存布局。
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