ONNX 实时graph优化方法

ONNX实时提供了各种图形优化来提高模型性能。图优化本质上是图级别的转换,从小型图简化和节点消除,到更复杂的节点融合和布局优化。

图形优化根据其复杂性和功能分为几个类别(或级别)。可以在线或离线执行。在联机模式下,优化在执行推断之前完成,而在脱机模式下,实时将优化的图形保存到磁盘。ONNX实时提供Python、C++、C++和C API,启用不同的优化级别,并在脱机与在线模式之间进行选择。

下面将详细介绍优化级别、在线/离线模式以及控制它们的各种API。

图优化级别Graph Optimization Levels

图形优化分为三个级别:

•基本

•扩展

•布局优化

属于一个级别的优化,在应用前一级别的优化之后执行(例如,在应用基本优化之后,应用扩展优化)。

默认情况下启用所有优化。

Basic图优化 Basic Graph Optimizations

  • 这些都是保留语义的图重写,去除了冗余节点和冗余计算。在图形分区之前运行,适用于所有执行提供程序。可用的基本图形优化如下:

•常量折叠:静态计算仅依赖常量初始值设定项的图形部分。这样就不需要在实时计算它们。

•冗余节点消除:在不改变图形结构的情况下删除所有冗余节点。目前支持以下此类优化:

• Identity Elimination

• Slice Elimination

• Unsqueeze Elimination

• Dropout Elimination

• Semantics-preserving node fusions

•语义保留节点融合:将多个节点融合/折叠为单个节点。例如,Conv Add fusion将Add操作符,折叠为Conv操作符的偏移。目前支持以下此类优化::

  • Conv Add Fusion
  • Conv Mul Fusion
  • Conv BatchNorm Fusion
  • Relu Clip Fusion
  • Reshape Fusion

Extended图优化 Extended Graph Optimizations

这些优化包括复杂的节点融合。它们在图形分区之后运行,并且仅应用于分配给CPU或CUDA执行提供程序的节点。可用的扩展图优化如下所示:

Optimization

Execution Provider

Comment

GEMM Activation Fusion

cpu

 

Matmul Add Fusion

cpu

 

Conv Activation Fusion

cpu

 

GELU Fusion

cpu or cuda

 

Layer Normalization Fusion

cpu or cuda

 

BERT Embedding Layer Fusion

cpu or cuda

Fuse BERT embedding layer, layer normalization and attention mask length

Attention Fusion

cpu or cuda

Attention mask has approximation in cuda execution provider

Skip Layer Normalization Fusion

cpu or cuda

Fuse bias of fully connected layer, skip connection and layer normalization

Bias GELU Fusion

cpu or cuda

Fuse bias of fully connected layer and GELU activation

GELU Approximation

cuda

Erf is approximated by a formula using tanh function

为了优化BERT模型的推理性能,GELU逼近和cuda执行支持provider,注意融合中使用了近似。结果可能略有不同。根据评估,对准确度的影响可以忽略不计:F1 score for a BERT model on SQuAD v1.1 is almost same (87.05 vs 87.03)。

Layout优化 Layout Optimizations

这些优化更改了适用节点的数据布局,以实现更高的性能改进。在图形分区之后运行,并且仅应用于分配给CPU执行提供程序的节点。可用的布局优化如下:

  • NCHWc Optimizer: Optimizes the graph by using NCHWc layout instead of NCHW layout.

在线/离线模式选择 Online/Offline Mode

所有优化都可以在线或离线执行。在联机模式下,在初始化推理会话时,还将在执行模型推理之前,应用所有启用的图优化。每次启动会话时,应用所有优化,都会增加模型启动时间的开销(特别是对于复杂模型),这在输出场景中非常关键。这就是离线模式可以带来很多好处的地方。在脱机模式下,在执行图形优化之后,ONNX实时将生成的模型序列化到磁盘。随后,当为该模型创建新的推理会话时,可以使用已经优化的模型,来减少启动时间。

注意:

