ResNet50性能调优分享

网络训练跑通了,精度OK了,对很多人来说可能已经万事大吉了,但如果网络需要在生产环境跑,还有一个点不得不去关注,那就是性能。对于大的网络,训练一次可能需要上月的时间,这时候就真正的体会到时间就是金钱了。提高网络的性能,缩短训练的时间,可能会节省上百万的金钱。 下面给大家介绍下之前对ResNet50网络的性能调优案例,希望能帮助到大家。调优过程中用到了MindSpore中的调试调优工具:MindInsight,不仅可以调试性能,还可以调试精度,感兴趣的同学可以到官网了解下:MindInsight文档 — MindSpore master 文档

现象

我们将ResNet50网络batch size设置为32(代码可参考MindSpore ModelZoo中的ResNet50网络,当前代码已经是调优后的。本次主要给大家介绍下调优的经历),跑网络训练后发现单step时间约为90ms,性能很差。通常batch size为32时,单step耗时应在20ms以内。

原因分析

分析过程中,我们主要用到了MindInsight中的Profiler模块。如何跑Profiler收集性能数据大家可以到官网上查看教程,此次不再赘述。 将性能数据用UI页面可视化后,我们开始了此次的性能调优过程。 首先我们先看页面里的迭代轨迹部分。迭代轨迹将训练过程分为了3部分:迭代间隙表示前一个迭代结束到后一个迭代开始的时间,该段时间可以认为是后一个迭代等待数据的时间;前反向时间表示的是真正的前反向计算的时间;迭代拖尾表示的是反向完成后进行梯度更新的时间。从下图中我们看到迭代间隙的时间占了整个迭代的很大部分,因此我们需要重点关注数据处理的性能。

第二步,我们到数据准备详情页面,确认数据处理是否是性能瓶颈点。查看数据准备详情页面中的迭代间隙标签页,我们观察到,数据队列在前期有较多的数据,后期数据的个数变为0,分析原因是前期在图编译阶段已经开始了数据集的加载和增强,队列中随即缓存了多条数据;而后期正常训练开始后,队列中的数据被消费的速度要快于被生产的速度,因此数据队列逐渐变为空,说明此时数据变成了瓶颈。观察主机队列也是同样的情况。综合分析,正常训练过程中,数据处理为性能瓶颈点。

第三步,我们到数据准备详情页面中的数据处理标签页来查看具体问题。通过观察数据处理标签页的算子间队列关系,我们发现,Queue_3及其之后的队列使用率较低,即MapOp_3作为生产者生产数据的速度较慢,因此可以判定MapOp_3的性能还有优化空间,需要对该算子进行性能优化。

ResNet50性能调优分享

网络

应用性能调优

发表于 2021-10-30 12:02:484964查看

网络训练跑通了,精度OK了,对很多人来说可能已经万事大吉了,但如果网络需要在生产环境跑,还有一个点不得不去关注,那就是性能。对于大的网络,训练一次可能需要上月的时间,这时候就真正的体会到时间就是金钱了。提高网络的性能,缩短训练的时间,可能会节省上百万的金钱。 下面给大家介绍下之前对ResNet50网络的性能调优案例,希望能帮助到大家。调优过程中用到了MindSpore中的调试调优工具:MindInsight,不仅可以调试性能,还可以调试精度,感兴趣的同学可以到官网了解下:MindInsight文档 — MindSpore master 文档

现象

我们将ResNet50网络batch size设置为32(代码可参考MindSpore ModelZoo中的ResNet50网络,当前代码已经是调优后的。本次主要给大家介绍下调优的经历),跑网络训练后发现单step时间约为90ms,性能很差。通常batch size为32时,单step耗时应在20ms以内。

原因分析

分析过程中,我们主要用到了MindInsight中的Profiler模块。如何跑Profiler收集性能数据大家可以到官网上查看教程,此次不再赘述。 将性能数据用UI页面可视化后,我们开始了此次的性能调优过程。 首先我们先看页面里的迭代轨迹部分。迭代轨迹将训练过程分为了3部分:迭代间隙表示前一个迭代结束到后一个迭代开始的时间,该段时间可以认为是后一个迭代等待数据的时间;前反向时间表示的是真正的前反向计算的时间;迭代拖尾表示的是反向完成后进行梯度更新的时间。从下图中我们看到迭代间隙的时间占了整个迭代的很大部分,因此我们需要重点关注数据处理的性能。

第二步,我们到数据准备详情页面,确认数据处理是否是性能瓶颈点。查看数据准备详情页面中的迭代间隙标签页,我们观察到,数据队列在前期有较多的数据,后期数据的个数变为0,分析原因是前期在图编译阶段已经开始了数据集的加载和增强,队列中随即缓存了多条数据;而后期正常训练开始后,队列中的数据被消费的速度要快于被生产的速度,因此数据队列逐渐变为空,说明此时数据变成了瓶颈。观察主机队列也是同样的情况。综合分析,正常训练过程中,数据处理为性能瓶颈点。

