# 模型编译的性能优化总结

如果在模型编译过程中发现step=1的耗时很长，可分析模型编译是否能进行性能优化。

MindSpore静态图模式下，部分场景可以通过改变网络写法，使用等价语义替换，或者设置编译选项改变编译机制来优化网络编译性能。

**1 规避动态shape来优化编译性能**

当step = 1和step != 1的耗时差不多且都很慢时，可能网络在进行多次编图。可能原因为：网络中存在动态shape。

网络多次编图的判定方法

1.export GLOG\_v=1， 开启mindspore的info日志

2.开始训练，只需要训练几个step即可

3.在训练日志中grep “Start compiling” 和grep “End compiling”，正常只有一次Start和End。如有多次则网络在多次编图，考虑图中存在动态shape

动态shape的判定方法

当前只能通过打印网络中输入，看是否动态变化来判定网络是否为动态shape。

之后将推出动态shape判定工具。

**2 优化编图来优化编译性能**

**2.1 使用Select算子优化编译性能**

当图中存在控制流算子时，网络会被切分成多个执行子图，子图间进行流程跳转和数据传递造成模型编译慢。

当分支中算子数量较少时，可通过使用Select算子来替换控制流算子，达到优化编译性能。当分支中算子数量较多，建议保留使用if语句。

示例代码：

if语句代码：

```
if ms.ops.reduce_sum(object_masks) == 0:
    stage2_loss = stage2_loss.fill(0.0)
修改为使用select代码：
stage2_loss = ms.ops.select(ms.ops.equal(ms.ops.reduce_sum(object_masks), 0), stage2_loss.fill(0), stage2_loss,)
```

具体可参考：使用select算子优化编译性能

**2.2 使用vmap优化编译性能**

```
mindspore.vmap(` *fn* `, ` *in_axes=0* `, ` *out_axes=0* `)
```

自动向量化（Vectorizing Map，vmap），是一种用于沿参数轴映射函数 fn 的高阶函数。由于自动向量化并不在函数外部执行循环，而是将循环逻辑下沉至函数的各个原语操作中，可获得更好的性能

在处理无依赖关系的批量数据且相关的算子支持vmap功能时，可以使用vmap替代for循环处理批量数据来优化编译性能。

**具体可参考：**

[vmap详解](https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore/mindspore.vmap.html?highlight=vmap)

[vmap替换for循环代码来优化编译性能样例](https://mindspore.cn/tutorials/experts/zh-CN/r2.0/network/op_overload.html?&highlight=%25E6%258E%25A7%25E5%2588%25B6%25E6%25B5%2581%25E7%25AE%2597%25E5%25AD%2590#%25E4%25BD%25BF%25E7%2594%25A8vmap%25E4%25BC%2598%25E5%258C%2596%25E7%25BC%2596%25E8%25AF%2591)

**2.3 使用HyperMap优化编译性能**

HyperMap是一个特殊的类，类对象构造时需要传入映射函数f，调用对象时需要传入f的n个参数序列，更多使用方法见：HyperMap。映射函数f必须是MultitypeFuncGraph类型, 可参考MultitypeFuncGraph。

在使用for循环批量处理列表元素时，可以通过HyperMap等价语义替换来优化网络编译性能。

具体可参考：HyperMap替换for循环代码来优化编译性能样例

**3 使用编译缓存优化编译性能**

编译缓存的本质是存储了网络模型的编译中间过程文件，当网络模型不变时，生产的编译中间过程文件也是一样的，因此可以复用上一次编程产生的中间过程文件。

mindspore在模型编译过程中会生成kernel\_meta等缓存文件。

在进行训练或者推理时，如果某个网络结构未作任何变更，那么可以通过使用编译缓存来缩短编译时间。

方法1：

脚本中可不删除kernel\_meta等缓存文件。

方法2：

设置set\_context\(enable\_compile\_cache=False\) 来优化编译性能。

具体可参考：[使用编译缓存优化编译性能](https://mindspore.cn/tutorials/experts/zh-CN/r2.0/network/op_overload.html?&highlight=%25E6%258E%25A7%25E5%2588%25B6%25E6%25B5%2581%25E7%25AE%2597%25E5%25AD%2590#%25E4%25BD%25BF%25E7%2594%25A8%25E7%25BC%2596%25E8%25AF%2591%25E7%25BC%2593%25E5%25AD%2598%25E)

