摘要:“高性能推理”是ModelBox宣传的主要特性之一,不信谣不传谣的我决定通过原生API和ModelBox实现相同案例进行对比,看一下ModelBox推理是否真的“高性能”。

本文分享自华为云社区《ModelBox推理真的高效吗?》,作者:吴小鱼。

“高性能推理”是ModelBox宣传的主要特性之一,不信谣不传谣的我决定通过原生API和ModelBox实现相同案例进行对比,看一下ModelBox推理是否真的“高性能”。

我们分别使用onnxruntime与ModelBox Windows SDK对相同的模型实现相同的推理逻辑进行端到端性能对比,为了防止测试视频帧率成为性能瓶颈,我们准备了120fps的视频作为测试输入。

如果对Windows ModelBox SDK使用还不熟悉,可以参考我们的ModelBox 端云协同AI开发套件(Windows)上手指南。案例所需资源(代码、模型、测试数据等)均可从obs桶下载。

案例说明

为了充分考验不同框架的推理性能,我决定做一个稍微有那么一点点繁琐的双阶段单人人体关键点检测案例。案例具体流程如下:

其中,人形检测使用开源YOLOV7-tiny预训练模型,关键点检测使用开源PP-TinyPose预训练模型,在进行人形跟踪后我们过滤得到最早出现的id的检测框进行关键点检测。

onnxruntime推理

原生API推理代码位于资源包的onnxruntime_infer目录下,具体的代码组织为:

onnxruntime_infer
├─onnxruntime_infer.py # 推理入口脚本
├─utils.py # 人形检测后处理
├─sort.py # 跟踪
├─hrnet_post.py # 关键点检测后处理
└─smooth.py # 关键点时序滤波

其中,入口脚本onnxruntime_infer.py中指定了使用的模型文件与测试视频:

cam = cv2.VideoCapture("../data/dance_120fps.mp4")
size = (int(cam.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cam.get(cv2.CAP_PROP_FRAME_HEIGHT)))
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out_fps = cam.get(cv2.CAP_PROP_FPS)
res_cam = cv2.VideoWriter("../hilens_data_dir/rt_result.mp4", fourcc, out_fps, size)
det_sess = rt.InferenceSession("../model/det_human/yolov7-tiny.onnx", providers=["DmlExecutionProvider"])
pose_sess = rt.InferenceSession("../model/det_pose/pose.onnx", providers=["CPUExecutionProvider"])

人形检测模型为gpu推理,关键点检测模型为cpu推理,在使用ModelBox Windows SDK推理时也保持了同样的硬件配置。

fps取检测预处理开始到绘制关键点这一区间进行测试:

class DetPre:
def __init__(self, net_h=320, net_w=320):
self.net_h = net_h
self.net_w = net_w
def __call__(self, img_data):
buffer_meta = {}
buffer_meta["time"] = time.time()
resized_image, ratio, (dw, dh) = self.letterbox(img_data)
...
total_time += time.time() - buffer_meta.get("time")
idx += 1
res_img, pose_data = draw_pose(im, filter_box, pose_data, total_time / idx)
...

结果视频rt_result.mp4保存在hilens_data_dir文件夹下,查看结果:

可以看到,双阶段单人关键点技能在onnxruntime推理可以达到36fps左右。

ModelBox Windows SDK推理

ModelBox Windows SDK推理代码位于资源包的single_human_pose目录下,具体的代码组织为:

single_human_pose
├─bin
│ ├─main.bat // 启动脚本
│ └─mock_task.toml // 本地模拟运行输入输出配置文件
├─data
│ └─dance_120fps.mp4 // 测试视频
├─etc
│ └─flowunit // 功能单元目录
│ ├─det_post // 检测后处理
│ ├─det_pre // 检测预处理
│ ├─draw_pose // 关键点绘制
│ ├─expand_box // 单人图像切分
│ ├─object_tracker // 人形跟踪
│ └─pose_post // 姿态后处理
├─graph
│ └─single_human_pose.toml // 技能流程图
├─hilens_data_dir // 运行结果目录
│ ├─log
│ ├─mb_profile // 性能统计目录
│ │ ├─performance_[time].toml
│ │ └─trace_[time].toml
│ ├─dance_result.mp4 // 运行结果视频
│ └─rt_result.mp4
├─model // 推理功能单元
│ ├─det_human // 人形检测推理
│ │ ├─det_human.toml // 推理配置文件
│ │ └─yolov7-tiny.onnx // 推理模型
│ └─det_pose // 关键点检测推理
│ ├─det_pose.toml
│ └─pose.onnx
└─build_project.sh

