# 大模型动态图训练性能调优指南

大模型具有更多的参数量和更复杂的模型结构，在训练过程中需要耗费更多的计算资源和时间。尤其在AI框架动态图模式下易于开发调试带来了极大的灵活性，但也暴露了更多的性能及内存问题。本文将重点介绍昇思动态图下，大模型性能及内存常见的调优方法，以及如何使用工具快速分析并解决瓶颈，帮助大模型开发者们快速上手模型性能调优，提升训练效率，降低训练成本。

**1. 典型性能统计指标**

1.  单步时间\(s\)：执行完一个完整BS的时间。
2.  吞吐\(Samples/s\)：网络模型在单位时间内可以处理的最大输入的训练样本数据。throughput =BS ∗N /step \_time。其中，BS为每个数据并行维度的batch size大小，N为集群中数据并行维度的大小，step\_time为在分布式集群中，执行完一个完整BS的时间（单位为s）。
3.  MFU\(%\)：Model FLOPs Utilization，即模型算力利用率，是指模型一次前反向计算消耗的矩阵算力与机器算力的比值。它直接反映了模型在训练过程中对计算资源的有效利用程度。MFU的值受到多种因素的影响，包括但不限于：

    模型架构：不同架构的模型在分布式训练中的算力利用率可能存在显著差异。例如，Transformer架构的模型由于其并行性和矩阵运算密集的特点，通常能够在分布式训练中实现较高的MFU。

    分布式训练策略：包括数据并行、模型并行、流水线并行等不同的并行策略及这些策略的具体实现方式（如梯度累积、张量并行等），都会对MFU产生重要影响。

    硬件环境：显卡型号、数量、网络连接速度等硬件因素都会限制分布式训练的性能和算力利用率。

    软件优化：包括编译器优化、库函数优化、自动混合精度训练等软件层面的优化措施，也能在一定程度上提升MFU。

    数据集和批次大小：数据集的大小和复杂性，以及训练时使用的批次大小，也均会影响每次迭代中的计算量和算力利用率。

4.  线性度：单卡训练扩展到多卡、多机多集群后的效率度量指标称为线性度，又名加速比。一般根据吞吐率计算得到。即集群线性度为多机总吞吐率/（单机吞吐率\*集群卡数）。线性度的取值范围为0\~1，数值越接近于1，其性能指标越好，一般大于0.8认为较优。

**2. MindSpore动态图机制介绍**

**动态图PyNative框架**

MindSpore PyNative动态图模式采用pybind算子直调方法，提升API性能。2.3版本前，大部分API使用了小算子进行拼接，同时采用了单算子子图进行执行，需要进行单算子子图构图、编译优化、算子选择、算子编译等一系列操作，首轮性能较差。针对这两点进行性能优化，提出了算子直调的方式，即正向算子执行直接pybind调用到底层算子接口，减少整体流程和数据结构转换开销。不同API，性能提升0.5\~4倍。此外，提供了基础分布式能力接口，如硬件相关接口、重计算接口、通信基础接口等。

详细介绍见：[动态图支持算子直调](https://www.mindspore.cn/news/newschildren?id=3223&type=versionRelease)

**3. 性能调优**

为了优化前文介绍的性能度量指标，提升训练效率，一般从如下几个维度拆解优化。

·数据处理耗时：指模型加载训练数据和权重的时间，包括将数据从硬件存储设备读取到CPU、在CPU中进行数据的预处理、以及CPU数据传输到NPU的过程。对于需要切分到若干张NPU上的模型，数据加载时间还包括从一张NPU广播到其他NPU上的时间。

·Host下发耗时：指Python侧脚本逻辑及api接口launch的时间，一般希望这部分耗时与Device执行流水起来，避免Device空闲。

·Device执行耗时：NPU侧执行各个算子计算逻辑的时间。

·通信耗时：指在分布式训练中，设备之间进行通信传输的时间，可以通过优化网络拓扑、减少通信频率等方式来减少通信耗时。同时，通信和计算通常可以并行执行，并行库提供的并行技术会保证部分通信时间被掩盖。

**4. 用户编程checklist**

·关闭确定性计算

ms.set\_context\(deterministic='OFF'\)

·关闭流同步

ms.set\_context\(pynative\_synchronize=False\)

·使用高性能API

·mint：MindSpore提供了对标PyTorch的mint系列接口，绝大多数情况下，其性能会持平或高于原ops系列接口。详情参考API列表：[mint接口列表](https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore.mint.html)

·大模型融合算子，如RotaryPositionEmbedding、Swiglu等。

·避免冗余的数据拷贝

·尽量采用原地更新接口，减少冗余Tensormove操作

·减少不必要的转连续操作：当前aclnn算子大多支持非连续输入，尽量减少在脚本中大量使用.contiguous\(\)，或可以先is\_contiguous\(\)判断后再调用。

·避免频繁数据拷贝：需要数据拷贝时，尽量采用.from\_numpy接口，当数据连续时，会通过免拷贝方式将Numpy数组转换为张量。[mindspore.Tensor.from\_numpy](https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore/Tensor/mindspore.Tensor.from_numpy.html)

·减少原生Python累加等函数使用，如.sum\(\)（建议替换成mint.sum\(\)）

**5. 高阶优化特性**

·JIT：将Python函数编译为可调用的MindSpore静态图，MindSpore可以在运行时对图进行优化，提升该模块性能，一般选择在优化器构造函数处添加@jit标签。详见：[jit介绍](https://www.mindspore.cn/docs/zh-CN/master/api_python/mindspore/mindspore.jit.html)

**6. 性能分析案例**

[MindStudio Insight用户指南](https://www.hiascend.com/document/detail/zh/mindstudio/70RC3/msinsightug/msascendinsightug/Insight_userguide_0002.html)

