作者​:昇腾实战派
知识地图​:https://blog.csdn.net/Lumos_Lovegood/article/details/161601003

摘要

精度问题一直是AI领域中的难点问题,小模型领域模型数量繁多、模型种类多样,推理技术路线多样,精度问题的原因五花八门,定位时间通常较长。本文对小模型推理精度问题做了系统性的抽象,进行剖析和整理,试图建立一个结构性的框架来讨论小模型精度问题,也便于初学者对整个小模型精度领域建立起基本的概念。

本文先给出昇腾小模型推理精度问题的定义,详细拆解定义的每个词汇,根据定义给出小模型精度问题的两大重要分类,给出精度问题的判断标准,随后从三个不同角度讨论小模型推理精度问题的来源,pipeline维度和时间线维度侧重体现“存在性”,分别从模型业务流的各个阶段和各类操作分析可能出现的精度问题,根因维度侧重“构造性”,从模型、算子、框架/引擎、pipeline、硬件五大因素分析精度问题的来源。随后给出泛化性较广的通用精度问题定位方法,最后结合CV、OCR、语音等不同类别模型的真实精度问题案例进行讲解。

一览图

小模型精度问题综述

精度问题的定义

精度问题没有一个绝对的定义,这里总结一个小模型推理精度问题的笼统定义,即包含​​模型的业务在昇腾平台上使用特定合理输入推理时出现的客观各类结果不符合预期的稳定/偶现的现象​。

“包含模型的业务”:是精度问题的​实际场景​。一个精度问题一定存在一个或多个模型,可能只是单个模型直接输出异常的精度问题,可能是多模型串联复杂业务流中的精度问题。

“昇腾平台”:是精度问题的​物理载体​。一个精度问题一定对应一种昇腾硬件,可能是从其他平台迁移到昇腾平台发现精度问题,也可能是基于昇腾平台直接发现的精度问题。

“特定合理输入”:是精度问题判断的​两个充要条件之一​。一个精度问题一定存在一个或多个“特定合理输入”,精度问题是在这个“特定合理输入”的前提下展现出来的,即“bad case”,bad case可能是一个或多个(只有特定输入触发、只测试了某个输入),可能对于任意输入(原始输入如图片、语音等,模型中间输入如特定tensor)都会出现精度问题。这里的“合理”非常重要,是明确是否是精度问题的依据,也就是bad case是否能真正判断精度有问题,而不是一个错误前提。

“推理”:是精度问题从AI​​两大场景(训练、推理)的分类​。这里专注推理场景下的精度问题。

“客观各类结果不符合预期”:是精度问题判断的​两个充要条件之一​。也是精度问题的表象,这里说的不符合预期可能有多种情况,可以分为“有标杆场景”和“无标杆场景”,可能是跟CPU的输出对应不上,可能是OCR模型识别结果不正常等,且不能是主观认为的异常。

“稳定/偶现”:是精度问题的​频次表现​。精度问题可能是稳定复现,也可能是偶现的,通常都是稳定的,偶现问题更难定位,对应根因可能更为复杂。

“真假”精度问题

通常遇到的“精度问题”中,可能一部分占比并不是“真正的精度问题”,而是人的误判,错误前提等导致论断出现精度问题。从上帝视角看,精度问题可以分为“真正的精度问题”与“伪精度问题”,“真正的精度问题”即由如数值溢出等种种原因导致确实模型效果异常,“伪精度问题”即错误前提、错误判断,导致认为产生了精度问题,而实际并不存在问题。

“伪精度问题”的判断

从精度问题的定义里可以看到两个非常重要的指标,一是“特定合理输入”,二是“客观各类结果不符合预期”,不满足任意一个条件的即是“伪精度问题”。

“特定合理输入”需要我们保障bad case的合理性准确性。

“客观各类结果不符合预期”可以分为有标杆的判断和无标杆的判断。