•在脱机模式下运行时,确保使用与模型推理,将在其上运行的目标计算机,完全相同的选项(例如,执行提供程序、优化级别)和硬件(例如,不能在仅配备CPU的计算机上,运行为GPU执行提供程序预优化的模型)。

•启用布局优化时,脱机模式只能在保存脱机模型时在与环境兼容的硬件上使用。例如,如果模型为AVX2优化了布局,那么离线模型将需要支持AVX2的cpu。

使用说明 Usage

通用方法说明 General Note

Levels:

ONNX运行时定义GraphOptimizationLevel枚举,以确定将启用上述哪些优化级别。选择一个级别可以实现该级别的优化,也可以实现前面所有级别的优化。例如,启用扩展优化,也会启用基本优化。这些级别到枚举的映射如下:

  • GraphOptimizationLevel::ORT_DISABLE_ALL ->
    Disables all optimizations
  • GraphOptimizationLevel::ORT_ENABLE_BASIC -> Enables
    basic optimizations
  • GraphOptimizationLevel::ORT_ENABLE_EXTENDED
    -> Enables basic and extended optimizations
  • GraphOptimizationLevel::ORT_ENABLE_ALL ->
    Enables all available optimizations including layout optimizations

Online/Offline Mode:

要将优化模型序列化到磁盘,请将SessionOptions选项optimized_model_path设置为存储优化模型的所需路径。

Python API Usage

import onnxruntime as rt
 
sess_options = rt.SessionOptions()
 
# Set graph optimization level
sess_options.graph_optimization_level = rt.GraphOptimizationLevel.ORT_ENABLE_EXTENDED
 
# To enable model serialization after graph optimization set this
sess_options.optimized_model_filepath = "<model_output_path\optimized_model.onnx>"
 
session = rt.InferenceSession("<model_path>", sess_options)

C API Example:

  const OrtApi* Ort::g_api = OrtGetApi(ORT_API_VERSION);
  OrtEnv* env;
  g_ort->CreateEnv(ORT_LOGGING_LEVEL_WARNING, "test", &env);
  OrtSessionOptions* session_options;
  g_ort->CreateSessionOptions(&session_options)
 
  // Set graph optimization level
  g_ort->SetSessionGraphOptimizationLevel(session_options, ORT_ENABLE_EXTENDED);
 
  // To enable model serialization after graph optimization set this
  const wchar_t* optimized_model_path = L"optimized_model_path";
  g_ort->SetOptimizedModelFilePath(session_options, optimized_model_path);
 
  OrtSession* session;
  const wchar_t* model_path = L"model_path";
  g_ort->CreateSession(env, model_path, session_option, &session);

C# API Example:

SessionOptions so = new SessionOptions();
// Set graph optimization level
so.GraphOptimizationLevel = GraphOptimizationLevel.ORT_ENABLE_EXTENDED;
// To enable model serialization after graph optimization set this
so.OptimizedModelFilePath = "model_output_path\optimized_model.onnx"
 
var session = new InferenceSession(modelPath, so);

C++ API Example:

Ort::SessionOptions session_options;
// Set graph optimization level
session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
// To enable model serialization after graph optimization set this
session_options.SetOptimizedModelFilePath("optimized_file_path");
auto session_ = Ort::Session(env, "model_file_path", session_options);