第三步,我们到数据准备详情页面中的数据处理标签页来查看具体问题。通过观察数据处理标签页的算子间队列关系,我们发现,Queue_3及其之后的队列使用率较低,即MapOp_3作为生产者生产数据的速度较慢,因此可以判定MapOp_3的性能还有优化空间,需要对该算子进行性能优化。

我们查看了数据处理的代码,发现map算子的num_parallel_workers参数没有设置,而该参数的默认为1,代码如下:

if do_train:
    trans = [
        C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
        C.RandomHorizontalFlip(prob=0.5),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]
else:
    trans = [
        C.Decode(),
        C.Resize(256),
        C.CenterCrop(image_size),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]

data_set = data_set.map(operations=trans, input_columns="image")
复制

因此我们分析可以尝试提高该算子的并发数来提高网络的性能。

效果验证

我们将num_parallel_workers参数调整为12后,再次运行训练脚本,优化参考代码如下: data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=12) 通过MindInsight性能分析页面观察迭代轨迹,可以看到迭代间隙时长由72.8ms缩短到0.25ms,单step时长由90ms缩短到18.07ms。

ResNet50性能调优分享

网络

应用性能调优

发表于 2021-10-30 12:02:484964查看

网络训练跑通了,精度OK了,对很多人来说可能已经万事大吉了,但如果网络需要在生产环境跑,还有一个点不得不去关注,那就是性能。对于大的网络,训练一次可能需要上月的时间,这时候就真正的体会到时间就是金钱了。提高网络的性能,缩短训练的时间,可能会节省上百万的金钱。 下面给大家介绍下之前对ResNet50网络的性能调优案例,希望能帮助到大家。调优过程中用到了MindSpore中的调试调优工具:MindInsight,不仅可以调试性能,还可以调试精度,感兴趣的同学可以到官网了解下:MindInsight文档 — MindSpore master 文档

现象

我们将ResNet50网络batch size设置为32(代码可参考MindSpore ModelZoo中的ResNet50网络,当前代码已经是调优后的。本次主要给大家介绍下调优的经历),跑网络训练后发现单step时间约为90ms,性能很差。通常batch size为32时,单step耗时应在20ms以内。

原因分析

分析过程中,我们主要用到了MindInsight中的Profiler模块。如何跑Profiler收集性能数据大家可以到官网上查看教程,此次不再赘述。 将性能数据用UI页面可视化后,我们开始了此次的性能调优过程。 首先我们先看页面里的迭代轨迹部分。迭代轨迹将训练过程分为了3部分:迭代间隙表示前一个迭代结束到后一个迭代开始的时间,该段时间可以认为是后一个迭代等待数据的时间;前反向时间表示的是真正的前反向计算的时间;迭代拖尾表示的是反向完成后进行梯度更新的时间。从下图中我们看到迭代间隙的时间占了整个迭代的很大部分,因此我们需要重点关注数据处理的性能。

第二步,我们到数据准备详情页面,确认数据处理是否是性能瓶颈点。查看数据准备详情页面中的迭代间隙标签页,我们观察到,数据队列在前期有较多的数据,后期数据的个数变为0,分析原因是前期在图编译阶段已经开始了数据集的加载和增强,队列中随即缓存了多条数据;而后期正常训练开始后,队列中的数据被消费的速度要快于被生产的速度,因此数据队列逐渐变为空,说明此时数据变成了瓶颈。观察主机队列也是同样的情况。综合分析,正常训练过程中,数据处理为性能瓶颈点。

第三步,我们到数据准备详情页面中的数据处理标签页来查看具体问题。通过观察数据处理标签页的算子间队列关系,我们发现,Queue_3及其之后的队列使用率较低,即MapOp_3作为生产者生产数据的速度较慢,因此可以判定MapOp_3的性能还有优化空间,需要对该算子进行性能优化。

我们查看了数据处理的代码,发现map算子的num_parallel_workers参数没有设置,而该参数的默认为1,代码如下:

if do_train:
    trans = [
        C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
        C.RandomHorizontalFlip(prob=0.5),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]
else:
    trans = [
        C.Decode(),
        C.Resize(256),
        C.CenterCrop(image_size),
        C.Normalize(mean=mean, std=std),
        C.HWC2CHW()
    ]

data_set = data_set.map(operations=trans, input_columns="image")

因此我们分析可以尝试提高该算子的并发数来提高网络的性能。

效果验证

我们将num_parallel_workers参数调整为12后,再次运行训练脚本,优化参考代码如下: data_set = data_set.map(operations=trans, input_columns="image", num_parallel_workers=12) 通过MindInsight性能分析页面观察迭代轨迹,可以看到迭代间隙时长由72.8ms缩短到0.25ms,单step时长由90ms缩短到18.07ms。

至此,我们完成了ResNet50网络的性能调优工作。

总结

MindInsight调优工具对性能调优和精度调优提供了大量的数据,并形成了一套完整的方法论,需要的同学可以参考奥。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值