“有标杆场景”:有标杆场景是判断的黄金法则,“无标杆场景”也可归一到“有标杆场景”,只是有时候不方便或者没必要去做。这里的“标杆”可以是其他类型的硬件,可以是其他格式的模型如ONNX。如同样输入在CPU和NPU对应输出不一,同样输入在NPU转换OM后与ONNX对应不上,数据集测试精度与某论文不一致。

“无标杆场景”:不涉及标杆或不方便对比标杆,但可通过实际下游任务场景判断出现精度问题。如一个OCR模型,识别图片里的字母不对,识别错误、识别漏、乱码等明显精度存在异常的现象;或一个语音TTS模型,生成的语音都是背景噪声。

下面针对具体精度案例,进一步说明这两个指标对于“真正的精度问题”判断的重要性。

针对“特定合理输入”,最常见的就是bad case选择产生的问题,如验证一个目标检测模型,构造了随机输入,输出与标杆不一致判断为精度问题,但实际因为这里的bad case是随机产生的噪声数据导致输入无意义,实际下游评测结果精度无问题。这个就是典型的bad case不合理导致产生的“伪精度问题”。

针对“各类结果不符合预期”,首先来看“有标杆场景”,如标杆不准确,标杆的结果错误,与标杆对比认为出现精度问题,但这是由于选择了错误的标杆或标杆数据异常导致,实际并不存在精度问题,这个就是标杆不合理导致产生的“伪精度问题”,再如对比下游数据集精度,误差0.5%,认为存在精度问题,但实际与标杆误差在1%内认为并不存在精度问题,这个就是主观认为的结果不符合预期导致的“伪精度问题”;对“无标杆场景”,如一个OCR模型识别一张倒着的文字图片,识别完全错误,认为存在精度问题,但这是由于模型本身能力的问题,未经过前处理,图片质量不高影响模型效果,虽然bad case没有问题,但这个识别错误就是符合预期,只是没有相应标杆,你认为不符合预期,也是属于主观认为的结果不符合预期导致的“伪精度问题”;又如因为人的误用,使用了错误的测试脚本、测试方法。

精度问题标准

下面详细介绍精度问题的判断标准,证明不存在精度问题,理论上没法证明,因为不可能穷尽所有的场景,但证明存在精度问题,只需举出反例即可,也就是前面说的bad case,根据数量可以分为单bad case场景和bad case集合场景。

单bad case场景:一条bad case,可以是实际业务数据,也可以是人为构造的合理数据,优点在于快速,因为数据量少,简单,可以快速测出精度问题存在性。但需要注意的,就是“合理性”,比如不能是随机数导致全是噪声,模型中若含有topk算子则会导致无意义的排序,产生“伪精度问题”。

bad case集合:也就是bad case数量很多,通常是数据集场景,如数据集测试精度不满足基线,于标杆相差大等,那么区别的几条数据就是bad case集合,通过数据集测试不用人为构造数据,也不需要提供可能涉及敏感的业务数据,且对应标杆值通常明确。

由于不同类别的小模型,功能差异较大,评判标准也有所差异,需要具体讨论。

在bad case集合场景下,也就是数据集精度的标准下,通常认为精度误差大于1%则存在精度问题。

而单bad case场景下,可以通过中间输出或最终输出来判断,最终输出如CV目标检测类模型,输出一般为坐标和类别,若坐标相差一两个像素点,则通常不认为存在精度问题,而置信度相差1%以上则存在精度问题;中间输出如核心模型推理的输出tensor,对比与标杆(torch-gpu、onnx-cpu)等,结合余弦相似度与最大绝对误差等指标进行判断,通常认为余弦相似度小于99.9%则存在精度问题。值得注意的是,单bad case的评价是不一定准确的,可能存在即使针对某个单bad case认为有精度问题,但下游任务测试无问题的情况,数据集精度测试是判断存在精度问题的核心标准。

小模型精度问题来源

pipeline维度

总览

