AI学习者 · 2021年06月23日

AI框架中模型调试调优能力构建思考与实践

转载于:知乎
作者: 金雪峰

本文是AI框架分析专栏的第六篇,总体目录参见:

AI框架的演进趋势和MindSpore的构想:

金雪锋:AI框架的演进趋势和MindSpore的构想

1 模型调试调优面临的挑战

1.1 模型精度调优

模型的精度调优是AI模型开发过程中必不可少的一步。导致精度问题产生的原因十分多样,包括数据集问题、超参设置问题、算法设计和实现问题、python编程问题等等。用户在模型调试时发现的异常现象,比如loss不收敛、梯度爆炸等,又往往处于问题的表层,很难判断问题的根因所在。

以梯度消失为例,初始权重不合理、学习率设置不当、数据集未正确处理等都可能引起该异常,需要算法工程师不断积累经验、耗费大量时间进行定位。在算法复杂度日益变高的今天,构建强大易用的精度调优工具帮助算法工程师快速找到问题的根因,是提升网络开发效率的关键。

1.2 模型性能调优

大模型是当前深度学习领域研究的热点之一。模型的参数量和训练数据集的大小均以指数级的规模快速增长。以近期MindSpore和鹏城实验室共同发布的盘古-α模型为例,模型的参数量达到了2000亿,使用2K集群耗费数月时间进行训练。在这样的背景下,模型性能调优对减少训练时间和成本有着至关重要的意义。大模型的训练涉及数据并行、模型并行、pipeline并行、重计算、host-device并行等多种技术,简单的算子执行时间统计已经远远无法满足性能调优的需要。为不同训练规模、训练范式(强化学习等)的模型训练提供高效的性能调优工具,是对AI框架提出的全新诉求。

2 MindInsight——MindSpore调试调优工具

2.1 MindInsight介绍

MindInsight为MindSpore提供了强大而易用的可视化调优调试能力,其中包括六大部分:

  • 训练看板:通过Summary接口,将MindSpore训练中的标量数据(loss、learning\_rate等)、计算图、数据图、图像输入、张量、参数分布信息等记录到Summary文件,并在训练看板页面可视化。训练看板支持在页面实时观察不同step的数据变化情况。
  • 溯源与对比看板:模型溯源功能支持将同一模型多次训练时使用的参数进行分别记录,并统一在页面进行对比分析,得到各参数重要性和优化目标。对比看板支持将多次训练的标量统一展示,可快速分析不同的loss曲线等变化情况。
  • 调试器:调试器是为图模式训练提供的调试工具,可以用来查看分析计算图节点的中间结果,快速定位精度问题根因。
  • Profiler: 在MindSpore模型训练过程中,可使用Profiler()接口将算子执行时间、集合通信时间等信息记录到profiling文件中,并通过Profiler页面从多个维度进行可视化分析,快速定位性能问题根因。
  • 模型转换:将ONNX格式的模型文件作为输入,可以转换生成MindSpore格式的网络定义脚本和模型权重文件,可直接基于脚本和权重文件在MindSpore进行模型fine tune或重训。
  • 模型解释:为用户提供对模型决策依据的解释,帮助用户更好地理解模型、信任模型,当模型出现错误时可以有针对性地进行改进。目前已构建了显著图可视化、解释方法评估、不确定性、反事实等模型解释能力。

本文将聚焦MindInsight中调试器和Profiler两大特性,阐述MindInsight如何系统性地解决精度调优与性能调优的挑战。MindInsight功能的详细介绍可以参考

使用可视化组件MindInsight - MindSpore master documentation​www.mindspore.cn

2.2 调试器——自动化的模型精度调试工具

AI模型的训练涉及数据处理、数据增强、模型构建、超参设置与调优等多个步骤,其中任何一个环节出现错误都可能导致模型的精度不理想。在模型训练出现异常时,算法工程师往往只能够观察到loss不收敛等现象,需要进一步分析网络中的中间结果定位根因。使用”print”等传统方式,并不能很高效地进行问题分析,其原因在于:

a. 与传统的静态代码相比,AI模型中的参数和权重随着训练的进行不停发生变化,这意味着训练任务的分析可能涉及上百万规模的不断变化的张量,人工”print”的方式难以满足这种量级的分析诉求;

b. 很多精度问题,如inf/nan、梯度爆炸等,具有“传染性”,找到首先出现这些问题的网络节点是定位问题的关键。令问题更加复杂的是,找到问题首现节点后,还需要更进一步地去定位问题的根因。例如,模型训练时出现Nan,可能是除零导致,需要进一步溯源分析上游节点的输出中是否有0存在。这对异常发现和上下文分析提出了更高的要求。

