利用GPU预热以及同步执行正确计算卷积神经网络推理性能【附代码】

简介: 笔记

我们在评价一个卷积神经网络模型性能好坏时,通常会用AP,mAP来判断分类准确性,针对速度方面经常使用ms(毫秒),或者FPS(表示每秒处理多少张图像,或者说处理一张图像用多少秒)。在看一些代码的时候,常常会看到是直接用python中的time函数来计算,比如下面代码:

time1 = time.time()
output = model(image)
time2 = time.time()
total_time =  time2 - time1

但不知道大家在实际测试时候有没有发现一个问题,通过上面的计算给出的时间感觉并不准确,就好像你从运行代码开始,到最终给出的结果这个时间差距好像挺大的。【反正我是这么觉得】


其实这有一定的硬件影响【大家肯定觉得我再说废话,gpu和CPU不同肯定不一样】,那么如何可以更准确的计算这个时间呢?



GPU预热


我在查阅了一些资料的时候以及听到其他一些工程师说有关推理速度的时候,听到了一个词--“预热”,而这里的预热一般指的是GPU的预热。


什么叫GPU的预热呢,打个比方,我们打开电脑或者其他电子产品的时候,如果你立马用设备,会感觉有些卡顿,但如果你稍微等一下,让后台程序都跑起来再用,就明显快很多了,这就是设备的预热。同理的,GPU在你不用的时候是低功耗状态,它会把有些高性能的功能暂时关闭或降低性能,这时候如果你把模型放上面处理,你就能明显感觉到有点满,甚至你从点击程序运行以后要等个几秒钟才出结果,因为这个阶段GPU要完成很多初始化工作【当然了,这也和显卡好坏有关系】。


所以为了可以充分利用起显卡,也为了可以更准确的计算预测时间,我们可以采用模型预热的方式,其实方式很简单,就好比你让模型在显卡上先空跑一段时间。例如这样:

device = torch.device('cuda:0')
model.to(device)
model.eval()
# 预热,让模型先跑20轮
for i in range(20):
    output = model(x)

以ResNet50为例,先来看下没有预热时候测出来的速率:


predict time : 67.120902ms,FPS:14.898488646953012


再来看看预热以后计算出来的速率,是不是和上面比速度有提升呢?


predict time : 55.680942ms,FPS:17.95946634245771


预热代码:

import torch
from torchvision.models import resnet50
import time
epoch = 100
model = resnet50(pretrained=False)
device = torch.device('cuda:0')
x = torch.ones(1, 3, 640, 640).to(device)
model.to(device)
model.eval()
for _ in range(20):
    output = model(x)
times = torch.zeros(epoch)  # 用来存放每次测试结果
randn_input = torch.randn(1, 3, 640, 640).to(device)
with torch.no_grad():
    for i in range(epoch):
        time1 = time.time()
        output = model(randn_input)
        time2 = time.time()
        times[i] = time2 - time1
mean_time = times.mean().item()  # 单位是秒
print("predict time : {:.6f}ms,FPS:{}".format(mean_time*1000, 1/(mean_time)))


异步转同步


其实到这里还没有完,因为在实际计算时间的时候还牵扯一个GPU的异步处理,而python中的time函数往往是在CPU端运行的【如果你的模型本来就是用CPU推理的,那没什么问题】,这就表明你用time函数计算时间时,可能有些数据在GPU上还没处理完呢你就已经给出结果了,因此在利用GPU推理的时候,应当用torch官方提供的torch.cuda.synchronize()将模型切换到同步处理,这样的时间才是更准确的,并用torch.cuda.Event来代替time获得最终的时间。


先看一张图,图的左边是同步执行,右边是异步执行。同步执行中进程A需要等进程B执行完或者给一个响应才会继续执行进程A,而在异步执行中,进程A并不需要等待进程B的响应然后再继续执行,这就有可能会出现一种情况,一个代码可能比另一个代码先执行完。打个比方,进程A是CPU,进程B是GPU,你的模型是在GPU上执行的,如果你用time函数,实际得出的结果是进程A的,但你的模型其实已经在B中完成了,那么你这个时间就是不准确的。

40.png

为了可以更精确的判断我们的模型推理性能,我们需要将这个过程从异步转为同步。 代码如下:

import torch
from torchvision.models import resnet50
import time
epoch = 100
model = resnet50(pretrained=False)
device = torch.device('cuda:0')
x = torch.ones(1, 3, 640, 640).to(device)
starter, ender = torch.cuda.Event(enable_timing=True), torch.cuda.Event(enable_timing=True)
model.to(device)
model.eval()
for _ in range(20):
    output = model(x)
times = torch.zeros(epoch)  # 用来存放每次测试结果
randn_input = torch.randn(1, 3, 640, 640).to(device)
with torch.no_grad():
    for i in range(epoch):
        starter.record()
        output = model(randn_input)
        ender.record()
        # 异步转同步
        torch.cuda.synchronize()
        times[i] = starter.elapsed_time(ender)  # 单位是毫秒