pipeline维度是从模型或业务流程角度考虑的维度,模型推理过程一定存在一个pipeline,一般是前处理->核心模型推理->后处理,也就是经典的“三段式”,可能有一定的变种,如多个不同模型串联甚至并联,又或者没有前处理/后处理,比如前处理1->模型1推理->后处理1->模型2推理->后处理2。场景也可能比较复杂,pipeline可能整个都是在云端,也可能是端侧->云端->端侧。且前后处理的定义也是相对的,如这里的后处理1其实也可以认为是模型2的前处理,且前后处理可能也包含多个细分的子阶段。但体现出的都是推理流程的可划分性,总是分为不同的阶段,或大或小,或多或少。

按照该维度看待,精度问题的来源存在于一个或多个阶段中,如位于前处理阶段,原因是前处理未对齐;又如位于核心模型推理阶段,原因是算子数值溢出;又如一个精度问题是多个阶段产生的精度问题的叠加,既存在前处理对齐的问题又存在算子数值溢出等多个问题,解决一个阶段对应的子问题后仍不能解决整体精度问题,这样的例子在实际问题中很多。

前处理

前处理为将原始数据转化为模型可以接受的格式或者是一些推理前的额外操作。不同类别的模型对应典型的前处理不尽相同,根据小模型的分类,如CV类模型典型的前处理图片resize、padding、crop、色域转换等,OCR类模型典型的前处理图片方向矫正、亮度调整,语音类模型典型前处理VAD、重采样等。

在前处理中,可能导致精度问题的情况有很多,如图片被resize导致比例严重失调会影响模型效果,进而导致精度问题;又如OCR场景图片昏暗,字体歪斜甚至字体倒置等图片质量不佳的情况,未做前处理对图片进行调整,可能会严重影响精度;又如前处理的一些参数未与标杆对齐,从而导致有标杆场景的精度对不齐。

核心模型推理

核心模型推理为模型forward过程,从小模型推理技术路线看,核心的模型推理过程,存在torch_npu、torchair、onnx、om、paddle五条最终技术路线,其中可能涉及模型转换(如OM),模型代码修改(如torchair)等,针对核心模型推理阶段可能会引入较多的精度问题,下面根据路线详细展开介绍。

在这里插入图片描述

torch_npu

torch_npu路线在小模型领域是最常见的路线,也是最为简单的一种,通常是基于自动迁移进行某个模型的适配推理。

torch_npu路线通常不会出现精度问题,若torch_npu路线出现精度问题,即eager模式下的精度问题,可能是算子导致。若存在GPU标杆,可直接与标杆对比,否则可构造CPU标杆,通过与CPU进行对比,通过dump数据进行比较。

torchair

torchair路线是在torch_npu路线基础上进行的图模式适配,是torch_npu的进一步优化,通常为了性能考虑减轻host bound,有进一步适配的工作量。

由于torch_npu路线完全是torchair路线的前置,故这里存在两种情况:

(1)torch_npu路线精度有问题,torchair精度也有问题

该情况下,因为前置的torch_npu适配就存在精度问题,直接定位torchair精度问题无意义,需转换为torch_npu路线下的精度问题,通过取消图模式适配,回退到torch_npu。通常有以下的回退方式,注释掉核心的代码model = torch.compile(model, backend=npu_backend);或是设置参数disable=True控制回退到eager单算子模式。

(2)torch_npu路线精度无问题,torchair精度有问题

在确保torch_npu路线精度无问题的情况,torchair存在精度问题,由于torchair存在适配工作,精度问题的来源也就是在torchair适配过程,其中torchair精度问题又可细分为原生Dynamo导致的精度问题和Ascend IR计算图导致的精度问题。

“原生Dynamo导致的精度问题”:涉及pytorch原生的机制,并非昇腾因素导致。由于图模式下的逻辑可能与单算子模式不同,故可能导致模型结构出现差异从而导致精度问题。如y.extend(self.m(y[-1]) for _ in range(3)) 使用了生成器表达式, Dynamo对该代码结构的静态分析中,并不会更新每次计算后的y[-1]导致生成相同的输出,即[x1, self.m(x1), self.m(x1), self.m(x1)]导致语义不符,产生精度问题,通过显示循环展开来等价重写即可,这也就是torchair适配需要修改模型代码的部分。