一个好的模型精度调优工具,应该具备如下功能:

  • 数据获取:算法工程师可以方便地指定想要分析的信息(如梯度、权重),调优工具在训练过程中能够记录下相关数据数据。在图模式的训练中,由于模型中间节点的输出结果不会返回至Python层,调优工具需要结合框架构建数据获取的能力;
  • 自动诊断:算法工程能够指定异常监测条件(如梯度消失、权重无更新等),由调优工具自动化地对选定的数据进行分析,在监测条件触发时,返回首个满足条件的节点信息;
  • 可视化分析:支持实时/离线分析张量数据的统计信息和变化趋势,支持对异常点的上下文数据进行溯源分析。

基于上述设计思路,MindInsight构建了强大易用的模型精度调试工具,即使算法工程师没有丰富的经验,也可以利用调试器快速对模型精度进行异常检测和分析。上图展示了调试器的页面,主要由以下部分组成:

1. 节点列表:按命名空间层次化地将模型节点进行展开/聚合,用来选择训练时监测的节点。支持按照节点类型(梯度、权重、激活等)、节点名称进行快速筛选。可以切换逻辑卡号检测不同节点上的数据。

2. 计算图:展示经过图优化后最终的执行图,同样支持按照命名空间展开/聚合,与左边的节点列表进行联动展示;

3. 节点信息:选中计算图上某个节点,在右下方会展示该节点的详细信息,包括输入/输出张量(名称/Type/Shape/Value等)、输入/输出节点名称、堆栈信息(可以找到该节点对应脚本中哪一行代码)等。

4. 张量检查视图:一些张量的维度过多,无法在主页展示,可以点击张量信息TAB页中的查看按钮,进入张量检查视图查看详细信息。用户可以选择不同的维度展示张量的不同切片,也可以通过最大值、最小值、平均值等信息对张量进行分析。通过张量关系图,可以得知当前张量是通过哪些张量计算出来的,以及影响到了哪些张量,方便用户快速对节点的上下文进行溯源分析。

5. 监测点列表:为了对选中的节点进行自动化异常诊断,调试器中内置了丰富的条件判断函数,这些检测条件根据专家经验总结而来,能够覆盖大量常见的精度调优异常。一些典型的监测条件如下表所示:

监测条件

作用

张量溢出 (Tensor Overflow)

检查张量是否出现溢出

权重未更新 (Weight Not Change)

检查权重在不同的step间是否有更新

权重初始值 (Weight Initialization)

通过阈值判断权重初始值是否在合理范围

权重变化过大/过小
(Weight Change Large/Small)

通过阈值判断权重变化是否过大/过小

梯度爆炸/消失
(Gradient Exploding/Vanishing)

检查梯度值是否存在上溢/下溢

激活值范围 (Activation Range)

通过阈值判断激活值是否在合理范围

对于需要使用阈值进行判断的监测条件,调试器会给出经验值设置推荐,算法工程师也可根据网络的特点进行自定义配置。

6. 训练控制:调试器支持在线和离线两种模式。在线模式中,用户可以在训练过程中暂停训练,逐节点地分析该step的中间结果;离线模式下,用户可以先将张量数据保存至磁盘/对象存储,然后作为调试器的输入进行分析。调试器支持重设监测点对当前step的数据进行多次检查。

7. 异常触发列表:调试器的监测规则被触发时,训练暂停,在异常触发List中,可以看到被触发的规则和触发该规则的节点。

MindSpore调试器使用流程

上图中给出了调试器的推荐工作流程:以Debug模式启动训练后,算法工程师首先在节点列表中选择训练时想要监测的张量,并设置相对应的异常检测规则,调试器会在训练过程中对监测张量进行采样和分析,并在异常触发后暂停训练;此时,可以在数据分析页面对触发监测规则的张量进一步分析(实时或离线),调试器也会给出相对应的建议帮助根因溯源。

此外,MindInsight为用户提供了详细的精度调优方法论指导,详细内容可以参考:

金雪锋:AI框架如何帮助开发者提升精度调优效率​zhuanlan.zhihu.com

2.3 Profiler——支持万亿级参数模型可视化性能调优

随着AI模型训练的数据集大小和参数量规模爆炸式增长,算法工程师越来越需要对模型进行细粒度地性能调优,以节省训练成本。当前AI模型的性能调优有比较高的门槛,主要体现在:

1. 性能调优需要算法工程师对AI全栈软硬件有一定的了解,同时掌握算法和系统两方面的知识;

2. AI框架提供了抽象的模型开发接口,算法工程师难以获得影响模型训练的关键信息(数据处理、算子性能、集合通信等待与计算、内存使用等),很多时候需要在代码中手动打点进行数据的收集、汇总与分析。Nsight/nvprof等工具虽然可以收集GPU kernel的执行性能,但却很难将其和high-level的code进行协同映射分析,指导用户进行代码层面的调优;

3. 随着模型规模的不断增大,为了解决“内存墙”问题,使用了更多训练节点以及模型并行、pipeline并行等技术。集群训练调优需要收集更多更复杂的数据,对影响性能的多个指标综合进行考虑;

4. 针对强化学习等新的训练范式,需要提供相对应的调试方法帮助算法工程师进行系统性的性能分析。

