0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用AsyncInferQueue进一步提升AI推理程序的吞吐量

英特尔物联网 来源:英特尔物联网 2023-01-06 09:57 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

本文将介绍基于OpenVINO的异步推理队列类 AyncInferQueue,启动多个(>2)推理请求(infer request),帮助读者在硬件投入不变的情况下,进一步提升 AI 推理程序的吞吐量(Throughput)。

在阅读本文前,请读者先了解使用 start_async() 和 wait() 方法实现基于2个推理请求的异步推理实现方式。该异步推理实现方式相对于同步推理方式,极大提升了 AI 推理程序的吞吐量,但从任务管理器中可以看到,AI 推理硬件的利用率还有很大的提升空间。

d95eaa84-8d5d-11ed-bfe3-dac502259ad0.png

这意味着,AI 推理硬件还有潜力可挖,可以通过进一步提高推理请求个数来提升 AI 推理硬件的利用率,从而提高 AI 推理程序的吞吐量。

1.1

推理请求(InferRequest)和流(stream)

OpenVINO 运行时(Runtime)用推理请求(infer request)来抽象在指定计算设备上运行已编译模型(Compiled_Model)。从编写程序的角度看,推理请求是一个类,封装了支持推理请求以同步或异步方式运行的属性和方法。

推理请求(InferRequest)类的详细定义参考:

https://github.com/openvinotoolkit/openvino/blob/master/src/inference/include/openvino/runtime/infer_request.hpp#L34

推理请求的个数,由开发者定义;但计算设备能并行处理的推理请求个数,由硬件本身的处理单元(Processing Unit)决定。超过计算硬件并行处理数量的推理请求,会被计算硬件用队列储存起来,当计算硬件空闲后,队列中的推理请求将被依次取出并执行。

OpenVINO用流(stream)来抽象计算设备能并行处理推理请求的能力,通过属性:“NUM_STREAMS”,可以获取延迟优先或吞吐量优先模式下的计算硬件支持的最优streams数量,如下表所示。

d98c3af8-8d5d-11ed-bfe3-dac502259ad0.png

:上述数据在蝰蛇峡谷上测得,CPU=i7-12700H, 集成显卡=Iris Xe, 独立显卡=A770m

: GPU设备没有INFERENCE_NUM_THREADS属性

上述数据测试的源代码如下,欢迎各位读者在自己的硬件平台上测试:

from openvino.runtime import Core, get_version
core = Core()
print(get_version())
print(core.available_devices)
device = device = ['GPU.0', 'GPU.1', 'CPU', 'AUTO', 'AUTO:GPU,-CPU'][0]
cfgs = {}
cfgs['PERFORMANCE_HINT'] = ['THROUGHPUT', 'LATENCY', 'CUMULATIVE_THROUGHPUT'][0]
net = core.compile_model("model.onnx",device,cfgs)
# Get Supported properties
supported_properties = net.get_property('SUPPORTED_PROPERTIES')
print(f'Support properties for {device}:', supported_properties)
opt_nireq = net.get_property('OPTIMAL_NUMBER_OF_INFER_REQUESTS')
print(f'OPTIMAL_NUMBER_OF_INFER_REQUESTS for {device}:', opt_nireq)
nstreams = net.get_property('NUM_STREAMS')
print(f'nstreams for {device}:', nstreams)
performance_hint_num_requests = net.get_property('PERFORMANCE_HINT_NUM_REQUESTS')
print(f'performance_hint_num_requests for {device}:', performance_hint_num_requests)
if device == "CPU":
  # INFERENCE_NUM_THREADS
  inference_num_threads = net.get_property('INFERENCE_NUM_THREADS')
  print(f'inference_num_threads for {device}:', inference_num_threads)
else:
  gpu_queue_priority = net.get_property('GPU_QUEUE_PRIORITY')
print(f'GPU queue priority for {device}:', gpu_queue_priority)

向右滑动查看完整代码