“Ascend IR计算图导致的精度问题”:涉及昇腾Ascend IR,非pytorch原生问题。可能是一个算子成Ascend IR图后导致的精度问题,这时对应算子问题,需要排查单算子成图和Ascend IR实现;也可能是整图中存在精度问题,可以通过dump数据与eager模式对比,这里的标杆就是已验证无精度问题的torch_npu的eager模式,作为自我标杆。

onnx

onnx路线主要是指onnxruntime-cpu和onnxruntime-cann,而onnx则是由其他框架统一导出的通用格式,可能是pytorch->onnx,可能是paddle->onnx或者其他框架,也可能是直接拿到的onnx模型,故可能存在**2onnx的转换步骤。

若存在**2onnx的转换步骤,其中涉及不同框架下导出onnx的工具/接口,如torch.onnx.export接口是pytorch框架下模型导出onnx的接口,paddle2onnx工具是paddlepaddle框架下模型导出onnx的工具,全部都是框架原生自带的功能,一般该转换不会出现精度问题,也不涉及昇腾技术栈。如paddle2onnx会看护模型,有的模型未适配,无法导出onnx,则不存在所谓精度问题,而能导出onnx的模型,一般经过验证。少数情况下onnx本身存在问题,可能是导出的问题。

前面论述了得到onnx的经过,然后就是onnx的推理了,其中onnxruntime-cpu,使用host cpu推理onnx,在确保onnx导出正常无问题的情况下,推理阶段认为也不会存在精度问题,可以作为自我标杆。

而针对onnxruntime-cann,其核心也是将onnx转换为om进行推理,可以转换为om技术路线下的精度问题。但值得注意的是,由于这个转换是自动完成的,差异就在这个自动里,可能存在一些隐含的导致精度问题的另类原因。如当存在多进程多实例推理时,自动转换om的过程存在文件的竞争读写,会导致模型转换有误,从而导致精度问题。

om

om路线是通过ATC工具得到的昇腾平台专属的离线模型,模型转换过程中可以实现算子调度的优化、权值数据重排、内存使用优化,通常性能会得到较大优化,但与此同时也可能引入精度问题。通常onnx是om的前置阶段,而onnx一般不会出现精度问题,而om由onnx转换得到,故这里天然就有了个自我的标杆,即使用onnx-cpu对比om-npu。

通常om路线中的精度问题同样分为转换阶段和推理阶段可能遇到的问题,转换阶段主要为整网/算子精度模式设置错误导致、图融合导致、高性能模式引入、aipp操作导致等。推理阶段,om主要使用acl接口或aisbench离线推理接口进行推理,推理阶段一般不会存在精度问题。

paddle

paddle路线主要是指使用paddlepaddle框架原生的支持NPU硬件能力,进行原生推理,基于paddle-custom-npu插件,若通过paddle2onnx转为onnx再转为om,完全离线推理则不涉及此路线。原生paddlepaddle接入aclnn/aclop算子,若存在精度问题,通常也是算子问题。此外,还可以使用高性能推理管道HPIP进行om的推理,但不支持动态shape,有较多局限性,该场景下的精度问题可以转换为静态shape的om路线下的精度问题。

后处理

后处理为将模型推理得到的输出转化可以直观理解的数据,或者是推理结束后一些额外需要完成的操作。同样根据模型种类不尽相同,如CV类模型典型的后处理非极大值抑制nms、画框,OCR类模型典型的后处理OTS到HTML格式转换、合成Markdown/JSON等,语音类模型典型后处理如ASR场景下对标点的增加等。

由于后处理是最终输出的前一步,即使前面核心模型推理阶段都能对齐,没有精度问题,但后处理阶段出现问题同样会导致精度问题,如后处理流程、参数等未对齐。

时间线维度

时间线维度是从人做事的时间线来看待,侧重的是发现这个精度问题之前,你都做了些什么,这个问题是如何一步步出现的。典型的场景,如对一个pytorch下的小模型适配离线推理,可能的时间线是这样的:

下载模型代码权重->搭建环境->修改模型代码替换算子->模型导出onnx->onnxsim工具进行onnx优化->使用auto_optimizer进行优化->配置aipp->配置fusion_switch_file文件->ATC命令转换OM->使用aisbench工具对于onnx进行模型验证。

与pipeline维度侧重的模型业务的数据流动不同,时间线维度是真实的一步步可执行操作,可能是修改了模型的某处代码,可能是添加了某个环境变量,同样的,精度问题也可能是在某一次操作中引入的,如在下载模型权重时就下载了错误的权重导致产生精度问题,配置aipp错误导致产生精度问题,fusion_switch_file配置的融合规则导致出现精度问题,ATC转换时精度不足导致数值溢出产生精度问题,某个代码文件的修改导致出现精度问题,某个环境变量设置的值导致出现精度问题,某处路径填写错误读取了错误数据导致出现精度问题。

时间线维度贯穿整个精度问题的经过,pipeline维度有个致命的缺陷,他本质是模型的执行,如果精度问题不是由模型执行的pipeline导致的,而且其他过程如数据集精度评估和计算过程,该阶段是在数据集推理完之后,并不是模型pipeline中,如在评估过程如精度计算方式有误,或者评估使用的推理结果不对应,或数据集版本下载错误,都认为产生精度问题。时间线维度对于“伪精度问题”的判断有重要作用,“伪精度问题”通常不能从pipeline维度进行分析,因为原因出现在输入输出处理,精度评估计算等环节,与模型推理不相关。

根因维度

总览

针对精度问题的来源,前面提到的pipeline维度、时间线维度主要是体现“存在性”,核心思想把精度问题嵌入业务pipeline、时间线中,这里从另一个角度根因维度看待精度问题的来源,体现的是“可构造性”,是实际精度问题出现的根本原因。从根因维度,我们即可构造“真正的精度问题”。

根因维度看待,可以分为模型、算子、框架/引擎、pipeline、硬件五大类,同样的,一个精度问题可能存在一个或多个根因。需要明确的一点是,前面我们提到精度问题存在有标杆场景和无标杆场景,这是对于判断是否精度问题而言,而在分析根因维度上,一切都是有标杆场景,因为标杆可以是客观存在的,不是没有实际对比,就不存在这个客观绝对的标杆,也就是上帝视角假想一个标杆,那么绝大多数精度问题可以归结为因为原因导致地方出现**差异,也就是与标杆的某方面区别。

模型

模型维度的根因可以分为模型结构差异、模型权重差异。

模型结构差异是指模型的结构与标杆不一致,如在性能优化过程中修改了模型代码,影响模型结构导致产生精度问题;在模型转换时如onnx->om,涉及图融合、算子融合等优化,会改变模型结构,可能会产生结构导致的精度问题;在torchair适配中,由于计算图生成逻辑的差异,Dynamo在静态分析代码过程可能涉及语义的差异,从而导致模型结构出现差异,产生精度问题。

模型权重差异是权重文件如.pt、.onnx等的差异,可能是下载链接不同,客户微调后的多个版本区别等等,由于权重不一样自然导致产生精度问题。

算子

算子维度的根因可以分为算子数值错误、算子实现差异、算子内存踩踏。

算子数值错误,包括数据类型不足导致精度溢出、算子本身存在精度问题,或者某种数据类型下存在计算问题。通常情况下不存在算子的精度问题。遇到更多的是数值溢出的情况,比如数值上溢下溢,nan,比如使用fp16计算,产生数值溢出。

算子实现差异,是因为算子的实现与标杆不一致导致产生的精度问题。比如有些算子在不同的PyTorch版本下,适配层实现有差异;又比如ONNX标准算子ScatterND和OM对应算子的语义不一致,ONNX中的ScatterND支持使用负数为index,而OM不允许,从而产生精度问题。

算子内存踩踏,是因为算子计算的内存问题导致的精度错误。通常表现推理结果与预期结果差距较大,且数值无规律,例如分核计算和分ub计算,出现非整块,计算复杂,数据类型变化时,容易出现此类问题,可能是偶现的。