mean_time = times.mean().item()
print("predict time : {:.6f}ms,FPS:{}".format(mean_time, 1000/mean_time))

elapsed_time()这个函数返回的时间单位是毫秒,需要和time函数区分。用synchronize()可以将GPU默认的异步转同步,等待事件的完成。

现在再来看一下这次的测量时间:


predict time : 47.589127ms,FPS:21.01320347146227


注意,上面说的这些东西也受硬件、分辨率、以及你模型大小以及计算量影响的,上面说的仅是一个参考。  



相关实践学习
在云上部署ChatGLM2-6B大模型(GPU版)
ChatGLM2-6B是由智谱AI及清华KEG实验室于2023年6月发布的中英双语对话开源大模型。通过本实验,可以学习如何配置AIGC开发环境,如何部署ChatGLM2-6B大模型。
目录
相关文章
|
3月前
|
存储 并行计算 调度
迈向可编程观测:在GPU Kernel中构建类eBPF风格的性能探针
本文旨在梳理作者学习路径,带领读者共同探索 GPU Kernel 性能分析从宏观到微观的技术演进。
691 24
迈向可编程观测:在GPU Kernel中构建类eBPF风格的性能探针
|
2月前
|
机器学习/深度学习 PyTorch TensorFlow
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic,深度学习探索者。深耕TensorFlow与PyTorch,分享框架对比、性能优化与实战经验,助力技术进阶。
|
4月前
|
存储 机器学习/深度学习 人工智能
GPU云存储性能:加速AI与高性能计算的关键
在人工智能(AI)、机器学习(ML)和高性能计算(HPC)飞速发展的今天,数据存储和处理的效率已成为决定项目成败的关键因素。传统的云存储方案往往无法满足GPU密集型工作负载的需求,而GPU云存储性能的优化正成为企业提升计算效率、降低延迟的核心突破口。本文将深入探讨GPU云存储性能的重要性、关键技术及优化策略,助您在数据驱动的竞争中占据先机。
|
3月前
|
人工智能 运维 安全
从被动防御到主动免疫进化!迈格网络 “天机” AI 安全防护平台,助推全端防护性能提升
迈格网络推出“天机”新版本,以AI自学习、全端防护、主动安全三大核心能力,重构网络安全防线。融合AI引擎与DeepSeek-R1模型,实现威胁预测、零日防御、自动化响应,覆盖Web、APP、小程序全场景,助力企业从被动防御迈向主动免疫,护航数字化转型。
从被动防御到主动免疫进化!迈格网络 “天机” AI 安全防护平台,助推全端防护性能提升
|
2月前
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
210 4
|
3月前
|
机器学习/深度学习 人工智能 算法
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic带你深入卷积神经网络(CNN)核心技术,从生物启发到数学原理,详解ResNet、注意力机制与模型优化,探索视觉智能的演进之路。
405 11
|
3月前
|
人工智能 监控 数据可视化
如何破解AI推理延迟难题:构建敏捷多云算力网络
本文探讨了AI企业在突破算力瓶颈后,如何构建高效、稳定的网络架构以支撑AI产品化落地。文章分析了典型AI IT架构的四个层次——流量接入层、调度决策层、推理服务层和训练算力层,并深入解析了AI架构对网络提出的三大核心挑战:跨云互联、逻辑隔离与业务识别、网络可视化与QoS控制。最终提出了一站式网络解决方案,助力AI企业实现多云调度、业务融合承载与精细化流量管理,推动AI服务高效、稳定交付。
|
5月前
|
机器学习/深度学习 数据采集 算法
贝叶斯状态空间神经网络:融合概率推理和状态空间实现高精度预测和可解释性
本文将BSSNN扩展至反向推理任务,即预测X∣y,这种设计使得模型不仅能够预测结果,还能够探索特定结果对应的输入特征组合。在二元分类任务中,这种反向推理能力有助于识别导致正负类结果的关键因素,从而显著提升模型的可解释性和决策支持能力。
435 42
贝叶斯状态空间神经网络:融合概率推理和状态空间实现高精度预测和可解释性
|
3月前
|
机器学习/深度学习 传感器 数据采集
【故障识别】基于CNN-SVM卷积神经网络结合支持向量机的数据分类预测研究(Matlab代码实现)
【故障识别】基于CNN-SVM卷积神经网络结合支持向量机的数据分类预测研究(Matlab代码实现)
235 0
|
5月前
|
机器学习/深度学习 人工智能 PyTorch
零基础入门CNN:聚AI卷积神经网络核心原理与工业级实战指南
卷积神经网络(CNN)通过局部感知和权值共享两大特性,成为计算机视觉的核心技术。本文详解CNN的卷积操作、架构设计、超参数调优及感受野计算,结合代码示例展示其在图像分类、目标检测等领域的应用价值。
297 7

热门文章

最新文章