深度学习模型部署综述(ONNX/NCNN/OpenVINO/TensorRT)(上)

本文涉及的产品
交互式建模 PAI-DSW,每月250计算时 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
模型训练 PAI-DLC,100CU*H 3个月
简介: 今天自动驾驶之心很荣幸邀请到逻辑牛分享深度学习部署的入门介绍,带大家盘一盘ONNX、NCNN、OpenVINO等框架的使用场景、框架特点及代码示例。

费尽心血训练好的深度学习模型如何给别人展示?只在服务器上运行demo怎么吸引别人的目光?怎么才能让自己的成果落地?这篇文章带你进入模型部署的大门。


0 前言



模型部署的步骤:


  1. 训练一个深度学习模型;
  2. 使用不同的推理框架对模型进行推理转换;
  3. 在应用平台运行转换好的模型。


步骤看起来比较简单,但是牵扯的到的知识还是比较多。在实际应用过程中,我们使用的模型通常不会太简单,因为要确保模型的精度。但是,实际应用场景往往需要模型速度与精度能达到一个较好的平衡。因此这就需要在算法(剪枝,压缩等)与底层(手写加速算作)去优化模型。但是,我们现在可以站在巨人的肩膀上去眺望世界,因此,该文章会给大家介绍一些常用的开源推理框架,大家一起参考学习。毕竟大牛团队做出来的好用一些。。。


1 ONNX、NCNN、OpenVINO、 TensorRT、Mediapipe模型部署那家强?



1.1 ONNX


简介:


开放神经网络交换ONNX(Open Neural Network Exchange)是一套表示深度神经网络模型的开放格式,由微软和Facebook于2017推出,然后迅速得到了各大厂商和框架的支持。通过短短几年的发展,已经成为表示深度学习模型的实际标准,并且通过ONNX-ML,可以支持传统非神经网络机器学习模型,大有一统整个AI模型交换标准。ONNX定义了一组与环境和平台无关的标准格式,为AI模型的互操作性提供了基础,使AI模型可以在不同框架和环境下交互使用。硬件和软件厂商可以基于ONNX标准优化模型性能,让所有兼容ONNX标准的框架受益,简单来说,ONNX就是模型转换的中间人


使用场景:


640.png


无论你使用什么样的训练框架来训练模型(比如TensorFlow/Pytorch/OneFlow/Paddle),你都可以在训练后将这些框架的模型统一转为ONNX存储。ONNX文件不仅存储了神经网络模型的权重,还存储了模型的结构信息、网络中各层的输入输出等一些信息。目前,ONNX主要关注在模型预测方面(inferring),将转换后的ONNX模型,转换成我们需要使用不同框架部署的类型,可以很容易的部署在兼容ONNX的运行环境中。


使用方法:

[代码示例]在 ONNX 模型上运行形状推理:https://github.com/onnx/onnx