我们可以查看技能流程图graph/single_human_pose.toml了解技能逻辑:

fps在关键点绘制功能单元中进行计算,计算的为端到端全流程fps:

class draw_poseFlowUnit(modelbox.FlowUnit):
def open(self, config):
...
self.start_time = time.time()
self.idx = 0
...
def process(self, data_context):
...
self.idx += 1
self.draw(out_img, bbox, pose_data, self.idx / (time.time() - self.start_time))
...

在bin/mock_task.toml中配置输入输出:

# 任务输入,mock模拟目前仅支持一路rtsp或者本地url
# rtsp摄像头,type = "rtsp", url里面写入rtsp地址
# 其它用"url",比如可以是本地文件地址, 或者httpserver的地址,(摄像头 url = "0")
[input]
type = "url"
url = "../data/dance_120fps.mp4"
# 任务输出,目前仅支持"webhook", 和本地输出"local"(输出到屏幕,url="0", 输出到rtsp,填写rtsp地址)
# (local 还可以输出到本地文件,这个时候注意,文件可以是相对路径,是相对这个mock_task.toml文件本身)
[output]
type = "local"
url = "../hilens_data_dir/dance_result.mp4"

在技能流程图中开启性能统计配置项:

[profile]
profile=true
trace=true

之后双击bin/main.bat或在bash中运行技能:

./bin/main.bat

运行完成后生成的视频与性能统计文件都在hilens_data_dir文件夹下:

可以看到使用ModelBox SDK进行推理可以达到79fps,名不虚传哇,我们可以在Chrome浏览器chrome://tracing/中加载性能统计文件查看:

逐项查看后发现耗时最久的是检测后处理功能单元,平均耗时11.69ms,因为ModelBox是静态图并行推理,fps取决于耗时最久的功能单元,理论计算fps = 1000 / 11.69 \approx 85fps=1000/11.69≈85,与我们在程序中打点计算结果接近。

总结:ModelBox真的很快,nice!

点击关注,第一时间了解华为云新鲜技术~

