• 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,代码如下:

    1. if do_train:
    2. trans = [
    3. C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
    4. C.RandomHorizontalFlip(prob=0.5),
    5. C.Normalize(mean=mean, std=std),
    6. C.HWC2CHW()
    7. ]
    8. else:
    9. trans = [
    10. C.Decode(),
    11. C.Resize(256),
    12. C.CenterCrop(image_size),
    13. C.Normalize(mean=mean, std=std),
    14. C.HWC2CHW()
    15. ]
    16. 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,代码如下:

    1. if do_train:
    2. trans = [
    3. C.RandomCropDecodeResize(image_size, scale=(0.08, 1.0), ratio=(0.75, 1.333)),
    4. C.RandomHorizontalFlip(prob=0.5),
    5. C.Normalize(mean=mean, std=std),
    6. C.HWC2CHW()
    7. ]
    8. else:
    9. trans = [
    10. C.Decode(),
    11. C.Resize(256),
    12. C.CenterCrop(image_size),
    13. C.Normalize(mean=mean, std=std),
    14. C.HWC2CHW()
    15. ]
    16. 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调优工具对性能调优和精度调优提供了大量的数据,并形成了一套完整的方法论,需要的同学可以参考奥。

  • 相关阅读:
    OpenCV + Kotlin 实现 USB 摄像头(相机)实时画面、拍照
    react redux 状态管理
    让机械设计先进、高效的机械设计云平台----工业软件讲坛第四次讲座
    实验(三):单片机I/O口实验-模拟开关灯
    二叉树(上)
    函数类型和函数指针
    关于 Notion-Like 工具的反思和畅想
    5G建网初期SSB波束设置策略
    【力扣】278. 第一个错误的版本
    【论文阅读】23_SIGIR_Disentangled Contrastive Collaborative Filtering(分离对比协同过滤)
  • 原文地址:https://blog.csdn.net/Kenji_Shinji/article/details/126747167