【Atlas 200 DK玩转系列】【模型转换】模型转换失败时该怎么做(一)

举报
山人_mhc 发表于 2020/03/25 15:46:14 2020/03/25
【摘要】 Atlas200DK使用FAQ


OMG是Framework的一个模型转换工具,OMG处理流程包含Parse解析->Optimize优化->Quantization量化->Build构建->Fusion融合和获取Task信息这几个步骤。

  • Parse解析中,Framework对原始网络文件及权重数据进行解析。如果网络本身有不满足Framework处理的要求的地方,会在此阶段打印错误日志。

  • Optimize优化中,Framework会对整个网络进行不同形式的优化,且当前的优化实际上是会在整个模型转换过程多个阶段的中进行,包括Scope融合,Pattern融合,节点删除等等。此阶段较少出现终止转换的报错,可能会出现一些不影响模型转换的ERROR,例如Pattern融合失败。

  • 量化是模型转换中的可选流程,仅在转换命令中携带了量化配置才会进行量化。量化的过程是使用校准集作为输入,在host上进行量化推理,并根据结果计算量化参数,最终保存到模型中。量化过程基本与其他流程独立,所支持的算子也只是整个D平台支持算子的子集。

  • Build阶段是模型转换出错较多的阶段。此阶段将已经优化、量化完成的模型,按照模型拓扑结构,逐个算子进行build,完成om模型中的算子构建。此过程将根据算子输入shape和算子参数,计算算子输出shape并进行权重数据转换。此阶段常见问题是shape信息与Davinci要求的不匹配,或者算子参数组合不支持。

  • Fusion融合和获取Task信息阶段将build完成的算子进行底层优化融合,然后进行一次“假推理”,获得算子推理task信息。此阶段出错,主要还是底层校验算子报错,不满足其推理的要求。需要结合算子实际情况,根据整个模型转换的处理过程,分析出错原因。

  • Serialize阶段,将om算子,task信息等全部序列化保存为om模型文件,几乎不会报错。

  • 当前Framework与具体的算子和网络存在一定耦合性,定位问题需要先明确Framework在业务流程各个阶段的动作和目标,然后结合具体问题场景进行分析!

当然在模型转换时,必须知道如下约束(在昇腾社区网站资料中也有):

  • 只支持原始框架类型为Caffe和TensorFlow的模型转换,当原始框架类型为Caffe时,输入数据类型为float32;当原始框架类型为TensorFlow时,输入数据类型为int32、bool、uint8、float32。

  • 当原始框架类型为Caffe时,模型文件(.prototxt)和权重文件(.caffemodel)的op name、op type必须保持名称一致(包括大小写)。

  • 当原始框架类型为Caffe时,除了top与bottom相同的layer以外(例如BatchNorm,Scale,ReLU等),其他layer的top名称需要与其name名称保持一致。

  • 当原始框架类型为TensorFlow时,只支持FrozenGraphDef格式。

  • 不支持动态shape的输入,例如:NHWC输入为[?,?,?,3]多个维度可任意指定数值。模型转换时需指定固定数值。

  • 输入数据最大支持四维,转维算子(reshape、expanddim等)不能输出五维。

  • 模型中的所有层算子除const算子外,输入和输出需要满足dim!=0。

  • 模型转换不支持含有训练算子的模型。

  • 量化(uint8)后的模型不支持模型转换。

  • 模型中的算子只支持2D卷积,暂不支持3D卷积。

  • 只支持《算子规格说明Ascend 310 算子规格说明Atlas 200 AI加速模块 1.0.2 算子清单 (型号 3000)Atlas 300 AI加速卡 1.0.2 算子清单(型号 3000, 3010)Atlas 500 智能小站 1.0.2
    算子清单(型号 3000, 3010)》中的算子算子规格说明中的算子, 并需满足算子限制条件。


那么接下来,我们随机给出一些案例,来实际看下该如何处理;

案例一:caffe模型转换失败,报错信息如下:

[ERROR] FMK:2019-06-21-06:05:57.729.503 GetOutputDesc:framework/domi/omg/../omg/model/op_builder/concat_op_builder.cpp:181:"all input must have the same dim value except concat_axis,out_desc.dim(2):31,input_desc(1).dim(2):32 Error Code:0xFFFFFFFF()" 
[ERROR] FMK:2019-06-21-06:05:57.729.522 Build:framework/domi/omg/../omg/model/op_builder/op_builder.cpp:41:""Get output descriptors" failed. Node: concat1." 
[ERROR] FMK:2019-06-21-06:05:57.729.536 SetInputOutputDesc:framework/domi/omg/../omg/model/model_builder.cpp:594:"Op build failed. Node: concat1." 
[ERROR] FMK:2019-06-21-06:05:57.729.555 Build:framework/domi/omg/../omg/model/model_builder.cpp:2868:"SetInputOutputDesc Failed!" 
[ERROR] FMK:2019-06-21-06:05:57.729.568 Generate:framework/domi/omg/omg.cpp:800:"OMG builder Build() return fail." 
[ERROR] FMK:2019-06-21-06:05:57.732.193 main:framework/domi/omg_main/main.cpp:815:"OMG Generate execute failed!!"


分析:

从上面的日志中明显可以看出,在Build阶段报错,我们知道此阶段将已经优化、量化完成的模型,按照模型拓扑结构,逐个算子进行build,完成om模型中的算子构建。此过程将根据算子输入shape和算子参数,计算算子输出shape并进行权重数据转换。此阶段常见问题是shape信息与Davinci要求的不匹配,或者算子参数组合不支持。所以着重看该阶段的输入shape是否ok?

从上面的出错信息可以看出,是因为网络中的某一层的输入维度不对导致无法进行计算,又由于报错文件是concat_op_builder.cpp,可推断是concat计算时的两个输入维度不匹配导致转换失败。

此网络的第一个输入数据的维度是31, 第二个数据维度的输入时32,那么需要从日志中分析是从网络中的哪一层开始不匹配的。

步骤1 将模型文件****.prototxt用Netron打开来分析。

图片1.png


最后一层concat的输入是一个卷积操作的输出和一个pooling的输出。


步骤2 查看模型转换日志,从后往前进行分析。

concat层的输入是【1,24,31,31】和【1,512,32,32】,显然无法进行计算。

图片2.png

然后继续往前查找,如下图所示,发现在左边分支最后一个pooling层的输入是【1,512,32,32】,经过计算后输出变成了【1,512,31,31】,是在该层导致了维度的变化(后面的几层卷积操作维度都没有发生变化)。

图片3.png

接下来需要查看pooling层是否有错误。


步骤3 查看prototxt文件,stride为1代表步长为1,两次MAX操作之间的数据存在重叠,输出数据维度少1,所以怀疑模型文件多了这一层pooling或者是右边分支少了这一层pooling。

图片4.png

步骤4 根据模型文件的确认结果将左侧pooling层删除,或者在右侧增加pooling层,也可以重新在caffe下训练并给出正确的模型文件再进行模型转换。

----结束


ok,在下一个博客,我们继续讨论更多案例。





【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。