为了解决以上问题,MindSpore构建了强大的可视化Profiler工具。用户无需进行代码打点,通过简单的API调用即可一次性地收集完整的全栈性能数据。Profiler会对收集到的数据进行自动分析挖掘,提取出其中的关键点,并在可视化页面给用户针对性的调优指导。用户可按照Top-Down的层次化分析方法,快速了解训练性能:

1. 由迭代轨迹展开的单机性能分析

上图展示了Profiler单卡性能分析页面,由如下部分组成:

1)迭代轨迹:Profiler将整个耗时划分为三个阶段。迭代间隙表示训练获取数据的等待时间,前向+反向阶段表示计算耗时,迭代拖尾包括前反向计算结束到参数更新完成的时间。用户可以根据各阶段耗时比例,针对耗时占比较大的阶段在其他页面进一步分析。对于多卡场景,迭代轨迹还会展示通信算子耗时时长及其与计算算子的并行概览,让用户对于通信算子执行情况有整体的了解。

2)数据准备:如果迭代间隙耗时占比较高,说明数据跟不上计算的处理速度,用户可以到数据准备页面,继续分析是数据处理速度慢,还是数据从Host发往Device性能较差。

3)算子耗时统计排名:如果前向+反向阶段耗时占比较高,用户可以到该页面查看计算算子的耗时时长,分析是否有算子耗时不合理并针对耗时较长的算子做对应的优化。

4)时间线:时间线中可以展示算子执行序、算子间的并行情况等信息,用户可以通过该页面详细分析各算子是如何执行的,对于集群场景,也可以分析通信算子与计算算子的并行情况。

5)小助手:综合Profiling数据,对可能存在的性能瓶颈点提示用户重点关注。

2. 由多机到单卡的集群性能分析

对于集群场景,直接从单卡视角进行分析比较困难。尤其是大规模集群中,各个节点、链路的性能可能存在差异,性能下降的根因很难通过单卡的数据进行分析。Profiler以集群视角汇总了多项性能关键数据,并对多卡数据提供了排序、分析功能,用户可快速的从K级集群中找到慢节点、慢链路等,并从集群页面跳转到对应的单卡页面,进一步定界节点慢的原因,找到最小性能瓶颈点。

以上图为例,图中展示了集群中所有节点的关键阶段耗时,对各阶段耗时做排序分析后可以快速地找到集群内的瓶颈节点。同时,可以点击对应节点的Details按钮(上图红框内),跳转到单卡页面,进行进一步的性能分析。

针对集群性能分析中比较关键的集合通信操作,Profiler将其细分为通信等待(该芯片集合通信等待同步的时间)、通信耗时(集合通信数据传输与计算的时间)等阶段,方便用户判断通信算子主要耗时是在通信还是在等待。同时针对通信链路,Profiler提供了该链路上的通信数据量、通信耗时、链路类型等信息,用户可以观察集群中是否出现链路拥塞等问题。

3. 资源使用分析

训练过程中设备资源的使用情况也是用户非常关注的,比如芯片内存的占用和CPU/NPU的利用率。Profiler提供了模型在芯片侧内存使用情况的可视化,包括模型的内存分配概览(包括总可用内存、峰值内存等信息等)、模型运行过程中占用内存大小随执行顺序的变化以及每个执行算子的内存使用分解情况。用户可以根据内存信息来调试可能出现的OOM问题,对于模型并行、pipeline并行等集群训练,也可以根据内存信息调整算子或stage的切分。

针对Host侧CPU利用率,Profiler会记录整机、当前进程以及数据处理算子占用的CPU利用率变化趋势,方便用户观察在训练过程中CPU利用率的变化情况。特别是大集群场景下,用户无法同时对上千个进程进行监控,此时CPU利用率的记录就显得格外重要(我们遇到过一个真实的案例,K级集群训练过程中性能不达标,最终发现是某一个进程对应的用户CPU利用率低导致数据处理性能跟不上芯片的计算速度)。同时,通过对数据处理算子占用CPU利用率的可视化,用户可以对数据处理算子的线程数做对应的调整,以充分发挥数据处理的并发能力,提高整个训练的端到端性能。

4. 调优方法推荐

Profiler虽然收集展示了详细的性能数据,算法工程师仍然需要具备丰富的经验,才能够根据这些数据定位到性能瓶颈的所在。为了降低性能调优的门槛,Profiler内置了丰富的专家规则对性能数据进行自动化分析,在“小助手”模块展示分析结果。例如,数据处理时间较长时,“小助手”中会展示当前哪个数据处理算子是性能瓶颈,并提示用户通过增加该算子的处理线程参数提示性能。

在后续计划中,Profiler会进一步构建源码映射等能力,帮助用户快速找到需要修改的代码行;同时,会支持强化学习、多种并行策略等更多的场景,进一步提升Profiler的覆盖面;最后,Profiler也会在训练性能预测等方向进行探索,在训练前对关键的参数进行配置指导。

END

推荐阅读

更多嵌入式AI技术干货请关注嵌入式AI专栏。
推荐阅读
关注数
18802
内容数
1348
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息