ONNX 实时graph优化方法的更多相关文章

  1. redmine在linux上的mysql性能优化方法与问题排查方案

    iredmine的linux服务器mysql性能优化方法与问题排查方案     问题定位:   客户端工具: 1. 浏览器inspect-tool的network timing工具分析   2. 浏览 ...

  2. 基于TensorRT车辆实时推理优化

    基于TensorRT车辆实时推理优化 Optimizing NVIDIA TensorRT Conversion for Real-time Inference on Autonomous Vehic ...

  3. GPU优化方法[转]

    CUDA优化的最终目的是:在最短的时间内,在允许的误差范围内完成给定的计算任务.在这里,“最短的时间”是指整个程序运行的时间,更侧重于计算的吞吐量,而不是单个数据的延迟.在开始考虑使用GPU和CPU协 ...

  4. HBase性能优化方法总结(转)

    本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,这里涉及的不多,这部分可以参考:淘宝Ken Wu同学的博客. 1. 表的设计 1.1 Pr ...

  5. 性能优化之永恒之道(实时sql优化vs业务字段冗余vs离线计算)

    在项目中,随着时间的推移,数据量越来越大,程序的某些功能性能也可能会随之下降,那么此时我们不得不需要对之前的功能进行性能优化.如果优化方案不得当,或者说不优雅,那可能将对整个系统产生不可逆的严重影响. ...

  6. HBase性能优化方法总结(转)

    原文链接:HBase性能优化方法总结(一):表的设计 本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客. ...

  7. HBase性能优化方法总结(二):写表操作

    转自:http://www.cnblogs.com/panfeng412/archive/2012/03/08/hbase-performance-tuning-section2.html 本文主要是 ...

  8. HBase性能优化方法总结(三):读表操作

    本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客. 下面是本文总结的第三部分内容:读表操作相关的优化方法 ...

  9. Deep Learning基础--参数优化方法

    1. 深度学习流程简介 1)一次性设置(One time setup)          -激活函数(Activation functions) - 数据预处理(Data Preprocessing) ...

随机推荐

  1. hdu4585 STL水题

    题意:       成立少林寺,刚开始有一个大师,id是1,攻击力是10E,现在陆续来人,每个人有自己的id,和自己的攻击力,但是每一个新来的要和之前的和尚pk,他必须选择和他攻击力差值最小的那个,如 ...

  2. 【python】Leetcode每日一题-二叉搜索树节点最小距离

    [python]Leetcode每日一题-二叉搜索树节点最小距离 [题目描述] 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例1: 输入:root = [4 ...

  3. Eureka讲解与应用

    Eureka[juˈriːkə] 简介 Eureka是Netflix服务发现的服务端与客户端,Eureka提供服务注册以及服务发现的能力,当是Eureka Server时(注册中心),所有的客户端会向 ...

  4. gitlab + php自动部署

    功能简介 本地往服务器推送代码之后,触发web钩子,服务器拉取刚刚推送的代码 步骤 1.在gitlab后台配置钩子 项目->编辑项目->Web钩子->新增钩子 2.在服务器端为www ...

  5. 一句 Task.Result 就死锁, 这代码还怎么写?

    一:背景 1. 讲故事 前些天把 .NET 高级调试 方面的文章索引到 github 的过程中,发现了一个有意思的评论,详见 文章,截图如下: 大概就是说在 Winform 的主线程下执行 Task. ...

  6. Mybatis学习之自定义持久层框架(二) 自定义持久层框架设计思路

    前言 上一篇文章讲到了JDBC的基本用法及其问题所在,并提出了使用Mybatis的好处,那么今天这篇文章就来说一下该如何设计一个类似Mybatis这样的持久层框架(暂时只讲思路,具体的代码编写工作从下 ...

  7. 【Azure Redis 缓存】Azure Cache for Redis服务中,除开放端口6379,6380外,对13000,13001,15000,15001 为什么也是开放的呢?

    问题描述 在使用安全检测工具对Azure Redis服务端口进行扫描时,发现Redis对外开放了13001, 13000,15000,15001端口.非常不理解的是,在门户上只开放了6379,6380 ...

  8. Linux x86_64与i386区别之 —— 内存寻址

    毫无疑问,不管是32位,还是64位处理器,所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是 存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不 ...

  9. I/O流以及文件的基本操作

    文件操作: 文件操作其实就是一个FIle类:我们学习文件操作就是学习File类中的方法: 文件基操: 第一部分:学习文件的基本操作(先扒源码以及文档) Constructor Description ...

  10. Spring与Springboot

    1.Spring能做什么 1.1.Spring的能力 1.2.Spring的生态 https://spring.io/projects/spring-boot 覆盖了: web开发 数据访问 安全控制 ...