利用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大模型。
目录
相关文章
|
1月前
|
人工智能 并行计算 PyTorch
以Lama Cleaner的AI去水印工具理解人工智能中经常会用到GPU来计算的CUDA是什么? 优雅草-卓伊凡
以Lama Cleaner的AI去水印工具理解人工智能中经常会用到GPU来计算的CUDA是什么? 优雅草-卓伊凡
176 4
|
1月前
|
机器学习/深度学习 人工智能 芯片
42_大语言模型的计算需求:从GPU到TPU
随着2025年大语言模型技术的持续突破和规模化应用,计算资源已成为推动AI发展的关键驱动力。从最初的CPU计算,到GPU加速,再到专用AI加速器的崛起,大语言模型的计算需求正在重塑全球数据中心的基础设施架构。当前,全球AI半导体市场规模预计在2027年将达到2380亿美元(基本情境)甚至4050亿美元(乐观情境),这一增长背后,是大语言模型对计算能力、内存带宽和能效比的极致追求。
|
6月前
|
算法 JavaScript 数据安全/隐私保护
基于GA遗传优化的最优阈值计算认知异构网络(CHN)能量检测算法matlab仿真
本内容介绍了一种基于GA遗传优化的阈值计算方法在认知异构网络(CHN)中的应用。通过Matlab2022a实现算法,完整代码含中文注释与操作视频。能量检测算法用于感知主用户信号,其性能依赖检测阈值。传统固定阈值方法易受噪声影响,而GA算法通过模拟生物进化,在复杂环境中自动优化阈值,提高频谱感知准确性,增强CHN的通信效率与资源利用率。预览效果无水印,核心程序部分展示,适合研究频谱感知与优化算法的学者参考。
|
2月前
|
机器学习/深度学习 人工智能 容灾
硅谷GPU云托管:驱动AI革命的下一代计算基石
在人工智能与高性能计算席卷全球的今天,硅谷作为科技创新的心脏,正通过GPU云托管服务重新定义计算能力的边界。无论您是初创公司的机器学习工程师,还是跨国企业的研究团队,硅谷GPU云托管已成为实现突破性创新的关键基础设施。
|
6月前
|
人工智能 并行计算 监控
在AMD GPU上部署AI大模型:从ROCm环境搭建到Ollama本地推理实战指南
本文详细介绍了在AMD硬件上构建大型语言模型(LLM)推理环境的全流程。以RX 7900XT为例,通过配置ROCm平台、部署Ollama及Open WebUI,实现高效本地化AI推理。尽管面临技术挑战,但凭借高性价比(如700欧元的RX 7900XT性能接近2200欧元的RTX 5090),AMD方案成为经济实用的选择。测试显示,不同规模模型的推理速度从9到74 tokens/秒不等,满足交互需求。随着ROCm不断完善,AMD生态将推动AI硬件多元化发展,为个人与小型组织提供低成本、低依赖的AI实践路径。
2259 1
在AMD GPU上部署AI大模型:从ROCm环境搭建到Ollama本地推理实战指南
|
6月前
|
存储 消息中间件 弹性计算
阿里云服务器ECS计算型c7和通用算力型u1在适用场景、计算性能、网络与存储性能等方面的对比
阿里云ECS服务器u1和c7实例在适用场景、性能、处理器特性等方面存在显著差异。u1为通用算力型,性价比高,适合中小企业及对性能要求不高的场景;c7为企业级计算型,采用最新Intel处理器,性能稳定且强大,适用于高性能计算需求。u1支持多种CPU内存配比,但性能一致性可能受底层平台影响;c7固定调度模式,确保高性能与稳定性。选择时可根据预算与性能需求决定。
337 23
|
8月前
|
存储 测试技术 对象存储
容器计算服务ACS单张GPU即可快速搭建QwQ-32B推理模型
阿里云最新发布的QwQ-32B模型拥有320亿参数,通过强化学习大幅度提升了模型推理能力,其性能与DeepSeek-R1 671B媲美,本文介绍如何使用ACS算力部署生产可用的QwQ-32B模型推理服务。
|
6月前
计算网络号的直接方法
子网掩码用于区分IP地址中的网络部分和主机部分,连续的“1”表示网络位,“0”表示主机位。例如,255.255.255.0 的二进制为 11111111.11111111.11111111.00000000,前24位是网络部分。通过子网掩码可提取网络号,如 IP 192.168.1.10 与子网掩码 255.255.255.0 的网络号为 192.168.1.0。此外,文档还介绍了十进制与二进制间的转换方法,帮助理解IP地址的组成与计算。
388 11
|
8月前
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
642 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
|
8月前
|
人工智能 运维 Serverless
Serverless GPU:助力 AI 推理加速
Serverless GPU:助力 AI 推理加速
356 1

热门文章

最新文章