MindSpore简要性能分析
技术背景
在之前的一篇博客中,我们介绍过MindInsight的安装与使用。不过在前面的文章中,我们主要介绍的是MindInsight与SummaryCollector的配合使用,更多的是用于对结果进行回溯。这篇文章我们简要的从性能分析的角度,来介绍一下MindInsight的一些使用方法。
MindInsight的安装与启动
这部分内容在前面的博客中已经介绍过一次,这里简单的重复一下相关的内容。安装我们还是推荐使用pip进行安装和管理:
$ python3 -m pip install mindinsight
启动的方法很简单,就是在指定的目录下运行:
mindinsight start
如果在terminal里面显示如下内容,则表示安装成功。
Web address: http://127.0.0.1:8080
service start state: success
使用Profiler分析算子性能
当我们构建好相关的网络之后,类似于CPU中的line_profiler,这里我们可以用MindSpore中所支持的Profiler来直接进行网络性能评估。这里的Profiler主要以算子为单位进行统计,最终会输出每一个算子的调用次数以及相关的占用时长。使用方法非常简单,就是在代码的开头写一句:profiler = ms.Profiler(start_profile=True)
,以及在结尾处写一句:profiler.analyse()
即可。
下面这个案例是MindSponge的一个能量极小化的案例。MindSponge是一个基于MindSpore框架开发的分子动力学模拟框架,更多的介绍和相关信息可以参考MindSponge教程系列博客。简单来说,这里我们只是模拟几百个水分子的动力学演化过程。
import os
os.environ['GLOG_v']='4'
os.environ['MS_JIT_MODULES']='sponge'
import mindspore as ms
from mindspore import context
from mindspore.nn import Adam
if __name__ == "__main__":
import sys
sys.path.insert(0, '..')
from sponge import Sponge, Molecule, ForceField, WithEnergyCell
from sponge.callback import RunInfo
context.set_context(mode=context.GRAPH_MODE, device_target='GPU', device_id=1)
profiler = ms.Profiler(start_profile=True)
system = Molecule(template='water.tip3p.yaml')
system.set_pbc_box([0.4, 0.4, 0.4])
system.repeat_box([5, 5, 5])
potential = ForceField(system, parameters=['TIP3P'], use_pme=False)
opt = Adam(system.trainable_params(), 1e-3)
sim = WithEnergyCell(system, potential)
mini = Sponge(sim, optimizer=opt)
run_info = RunInfo(10)
mini.run(200, callbacks=[run_info])
profiler.analyse()
该模拟过程的输出如下所示:
[MindSPONGE] Started simulation at 2023-09-11 10:57:03
[MindSPONGE] Compilation Time: 2.49s
[MindSPONGE] Step: 0, E_pot: 11003.434, Time: 2494.60ms
[MindSPONGE] Step: 10, E_pot: 9931.012, Time: 55.70ms
[MindSPONGE] Step: 20, E_pot: 9860.436, Time: 51.15ms
[MindSPONGE] Step: 30, E_pot: 9833.985, Time: 50.74ms
[MindSPONGE] Step: 40, E_pot: 9820.092, Time: 52.73ms
[MindSPONGE] Step: 50, E_pot: 9805.144, Time: 48.95ms
[MindSPONGE] Step: 60, E_pot: 9781.4375, Time: 47.87ms
[MindSPONGE] Step: 70, E_pot: 9740.486, Time: 48.46ms
[MindSPONGE] Step: 80, E_pot: 9684.311, Time: 48.67ms
[MindSPONGE] Step: 90, E_pot: 9619.269, Time: 52.02ms
[MindSPONGE] Step: 100, E_pot: 9555.06, Time: 51.39ms
[MindSPONGE] Step: 110, E_pot: 9498.154, Time: 47.72ms
[MindSPONGE] Step: 120, E_pot: 9450.13, Time: 49.52ms
[MindSPONGE] Step: 130, E_pot: 9408.7705, Time: 48.77ms
[MindSPONGE] Step: 140, E_pot: 9370.615, Time: 50.83ms
[MindSPONGE] Step: 150, E_pot: 9332.237, Time: 48.89ms
[MindSPONGE] Step: 160, E_pot: 9290.162, Time: 49.57ms
[MindSPONGE] Step: 170, E_pot: 9240.263, Time: 52.04ms
[MindSPONGE] Step: 180, E_pot: 9177.134, Time: 51.12ms
[MindSPONGE] Step: 190, E_pot: 9094.976, Time: 53.40ms
[MindSPONGE] Finished simulation at 2023-09-11 10:57:15
[MindSPONGE] Simulation time: 11.91 seconds.
--------------------------------------------------------------------------------
运行结束后,会在路径下生成一个data/profiler/
的目录,里面存放有我们所需的性能分析相关信息。但是需要注意的是,profiler本身也会占用很多的运行时间,所以使用profiler和不使用profiler的运行时间会有比较大的差别。我们如果只是希望对算法代码进行优化,只要保持在同一个条件(使用或不使用profiler)下进行分析即可。
MindInsight性能分析
如果在前面代码运行的路径下直接启动MindInsight,然后把http://127.0.0.1:8080
复制到浏览器里面打开,就可以看到对应的性能数据,如下图所示:

除了图形化的数据展示之外,还可以在列表中逐项展开,去查看每一个Operator的占用时间:

在这个结果中我们发现,由于使用了太多的Cast,有可能导致整体代码运行速度低下。如此一来,我们就可以挨个去查找代码中所用到的Cast算子,然后有针对性的进行优化:
$ grep -n -r "Cast" ~/projects/gitee/dechin/mindsponge/sponge/
/home/dechin/projects/gitee/dechin/mindsponge/sponge/potential/energy/coulomb.py:399: self.cast = ops.Cast()
/home/dechin/projects/gitee/dechin/mindsponge/sponge/potential/energy/coulomb.py:490: self.cast = ops.Cast()
$ grep -n -r "F.cast" ~/projects/gitee/dechin/mindsponge/sponge/
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/fullconnect.py:75: fc_idx = nrange + F.cast(no_idx <= nrange, ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/distance.py:142: max_neighbours = ops.count_nonzero(F.cast(mask, ms.float16), -1, dtype=ms.float16) - 1
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/distance.py:143: return F.cast(ops.reduce_max(max_neighbours), ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/distance.py:239: distances = F.cast(distances, ms.float16)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/distance.py:242: distances = F.cast(distances, ms.float32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/grids.py:324: sorted_grid_idx, sort_arg = self.sort(F.cast(atom_grid_idx, ms.float16))
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/grids.py:325: sorted_grid_idx = F.cast(sorted_grid_idx, ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/grids.py:356: grid_neigh_atoms, _ = self.sort(F.cast(grid_neigh_atoms, ms.float16))
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/grids.py:357: grid_neigh_atoms = F.cast(grid_neigh_atoms, ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/partition/grids.py:360: max_neighbours = F.cast(msnp.amax(F.cast(max_neighbours, ms.float32)), ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/metrics/metrics.py:455: classes_w_tensor = F.cast(classes_w_t2, mstype.float32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/metrics/metrics.py:482: classes_num = F.cast(classes_num, mstype.float32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/metrics/metrics.py:541: target = F.cast(target, mstype.float32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/metrics/metrics.py:542: probs = F.cast(prediction, mstype.float32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/function/operations.py:295: n = func.keepdims_sum(F.cast(mask, ms.int32), -2)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/function/functions.py:618: return F.cast(image, ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/function/functions.py:1409: value = F.cast(value, dtype)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/function/functions.py:1441: value = F.cast(value, dtype)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/system/residue/residue.py:262: self.natom_tensor = msnp.sum(F.cast(self.atom_mask, ms.float32), -1, keepdims=True)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/system/residue/residue.py:572: F.cast(self.atom_mask, ms.int32), -1, keepdims=True)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/system/molecule/molecule.py:633: self.system_natom = msnp.sum(F.cast(self.atom_mask, ms.float32), -1, keepdims=True)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/sampling/bias/metad.py:191: cutoff_bins = F.cast(cutoff_bins, ms.int32)
/home/dechin/projects/gitee/dechin/mindsponge/sponge/sampling/bias/metad.py:398: return F.cast(nearest_grid, ms.int32)
这里优化的思路和过程我们暂时就不做展示了,本文主要介绍的是一个性能优化的思路:先用profiler定位到性能决速步,然后有针对性的进行优化
。
MindInsight查看计算图
在使用AI框架进行计算的时候,我们的各种算子会被编译成一张大的计算图,使用MindInsight就可以对这个计算图进行可视化。使用方法也很简单,在设置context的时候多加上两项配置即可:
context.set_context(mode=context.GRAPH_MODE, device_target='GPU', device_id=1,)
save_graphs=True, save_graphs_path='./graphs/')
需要留意的是,这个save_graphs_path
一定要配置上,否则输出的一大堆文件在当前目录下,直接没眼看。接下来同样的运行代码,会在当前目录下生成一个graphs/
文件夹。此时刷新一下MindInsight的页面,点击最上面的训练列表
,这个时候就会看到有两个数据列:

其中graphs
这个数据列就是计算图的内容,点进去以后的界面如下所示:

如果我们比较关注计算图的话,就可以点进计算图的界面:

这个计算图的界面是根据右边的目录展开而展开的,如果我们想关注某一个模块的细节,就可以点进目录树:

这样的计算图结构,便于大家对整体的性能进行调节和优化。
总结概要
当我们需要优化程序性能的时候,首先我们就需要了解程序的主要耗时模块在哪里,也就是通常所谓的决速步,或者瓶颈模块,这样就可以有针对性的去进行优化。在MindSpore相关的程序中,我们可以使用MindInsight这一强力的性能分析可视化工具来进行分析。该工具会给出每个算子的调用次数以及总耗时等参数,能够给性能优化带来不少重要的参考。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/optimize.html
作者ID:DechinPhy
更多原著文章:https://www.cnblogs.com/dechinphy/
请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
MindSpore简要性能分析的更多相关文章
- java常用容器简要性能分析(List。Map。Set)
嗯,实习的时候看到这个,感觉蛮好,这里摘录学习,生活加油: 我曾经害怕别人嘲笑的目光,后来,发现他们的目光不会在我身上停留太久,人们更愿意把目光放在自己身上. 知乎上看到,讲给自己. List Lis ...
- 1.linux服务器的性能分析与优化
[教程主题]:1.linux服务器的性能分析与优化 [课程录制]: 创E [主要内容] [1]影响Linux服务器性能的因素 操作系统级 CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处 ...
- JS几种数组遍历方式以及性能分析对比
前言 这一篇与上一篇 JS几种变量交换方式以及性能分析对比 属于同一个系列,本文继续分析JS中几种常用的数组遍历方式以及各自的性能对比 起由 在上一次分析了JS几种常用变量交换方式以及各自性能后,觉得 ...
- CLR Profiler 性能分析工具 (转)
原文地址:http://www.cnblogs.com/kevinlzf/archive/2010/11/12/1876066.html 下载地址:http://www.microsoft.com/e ...
- linux服务器的性能分析与优化(十三)
[教程主题]:1.linux服务器的性能分析与优化 [主要内容] [1]影响Linux服务器性能的因素 操作系统级 Ø CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处理器可以在同一时间 ...
- JS几种变量交换方式以及性能分析对比
前言 "两个变量之间的值得交换",这是一个经典的话题,现在也有了很多的成熟解决方案,本文主要是列举几种常用的方案,进行大量计算并分析对比. 起由 最近做某个项目时,其中有一个需求是 ...
- Python程序的性能分析指南(转)
原文地址 :http://blog.jobbole.com/47619/ 虽然不是所有的Python程序都需要严格的性能分析,不过知道如何利用Python生态圈里的工具来分析性能,也是不错的. 分析一 ...
- 浅谈Unity的渲染优化(1): 性能分析和瓶颈判断(上篇)
http://www.taidous.com/article-667-1.html 前言 首先,这个系列文章做个大致的介绍,题目"浅谈Unity",因为公司和国内大部分3D手游开发 ...
- .NET内存性能分析宝典
.NET Memory Performance Analysis 知道什么时候该担心,以及在需要担心的时候该怎么做 译者注 **作者信息:Maoni Stephens ** - 微软架构师,负责.NE ...
- 如何进行python性能分析?
在分析python代码性能瓶颈,但又不想修改源代码的时候,ipython shell以及第三方库提供了很多扩展工具,可以不用在代码里面加上统计性能的装饰器,也能很方便直观的分析代码性能.下面以我自己实 ...
随机推荐
- ODOO13之 八:Odoo 13开发之业务逻辑 – 业务流程的支持
在前面的文章中,我们学习了模型层.如何创建应用数据结构以及如何使用 ORM API 来存储查看数据.本文中我们将利用前面所学的模型和记录集知识实现应用中常用的业务逻辑模式. 本文的主要内容有: 以单据 ...
- K8s Pod状态与容器探针
1.pod的调度流程及常见状态 1.1.pod的调度流程 Pod创建过程如上图所示,首先用户向apiserver发送创建pod的请求,apiserver收到用于创建pod请求后,对应会对该用户身份信息 ...
- STP生成树实验
实验拓扑 实验需求 所有设备都运行STP 改变阻塞端口 实验步骤 1.所有设备都运行STP ,等到收敛完毕,观察状态 [SW1]stp mode stp [SW2]stp mode stp [SW3] ...
- 如何让别人访问你本地允许的Vue本地项目
步骤一: 将config/index.js 中的host: localhost 改为 host:'0.0.0.0'步骤二:在package.json 将scripts 下面的dev 后 ...
- MySQL锁表解锁表
CREATE TABLE t1 ( id int(11) NOT NULL, val varchar(10) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoD ...
- C++面试八股文:static_cast了解一下?
某日二师兄参加XXX科技公司的C++工程师开发岗位第20面: 面试官:C++中支持哪些类型转换? 二师兄:C++支持C风格的类型转换,并在C++11引入新的关键字规范了类型转换. 二师兄:C++11引 ...
- 一文了解Go语言的函数
1. 引言 函数是编程中不可或缺的组成部分,无论是在Go语言还是其他编程语言中,函数都扮演着重要的角色.函数能够将一系列的操作封装在一起,使得代码更加模块化.可重用和易于维护. 在本文中,我们将详细介 ...
- 数据库varchar和tinyint和int和java实体属性的对应关系的学习
大家好,最近做项目碰到群里小伙伴的对于项目中用到的这几个类型,自己的java实体类属性该用什么类型干到困惑,于是乎,我决定为大家解密! 相信我,绝对干货,看完了,工资+200~哈哈哈,扯远了,闲话不对 ...
- python3使用PIL添加中文文本水印背景
环境:Windows10_x64 Python版本 :3.9.2 Pillow版本:9.1.1 写的博客文章被转载且不注明出处的情况时有发生,甚至有部分转载者将文章配图添加自己的水印!为了保护作 ...
- C#.NET Framework 使用BC库(BouncyCastle) RSA 公钥加密 私钥解密 ver:20230706
C#.NET Framework 使用BC库(BouncyCastle) RSA 公钥加密 私钥解密 ver:20230706 环境说明: .NET Framework 4.6 的控制台程序 . 20 ...