import onnx
from onnx import helper, shape_inference
from onnx import TensorProto
# 预处理:创建一个包含两个节点的模型,Y是未知的
node1 = helper.make_node("Transpose", ["X"], ["Y"], perm=[1, 0, 2])
node2 = helper.make_node("Trans
                         pose", ["Y"], ["Z"], perm=[1, 0, 2])
graph = helper.make_graph(
    [node1, node2],
    "two-transposes",
    [helper.make_tensor_value_info("X", TensorProto.FLOAT, (2, 3, 4))],
    [helper.make_tensor_value_info("Z", TensorProto.FLOAT, (2, 3, 4))],
)
original_model = helper.make_model(graph, producer_name="onnx-examples")
# 检查模型并打印Y的信息
onnx.checker.check_model(original_model)
print(f"Before shape inference, the shape info of Y is:\n{original_model.graph.value_info}")
# 在模型上进行推理
inferred_model = shape_inference.infer_shapes(original_model)
# 检查模型并打印Y的信息
onnx.checker.check_model(inferred_model)
print(f"After shape inference, the shape info of Y is:\n{inferred_model.graph.value_info}")


1.2 NCNN


简介:

ncnn 是一个为手机端极致优化的高性能神经网络前向计算框架,也是腾讯优图实验室成立以来的第一个开源项目。ncnn 从设计之初深刻考虑手机端的部署和使用,无第三方依赖,跨平台,手机端 CPU 的速度快于目前所有已知的开源框架。基于 ncnn,开发者能够将深度学习算法轻松移植到手机端高效执行,开发出人工智能 App。ncnn 目前已在腾讯多款应用中使用,如 QQ、Qzone、微信、天天P图等。


使用场景:

640.png


从NCNN的发展矩阵可以看出,NCNN覆盖了几乎所有常用的系统平台,尤其是在移动平台上的适用性更好,在Linux、Windows和Android、以及iOS、macOS平台上都可以使用GPU来部署模型。


框架特点:

  • 支持卷积神经网络,支持多输入和多分支结构,可计算部分分支
  • 无任何第三方库依赖,不依赖 BLAS/NNPACK 等计算框架
  • 纯 C++ 实现,跨平台,支持 Android / iOS 等
  • ARM Neon 汇编级良心优化,计算速度极快
  • 精细的内存管理和数据结构设计,内存占用极低
  • 支持多核并行计算加速,ARM big.LITTLE CPU 调度优化
  • 支持基于全新低消耗的 Vulkan API GPU 加速
  • 可扩展的模型设计,支持 8bit 量化和半精度浮点存储,可导入 caffe/pytorch/mxnet/onnx/darknet/keras/tensorflow(mlir) 模型
  • 支持直接内存零拷贝引用加载网络模型
  • 可注册自定义层实现并扩展


使用方法:

[代码示例]输入数据并推理输出:https://github.com/Tencent/ncnn/wiki

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "net.h"
int main()
{
 // opencv读取输入图片
    cv::Mat img = cv::imread("image.ppm", CV_LOAD_IMAGE_GRAYSCALE);
    int w = img.cols;
    int h = img.rows;
    // 减均值以及缩放操作,最后输入数据的值域为[-1,1]
    ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 60, 60);
    float mean[1] = { 128.f };
    float norm[1] = { 1/128.f };
    in.substract_mean_normalize(mean, norm);
 // 构建NCNN的net,并加载转换好的模型
    ncnn::Net net;
    net.load_param("model.param");
    net.load_model("model.bin");
 // 创建网络提取器,设置网络输入,线程数,light模式等等
    ncnn::Extractor ex = net.create_extractor();
    ex.set_light_mode(true);
    ex.set_num_threads(4);
    ex.input("data", in);
 // 调用extract接口,完成网络推理,获得输出结果
    ncnn::Mat feat;
    ex.extract("output", feat);
    return 0;


1.3 OpenVINO


简介:

OpenVINO是一种可以加快高性能计算机视觉和深度学习视觉应用开发速度的工具套件,支持各种英特尔平台的硬件加速器上进行深度学习,并且允许直接异构执行。OpenVINO™工具包是用于快速开发应用程序和解决方案的综合工具包,可解决各种任务,包括模拟人类视觉,自动语音识别,自然语言处理,推荐系统等。该工具包基于最新一代的人工神经网络,包括卷积神经网络(CNN),循环和基于注意力的网络,可在英特尔®硬件上扩展计算机视觉和非视觉工作负载,从而最大限度地提高性能。它通过从边缘到云的高性能,人工智能和深度学习推理来加速应用程序。


使用场景:

640.png


框架特点:


OpenVINO在模型部署前,首先会对模型进行优化,模型优化器会对模型的拓扑结构进行优化,去掉不需要的层,对相同的运算进行融合、合并以加快运算效率,减少内存拷贝;FP16、INT8量化也可以在保证精度损失很小的前提下减小模型体积,提高模型的性能。在部署方面,OpenVIVO的开发也是相对比较简单的,提供了C、C++和python3种语言编程接口。它最大的优势呢,其实还是在Intel的不同硬件平台上进行部署的时候,移植会很方便。推理引擎对不同的硬件提供统一的接口,底层实现直接调用硬件指令集的加速库,应用程序开发人员不需要关心底层的硬件实现,即可在不同的硬件平台上加速模型推理。

  • 在边缘启用基于CNN的深度学习推理
  • 支持通过英特尔®Movidius™VPU在英特尔®CPU,英特尔®集成显卡,英特尔®神经计算棒2和英特尔®视觉加速器设计之间进行异构执行
  • 通过易于使用的计算机视觉功能库和预先优化的内核加快上市时间
  • 包括对计算机视觉标准(包括OpenCV *和OpenCL™)的优化调用

使用方法:

[代码示例]在应用程序中实现典型的 OpenVINO™ 运行推理:https://docs.openvino.ai/latest/openvino_docs_OV_UG_Integrate_OV_with_your_application.html


#include <openvino/openvino.hpp>
// 1.创建 OpenVINO™ 核心以管理可用设备和读取模型对象
ov::Core core;
// 2.为特定设备编译模型
ov::CompiledModel compiled_model = core.compile_model("model.onnx", "AUTO");
// 3.创建推理请求
ov::InferRequest infer_request = compiled_model.create_infer_request();
// 4.设置输入
// 获取模型的输入端口
auto input_port = compiled_model.input();
// 从外部存储器创建张量
ov::Tensor input_tensor(input_port.get_element_type(), input_port.get_shape(), memory_ptr);
// 为模型设置一个输入张量
infer_request.set_input_tensor(input_tensor);
// 5.开始推理
infer_request.start_async();
infer_request.wait();
// 6.处理推理结果
// 通过tensor_name获取输出张量
auto output = infer_request.get_tensor("tensor_name");
const float \*output_buffer = output.data<const float>();
// output_buffer[] - 访问输出张量数据
// 7.释放分配的对象(仅适用于C)
ov_shape_free(&input_shape);
ov_tensor_free(output_tensor);
ov_output_const_port_free(input_port);
ov_tensor_free(tensor);
ov_infer_request_free(infer_request);
ov_compiled_model_free(compiled_model);
ov_model_free(model);
ov_core_free(core);
// 为项目创建结构
project/
   ├── CMakeLists.txt  - CMake file to build
   ├── ...             - Additional folders like includes/
   └── src/            - source folder
       └── main.cpp
build/                  - build directory
   ...
// 创建 Cmake 脚本
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
find_package(OpenVINO REQUIRED)
add_executable(${TARGET_NAME} src/main.cpp)
target_link_libraries(${TARGET_NAME} PRIVATE openvino::runtime)
// 构建项目
cd build/
cmake ../project
cmake --build .



原文首发微信公众号【自动驾驶之心】:一个专注自动驾驶与AI的社区(https://mp.weixin.qq.com/s/NK-0tfm_5KxmOfFHpK5mBA

相关文章
|
7天前
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型的分布式训练
使用Python实现深度学习模型的分布式训练
121 73
|
10天前
|
机器学习/深度学习 数据采集 供应链
使用Python实现智能食品消费需求分析的深度学习模型
使用Python实现智能食品消费需求分析的深度学习模型
54 21
|
12天前
|
机器学习/深度学习 数据采集 搜索推荐
使用Python实现智能食品消费偏好预测的深度学习模型
使用Python实现智能食品消费偏好预测的深度学习模型
55 23
|
13天前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费习惯预测的深度学习模型
使用Python实现智能食品消费习惯预测的深度学习模型
60 19
|
11天前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费模式预测的深度学习模型
使用Python实现智能食品消费模式预测的深度学习模型
38 2
|
15天前
|
机器学习/深度学习 传感器 数据采集
深度学习在故障检测中的应用:从理论到实践
深度学习在故障检测中的应用:从理论到实践
70 5
|
7天前
|
机器学习/深度学习 网络架构 计算机视觉
深度学习在图像识别中的应用与挑战
【10月更文挑战第21天】 本文探讨了深度学习技术在图像识别领域的应用,并分析了当前面临的主要挑战。通过研究卷积神经网络(CNN)的结构和原理,本文展示了深度学习如何提高图像识别的准确性和效率。同时,本文也讨论了数据不平衡、过拟合、计算资源限制等问题,并提出了相应的解决策略。
44 19
|
7天前
|
机器学习/深度学习 传感器 人工智能
探索深度学习在图像识别中的应用与挑战
【10月更文挑战第21天】 本文深入探讨了深度学习技术在图像识别领域的应用,并分析了当前面临的主要挑战。通过介绍卷积神经网络(CNN)的基本原理和架构设计,阐述了深度学习如何有效地从图像数据中提取特征,并在多个领域实现突破性进展。同时,文章也指出了训练深度模型时常见的过拟合问题、数据不平衡以及计算资源需求高等挑战,并提出了相应的解决策略。
50 7
|
17天前
|
机器学习/深度学习 自动驾驶 算法
深度学习在图像识别中的应用
本文将探讨深度学习技术在图像识别领域的应用。我们将介绍深度学习的基本原理,以及如何利用这些原理进行图像识别。我们将通过一个简单的代码示例来演示如何使用深度学习模型进行图像分类。最后,我们将讨论深度学习在图像识别领域的未来发展趋势和挑战。
|
17天前
|
机器学习/深度学习 数据采集 算法
深度学习在图像识别中的应用与挑战
本文探讨了深度学习技术在图像识别领域的应用,重点分析了卷积神经网络(CNN)的基本原理、优势以及面临的主要挑战。通过案例研究,展示了深度学习如何提高图像识别的准确性和效率,同时指出了数据质量、模型泛化能力和计算资源等关键因素对性能的影响。

热门文章

最新文章