# MindInsight_Profiler_Guide **Repository Path**: maning202007/MindInsight_Profiler_Guide ## Basic Information - **Project Name**: MindInsight_Profiler_Guide - **Description**: The MindInsight Profiler Guide for Internal Huawei users - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2020-07-14 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MindInsight Profiler使用说明 - [MindInsight Profiler使用说明](#MindInsight-Profiler使用说明) - [MindInsight Profiler概述](#MindInsight-Profiler概述) - [操作流程](#操作流程) - [Profiler环境准备](#Profiler环境准备) - [准备训练脚本](#准备训练脚本) - [启动MindInsight](#启动MindInsight) - [性能分析](#性能分析) - [迭代轨迹分析](#迭代轨迹分析) - [算子性能分析](#算子性能分析) - [MindData性能分析](#MindData性能分析) - [Timeline分析](#Timeline分析) - [Profiler CLI](#Profiler-CLI) - [启动命令](#启动命令) - [查看命令](#查看命令) - [导出csv文件](#导出csv文件) - [training trace](#training-trace) - [离线解析](#离线解析) - [规格](#规格) - [Frequently Asked Questions](#Frequently-Asked-Questions) - [Ask for Help](#Ask-for-Help) ## MindInsight Profiler概述 MindInsight Profiler是系统化的性能分析工具,能够帮助理解、分析、调试MindSpore程序性能。当前,只支持调试运行在Ascend芯片上的程序。 使用MindInsight Profiler,用户可以: * 方便地在训练脚本中启动、停止Profile功能 * 查看训练的迭代轨迹统计信息,快速定位性能瓶颈所在的阶段 * 分析神经网络中算子的执行性能 * 分析训练数据准备(MindData)阶段的性能 * 查看训练timeline,分析stream/task在Ascend芯片上的执行序列和执行时间 ## 操作流程 - 准备训练脚本,并在训练脚本中调用性能调试接口,接着运行训练脚本。 - 启动MindInsight,并通过启动参数指定profile文件目录,启动成功后,根据IP和端口访问可视化界面,默认访问地址为 `http://127.0.0.1:8080`。 - 在训练列表找到对应训练,点击性能分析,即可在页面中查看训练性能数据。 ## Profiler环境准备 使用Profiler前,用户需要首先安装Ascend芯片的run包,以及与run包匹配的MindSpore和MindInsight版本。MindInsight使用pip install命令安装whl包。 然后,按照如下顺序检查Profiler的使用环境: 1. 检查配置Ada服务 Ada服务用来收集profile相关的数据,首先检查系统ada服务是否正常,确认ada服务的启动用户是否与执行训练的用户一致(如root)。 有root权限的用户建议直接使用root登录,否则使用HwHiAiUser(Ada服务的默认启动用户)登录。 Run包刷新或者OS重启后,建议进行检查,如果ada服务启动用户与MindSpore训练时的用户不一致,profiling数据可能无法生成。 如果Ada服务异常或用户不一致,可按照如下步骤配置: - 拷贝证书到root目录 ``` mkdir -p /root/ide_daemon; cp -rf /home/HwHiAiUser/ide_daemon/* /root/ide_daemon ``` - 在root用户下重启ada进程 ``` pkill ada; /usr/local/HiAI/driver/tools/ada ``` 2. 检查关闭profiling文件的压缩功能,步骤如下: - 打开profiling的压缩配置文件 ``` vi /var/log/npu/conf/slog/ziplog.conf ``` - 查看profiling子项的压缩开关COMPRESS_SWITCH,如果不为0,则修改配置为0 Ada进程启动的tips: - 不要在conda环境下启动 - Ada启动后, 通过ps -ef命令确认启动成功 ## 准备训练脚本 为了收集神经网络的性能数据,需要在训练脚本中添加MindInsight Profiler接口。首先,在set context之后和初始化网络之前,需要初始化MindInsight `Profiler`对象; 然后在训练结束后,调用`Profiler.analyse()`停止性能数据收集并生成性能分析结果。 样例代码如下: ```python from mindinsight.profiler import Profiler from mindspore import Model, nn, context def test_profiler(): # Init context env context.set_context(mode=context.GRAPH_MODE, device_target='Ascend', device_id=int(os.environ["DEVICE_ID"])) # Init Profiler profiler = Profiler(output_path='./data', is_detail=True, is_show_op_path=False, subgraph='all') # Init hyperparameter epoch = 2 # Init network and Model net = Net() loss_fn = CrossEntropyLoss() optim = MyOptimizer(learning_rate=0.01, params=network.trainable_params()) model = Model(net, loss_fn=loss_fn, optimizer=optim, metrics=None) # Prepare mindrecord_dataset for training train_ds = create_mindrecord_dataset_for_training() # Model Train model.train(epoch, train_ds) # Profiler end profiler.analyse() ``` 其中, `Profiler`对象的参数配置包括: - subgraph: 统计的子图信息,可选项有'all', 'Default', 'Gradients',默认值为'all' - is_detail: 除了按照算子类型汇总数据外,是否要统计详细的算子实例信息,默认值为True - is_show_op_path: 算子实例是否显示带graph和scope的全名,设置为True时生效,默认值为False - output_path: 生成的统计数据文件存放路径,默认值为'./data' - optypes_to_deal: 按算子类型过滤,只统计显示特定类型的算子统计信息,比如Conv2d; 默认值为空,统计所有算子类型数据 - optypes_not_deal: 按照算子类型过滤,不统计显示特定类型的算子统计信息,默认值为 ["Variable"] 训练结束后,可以通过MindInsight UI从多个维度进行性能分析。 ## 启动MindInsight 启动命令示例: ``` mindinsight start --port 9001 --workspace /home/wy/workspace --summary-base-dir ./ ``` 参数配置: * port: 指定端口号,默认8080,但8080容易和其他服务的端口冲突,建议设置自己的端口号 * workspace: 指定workspace目录,目前主要用于存放MindInsight日志,默认路径:[HOME]/mindinsight * summary-base-dir: 指定profile数据存放的根目录 ![mindinsight_start](docs/mindinsight_start.png) 在浏览器中输入 ip:port(如10.110.43.56:9001)即可打开mindinsight页面。可以使用`MindInsight stop --port 9001`命令关闭MindInsight。 **需要注意的是,如果想非localhost访问UI,需要进行如下操作:** * 找到mindinsight包的位置 ```pip show mindinsight``` * cd到Location下的mindinsight目录,如: ```cd /root/wy/lib/python3.7/site-packages/mindinsight``` * 打开conf目录下的contants.py文件,按照下图,修改HOST、ENABLE_CORS和SUPPORT_REQUEST_METHODS: ![mindinsight_remote_start](docs/mindinsight_remote_start.png) ## 性能分析 用户从训练列表中选择指定的训练,点击性能调试,可以查看该次训练的性能数据。 ![performance_overall.png](./docs/performance_overall.png) 图1: 性能数据总览 图1展示了性能数据总览页面,包含了迭代轨迹(Step Trace)、算子性能、MindData性能和Timeline等组件的数据总体呈现。各组件展示的数据如下: - 迭代轨迹:将训练Step划分为几个阶段,统计每个阶段的耗时,按时间线进行展示;总览页展示了迭代轨迹图; - 算子性能:统计单算子以及各算子类型的执行时间,进行排序展示;总览页中展示了各算子类型时间占比的饼状图; - MindData性能:统计训练数据准备各阶段的性能情况;总览页中展示了各阶段性能可能存在瓶颈的step数目; - Timeline:按设备统计每个stream中task的耗时情况,在时间轴排列展示;总览页展示了Timeline中stream和task的汇总情况。 用户可以点击查看详情链接,进入某个组件页面进行详细分析。MindInsight也会对性能数据进行分析,在左侧的智能小助手中给出性能调试的建议。 ### 迭代轨迹分析 使用迭代轨迹分析组件可以快速了解训练各阶段在总时长中的占比情况。迭代轨迹将训练的一个step划分为迭代间隙 (两次step执行的间隔时间)、前向与反向执行、all reduce等几个阶段, 并显示出每个阶段的时长,帮助用户定界出性能瓶颈所在的执行阶段。 ![step_trace.png](./docs/step_trace.png) 图2: 迭代轨迹分析 图2展示了迭代轨迹分析页面。在迭代轨迹详情中,会展示各阶段在训练step中的起止时间,默认显示的是各step的平均值,用户也可以在下拉菜单选择某个step查看该step的迭代轨迹情况。 在页面下方显示了迭代间隙、前后向计算、迭代拖尾时间(前后向计算结束到参数更新完成的时间)随着step的变化曲线等,用户可以据此判断某个阶段是否存在性能优化空间。 迭代轨分析时需要识别fp第一个算子和bp最后一个算子。 - fp第一个节点和bp结束的节点由mindspore自动进行识别,识别方法是: fp begin默认为get_next之后连接的算子,bp end默认为最后一次allreduce之前的算子。 这种判断方法对某些特殊网络而言会存在问题,比如EfficientNet;**用户需要根据网络特点来判断自动打点是否合理**。 如果不想使用默认的打点,可以进行手动配置,配置方法为设置FP_POINT和BP_POINT两个环境变量: ![FP_BP_POINT](docs/fp_bp_point.png) - 用户也可以将某个AllReduce算子名称配置到环境变量,这样可以将其加入到迭代轨迹展示中。 ### 算子性能分析 使用算子性能分析组件可以对MindSpore运行过程中的各个算子的执行时间进行统计展示。 ![op_type_statistics.png](./docs/op_type_statistics.PNG) 图3: 算子类别统计分析 图3展示了按算子类别进行统计分析的结果,包含以下内容: - 可以选择饼图/柱状图展示各算子类别的时间占比,每个算子类别的执行时间会统计属于该类别的算子执行时间总和; - 统计前20个占比时间最长的算子类别,展示其时间所占的百分比以及具体的执行时间(毫秒)。 ![op_statistics.png](./docs/op_statistics.PNG) 图4: 算子统计分析 图4展示了算子性能统计表,包含以下内容: - 选择全部:按单个算子的统计结果进行排序展示,展示维度包括算子名称、算子类型、算子执行时间、算子全scope名称、算子信息等;默认按算子执行时间排序; - 选择分类:按算子类别的统计结果进行排序展示,展示维度包括算子分类名称、算子类别执行时间、执行频次、占总时间的比例等。点击每个算子类别,可以进一步查看该类别下所有单个算子的统计信息; - 搜索:在右侧搜索框中输入字符串,支持对算子名称/类别进行模糊搜索。 ### MindData性能分析 使用MindData性能分析组件可以对训练数据准备过程进行性能分析。数据准备过程可以分为三个阶段:数据处理pipeline、数据发送至device以及device侧读取训练数据,MindData性能分析组件会对每个阶段的处理性能进行详细分析,并将分析结果进行展示。 ![minddata_profile.png](./docs/minddata_profile.png) 图5: MindData性能分析 图5展示了MindData性能分析页面,包含迭代间隙和数据处理两个TAB页面。 迭代间隙TAB页主要用来分析数据准备三个阶段是否存在性能瓶颈,数据队列图是分析判断的重要依据: - 数据队列Size代表Device侧从队列取数据时队列的长度,如果数据队列Size为0,则训练会一直等待,直到队列中有数据才会开始某个step的训练;如果数据队列Size大于0,则训练可以快速取到数据,MindData不是该step的瓶颈所在; - 主机队列Size可以推断出数据处理和发送速度,如果主机队列Size为0,表示数据处理速度慢而数据发送速度快,需要加快数据处理; - 如果主机队列Size一直较大,而数据队列的Size持续很小,则数据发送有可能存在性能瓶颈。 ![data_op_profile.png](./docs/data_op_profile.png) 图6: 数据处理Pipeline分析 图6展示了数据处理TAB页面,可以对数据处理pipeline做进一步分析。不同的数据算子之间使用队列进行数据交换,队列的长度可以反映出算子处理数据的快慢,进而推断出pipeline中的瓶颈算子所在。 算子队列的平均使用率代表队列中已有数据Size除以队列最大数据Size的平均值,使用率越高说明队列中数据积累越多。算子队列关系展示了数据处理pipeline中的算子以及它们之间的连接情况,点击某个 队列可以在下方查看该队列中数据Size随着时间的变化曲线,以及与数据队列连接的算子信息等。对数据处理pipeline的分析有如下建议: - 当算子左边连接的Queue使用率都比较高,右边连接的Queue使用率比较低,该算子可能是性能瓶颈; - 对于最左侧的算子,如果其右边所有Queue的使用率都比较低,该算子可能是性能瓶颈; - 对于最右侧的算子,如果其左边所有Queue的使用率都比较高,该算子可能是性能瓶颈。 对于不同的类型的MindData算子,有如下优化建议: - 如果Dataset算子是性能瓶颈,建议增加num_parallel_workers; - 如果GeneratorOp类型的算子是性能瓶颈,建议增加num_parallel_workers,并尝试将其替换为MindRecordDataset; - 如果MapOp类型的算子是性能瓶颈,建议增加num_parallel_workers,如果该算子为python算子,可以尝试优化脚本; - 如果BatchOp类型的算子是性能瓶颈,建议调整prefetch_size的大小。 ### Timeline分析 Timeline组件可以展示: - 算子分配到哪个设备(AICPU、AICore等)执行; - MindSpore对该网络的流切分策略; - 算子在Device上的执行序列和执行时长 通过分析Timeline,用户可以对训练过程进行细粒度分析:从High Level层面,可以分析流切分方法是否合理、迭代间隙和拖尾时间是否过长等;从Low Level层面,可以分析 算子执行时间等。 用户可以点击总览页面Timeline部分的下载按钮,将Timeline数据文件 (json格式) 保存至本地,再通过工具查看Timeline的详细信息。推荐使用 `chrome://tracing` 或者 [Perfetto](https://ui.perfetto.dev/#!viewer) 做Timeline展示。 - Chrome tracing:点击左上角"load"加载文件。 - Perfetto: 点击左侧"Open trace file"加载文件。 ![timeline.png](./docs/timeline.png) 图7: Timeline分析 Timeline主要包含如下几个部分: - *Device及其stream list*: 包含device上的stream列表,每个stream由task执行序列组成,一个task是其中的一个小方块,大小代表执行时间长短; - *算子信息*: 选中某个task后,可以显示该task对应算子的信息,包括名称、type等 可以使用W/A/S/D来放大、缩小地查看timline图信息 **需要注意的是,为了避免Timeline数据过大而导致解析时间过长,MindInsight UI只会展示前20MB的Timeline数据。** ## Profiler CLI ### 启动命令 ```profiler_cli --op_type aicore_detail --op_path ./data/profiler --device_id 4``` 参数说明: * op_type: aicpu/aicore_cpu/aicore_detail中的一个,默认为aicore_detail * op_path: profiler文件夹路径 * device_id: 卡号,默认为0 ### 查看命令 ```op``` 或者 ```op --full_name XXX/XXX/XXX``` 参数说明: * full_name:非必选, 算子完整名称,没有full_name时,输出所有算子的op_name、op_type、avg_execution_time、subgraph、full_op_name、op_info信息,有full_name时输出算子详细输入输出信息 ![cli_op.png](./docs/cli_op.png) ![cli_op_fullname.png](./docs/cli_op_fullname.png) ### 导出csv文件 ```op --dump_csv ./dump_out``` 参数说明: * dump_csv: 指定生成csv文件的目录 ![cli_dump_csv2.PNG](./docs/cli_dump_csv2.PNG) ![cli_dump_csv.PNG](./docs/cli_dump_csv.PNG) ### training trace ```step --step_id 1``` 参数说明: * step_id: step_id,默认为0。0查询平均值对应的图,1-n查询第x个step对应的图 ![cli_step.PNG](./docs/cli_step.PNG) ### 离线解析 prof --job_id JOBXXXXXXXXXXXXXXXXXXXX --device_id 3 --output_path ./data 参数说明: * job_id: 训练时会在/var/log/npu/profiling目录下生成名称为job_id的文件夹,如果训练时没有使用profiler,也可以在训练结束后用profiler解析job_id文件夹中的数据 * device_id: 指定解析哪张卡的数据,默认为0 * output_path: 指定输出结果位置,默认为./data目录 ![cli_prof.PNG](./docs/cli_prof.PNG) ## 规格 为了控制性能测试时生成数据的大小,大型网络建议性能调试的step数目限制在10以内。 ## Frequently Asked Questions 1. 执行```/usr/local/HiAi/driver/tools/ada```指令,抛出错误信息“daemon init failed, exit” - 确认当前用户下 ~/ide_daemon的文件夹下证书是否存在,如果没有证书,更换启动用户为安装用户,或者复制证书 - 文件夹权限对IDE-daemon所属用户是否有读写权限,如果没有请增加读写权限 2. 安装mindinsight后,执行mindinsight命令行相关命令,提示找不到mindinsight命令 - 确定mindinsight命令可执行文件的路径,通常在“python安装目录/bin”下面 - 执行which mindinsight命令,查看linux会在哪些路径下查找mindinsight命令 - 如果前两步对应的路径不同时,会导致找不到mindinsight命令,可以在第二步路径下建立mindinsight软连接,连接到实际可执行文件的位置,如 ```ln -s /usr/local/python3.7/bin/mindinsight /usr/local/python3/bin/mindinsight``` 3. profier.analyse提示” Fail to get profiling job, please check whether profiling job path is exist under path”错误 - 检查profiling JOB目录有没生成 ``` ls –alrt /var/log/npu/profiling/ ``` 如果没有生成,则检查ada服务是否正常 - 检查job profiling路径下,host_start.log文件是否生成 ``` cd /var/log/npu/profiling/JOBDEAHCGBCECAHBJDJIBCAAAAAAAAAA ls –l host_start.log ``` 如果没有生成,则检查ada服务是否正常,是否开启了文件压缩功能 - 检查device id是否匹配 检查训练脚本,环境变量是否设置了”DEVICE_ID” 比如: export DEVICE_ID=”4” 如果没有设置,profiler默认取device 0,可能与实际devcie id不匹配 4. 如果之前没有使用MindInsight Profiler,原有的Profile数据能否集成到MindInsight Profiler中? 可以集成。 场景:直接使用ada工具profile训练,Job目录文件在默认目录下(/var/log/npu/profiling)已经生成。 集成步骤: * 检查JOB目录在/var/log/npu/profiling/下存在,如: ``` ls -l /var/log/npu/profiling |grep JOBHEJDICBADIBHFCCCFJGAAAAAAAAAA ``` ![profiling_job_dir](docs/profiling_job_dir.png) * 执行python,进行数据解析 ``` # python Python 3.7.5 (default, Jan 11 2020, 18:38:06) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from mindinsight.profiler.profiling import Profiler >>> profiler = Profiler(job_id="JOBHEJDICBADIBHFCCCFJGAAAAAAAAAA") >>> profiler.analyse() ``` * 生成结果位置和训练脚本中进行集成相同 5. 安装mindinsight后,执行mindinsight命令行相关命令,提示找不到mindinsight命令 解决办法: * 确定mindinsight命令可执行文件的路径,通常在“python安装目录/bin”下面 * 执行```which mindinsight```命令,查看linux会在哪些路径下查找mindinsight命令 * 如果前两步对应的路径不同时,会导致找不到mindinsight命令,可以在第二步路径下建立mindinsight软连接,连接到实际可执行文件的位置,如 ```ln -s /usr/local/python3.7/bin/mindinsight /usr/local/python3/bin/mindinsight``` ## Ask For Help 如果遇到问题,可以发送邮件到wangyue53@huawei.com寻求帮助