框架/引擎

框架/引擎维度的根因主要是框架/引擎BUG、框架/引擎使用错误。

不同于大模型或者训练场景,存在非常多上层推理/训练框架如MindIE、vLLM、MindSpeed、Megatron,小模型推理领域不太有笨重的上层框架,一般是直接基于pytorch,图模式场景下底层推理引擎基于GE,可能还存在ONNXRUNTIME-CANN、RTS等涉及的问题。

框架/引擎BUG是指由于框架或者引擎侧的已知/未知BUG导致出现的精度问题,与版本强相关,通常可以通过版本升级、降级解决。

pipeline

pipeline维度的根因可以分为pipeline模块增删、pipeline参数未对齐,体现的都是pipeline的各种差异。

pipeline模块增删是指业务的pipeline中有些模块相比标杆缺少或增加,最常见的是前处理或后处理不一致,如一个OCR业务pipeline中,未开启文档方向矫正模块,对应是一个前处理,导致数据质量不佳产生推理精度问题;又如一个CV模型要求输入NCHW的数据排布格式,而前处理使用OpenCV读取的图像默认数据格式为NHWC,未进行格式转换,产生精度问题,这也是缺少了转换模块导致。

pipeline参数未对齐是指一些非模型参数与标杆不相符,如各种阈值,在CV任务中,阈值过大可能导致过滤掉了结果从而导致结果不正确产生精度问题。

硬件

硬件维度的根因可以分为硬件故障、硬件底层差异。

硬件故障是指因为硬件的某些原因导致的精度问题,通常是偶现的。

硬件底层差异是不同硬件底层架构与标杆存在区别,如浮点舍入模式的差异、计算过程的差异,累加顺序不同也可能产生差异,这样的差异是无法消除的,也并非算子问题,可能会产生累计误差导致的精度问题。

小模型精度问题定位方法

“瞪眼”法

“瞪眼”法,类似数学中的“显然”、“不难看出”、“观察到”,通过个人经验结合精度问题现象,进行合理的猜测分析,并进行验证,从而有几率直接解决问题,避开复杂的正向定位过程。该方法依赖定位人遇到的精度问题数量,对问题的理解程度,侧重熟能生巧和见多识广。

如在OCR领域的一个版面分析模型PP-DocLayout适配中,发现文档中有未检测出的段落,与官方调用API得到结果不一致,属于精度问题,观察到未检测到的段落在官方识别结果中的置信度较低,怀疑是阈值设置问题,自动过滤掉了该框,调高阈值后则能正常识别出结果。

又如对一个OCR模型,发现对于倒着的图片识别不了结果,从经验看,一般OCR要经过前处理的方向矫正,增加模型识别效果,怀疑是没有进行方向矫正,从而影响模型精度,修改参数增加前处理后识别正常。

套路法

套路法,即按照固定的模板套路,对某种类型的精度问题进行尝试,从而可能解决遇到的问题,这里一般都是前人总结的精度问题大量出现的原因和场景,以及解决方法,后人甚至无需了解太多,匹配到模板后按照套路执行操作,说不定就解决了,对定位人的能力要求较低。

这里罗列几个最常见的套路:

当在OM场景下遇到精度问题,与ONNX精度对不齐,可以依次配置以下变量尝试,通常能解决40%的OM场景下的精度问题。

(1)–fusion_switch_file:融合规则(包括图融合和UB融合)开关配置文件路径以及文件名,遇到精度问题时可尝试直接取消全部融合,排除融合规则导致的精度问题

{
    "Switch":{
        "GraphFusion":{
            "ALL":"off"
        },
        "UBFusion":{
            "ALL":"off"
         }
    }
}

(2)–precision_mode_v2:设置网络模型的精度模式,通过调整数值类型,避免数值溢出等算子精度问题,从最大精度模式开始设置,若问题解决,则可以尝试其他低一级的精度模式

origin>mixed_float16>fp16>mixed_bfloat16

(3)–buffer_optimize=off_optimize可以关闭内存复用,设置–disable_reuse_memory=1可以关闭数据缓存优化,尝试排除内存踩踏问题