1.1.1

CPU 的流与推理请求

对于 CPU 来说,一个流(stream)只能服务一个推理请求。通过属性ov::range_for_streams,可以查到 CPU 支持的流数量的范围;流的数量无需开发者使用代码显示设置,OpenVINO 运行时会根据延迟优先或吞吐量优先来自动设置。

d9ada4a4-8d5d-11ed-bfe3-dac502259ad0.png

1.1.2

GPU 的流与推理请求

对于 GPU 来说,一个流(stream)可以同时服务两个推理请求。通过属性 ov::range_for_streams,可以查到 GPU 支持的流数量的范围:[1, 2];流的数量无需开发者使用代码显示设置,OpenVINO 运行时会根据延迟优先或吞吐量优先来自动设置。

d9c8a84e-8d5d-11ed-bfe3-dac502259ad0.png

参考代码:

https://www.jianshu.com/p/1748444e6a50

1.2

AsyncInferQueue类

OpenVINO运行时(Runtime)提供 AsyncInferQueue 类来抽象并管理异步推理请求池,其常用方法和属性有:

__init__(self, compiled_model, jobs = 0):创建AsyncInferQueue对象

set_callback(func_name):为推理请求池中所有的推理请求设置统一的回调函数

start_async(inputs, userdata = None):异步启动推理请求

wait_all():等待所有的推理请求执行完毕

1.2.1

基于AsyncInferQueue类的

异步推理范例程序

基于 AsyncInferQueue 类 YOLOv5 模型的异步推理范例程序的核心代码部分如下所示:

完整范例代码请下载:yolov5_async_infer_queue.py

https://gitee.com/ppov-nuc/yolov5_infer/blob/main/yolov5_async_infer_queue.py

运行代码前,请参考运行环境搭建流程。

...
def preprocess(frame):
  # Preprocess the frame
  letterbox_im, _, _= letterbox(frame, auto=False) # preprocess frame by letterbox
  im = letterbox_im.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB
  im = np.float32(im) / 255.0  # 0 - 255 to 0.0 - 1.0
  blob = im[None] # expand for batch dim
  return blob, letterbox_im.shape[:-1], frame.shape[:-1]
def postprocess(ireq: InferRequest, user_data: tuple):
  result = ireq.results[ireq.model_outputs[0]]
  dets = non_max_suppression(torch.tensor(result))[0].numpy()
  bboxes, scores, class_ids= dets[:,:4], dets[:,4], dets[:,5]
  # rescale the coordinates
  bboxes = scale_coords(user_data[1], bboxes, user_data[2]).astype(int)
  print(user_data[0],"	"+f"{ireq.latency:.3f}"+"	", class_ids)
  return 
# Step1:Initialize OpenVINO Runtime Core
core = Core()
# Step2: Build compiled model
device = device = ['GPU.0', 'GPU.1', 'CPU', 'AUTO', 'AUTO:GPU,-CPU'][0]
cfgs = {}
cfgs['PERFORMANCE_HINT'] = ['THROUGHPUT', 'LATENCY', 'CUMULATIVE_THROUGHPUT'][0]
net = core.compile_model("yolov5s.xml",device,cfgs)
output_node = net.outputs[0]
b,n,input_h,input_w = net.inputs[0].shape
# Step3: Initialize InferQueue
ireqs = AsyncInferQueue(net)
print('Number of infer requests in InferQueue:', len(ireqs))
# Step3.1: Set unified callback on all InferRequests from queue's pool
ireqs.set_callback(postprocess)
# Step4: Read the images
image_folder = "./data/images/"
image_files= os.listdir(image_folder)
print(image_files)
frames = []
for image_file in image_files:
  frame = cv2.imread(os.path.join(image_folder, image_file))
  frames.append(frame)
