-
今年4月份到10月份参加了华为众智项目新一期的开发,在模型迁移过程中学到了很多,也积累了一些迁移方面的经验,想通过这个帖子分享给大家。模型结构简介:在分享迁移经验之前首先简单介绍一下DPRNN模型,便于大家对这个模型有一个简单的了解。双路径循环神经网络(DPRNN)是一个时域单通道语音分离的高效长序列建模,它由三个处理阶段组成:编码器、分离阶段和解码器。首先,编码器模块用于将混合波形的短段转换为它们在中间特征空间中的对应表示。然后,该表示用于在每个时间步估计每个源的乘法函数(掩码)。最后利用解码器模块对屏蔽编码器特征进行变换,重构源波形。下图是论文中关于语音分离阶段流程的解释。看完上面的模型简介之后,相信大家已经对DPRNN模型有了一个大致的认识。接下来就是我在做此项目过程中具体的流程规划。模型迁移流程在正式进行模型迁移工作之前,首先要详细阅读论文并且熟悉论文对应的源码,然后就是阅读mindspore开发文档,熟悉mindspore整体的开发流程,查询torch与mindspore算子对应关系,这样可以有效减少模型迁移的时间。DPRNN模型的迁移流程如下:将torch源码迁移成mindspore版本代码,并在pynative动态图模式下跑通(pynative模式下,可以方便地设置断点,获取网络执行的中间结果).将mindspore版本代码在graph图模式下跑通通过调整模型超参,初始化等方法提升模型评估精度310推理代码编写训练,评估以及310推理的单卡和多卡运行脚本编写迁移难点模型的迁移主要分为三个阶段,分别为数据预处理,网络主干以及loss。下面是在这三个阶段中遇到的问题以及解决办法:数据预处理在这一阶段的开发中,我发现mindspore库中缺少一个重要的音频处理算子:torchaudio,通过查询库上代码和各版本的源码,了解到原始音频是应该先处理为一个二进制的json文件,再将这个json文件传入训练的网络之中。所以我重写了预处理文件,为了验证结果,将这部分代码处理后的json文件传入了torch代码中,发现效果基本一致,完美规避了torchaudio没有mindspore对应算子的问题。网络主干首先是一维卷积算子nn.Conv1d,由于初始化的方式不同,torch版本和mindspore版本的输入输出有很大的差异,经过尝试,发现使用HeUniform()初始化方法可以得到和torch版本相同的输出。然后是nn.GroupNorm归一化算子,通过代码报错发现mindspore版本的GroupNorm算子不能对三维向量进行运算,而对应的torch版本算子却可以正常运行,所以只能对向量先进行扩维操作,然后通过transpose函数进行向量转置,通过GroupNorm算子之后再进行转置以及降维操作,通过此方法可以得到和torch版本GroupNorm算子相同的输出。对于nn.LSTM算子,mindspore1.5版本环境下需要加上两个Tensor(h_0,c_0)的元组,数据类型为mindspore.float32或mindspore.float16,shape为(num_directions * num_layers, batch_size, hidden_size),如果不加这两个参数脚本运行会报错。但是mindspore1.6以及之后的版本都可以不加这两个参数。两版代码的区别我放在下面的代码区。mindspore1.5版本可运行的LSTM算子部分代码如下:def __init__(self, out_channels,hidden_channels, rnn_type='LSTM', norm='ln',dropout=0, bidirectional=False, num_spks=2): super(Dual_RNN_Block, self).__init__() # RNN model self.intra_rnn = nn.LSTM(out_channels, hidden_channels, 1, batch_first=True, dropout=dropout, bidirectional=bidirectional) self.h0 = Tensor(np.ones([2 * 1, 516, hidden_channels]).astype(np.float32)) self.c0 = Tensor(np.ones([2 * 1, 516, hidden_channels]).astype(np.float32)) self.inter_rnn = nn.LSTM(out_channels, hidden_channels, 1, batch_first=True, dropout=dropout, bidirectional=bidirectional) self.h1 = Tensor(np.ones([2 * 1, 500, hidden_channels]).astype(np.float32)) self.c1 = Tensor(np.ones([2 * 1, 500, hidden_channels]).astype(np.float32)) def construct(self, x): ''' x: [B, N, K, S] out: [Spks, B, N, K, S] ''' B, N, K, S = x.shape # intra RNN # [BS, K, N] intra_rnn = x.transpose((0, 3, 2, 1)).view(B*S, K, N) # [BS, K, H] intra_rnn, (hn, cn) = self.intra_rnn(intra_rnn, (self.h0, self.c0))mindspore1.6以及之后版本可运行的LSTM算子部分代码如下:def __init__(self, out_channels,hidden_channels, rnn_type='LSTM', norm='ln',dropout=0, bidirectional=False, num_spks=2): super(Dual_RNN_Block, self).__init__() # RNN model self.intra_rnn = nn.LSTM(out_channels, hidden_channels, 1, batch_first=True, dropout=dropout, bidirectional=bidirectional) self.inter_rnn = nn.LSTM(out_channels, hidden_channels, 1, batch_first=True, dropout=dropout, bidirectional=bidirectional) def construct(self, x): ''' x: [B, N, K, S] out: [Spks, B, N, K, S] ''' B, N, K, S = x.shape # intra RNN # [BS, K, N] intra_tran = x.transpose((0, 3, 2, 1)).view(B*S, K, N) # [BS, K, H] intra_rnn, _ = self.intra_rnn(intra_tran)loss使用SI-SNR标准来计算loss,这也是语音分离任务中普遍使用的loss函数。这一部分基本没遇到什么问题。模型迁移过程中为了随时debug调试,推荐大家使用pynative模式进行开发,但是最终的交付目标是graph模式运行成功,所以最后我们需要在graph模式下再将整个训练的过程走一遍。在这一部分中,由于语音分离模型的特殊性,传入的语音长度不尽相同,所以源码对语音进行了切割处理,但是在pynative模式下正常运行的代码到了graph模式下就会出现op compale failed的问题,最终我们发现在graph模式下计算动态长度会出现一些问题,所以进行了先处理、再编译的方式处理数据,成功解决了graph模式不能运行的问题。模型调优经验除去之前因为mindspore环境原因导致loss一直不下降(在-2~0之间来回震荡),模型调参提升精度是整个项目耗时最长的阶段。在mindspore版本代码graph图模式下跑通之后,loss下降趋势与torch源码loss下降趋势有很大差异,比如torch源码sisnr评估精度是12.68,但是刚迁移完成没经过任何调优的mindspore版本代码sisnr精度只能到5.11,这个时候就需要通过调整模型参数、优化器、初始化函数以及学习率等方法来提升模型的精度。调整优化器torch源码使用的是Adam优化器,但是最初的mindspore版本代码使用Adam优化器之后效果却不尽人意,在conv-tasnet网络使用SGD优化器取得显著效果之后,我也试着把Adam优化器改为SGD优化器,最后效果反而比使用Adam优化器版本代码的效果更差,经过各种查询,得出SGD优化器对全卷积网络模型精度提升很多,但是对DPRNN这种含有LSTM的网络来说,使用SGD优化器不是一个很好的选择。在尝试了各种优化器之后,我最终换回了Adam优化器,后来发现通过调整优化器中weight-decay参数对应值可以取得不错的效果。调整初始化函数源码的初始化策略在mindspore上并无对应,而mindspore默认的初始化函数效果又很差,通过不断的尝试与对比,发现Heuniform初始化函数效果最好。调整学习率torch源码使用的初始学习率为5e-4,通过使用ReduceLROnPlateau学习率策略动态调整学习率,当特定的度量指标,如训练损失、验证损失或准确率不再变化时,学习率就会降低为原来的1/2,但是mindspore1.9以下的版本却没有这个算子对应,所以只能通过加载模型文件继续训练的方法找到最合适的学习率,最后通过nn.piecewise_constant_lr函数将合适的学习率整合成动态学习率,代码如下:milestone = [15 * num_steps, 45 * num_steps, 75 * num_steps, 100 * num_steps] learning_rates = [args.lr, args.lr1, args.lr2, args.lr3] lr = nn.piecewise_constant_lr(milestone, learning_rates) optimizer = nn.Adam(net.trainable_params(), learning_rate=lr, weight_decay=args.l2)310推理编写310推理的时候报过out of memory错误,我使用的模型总共需要6层dprnn block,使用5层block时310推理可以正常运行。但当使用6层block的时候,可以export出mindir文件,但是310推理却报out of memory错误,在gitee上提了issue之后,工程师建议看做没做8bit量化,如果是全卷机网络可以把输入大小减少些。后续将输入通道大小减少一半,在未影响精度的前提下310推理可以正常运行,如果之后有同学在310推理的时候也遇到这个问题的话,可以尝试一下这个方法。除此之外的其他部分当时我参考了gitee上modelZoo库中模型中的310推理,几乎没做任何改动。只适当修改了执行脚本,没遇到什么太多的问题。总结总之,如果在模型迁移开发中遇到了问题,可以去gitee上提交issue,会有工程师给你提供解决问题的方法,虽然mindpsore还有一些不足之处,但它也在不断完善,不断进步,希望这个帖子可以对大家有一点点帮助,也祝愿Mindpsore平台越来越好。
-
前言本文记录了完成华为昇腾众智项目的主要过程、遇到的问题及解决方案等。项目介绍我所做的模型是gdprnn,此模型是一个语音分离任务的模型,gdprnn由三个处理模块组成,编码器、分离模块和解码器。首先,编码器模块用于将混合波形的短段转换为它们在中间特征空间中的对应表示。然后,该表示用于主模型进行分离。最后,利用解码器模块对主模型输出结果重构,得到源波形。gdprnn被广泛的应用在语音分离等任务上,取得了显著的效果。论文: Voice Separation with an Unknown Number of Multiple Speakers源码地址:cid:link_1项目目标完成gdprnn从Pytorch到Mindspore的迁移任务迁移完成后在确保在Ascend上达到Pytorch源码精度在Ascend 310上完成推理,并达到Pytorch源码精度数据集使用的数据集为: librimix,LibriMix 是一个开源数据集,用于在嘈杂环境中进行语音分离。 要生成 LibriMix数据集,请参照开源项目:cid:link_3数据处理常用的数据集可以直接调用mindspore.dataset接口实现,其使用方法可在MindSpore编程指南中查看。在数据处理过程中基本没遇到什么难题,唯一要注意的是,数据最好使用numpy去处理,对性能会有很大提升网络迁移使用MindSpore定义神经网络需要继承mindspore.nn.cell,cell是所有神经网络的基类。MindSpore在构建网络时使用construct构建网络前向过程。在网络迁移过程中可以参考Mindspore官网中Pytorch和MindSpore的API映射关系。在迁移过程中遇到MindSpore没有与Pytorch对应index_add算子,为实现相同操作,我自定义了两个矩阵来替代index_add算子训练在训练过程中首先使用MindSpore封装好的函数model.train进行训练,不过在训练训练过程中不能对方向传播和梯度进行操作,进而将训练改为TrainOneStep进行训练,采用for loop结构能更方便进行梯度截断等操作。在云上训练过程中遇到八卡生成ckpt冲突问题,我为每张卡创建一个文件,解决了此问题310推理在导出mindir后,进行310推理过程,会报一个mindir的错误,然而并没有发现mindir有什么问题,最终我调低日志等级后发现错误的真正原因,并顺利解决。310 Ascend不能执行复杂的python 脚本,尽可能使用CPU执行python脚本,不过在使用CPU执行脚本后报错Illegal Instruction,排查之后确定原因:进程代码段中数据是作为指令运行的,如果不小心代码段被错误覆盖,那么CPU可能无法识别对应的代码,进而造成Illegal Instruction。同样,如果栈被不小心覆盖了,造成返回地址错误、CPU跳转到错误地址,执行没有意义的内存数据,进而造成Illegal Instruction。a *= b就是a = a * * b,前面的a把后面的a覆盖了,最终为每个变量命名均不相同便解决此问题性能调优在精度达标后发现MindSpore的性能要比Pytorch慢很多,使用二分法确定性能慢的原因是MindSpore的lstm比Pytorch要慢很多,此问题已交由工程师解决,在去掉lstm后性能仍然比Pytorch要慢一些,与工程师沟通解决profile报错的问题,并使用profile确定性能慢的算子,最终将数据从float32改为float16性能得到极大提升
-
Conv-Tasnet开发经验分享我曾经参加过两期昇腾众智迁移项目,现在积累了不少心得,希望能帮助到新加入的小伙伴们~项目背景2021.10 参与师兄目标追踪算法Siamfc的预训练脚本开发,并成功上线模型2022.4 参加新一期的昇腾众智开发项目,并负责语音分离模型Conv-Tasnet的910与310开发开发经验SiamFC是一种基于全卷积孪生网络的目标跟踪算法,使用了ILSVRC15的目标跟踪视频数据集上进行端到端的训练,网络结构是一个关于搜索区域的全卷积网络,并且滑动窗口估计可通过计算两个输入的互相关性并插值得到。 我的工作撰写训练手册参加训练脚本开发算子性能分析在此处我初步了解了整个项目的开发流程,具体为Pytorch-GPU>>MindSpore-GPU>>Mindspore-Ascend两步。总体开发过程由于我参与的比较晚,工作并不算太重要,所以在这里不过多介绍。下面着重分享由我个人开发的Conv-tasnet模型的开发经验:1. 通读论文,并运行源码这是初始的一步,也是重要的一步,一篇论文很有可能有多篇源码,但是效果最好的可能并不是最符合论文要求的。拿Conv-Tasnet举例,在github上star数最多的代码是asteroid这篇代码,但是在我复现的过程中发现它的精度竟然超出了论文标称精度2左右,这明显是不合常理的。在结合了论文对代码进行逐步分析时,我发现它的数据预处理方式和论文并不一致,这也导致我后面放弃了使用这套代码进行开发。2. 阅读MindSpore开发文档开发文档中有从数据集预处理到训练的一系列样例,在安装好Mindspore框架后强烈推荐大家按照官方文档的测试样例试写下整个开发过程的代码,这有助于我们尽快上手Mindspore框架。3. 查询算子对应关系我们知道,Pytorch和Mindspore的算子不全是一一对应的关系,例如我遇到的torch.index_select这个算子,在Mindspore上就没有完全一致的算子对应,这时候,我们需要收集好所有无对应算子,并写入一个文档待我们开发时使用。4. 选择合适的Mindspore版本进行开发按照经验来说应该是以最新版本进行开发,但是如果模型太大,有云上训练模型需求的,可以参照openi启智社区上官方镜像的Mindspore版本进行开发,避免因为开发版本过高,后期无法云上训练。5. 进行数据预处理部分代码开发在这一阶段的开发中,我们发现mindspore的缺少一个重要的音频处理算子:torchaudio,由于音频处理不是我们擅长的区域,所以我们查询了库上代码和各版本的源码,知道了原始音频是应该先处理为一个二进制的json文件,再将这个json文件传入我们训练的网络之中。所以我们重写了preprocess.py也就是预处理文件,为了验证结果,我们将这部分代码处理后的json文件传入了torch代码中,发现效果基本一致,完美规避了torchaudio这个算子不对应的问题。6. 网络主体结构开发在网络主体结构开发中,遇到了很多问题,以我开发时使用的Mindspore1.6.1版本进行举例,就遇到了包括但不限于以下几条问题:torch.index_select无对应算子不支持跳跃切片操作自定义layernorm层无法在construct内再次初始化nn.cell无法进入为此,我们在组内讨论以及和华为工程师的探讨中,提出了很多解决方案 对于index-select算子,需要处理的是一个四维的矩阵,但是在mindspore官方给出的测试样例中不支持指定dim操作,与其对应的算子的逻辑是在每个点位都拥有一个数值来对相应点位进行计算,但是在扩散到四维之时,由于我们无法给出每个点位的数值,并且由于替代的那个indice在官方定义中是tuple类型的,我们目前要在传入的四维张量中对特定维进行操作,所以无法用官方算子进行迁移。同时,我们尝试使用了scatter-add算子进行替代,但是效果也并不理想。后来尝试用了一个while循环和切片操作做替代,不过时间性能很差,一个操作要用3090跑一分钟以上。在经历了种种尝试后,最终我们观测到要处理的tensor是一有规律的,所以我们采用了矩阵乘法这一操作,将这个算子成功规避。对于不支持跳跃切片,我们联系了工程师,工程师进行反馈:1.7.1版本不会报tbe错误,所以我们改为使用tbe算子进行开发。 layernorm层不支持源码式初始化,我使用了如下方法定义class ChannelwiseLayerNorm(nn.Cell): """Channel-wise Layer Normalization (cLN)""" def __init__(self, channel_size): super(ChannelwiseLayerNorm, self).__init__() self.gamma1 = np.ones((1, channel_size, 1)).astype(np.float32) self.gamma2 = Tensor.from_numpy(self.gamma1) self.beta1 = np.zeros((1, channel_size, 1)).astype(np.float32) self.beta2 = Tensor.from_numpy(self.beta1) self.mean = ops.ReduceMean(keep_dims=True) self.pow = ops.Pow() def construct(self, y): """ Args: y: [M, N, K], M is batch size, N is channel size, K is length Returns: cLN_y: [M, N, K] """ mean = self.mean(y, 1) # [M, 1, K] var = y.var(axis=1, keepdims=True, ddof=0) # [M, 1, K] cLN_y = self.gamma2 * (y - mean) / self.pow(var + EPS, 0.5) + self.beta2 return cLN_y对比源码定义为class ChannelwiseLayerNorm(nn.Module): """Channel-wise Layer Normalization (cLN)""" def __init__(self, channel_size): super(ChannelwiseLayerNorm, self).__init__() self.gamma = nn.Parameter(torch.Tensor(1, channel_size, 1)) # [1, N, 1] self.beta = nn.Parameter(torch.Tensor(1, channel_size,1 )) # [1, N, 1] self.reset_parameters() def reset_parameters(self): self.gamma.data.fill_(1) self.beta.data.zero_() def forward(self, y): """ Args: y: [M, N, K], M is batch size, N is channel size, K is length Returns: cLN_y: [M, N, K] """ mean = torch.mean(y, dim=1, keepdim=True) # [M, 1, K] var = torch.var(y, dim=1, keepdim=True, unbiased=False) # [M, 1, K] cLN_y = self.gamma * (y - mean) / torch.pow(var + EPS, 0.5) + self.beta return cLN_y对于nn.Cell进不去的问题,我选择了一种最笨的方法,就是每层网络都分开写,不再用一个Sequential来接受整合。 在整个网络写完之后,大家可以写一下单元测试,对比源码传入同样的数据(我这里是一个[1, 32000]的Tensor)观察传出的形状是否和源码相似,如果相似,那么这一部分的工作就可以暂时告终了。7. graph模式运行训练脚本开发时为了随时debug,所以推荐大家使用pynative模式进行开发,但是最终的交付目标则是graph模式运行成功,那么我们需要在graph模式下再将整个训练的过程走一遍。在这一部分中,由于语音分离模型的特殊性,传入的语音长度不尽相同,所以源码对语音进行了切割处理,但是在pynative模式下正常运行的代码到了graph模式下就会出现op compale failed的问题,最终我们发现在Graph下计算动态长度会出现一些问题,所以进行了先处理、再编译的方式处理数据,成功解决了graph模式不能运行的问题。8. 模型调优这是迁移模型工作中耗时最长的一项工作,为了达到和源码一样的精度,我们需要调整参数来适应这套新的Mindspore代码,下面是我总结的调参心得:调整动态学习率更换优化器更改weight-decay对应值修改训练轮数使用fp32代替fp16的矩阵乘法更改初始化策略1.更改动态学习率。我最早使用的是1e-3的学习率,但是在这个学习率下,loss只能达到-2左右,效果很差(源码为-14)所以我改为每25个epoch将学习率减半,配合优化器的更改这时loss便可以成功降到-10左右。2.更换优化器。不要迷信adam优化器。源码使用了adam优化器,但是在迁移到mindspore之后,我发现loss会在-2至-6之间震荡,并且再不下降,因此我尝试了momentum等各类优化器,最终发现最传统的SGD效果非凡,配合动态学习率可以下降至-10左右。3.经过尝试 ,Conv-Tasnet代码在0.01的weightdecay下表现最好。4.使用fp32代替fp16,这会增加精度,但是代价是性能下降100ms/step左右5.更改初始化策略,源码的初始化策略在mindspore上并无对应,这时我们有两种解决办法,第一种是自己实现,第二种是观察mindspore中初始化策略的分布,找出和源码类似的进行使用,在这里我使用的是后者。 其实我还进行了很多种尝试,例如loss_scale的调整等,但是最终我们发现对于语音模型loss_scale的效果并不明显,所以没有使用这一方法。9. 310推理这一部分当时我们copy了库上的模型中的310推理,几乎没做任何改动。只适当修改了执行脚本,基本没有碰到问题。Mindspore是一个开放包容的平台,如果大家遇到了问题,最好的方式就是和工程师沟通,或者在官方库中提出issue。亲测,提出issue基本上都会有专门的工程师作出回应。这就是我今天想分享给大家的经验了,祝昇腾社区越办越好!
-
MindX SDK -- 基于RGB图片的低光增强参考设计案例1 案例概述1.1 概要描述在本系统中,目的是基于MindX SDK,在华为云昇腾平台上,开发端到端低光增强的参考设计,实现对低光图像进行光照增强的功能,达到功能要求1.2 特性及适用场景对于夜间图像、低照度图像的增强均适用1.3 模型介绍本案例采用的模型为BMVC2022会议上提出的Illuminantion-Adaptive-Transformer(IAT)[1]模型,模型选型如下表:模型类型模型名称参考链接低光增强模型IATcid:link_11.4 实现流程1、基础环境:Ascend 310、mxVision、Ascend-CANN-toolkit、Ascend Driver2、模型转换:Pytorch .pth模型转.onnx模型,再由.onnx模型转昇腾离线模型:best_Epoch_lol_v1.pth --> IAT_lol-sim.onnx --> iatsim.om3、pythonV2 推理流程代码开发技术流程图如下:2 软件方案介绍2.1 技术原理本方案中,将 PyTorch 版本的低光图像增强模型 IAT[1],转化为昇腾的om模型。对于输入的夜间低照度图像,通过调用昇腾om模型进行处理,最终生成经过低光增强后的图像。2.2 项目方案架构介绍本系统设计了不同的功能模块。主要流程为:读取输入低光图片,调整输入图片到特定尺寸,并利用IAT模型进行低光增强,得到增强后的图片。各模块功能描述如表2.1所示:表2.1 系统方案中各模块功能:序号子系统功能描述1输入图片使用opencv的cv2.imread读取图片2图像缩放(预处理)调用opencv的cv2.resize将图片缩放到400*600(高宽)大小3数据格式转换(预处理)将numpy.ndarray格式的图片数据转换为MINDX_SDK的Tensor格式4OM模型推理通过低光增强模型对低光图片进行增强,选取的模型为Pytorch框架下的IAT模型,需要先生成.onnx模型并简化,再使用转换工具转化5后处理将低光增强后的张量转化为图像格式向量6结果输出将最终结果保存成图片格式输出3 开发环境准备3.1 环境依赖说明推荐系统为ubantu 18.04或centos 7.6环境依赖软件和版本如下表:依赖软件版本ubuntu18.04.1 LTSMindX SDK3.0.RC3Python3.9.2CANN5.1.RC2.alpha008numpy1.22.3opencv-python4.5.5onnxsim0.4.104 编译与运行示例步骤如下:步骤1 (下载原模型代码)下载 PyTorch 版本 IAT代码步骤2 (设置环境变量). ${sdk_path}/set_env.sh . ${ascend_toolkit_path}/set_env.sh步骤3 (执行编译的步骤) 1.pytorch 模型转换 onnx 文件 将 pth2onnx.py 放到 Illumination-Adaptive_Transformer/IAT_enhance/项目目录下,运行:python pth2onnx.py 在该目录下会生成名为IAT_lol.onnx的onnx模型文件 2.简化 onnx 文件 在上述目录下继续运行:onnxsim IAT_lol.onnx IAT_lol-sim.onnx 会在路径下生成简化后的IAT_lol-sim.onnx模型文件 已经简化好的onnx模型可供参考:IAT_lol-sim.onnx 3.onnx 文件转换 om 文件atc --framework=5 --model=./IAT_lol-sim.onnx --input_shape="input_1:1,3,400,600" --output=IAT_lol-sim --soc_version=Ascend310步骤4 (运行及输出结果)将要推理的图片放到本项目./data/文件夹下, 并将其改为test.png, 将.om模型放到./models/文件夹下, 命名为iatsim.om。运行:python main.py即可在./data/目录下得到推理后的结果.5 指标验证5.1 模型规模测试模型计算量测试需要利用python相关的模型测试工具 fvcore, 在原模型环境中可以使用以下命令进行安装:pip install fvcore利用fvcore的相关工具即可测得IAT模型的计算量,测试方法代码如下:def evaluate_net(): from model.IAT_main import IAT from fvcore.nn import FlopCountAnalysis # 创建IAT网络 model = IAT() model = model.cuda() # 创建输入网络的tensor tensor = torch.rand(1, 3, 400, 600).cuda() # 分析FLOPs flops = FlopCountAnalysis(model, tensor) print("FLOPs: ", flops.total())测试结果如下:根据IAT论文所述,该模型参数量约为90K,通过测试得到计算量约为6.019GFLOPs。5.2 精度测试步骤1-3 与4.1节一致步骤4 (获取LOL数据集)下载LOLv1数据集将数据集解压后将测试集目录(eval15)放到本项目./data/文件夹下,如下图所示:├── data ├──eval15 # 精度测试数据集 ├──high ├──low步骤5 (修改主函数并运行)切换到项目环境下,将main.py中的主函数改为调用test_precision(),运行:python main.py即可得到精度测试结果,测试结果如下:6 参考文献[1] Cui Z, Li K, Gu L, et al. Illumination Adaptive Transformer[J]. arXiv preprint arXiv:2205.14871, 2022.[1] Cui Z, Li K, Gu L, et al. Illumination Adaptive Transformer[J]. arXiv preprint arXiv:2205.14871, 2022.
-
Atlas200模块内部OS能否通过串口方式登录呢?
-
MindX SDK -- 工业指针型表计读数参考设计案例1 案例概述1.1 概要描述在本系统中,目的是基于MindX SDK,在华为云昇腾平台上,开发端到端工业指针型表计读数的参考设计,实现对传统机械式指针表计的检测与自动读数功能,达到功能要求。点击链接可以下载本项目到本地。注:本系统中只使用了两种类型的表盘数据参与训练和测试。我们通过预测的刻度根数来判断表盘类型,第一种表盘的刻度根数为50,第二种表盘的刻度根数为32。因此,目前系统只能实现这两种针表计的检测和自动读数功能。1.2 特性及适用场景在电力能源厂区需要定期监测表计读数,以保证设备正常运行及厂区安全。但厂区分布分散,人工巡检耗时长,无法实时监测表计,且部分工作环境危险导致人工巡检无法触达。针对上述问题,希望通过摄像头拍照后利用计算机智能读数的方式高效地完成此任务。注意事项:本系统中只使用了两种类型的表盘数据参与训练和测试。我们通过预测的刻度根数来判断表盘类型,第一种表盘的刻度根数为50,第二种表盘的刻度根数为32。因此,目前系统只能实现这两种针表计的检测和自动读数功能。本系统要求拍摄图片角度正常,尽可能清晰。如果拍摄图片角度不正常,导致图片模糊,则很难正确读出表数。本系统采用opencv进行图片处理,要求输入文件均为opencv可处理文件。1.3 模型介绍本项目主要使用了两个模型,分别是:用于目标检测的YOLOv5模型(PyTorch)和用于检测指针和刻度的语义分割模型DeepLabv3(pdmodel)。YOLOv5模型参考链接:cid:link_8DeepLabv3模型参考链接:cid:link_41.4 实现流程1、基础环境:Ascend 310、mxVision、Ascend-CANN-toolkit、Ascend Driver2、模型转换:目标检测模型: PyTorch模型转昇腾离线模型:yolov5.onnx --> yolov5.om语义分割模型: pdmodel模型转onnx模型:model.pdmodel --> DeepLabv3.onnx onnx模型转昇腾离线模型:DeepLabv3.onnx --> DeepLabv3.om3、业务流程编排与配置4、yolov5后处理开发5、mxpi_process3插件的后处理开发6、python推理流程代码开发:(1)YOLOv5的pipeline流程图如下: 图1. YOLOv5的pipeline流程图(2)DeepLabv3的pipeline流程图如下: 图2. DeepLabv3的pipeline流程图2 软件方案介绍2.1 项目方案架构介绍本系统识别的流程是:先将输入的图像送入流中解码和缩放大小,使用YOLOv5目标检测模型去检测图片中的表盘,结束流。将目标框裁剪下来,再送入流中解码和缩放大小,用DeepLabv3语义分割模型去得到工业表中的指针和刻度,对语义分割模型预测的结果进行读数后处理,找到指针指向的刻度,根据刻度的间隔和刻度根数计算表盘的读数。表2.1 系统方案中各模块功能:序号子系统功能描述1图像输入调用MindX SDK的appsrc输入图片2图像解码调用MindX SDK的mxpi_imagedecoder输入图片3图像放缩调用MindX SDK的mxpi_imageresize,放缩到1024*576大小4工业表检测调用MindX SDK的mxpi_tensorinfer,使用YOLOv5的检测模型,检测出图片中车辆5保存工业表的图像将YOLOv5检测到的工业表结果保存图片6图像输入调用MindX SDK的appsrc输入检测到的工业表7图像解码调用MindX SDK的mxpi_imagedecoder输入图片8图像放缩调用MindX SDK的mxpi_imageresize,放缩到512*512大小9指针刻度检测调用MindX SDK的mxpi_tensorinfer,使用DeepLabv3语义分割模型,检测图像中的指针与刻度10模型后处理调用MindX mxpi_semanticsegpostprocessor,得到语义分割的结果11读数后处理开发mxpi_process3插件,读出工业表的数字2.2 代码目录结构与说明本工程名称为工业指针型表计读数,工程目录如下图所示:├── build.sh ├── README.md ├── evaluate ├── deeplabv3_val #deeplabv3模型测试精度 ├── seg_evaluate.py ├── yolov5_val #yolov5模型测试精度 ├── det.py #1.使用om模型检测测试数据,将得到的结果保存成yolo格式的txt文件 ├── match.py #3.检测是否有的图像没有目标 ├── yolo2voc.py #2.将得到的检测结果yolo数据格式转换成voc格式 ├── images ├── README_img ├── DeepLabv3_pipeline.png ├── YOLOv5_pipeline.png ├── infer ├── det.py ├── main.py ├── seg.py ├── models ├── deeplabv3 ├── seg_aipp.cfg #deeplabv3的onnx模型转换成om模型的配置文件 ├── yolov5 ├── det_aipp.cfg #yolov5的onnx模型转换成om模型的配置文件 ├── pipeline #pipeline文件 ├── deeplabv3 ├── deeplabv3.cfg ├── deeplabv3.names ├── seg.pipeline ├── yolov5 ├── det.pipeline ├── plugins #开发读数处理插件代码 ├── process3 ├── build.sh ├── CMakeLists.txt ├── Myplugin.cpp ├── Myplugin.h ├── postprocess.cpp ├── postprocess.h3 开发环境准备3.1 环境依赖软件和版本环境依赖软件和版本如下表:软件名称版本ubuntu18.04.1 LTSMindX SDK2.0.4Python3.9.2CANN5.0.4numpy1.23.4opencv-python4.6.0MindX SDK开发套件部分可参考MindX SDK开发套件安装指导3.2 导入基础环境. /usr/local/Ascend/ascend-toolkit/set_env.sh . ${SDK安装路径}/mxVision/set_env.sh4 编译与运行示例步骤如下:步骤1 执行编译编译插件,在项目目录下执行如下命令cd ${MeterReader代码根目录}/plugins/process3 . build.sh步骤2 修改pipeline文件中的参数地址修改"${MeterReader代码根目录}/pipeline/yolov5/det.pipeline"第40行处文件的绝对路径,将pipeline中所需要用到的模型路径改为存放模型的绝对路径地址:40 "modelPath":"${MeterReader代码根目录}/models/yolov5/det.om"修改"${MeterReader代码根目录}/pipeline/deeplabv3/seg.pipeline"第30、38、39行处文件的绝对路径,将pipeline中所需要用到的模型路径、配置文件地址改为绝对路径地址:30 "modelPath":"${MeterReader代码根目录}/models/deeplabv3/seg.om" 38 "postProcessConfigPath":"${MeterReader代码根目录}/pipeline/deeplabv3/deeplabv3.cfg", 39 "labelPath":"${MeterReader代码根目录}/pipeline/deeplabv3/deeplabv3.names",步骤3 运行及输出结果总体运行。输入带有预测表盘的jpg图片,在指定输出目录下输出得到带有预测表盘计数的png图片。cd ${MeterReader代码根目录}/infer python main.py --ifile ${输入图片路径} --odir ${输出图片目录}执行结束后,可在命令行内得到yolo模型得到的表盘文件路径,以及通过后续模型得到的预测表盘度数。并可在设定的${输出图片路径}中查看带有预测表盘计数的图片结果。最后展示的结果图片上用矩形框框出了图片中的表计并且标出了预测的表盘读数。5 指标验证分别对yolo模型与deeplabv3模型进行精度测试。1、YOLOv5模型精度测试步骤一:执行以下命令创建所需要的文件目录cd ${MeterReader代码根目录}/evaluate/yolov5_val/ mkdir -p det_val_data/det_val_voc mkdir -p det_val_data/meter_det mkdir -p det_val_data/det_val_img mkdir -p det_val_data/det_sdk_txt mkdir -p det_val_data/det_sdk_voc步骤二:准备标签文件及推理图片下载YOLOv5表计检测数据集并解压到任意目录后,将数据集目录中"test"和"train"目录下的所有图片汇总拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/meter_det"目录下。我们提供了样例的模型验证集标签文件以供下载测试。完成下载并解压后,将"data/yolov5/det_val_voc"目录下的文件拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_val_voc"目录下。然后根据拷贝后目录下样例的txt标签文件名称(txt命名格式为:文件名.txt)在"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/meter_det"目录下找到对应名称的jpg图片并拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_val_img"目录下。步骤三:预处理数据集执行以下命令后,将在"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_sdk_txt"目录下生成当前"det.om"模型检测验证集数据的yolo格式结果,并以图片命名的txt格式保存:cd ${MeterReader代码根目录}/evaluate/yolov5_val python det.py再执行以下命令,将上述得到的yolo数据格式转换成voc数据格式,并保存至"${MeterReader代码根目录}/evaluate/yolov5_val/det_val_data/det_sdk_voc"目录下:python yolo2voc.py最后执行以下命令,检测验证集中的数据是否有无目标文件:python match.py注意事项:运行脚本之前需要把det_sdk_txt和det_sdk_voc文件夹下的文件清空。步骤四:精度推理登录并点击下载mAP-master.zip代码压缩包,上传服务器解压后,将代码包中的"main.py"脚本拷贝至"${MeterReader代码根目录}/evaluate/yolov5_val/"目录下,按照以下步骤修改部分代码:修改main.py第47、48、50行处文件路径47 GT_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_val_voc') 48 DR_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_sdk_voc') 49 # # if there are no images then no animation can be shown 50 IMG_PATH = os.path.join(os.getcwd(), 'det_val_data', 'det_val_img')修改main.py原第64行代码64 show_animation = False 65 if not args.no_animation:在main.py原第243行添加代码242 def draw_plot_func(dictionary, n_classes, window_title, plot_title, x_label, output_path, to_show, plot_color, true_p_bar): 243 to_show = False使用下面命令运行脚本,计算得到det.om在验证集上的mAP。python main.py经过测试,YOLOv5模型的mAP为100%。2、deeplabv3模型精度测试。执行以下命令,创建所需文件目录:cd ${MeterReader代码根目录}/evaluate/deeplabv3_val/ mkdir seg_val_img cd seg_val_img mkdir seg_test_img mkdir seg_test_img_groundtruth下载语义分割模型验证集voc格式数据,解压至"${MeterReader代码根录}/evaluate/deeplabv3_val/seg_val_img"目录下。然后执行以下命令拷贝数据:cp -r ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/meter_seg/meter_seg/images/val/. ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/seg_test_img/ cp -r ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/meter_seg/meter_seg/annotations/val/. ${MeterReader代码根目录}/evaluate/deeplabv3_val/seg_val_img/seg_test_img_groundtruth/采用Miou指标进行精度评价。使用下面命令运行脚本:cd ${MeterReader代码根目录}/evaluate/deeplabv3_val/ python seg_evaluate.py输出各个图的Miou指标,并求得平均值作为deeplabv3模型的精度指标。经测试,deeplabv3的模型的Miou为67%。6 常见问题6.1 模型转换问题问题描述当图像进入流后,输出到模型的图像格式为yuv,数据类型unit8,但是om模型的时候yolov5需要输入的图像格式为RGB。解决方案在转换模型时必须要在AIPP做色域转换,否则模型输入不正确。6.2 插件权限问题问题描述运行pipeline调用第三步的数值处理插件时报错,提示Check Owner permission failed: Current permission is 7, but required no greater than 6.解决方案将插件的权限调整为默认440(只读)即可chmod 440 "$MX_SDK_HOME/lib/plugins/libmxpi_sampleplugin.so"
-
如何查看昇腾服务器上正在跑的Mindspore的训练任务?有的训练任务在命令行一打bash run_standalone_train.sh [DATA_PATH]就看不到了。咋办呢?感谢!
-
昇腾服务器上Mindspore的训练任务,怎么把它中止啊?我们训练的时候跑了:bash run_standalone_train.sh [DATA_PATH]但是这个命令一打,命令行就立刻要收下一个命令了。看上去是异步的。我们看到内存在增长,可能要炸,想把参数调一下,所以应该怎么把训练任务中止啊?感谢!
-
求问ONNX模型如何转换到MindIR格式?感谢!
-
yolov5 6.0版本的模型 跑mindx sdk demo精度损失比较多,不出推理结果用的这个sdk demo,cid:link_0上面嵌套CANN 是5.0.4,用yolov5 6.0版本的模型, ATC模型转换之后, 跑5.0.4版本SDK(2.0.4)推理, 推理精度损失比较多, 推理基本不出结果, 这个模型转换之前在pytorch 推理是正常的, 并且yolov5 -5.0 这个版本模型转换之后在 mindx sdk 推理是正常的, 请问yolov5 6.0版本的模型有做适配吗? 还是需要做什么特别的处理?重现步骤转模型命令:atc --model=./smoke_sim_t.onnx --framework=5 --output=./smoke_yolo_sim_t2222 --input_format=NCHW --input_shape="images:1,3,640,640" --enable_small_channel=1 --insert_op_conf=./aipp_yolov5.cfg --soc_version=Ascend310 --log=infoaipp 配置文件:aipp_op {aipp_mode : staticrelated_input_rank : 0input_format : YUV420SP_U8src_image_size_w : 640src_image_size_h : 640crop : falsecsc_switch : truerbuv_swap_switch : falsematrix_r0c0 : 256matrix_r0c1 : 0matrix_r0c2 : 359matrix_r1c0 : 256matrix_r1c1 : -88matrix_r1c2 : -183matrix_r2c0 : 256matrix_r2c1 : 454matrix_r2c2 : 0input_bias_0 : 0input_bias_1 : 128input_bias_2 : 128var_reci_chn_0 : 0.0039216var_reci_chn_1 : 0.0039216var_reci_chn_2 : 0.0039216}yolov5-6.0 跑sdk推理打印输出如下所示(V5.0版本可以正常输出):本帖最后由 zhengchuang 于
-
Atlas300I-3000,CANN5.1RC2, Ascend310处理器您好,请问我在对多张输入图片预处理使用多线程的时候,发现各个子线程不能同时开启是什么问题呢?是因为资源不够的问题吗?开启线程: for img_name in img_list: thread_list.append(threading.Thread(target=jpg_pred,args=(img_name,))) i+=1 for t in thread_list: t.start() #time.sleep(0.02) for t in thread_list: t.join()子线程中的函数jpg_pred:def jpg_pred(img_name): print(1,time.time()) ret = acl.rt.set_context(context) #global input_data, img_src, image_filte_path print("predict: {}".format(img_name)) image_filte_path = img_path+"/{}".format(img_name) img_src = cv2.imread(image_filte_path) input_data = pre_process_ssd(img_src,height, width) for i in range(1000): if flag: scores, boxes = model_inference(input_data) break else: time.sleep(0.001) print("scores",scores) post_process_ssd(scores,boxes,img_src,image_filte_path,top_k=2) #input_data_list.append(input_data) #img_src_list.append(img_src) #image_filte_path_list.append(image_filte_path)def model_inference(input_data): global flag flag=False scores, boxes = model.execute([input_data,]) flag=True return scores, boxes我是想同时开启十几个线程,请问有线程数量上限吗?
-
硬件设备:Atlas 800 3010操作系统:Ubuntu内核版本: 4.15.0-112CPU架构:x86在测试验证openmmlab相关代码时出现以下问题:Segmentation fault
-
环境为 X86_64平台VMware虚拟机Ubuntu18.04.4桌面版, 使用ascend-deployer部署, 目标设备环境为CANN3.3.0根据教程安装方案-非昇腾设备-安装前准备-软件安装(ascend-deployer)-环境准备-3.3.0-CANN商用版-文档首页-昇腾社区 (hiascend.com)使用ascend-deployer进行开发环境安装, toolkit已经安装完, 在/usr/local/下有相关文件:也已经将set_env.sh中的环境写入~/.bashrc下执行 atc --model=$HOME/module/resnet50.prototxt --weight=$HOME/module/resnet50.caffemodel --framework=0 --output=$HOME/module/out/caffe_resnet50 --soc_version=Ascend310 命令后报错:求解如何处理
-
昇腾提供的npu-smi 命令类似NVIDIA的nvidia-smi 命令,请问也有相应的C++/python 接口用于查询相关信息吗? 还有如何查询当前程序所占用显存呢,麻烦相关技术人员帮忙解答一下谢谢!
-
Mind SDK -- 财务票据OCR识别参考设计案例1 案例概述1.1 概要描述在本系统中,目的是基于MindX SDK,在昇腾平台上,开发端到端财务票据OCR识别的参考设计,实现对财务票据中的文本信息进行OCR识别的功能,达到功能要求1.2 特性及适用场景本项目适用于票据图片完整清晰,倾斜角度较小的场景,并且建议图片分辨率不超过1280*1280,大小不超过1M。注:由于模型的限制,本项目暂只支持增值税发票、出租车发票和定额发票的识别1.3 模型介绍本项目涉及三种模型,分别是:用于分类的ResNet50模型(Mindspore)、用于文本检测的DBNet模型和用于文本识别的CRNN模型。相关模型文件在此处下载:resnet50、db、crnn1.4 实现流程1、基础环境:Ascend 310、mxVision、Ascend-CANN-toolkit、Ascend Driver 2、模型获取与训练:resnet50、db、crnn的训练 2、模型转换: mindspore模型转昇腾离线模型:resnet50.air --> resnet50.om PyTorch模型转昇腾离线模型:db.onnx --> db.om、crnn.onnx --> crnn.om 3、业务流程编排与配置 4、mxpi_textobjectpostprocessor插件的后处理库开发 5、python推理流程代码开发技术流程图如下所示:1.5 代码地址本项目的代码地址为:cid:link_122 软件方案介绍2.1 技术原理ResNet是ImageNet竞赛中分类问题效果比较好的网络,它引入了残差学习的概念,通过增加直连通道来保护信息的完整性,解决信息丢失、梯度消失、梯度爆炸等问题,让很深的网络也得以训练。参考论文DB(Differentiable Binarization)一种使用可微分二值图来实时文字检测的方法,和之前方法的不同主要是不再使用硬阈值去得到二值图,而是用软阈值得到一个近似二值图,并且这个软阈值采用sigmod函数,使阈值图和近似二值图都变得可学习。参考论文CRNN全称为Convolutional Recurrent Neural Network,是一种卷积循环神经网络结构,用于解决基于图像的序列识别问题,特别是场景文字识别问题。主要用于端到端地对不定长的文本序列进行识别,不用先对单个文字进行切割,而是将文本识别转化为时序依赖的序列学习问题,也就是基于图像的序列识别。参考论文2.2 项目方案架构介绍本系统设计了不同的功能模块。主要流程为:图片传入流中,通过分流插件分别送给分类模块和检测模块,其中分类模块将图像大小调整到224*224,然后利用resnet50分类模型对图片进行分类,将分类结果发送给串流插件;另一边检测模块接收图像传给dbnet模型进行文本检测,输出检测文本框坐标,然后通过坐标对原图像进行抠图,送入识别模块,crnn模型进行文本识别,将识别结果发送给串流插件,最后将结果组装成json输出。表2.2 系统方案中各模块功能:序号子系统功能描述1图像输入调用MindX SDK的appsrc输入图片2分流调用MindX SDK的mxpi_tee,分流给不同模块3图片分类利用resnet50的分类模型,配合后处理插件,得到分类结果4文本检测利用db的检测模型,配合后处理插件,输出检测结果5仿射变换调用MindX SDK的mxpi_warpperspective,根据检测结果进行仿射变换,得到文本框图片6文本识别利用crnn的识别模型,对文本框图片进行识别,配合后处理插件,输出识别结果7串流调用MindX SDK的mxpi_synchronize,将不同分支串流8结构化输出调用MindX SDK的mxpi_dataserialize,将分类、检测和识别结果组成json输出3 开发环境准备3.1 环境依赖说明环境依赖软件和版本如下表:软件名称版本Ubuntu18.04.1 LTSMindX SDK2.0.4Python3.9.2CANN5.0.4numpy1.22.3opencv-python4.5.5PIL8.4.03.2 环境搭建3.2.1 环境变量设置在编译运行项目前,需要设置环境变量:# Mind SDK环境变量: .${SDK-path}/set_env.sh # CANN环境变量: .${ascend-toolkit-path}/set_env.sh # 环境变量介绍 SDK-path:SDK mxVision安装路径 ascend-toolkit-path:CANN安装路径3.3 模型获取、训练与转换3.1 模型获取及训练3.1.1 resnet50训练代码参考链接3.1.2 db参考paddleocr文本检测训练3.1.3 crnn参考paddleocr文本识别训练3.2 模型转换此处提供训练后的中间模型供模型转换使用:resnet50、db、crnn在./models/resnet50目录下执行如下命令atc --model=./resnet.air --framework=1 --output=resnet50 --input_format=NCHW --input_shape="x:1,3,224,224" --enable_small_channel=1 --soc_version=Ascend310 --insert_op_conf="aipp.config"在./models/db目录下执行如下命令atc --model=./db.onnx --framework=5 --output_type=FP32 --output=db --input_format=NCHW --input_shape="x:1,3,-1,-1" --dynamic_image_size="1216,1280;1280,1216;1120,1280;1280,1120;1024,1280;1280,1024;928,1280;1280,928;832,1280;1280,832;736,1280;1280,736;704,1280;1280,704;672,1280;1280,672;640,1280;1280,640;608,1280;1280,608;576,1280;1280,576;544,1280;1280,544;512,1280;1280,512;480,1280;1280,480;448,1280;1280,448" --soc_version=Ascend310 --insert_op_conf=./det_aipp.cfg在./models/crnn目录下执行如下命令atc --model=./crnn.onnx --framework=5 --output_type=FP32 --output=crnn --input_format=NCHW --input_shape="x:1,3,48,320" --soc_version=Ascend310 --insert_op_conf="rec_aipp.cfg"执行完模型转换脚本后,会生成相应的.om模型文件。更多ATC工具细节请参考链接。4 推理流程开发实现4.1 pipeline编排appsrc # 输入 mxpi_imagedecoder # 图像解码 mxpi_tee # 分流 分流1: mxpi_imageresize # 图像缩放 mxpi_tensorinfer # 模型推理(图片分类) mxpi_classpostprocessor # 模型后处理(resnet50) 分流2: mxpi_imageresize # 图像缩放 mxpi_tensorinfer # 模型推理(文本检测) mxpi_textobjectpostprocessor # 模型后处理(db) mxpi_warpperspective # 仿射变换 mxpi_tensorinfer # 模型推理(文本识别) 串流: mxpi_textgenerationpostprocessor# 模型后处理(crnn) mxpi_synchronize # 串流 mxpi_dataserialize # 结构化输出 appsink # 输出4.2 db文本检测后处理库开发参考链接4.3 主程序开发1、初始化流管理。2、加载图像,进行推理。3、获取pipeline各插件输出结果,解析输出结果。4、根据识别结果在图上标出文本框信息和文本内容,根据分类结果创建文件名5、销毁流5 编译与运行步骤1 编译后处理插件DBPostProcess参考链接编译后处理插件,修改部分文件代码,具体如下:# 数字为行号,文件位于src/DBPostProcess/CMakeLists.txt 1 cmake_minimum_required(VERSION 3.5.2) 3 add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0 -Dgoogle=mindxsdk_private) # 数字为行号,文件位于src/DBPostProcess/DBPostProcess.h 72 bool IsValidTensors(const std::vector<TensorBase> &tensors) const;并将编译好的libDBPostProcess.so和libclipper.so放在项目目录./lib下,添加如下环境变量(其中project_path为项目路径)export LD_LIBRARY_PATH={project_path}/lib/:$LD_LIBRARY_PATH进入./lib目录,将编译完的.so文件权限修改为640。步骤2 配置pipeline文件将pipeline中相关模型路径,配置文件路径及插件路径配置正确步骤3 将要识别的票据图片放到./inputs目录下,执行如下命令python3 main.py待执行完毕可在./outputs目录下查看结果结果展示:6 指标验证6.1 精度测试本精度测试在昇腾310芯片上执行测试数据可在此处下载,将下载的数据解压到eval_data目录下,在项目目录下执行python3 eval.py可得精度结果如下所示,其中acc为db+crnn端到端精度,type_acc为resnet50精度精度结果如下表所示模型精度resnet500.99端到端OCR0.95346.2 性能测试npu性能测试采用ais-infer工具,ais-infer工具为华为自研的模型推理工具,支持多种模型的离线推理,能够迅速统计出模型在310P上的性能,支持真实数据和纯推理两种模式,配合后处理脚本,可以实现诸多模型的端到端过程,获取工具及使用方法可以参考推理工具ais-infer官方源码仓。将三个模型的om文件放到ais_infer.py同目录下,执行如下命令可得到三个模型的npu性能python3 ais_infer.py --model model/resnet50.om --batchsize 1 --loop 10python3 ais_infer.py --model model/db.om --batchsize 1 --loop 10 --dymHW 1216,1280python3 ais_infer.py --model model/crnn.om --batchsize 1 --loop 10gpu性能测试采用使用TensorRT,将三种模型的onnx文件放在装有对应gpu卡(T4)的服务器上,执行如下命令得到gpu性能trtexec --onnx=resnet50.onnx --fp16 --shapes=image:1x3x224x224trtexec --onnx=db.onnx --fp16 --shapes=x:1x3x1216x1280trtexec --onnx=crnn.onnx --fp16 --shapes=x:1x3x48x320可得性能如下表所示:模型gpu性能(T4)310性能(4卡)resnet50903.4893 fps1743.1472 fpsdb36.5123 fps45.4676 fpscrnn1159.875 fps1114.392 fps7 常见问题7.1 后处理插件路径问题问题描述:提示libclipper.so: cannot open shared object file: No such file or directory解决方案:这是由于没有将后处理插件的路径配置到环境变量中,添加如下环境变量,project_path为项目路径export LD_LIBRARY_PATH={project_path}/lib/:$LD_LIBRARY_PATH7.2 字体资源问题问题描述:提示cannot open resource解决方案:将字体文件路径正确配置到eval.py中add_text函数中,此处提供字体文件,下载后放置于项目目录下,如下fontstyle = ImageFont.truetype("SIMSUN.TTC", textSize, encoding="utf-8")
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签