二分法

二分法,也就是对某个维度进行二分,从而缩小问题的怀疑范围,最后定界到问题模块的过程。对定义了序关系的某个维度D,若存在D_ta使得该状态下无精度问题,则对任意存在问题的状态D_tb,可以构造一个D上的序列tb,t1,t2,…,tn,ta,使得t1,t2,…,收敛到tn,D_tn存在问题,且tn是触发问题的极小原子。

该方法只能将问题定位到极小原子,也就是一个引入问题的地方/操作/东西,但实际精度问题可能是由多重因素构成,比如既存在前处理没对齐,又存在后处理的参数不匹配等多个问题。这时候需要使用二分迭代法,搜索出整个集合,将tn剔除,重复运用二分法,得到新的导致问题的tn’,当不存在D_tb,也就是维度D上无论什么状态都没有精度问题了,则所有tn的集合就是全部导致问题的因素。

将二分法的理论运用到实际中,这里列举三个常用的维度。

pipeline二分​:pipeline维度天然有数据流向这个序关系,pipeline二分即对推理的pipeline进行分割,缩小到精度问题所在的阶段。如对paddleocr-vl模型的pipeline较为复杂,流程为get_input、doc_preprocessor、layout_detection、vlm_preprocess、predict、vlm_postprocess,当遇到精度问题时,从layout_detection处截断进行二分,layout_detection的中间输出为文档各类元素(文本/表格/图表/公式等)的坐标和类别,对于相同输入,若截断处的中间结果匹配,则精度问题模块在二分的后半部分;若不匹配,则精度问题模块在二分的前半部分。

版本二分​:版本有版本号,是随时间演进的,天然带有序关系,版本二分即对各类影响精度的软件进行替换,缩小问题所在版本。这里的版本可以是多种多样的,CANN版本,PTA版本,三方库版本等。当存在版本A下出现精度问题,版本B下不存在精度问题,则可以二分A到B之间版本,替换实验,将精度根因锁定在某个特定版本中。

时间线二分​:时间线维度本身就是用时间规定的,精度问题可能是由随时间进行的一系列操作中引入的,根据时间线动作进行分割,可以把精度问题的引入缩小到某个动作。当在t1时刻不存在精度问题,t4时刻存在精度问题,中间t2时刻修改了模型文件代码做了torchair适配,t3时刻又修改了前处理代码引入融合算子,那么二分时间线,将精度问题锁定在如增加了一行代码,修改了一个变量等具体操作。

实际案例中,各维度的二分可以互相结合,比如pipeline二分侧重的是寻找精度问题存在的模块,可以先通过pipeline二分定位到问题存在于后处理,后处理经过了性能优化,使用多个自定义算子替换原始计算逻辑,通过时间线维度,缩小到具体某个自定义算子的替换。

工具法

工具法,即使用精度定位工具来辅助问题定位,进行正向定位精度问题。昇腾提供了全场景精度工具链,专为模型开发的精度调试环节设计,可显著提升用户定位模型精度问题的效率,如MSIT、MindStudio Probe等工具,提供如dump数据,自动compare模型与标杆的中间结果等功能。

msit的一键式全流程精度比对(推理)功能 msit debug compare,该工具可自动dump标杆模型和问题模型的算子输出,匹配对应算子并计算相似度。

msit-代码预览-msit:基于昇腾平台的推理工具链项目 - AtomGit | GitCode

msprobe提供基于torch图模式(torchair)整网算子精度比对,通过采集torchair图模式下模型中间算子的输入、输出数据,对比两次推理结果是否一致,从而判断模型在不同算子上的精度是否一致。

MindStudio-Probe:针对昇腾提供的全场景精度工具链,帮助用户快速提高模型精度定位效率。 - AtomGit | GitCode

为什么这里不讲msit debug compare怎么使用,不讲对比出来的表怎么查看,本文章主要侧重搭建精度问题整体框架与方法论讲解,更多场景下的定位工具,工具的具体使用,可以查看官方文档。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