# 4.1 Warm up
for id, _ in enumerate(ireqs):
  # Preprocess the frame
  start = perf_counter()
  blob, letterbox_shape, frame_shape = preprocess(frames[id % 4])
  end = perf_counter()
  print(f"Preprocess {id}: {(end-start):.4f}.")
  # Run asynchronous inference using the next available InferRequest from the pool
  ireqs.start_async({0:blob},(id, letterbox_shape, frame_shape))
ireqs.wait_all()
# Step5: Benchmark the Async Infer
start = perf_counter()
in_fly = set()
latencies = []
niter = 16
for i in range(niter):
  # Preprocess the frame
  blob, letterbox_shape, frame_shape = preprocess(frames[i % 4]) 
  idle_id = ireqs.get_idle_request_id()
  if idle_id in in_fly:
    latencies.append(ireqs[idle_id].latency)
  else:
    in_fly.add(idle_id)
  # Run asynchronous inference using the next available InferRequest from the pool 
  ireqs.start_async({0:blob},(i, letterbox_shape, frame_shape) )
ireqs.wait_all()

向右滑动查看完整代码

运行结果如下所示,与基于单个推理请求的start_async()+wait()实现方式相比,基于 AsyncInferQueue 类的 YOLOv5 模型的异步推理程序的吞吐量明显得到提升。

d9de4492-8d5d-11ed-bfe3-dac502259ad0.png

1.3

结论

使用 OpenVINO Runtime 的 AsyncInferQueue 类,可以极大提升 AI 推理程序的吞出量。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • AI
    AI
    +关注

    关注

    91

    文章

    41138

    浏览量

    302608
  • 程序
    +关注

    关注

    117

    文章

    3848

    浏览量

    85472
  • 任务管理器
    +关注

    关注

    0

    文章

    15

    浏览量

    7951

原文标题:使用AsyncInferQueue进一步提升AI推理程序的吞吐量 | 开发者实战