不信谣不传谣,亲自动手验证ModelBox推理是否真的“高性能”的更多相关文章

  1. 五十七:flask文件上传之使用flask-wtf验证上传的文件

    1.安装:pip install flask-wtf2.定义表单验证的时候,对文件的字段,需使用:FileField3.验证器从flask_wtf.file中导入,FileRequired为验证文件必 ...

  2. thinkphp图片上传+validate表单验证+图片木马检测+缩略图生成

    目录 1.案例 1.1图片上传  1.2进行图片木马检测   1.3缩略图生成   1.4控制器中调用缩略图生成方法 1.案例 前言:在thinkphp框架的Thinkphp/Library/Thin ...

  3. springmvc文件上传AND jwt身份验证

    SpringMVC文件上传 思路:1.首先定义页面,定义多功能表单(enctype=“multipart/form-data”)2.在Controller里面定义一个方法,用参数(MultipartF ...

  4. 文件上传漏洞之js验证

    0x00 前言 只有前端验证=没有验证 0x01 剔除JS 打开burpsuite,进入Proxy的Options,把Remove all JavaScript选上. 设置浏览器代理直接上传PHP木马 ...

  5. 如何实现CDN的ns智能解析和动手验证Akamai的实现

    1.什么是ns智能解析 通常CDN业务中,智能解析域名,是根据请求方ip的不同给出不同的A记录. 而ns智能解析,是根据请求方ip的不同让他去不同的ns上解析域名,把ns推向离用户更近的边缘节点来缩短 ...

  6. Qt5.7 实现Https 认证全过程解析(亲自动手版)

    #### NetworkRequestManager.h #include <QSsl>#include <QSslKey>#include <QSslSocket> ...

  7. jquery实现上传文件大小类型的验证

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. 亲自动手用HTK实现YES NO孤立词识别

    很久以前的发在研学论坛的帖子了,再重新整理了一下,希望对新手有用. 完整版链接:http://yun.baidu.com/s/1hapcE 第一步 创建语音文件 录音 命令:HSLab any_nam ...

  9. MVC去掉传参时的验证:从客户端中检测到有潜在危险的Request.QueryString值

    解决方法:给Action添加属性[ValidateInput(false)]. 例: [ValidateInput(false)] public ActionResult Index(string o ...

  10. 亲自动手实现Python+pygame中国象棋游戏

    功能1:实现游戏整体界面显示 一.创建基本的结构 代码如下: import time import pygame def main(): # 初始化pygame pygame.init() # 创建用 ...

随机推荐

  1. 云图说|初识API中心APIHub

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要:API中心是为AP ...

  2. 如何使用DALL-E 3

    如何使用 DALL-E 3:OpenAI 图像生成指南 DALL-E 3 是 OpenAI 图像生成器的高级版本,它可以理解自然语言提示来创建详细图像. 它克服了以前版本的方形图像限制,现在支持各种宽 ...

  3. oceanbase 数据库SQL优化 (把你的脑袋当成CBO)

    OB一哥们找我优化条SQL,反馈在OceanBase存储过程执行时间很慢,需要626秒才能出结果,安排. INSERT INTO insurance_stat_sx (id, stat_date, c ...

  4. .NET 8正式发布

    11 月 15 日开始的为期三天的 .NET Conf 在线活动的开幕日上,.NET 8作为微软的开源跨平台开发平台正式发布..NET 团队着重强调云.性能.全栈 Blazor.AI 和 .NET M ...

  5. 将强化学习引入NLP:原理、技术和代码实现

    本文深入探讨了强化学习在自然语言处理(NLP)中的应用,涵盖了强化学习的基础概念.与NLP的结合方式.技术细节以及实际的应用案例.通过详细的解释和Python.PyTorch的实现代码,读者将了解如何 ...

  6. canvas实现动态替换人物的背景颜色

    起因 今天遇见一个特别有意思的小功能. 就是更换人物图像的背景颜色. 大致操作步骤就是:点击人物-实现背景颜色发生变化 将图片绘画到canvas画布上 我们需要将图片绘制到canvas画布上. 这样做 ...

  7. AtCoder Beginner Contest 329 (ABC329)

    A. Spread 不说了,代码. B. Next 不说了,代码. C. Count xxx Description 给定一个长度为 \(N\) 的字符串 \(S\),求 \(S\) 中非空连续,并且 ...

  8. Jdk_HashMap 源码 —— hash(Object)

    Jdk 源码 HashMap 的源码是在面试中考的算是比较多的,其中有很多高性能的经典写法,也值得多学习学习. 本文是本人在阅读和学习源码的过程中的笔记(不是教程),如有错误欢迎指正. Jdk Ver ...

  9. 实例讲解C++连接各种数据库,包含SQL Server、MySQL、Oracle、ACCESS、SQLite 和 PostgreSQL、MongoDB 数据库

    C++ 是一种通用的编程语言,可以使用不同的库和驱动程序来连接各种数据库.以下是一些示例代码,演示如何使用 C++ 连接 SQL Server.MySQL.Oracle.ACCESS.SQLite 和 ...

  10. 小米二面:Redis 如何保证数据不丢失?

    前段时间表妹收到了小米秋招补录的面试邀请,一面还算顺利,很快就通过了,但在看二面面试录屏的时候,我发现了一个问题,回答的不是很好,也就是我们今天要聊的这个问题:Redis 如何保证数据不丢失? 很多人 ...