文章出处:【微信号:英特尔物联网,微信公众号:英特尔物联网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    奥迪与上汽集团进一步深化战略合作

    基于双方长期稳固的合作根基,奥迪与上汽集团正式签署战略合作协议,进一步深化合作。协议聚焦AUDI品牌未来车型的全价值链布局,核心覆盖整车研发领域,并将在上海设立奥迪创新技术中心。
    的头像 发表于 04-21 14:01 146次阅读

    如何进一步从SPI NOR闪存启动电路板?

    稳定性。 根据 T2080 快速入门指南文档,DIP 设置设置为 JTAG 的硬编码 RCW,并且能够使用 CCS 读取硬编码的 RCW 值。 如何进一步从 SPI NOR 闪存启动电路板
    发表于 04-16 08:51

    英飞凌继续登顶全球微控制器市场榜首,进一步巩固领先地位

    在整体市场小幅下滑的背景下,2025年市场份额达到23.2%(2024年为21.4%)集成汽车以太网以进一步强化面向软件定义汽车的微控制器业务,并为人形机器人领域开辟增长机遇英飞凌为微控制器产品组合
    的头像 发表于 03-12 17:07 1351次阅读
    英飞凌继续登顶全球微控制器市场榜首,<b class='flag-5'>进一步</b>巩固领先地位

    伟创力与AMD进一步深化战略合作

    近日,伟创力宣布与全球领先的高性能与自适应计算芯片公司 AMD(超威半导体) 进一步深化战略合作,在美国本土制造 AMD Instinct 平台,加速先进 AI 基础设施落地。作为合作的首个成果
    的头像 发表于 03-11 15:11 410次阅读

    百度萝卜快跑与Uber进一步深化战略合作

    今天,萝卜快跑与全球最大的移动出行服务平台Uber共同宣布,双方将进一步深化战略合作,计划于2026年第季度在阿联酋迪拜正式推出全无人驾驶出行服务,这也是迪拜首次迎来全无人驾驶出行服务。
    的头像 发表于 02-11 16:50 1355次阅读

    用“分区”来面对超大数据集和超大吞吐量

    分区(partitions) 也被称为 分片(sharding),通常采用对数据进行分区的方式来增加系统的 可伸缩性,以此来面对非常大的数据集或非常高的吞吐量,避免出现热点。
    的头像 发表于 12-30 16:40 283次阅读
    用“分区”来面对超大数据集和超大<b class='flag-5'>吞吐量</b>

    天合储能与Lightshift Energy进一步扩大战略合作

    近日,天合储能宣布将与美国领先的储能开发、建设及运营方 Lightshift Energy(以下简称 “Lightshift”) 进一步扩大战略合作。在既有合作基础上,双方历史累计及在建、将建项目合计,保障联合交付储能项目规模超过 1GWh,持续支持美国多个州的电网建设与稳定运行。
    的头像 发表于 12-22 15:14 507次阅读

    BlackBerry QNX与众森软件进一步深化战略合作

    今日,深圳市众森软件有限公司(以下简称"众森软件")正式宣布与全球领先的实时操作系统与嵌入式软件供应商 QNX(BlackBerry有限公司旗下部门QNX)进一步深化战略合作。此次合作将进一步推动下代智能网联汽车与智慧出行解决
    的头像 发表于 12-04 16:40 2074次阅读

    上汽奥迪与创维汽车智能合作进一步深化升级

    近日,创维汽车智能迎来重要突破:上汽奥迪客户将当前公司开发的显示屏项目沿用至上汽奥迪其他主力车型。这决定不仅体现了客户对创维汽车智能技术实力与服务品质的高度认可,更标志着双方合作进一步深化升级。
    的头像 发表于 11-25 10:32 879次阅读

    使用罗德与施瓦茨CMX500的吞吐量应用层测试方案

    5G NR(New Radio)吞吐量应用层测试是评估5G网络性能的个重要方面,它主要关注的是在实际应用条件下,用户能够体验到的数据传输速率。这种测试通常包括了对下行链路和上行链路的吞吐量进行测量,以确保网络可以满足各种应用场
    的头像 发表于 09-02 13:56 8153次阅读
    使用罗德与施瓦茨CMX500的<b class='flag-5'>吞吐量</b>应用层测试方案

    蔚来进一步拓展其全球业务

    8月18日,蔚来公司宣布将于2025年至2026年期间陆续进入新加坡、乌兹别克斯坦和哥斯达黎加三个市场,进一步拓展其全球业务,为当地用户带来创新、可持续、高品质的智能电动出行体验。
    的头像 发表于 08-20 17:00 1490次阅读

    信而泰×DeepSeek:AI推理引擎驱动网络智能诊断迈向 “自愈”时代

    故障)”的自动化推理链条。3.预测性防御:智能基线洞察,防患于未然l 基于先进的时序分解算法,为每个关键业务终端/链路动态构建多维性能基线(吞吐量、时延、丢包率)。l 主动预警潜在风险,如带宽瓶颈
    发表于 07-16 15:29

    软通动力与中国联通合作关系进一步深化

    近日,软通动力成功中标联通(广东)产业互联网有限公司2025年软件技术开发集中采购项目,中标份额位列榜首。这突破性成果,不仅彰显了软通动力在数字技术服务领域的综合实力,也标志着其与中国联通合作关系的进一步深化。
    的头像 发表于 07-01 09:18 1349次阅读

    如何在Visual Studio 2022中运行FX3吞吐量基准测试工具?

    我正在尝试运行 John Hyde 的书“SuperSpeed by Design”中的 FX3 吞吐量基准测试工具。 但是,我面临些困难,希望得到任何指导。 具体来说,我正在使用 Visual
    发表于 05-13 08:05

    FX3进行读或写操作时CS信号拉低,在读或写完成后CS置高,对吞吐量有没有影响?

    从尽可能提高吞吐量的角度看,在进行读或写操作时CS信号拉低,在读或写完成后CS置高,对吞吐量有没有影响,还是应该CS直拉低比较好。
    发表于 05-08 07:13