张小白教你在200DK上的使用MindStudio 5.0.RC2的Windows版本进行卡通风格迁移

举报
张辉 发表于 2022/08/28 08:06:12 2022/08/28
【摘要】 MindStudio 体验官 升职记。

一、背景

其实这应该是张小白完成MindStudio体验官第一期体验的第2篇文章,因为这原本就是对标MindStudio团队提供的AI1S服务器镜像基础上,张小白试着在200DK上的实现。

本来张小白以为这应该很好解决的,哪里知道这反而变成了这次体验官活动中最大的拦路虎。好在最近在 @黄贺阳 的帮助下解决了。所以特意重新整理下相关的文字,以供大家参考。

张小白在AI1S服务器上使用MindStudio小助手使用的镜像完成了MindStudio卡通风格迁移的项目的复现。具体过程参见  https://bbs.huaweicloud.com/blogs/371113

张小白在200DK上完成了MindStudio YoLoV3目标检测项目的复现:https://bbs.huaweicloud.com/blogs/371600

但是显然,这个案例不是MindStudio体验官要求复现的项目,因为这次体验官的项目明确要求是MindX SDK项目,而YoLoV3这个是sample仓库的项目,并不是一个MindX SDK项目。

cke_33554.png

张小白在200DK上完成了MindStudio MMNet人像分割项目的复现:https://bbs.huaweicloud.com/blogs/371825

这篇文章从零开始介绍一直到最后运行成功,张小白也用两套环境(两台笔记本,两套x86虚拟机,两张200DK启动的TF卡)做了尝试。文章的实践性较强,如果环境还不会搭建的,可以参考这篇文字进行全流程的搭建。

张小白又在MMNet项目的基础上,完成了200DK上MindStudio FaceBoxes人脸检测项目的复现:https://bbs.huaweicloud.com/blogs/372229


这篇文章也成功地检测出目前MindStudio中下载插件配置文件的一个BUG( https://bbs.huaweicloud.com/forum/thread-0230967406263860003-1-1.html  ),功德无量。

那么现在,张小白依然在前面这两篇文字的基础上,来复现一下200DK上的卡通风格迁移项目吧!

二、安装MindStudio 5.0.RC2 for Windows

由于此时张小白也测出了MindStudio的一些其他BUG,@K 大大建议张小白下载新的MindStudio前端进行验证。

cke_46512.png

那就从MindStudio的最新版开始吧!这样也可以把MindStudio的相关配置过程再重现一下。

打开MindStudio官网:https://www.hiascend.com/software/mindstudio

cke_51921.png

点击立即下载:

cke_52901.png

当然,张小白对此是有点疑问的。因为张小白以前下载的日期应该也是8月份,所以那个时候下载的应该也是7月27日的版本才对。

不管了,点击最下面一个zip包右边的“软件包下载“吧!

cke_70090.png

耐心等待下载结束:

cke_73681.png

将其带目录解压到G盘(上次是E盘)

解压后如下:

cke_82427.png

点击MindStudio.bat,可以打开MindStudio:

cke_84439.png

cke_84847.png

当然,由于张小白机器上有一个版本的MindStudio,所以这次会打开前面的那个项目,我们点击 关闭项目:

cke_116745.png

三、使用MindStudio 5.0.RC2打开卡通风格迁移样例工程

为了完全复现,张小白特意在G盘也重新下载一个MindX SDK样例仓库(省得被E盘的MindX SDK仓库中已经修改过的代码所干扰。)

打开cmd窗口

G:

git clone https://gitee.com/ascend/mindxsdk-referenceapps.git

 cke_121908.png

用MindStudio打开工程目录:

G:\mindxsdk-referenceapps\contrib\CartoonGANPicture

cke_124472.png

点击确定:

cke_126173.png

点击信任项目,进入了工程的主页面:

cke_129085.png

这个时候,打开的项目还不是一个昇腾的工程,需要点击Ascend-》Convert to Ascend Project:

cke_143738.jpeg

按照以下方式填写:

cke_148537.png

点击OK

四、查看MindStudio相关配置

1、CANN配置

点击Ascend-》CANN Manager

cke_157160.png

当然,由于以前配置过,所以CANN Toolkit也被识别出来。

2、MindX SDK配置

点击Ascend-》MindX SDK Manager

cke_181066.png

同样的,mxVison 3.0.RC2也被识别出来。

五、工程编译

1、编译配置

从这个项目的程序架构来看,它是个C++的工程,使用cmake作为编译工具。

cke_194931.png

我们就来配置下编译参数:

点击 构建-》Edit Build Configuration:

cke_198847.png

点击+

cke_200282.png

点击确定。

2、编译

点击构建-》Build Project,仔细查看编译的输出窗口:

cke_210238.png

这里报了个错:

信息:/home/HwHiAiUser/mxVision-3.0.RC2/lib/libmxbase.so: undefined reference to `memset_s'

显然,这个问题张小白遇到过也解决过。

​​

打开CMakeLists.txt文件,在link_directories内增加一行:/usr/lib64

在target_link_libraries内增加一行:/usr/lib64/libc_sec.so

cke_221966.png

再重新编译:

cke_223667.png

可见可执行程序 CartoonGAN_picuture程序已经编译成功。

六、准备项目环境

我们选择原有的JPG图片:

cke_1963.jpeg

在项目工程下创建data目录:

cke_8538.png

创建data/images目录,将上面的图片复制过去。

创建data/output目录。

创建data/model目录:

cke_17835.png

七、使用MindStudio完成模型转换

1、准备原始pb模型

使用浏览器下载 https://mindx.sdk.obs.cn-north-4.myhuaweicloud.com/mindxsdk-referenceapps%20/contrib/CartoonGANPicture/model.zip

cke_20620.png

解压到data目录(zip文件本身带目录,选择解压到当前目录下即可)

cke_23377.png

2、模型转换

​点击Ascend-》Model Converter:

cke_26038.png

Model File想选择刚才的pb文件,其实不行。非要选择后台的文件。。。

这个有点尴尬了。张小白不是想在MindStudio前台界面上完成模型转换功能吗?

如果是远程在后台执行,那张小白干嘛不直接使用命令行转换呢?


无奈,只好选择200DK上同样目录下的文件(这个目录是原来在200DK后台git clone MindX SDK样例仓创建的)

 cke_41454.png

点击确定:

cke_42229.png

系统会进行模型解析,解析完毕后,会显示如下:

cke_46235.png

当然,上图中模型的输出目录应该放在 G:\mindxsdk-referenceapps\contrib\CartoonGANPicture\data\model ,改一下即可。

cke_54189.png

结果如下:

cke_55984.png

​​

 点击Next:

cke_57015.png

打开Data Preprocessing:

cke_59047.png

打开Load Aipp Configuration:

cke_62010.png

选择AIPP的文件名,应该是 G:\mindxsdk-referenceapps\contrib\CartoonGANPicture\data\model\insert_op.cfg 才对:

cke_67593.png

系统又去200DK后台找文件了!

算了,还是找给它吧!

cke_80948.png

显示如下:

cke_83652.png

点击Next:

cke_86255.png

先切换到200DK的终端把原来转换好的om模型备份一下吧!

cke_93658.png

 切换回到MindStudio,点击Finish:

cke_101128.png

系统开始做模型转换。。。

cke_102736.png

模型转换成功了。

cke_103881.png

但是张小白比较了一下 原来的命令行命令:

atc --output_type=FP32 --input_shape="train_real_A:1,256,256,3"  --input_format=NHWC --output="cartoonization" --soc_version=Ascend310 --insert_op_conf=insert_op.cfg --framework=3 --model="cartoonization.pb" --precision_mode=allow_fp32_to_fp16

以及刚才生成的atc命令:

/home/HwHiAiUser/Ascend/ascend-toolkit/5.1.RC2/atc/bin/atc  --input_shape="train_real_A:1,256,256,3" --check_report=/home/HwHiAiUser/modelzoo/cartoonization/Ascend310/network_analysis.report --input_format=NHWC --output="/home/HwHiAiUser/modelzoo/cartoonization/Ascend310/cartoonization" --soc_version=Ascend310 --framework=3 --model="/home/HwHiAiUser/mindxsdk-referenceapps/contrib/CartoonGANPicture/data/model/cartoonization.pb" 

发现少了一个参数:

--precision_mode=allow_fp32_to_fp16

张小白仔细想了一下,还是决定在Addtional Arguments里面加上这个参数吧!

cke_116321.png

输入后按TAB键:

cke_119702.png

这回有这个参数了。

点击Finish重新进行模型转换:

cke_127121.png

耐心等待转换结束:

cke_128850.png

转换完毕。

奇怪了,模型转换之后,模型呢?

cke_545.png

哦。原来张小白第二次模型转换的时候忘记选 output path了!

cke_3858.png

到这里了:

C:\Users\zhang\modelzoo\cartoonization\Ascend310

cke_5247.png

只好手工把om文件拷贝过去:

cke_8835.png

好了,万事俱备,只欠执行了!

(当然现在的代码执行应该会报个比较严重的错误...)

八、调试、运行项目

点击运行-》运行 CartoonGANPicture:

cke_20362.png

显示如下:

cke_21730.png

这就是张小白遇到的那个大BUG:

E20220827 14:01:24.365751 22956 DvppWrapperBase.cpp:607] [507013][Error code unknown] DvppJpegDecode, fail to synchronize stream. 

E20220827 14:01:24.365921 22956 DvppWrapper.cpp:256] [507013][Error code unknown] Fail to set input data information. 

E20220827 14:01:24.365957 22956 DvppWrapper.cpp:192] [507013][Error code unknown] DvppJpegDecode, fail to GetImageData. 

E20220827 14:01:24.365998 22956 CartoonGANPicture.cpp:73] DvppWrapper DvppJpegDecode failed, ret=507013. 

E20220827 14:01:24.366017 22956 CartoonGANPicture.cpp:214] ReadImage failed, ret=507013. 

E20220827 14:01:24.366043 22956 main.cpp:96] CartoonGANPicture process failed, ret=507013.

不要紧,华为的人已经有了解决方案了!

打开CartoonGANPicture.cpp代码:

将ReadImage函数改为以下内容:

APP_ERROR CartoonGANPicture::ReadImage(const std::string &imgPath, MxBase::TensorBase &tensor)
{
    printf("xxxx\n");
    MxBase::DvppDataInfo inputDataInfo = {};
    MxBase::DvppDataInfo outputDataInfo = {};

    // std::string strImage = FileUtils::ReadFileContent(imgPath);
    // input.dataSize = strImage.size();
    std::ifstream file(imgPath, std::ios::binary);
    if (!file) {
        LogError << "hhy Invalid file.";
    }
    long fileSize = fs::file_size(imgPath);
    std::vector buffer;
    buffer.resize(fileSize);
    file.read(buffer.data(), fileSize);
    file.close();
    std::string fileStr(buffer.data(), fileSize);
    
    printf("0000 : Ý869a910-4485-4426-9428-2edf4602b807n", (size_t)fileStr.size());
    MemoryData hostMemory((void *)fileStr.c_str(), (size_t)fileStr.size(), MemoryData::MEMORY_HOST, 0);
    MemoryData dvppMemory(nullptr, (size_t)fileStr.size(), MemoryData::MEMORY_DVPP, 0);
    printf("aaaa\n");
    APP_ERROR ret = MemoryHelper::MxbsMallocAndCopy(dvppMemory, hostMemory);
    printf("bbbb\n");
    ret = dvppWrapper_->DvppJpegPredictDecSize(hostMemory.ptrData, hostMemory.size, inputDataInfo.format, outputDataInfo.dataSize);
    printf("bbbb2\n");
    inputDataInfo.dataSize = dvppMemory.size;
    inputDataInfo.data = (uint8_t*)dvppMemory.ptrData;
    ret = dvppWrapper_->DvppJpegDecode(inputDataInfo, outputDataInfo);
    printf("cccc\n");
    ret = MemoryHelper::Free(dvppMemory);


    MxBase::DvppDataInfo &output = outputDataInfo;
    // MemoryData hostMemory((void *)strImage.c_str(), (size_t)strImage.size(), MemoryData::MEMORY_HOST, 0);
    // 图像解码
    // ret = dvppWrapper_->DvppJpegDecode(imgPath, output);
    // if (ret != APP_ERR_OK) {
    //     LogError << "DvppWrapper DvppJpegDecode failed, ret=" << ret << ".";
    //     return ret;
    // }
    // 将数据转为到DEVICE侧,以便后续处理
    MxBase::MemoryData memoryData((void*)output.data, output.dataSize,
                                  MxBase::MemoryData::MemoryType::MEMORY_DEVICE, deviceId_);
    imageWidth_ = output.width;
    imageHeight_ = output.height;
    widthStride_ = output.widthStride;
    heightStride_ = output.heightStride;

    // 对解码后图像对齐尺寸进行判定
    if (output.heightStride % VPC_H_ALIGN != 0) {
        LogError << "Output data height(" << output.heightStride << ") can't be divided by " << VPC_H_ALIGN << ".";
        MxBase::MemoryHelper::MxbsFree(memoryData);
        return APP_ERR_COMM_INVALID_PARAM;
    }
    std::vector shape = {output.heightStride * YUV_BYTE_NU / YUV_BYTE_DE, output.widthStride};
    tensor = MxBase::TensorBase(memoryData, false, shape, MxBase::TENSOR_DTYPE_UINT8);

    return APP_ERR_OK;
}

cke_42490.png

并把原来的ReadImage函数删掉。

重新编译,点击 构建-Rebuild Project:

cke_596.png

又报错了,好像是少了定义部分:

在该cpp代码头加上以下语句:

#include 

#include "boost/filesystem.hpp"
#include "MxBase/MemoryHelper/MemoryHelper.h"

using namespace MxBase;
namespace fs = boost::filesystem;

cke_4392.png

再重新编译:

cke_16298.png

编译成功,再重新运行:

cke_17348.png

运行成功!

上图中的图片就是原图片卡通化的结果。

这里提一下出错的时候怎么看日志的问题:

当时报错的时候,可以查看 /var/log/npu/slog/device-app-xxxx下的日志,找到最近时间的log目录:

cke_21274.png

我们可以看到最后几次日志目录,分别进去打开log看看:

cke_24060.png

从这里能看出,系统报了 无法进行异步拷贝的操作,说明200DK不支持异步拷贝(具体为啥不支持张小白也不清楚!)。把这个错误log发给昇腾技术,可能有助于尽早解决问题。

九、体验总结

众所周知,这是个不带pipeline的MindX SDK项目,自然是个非主流的MindX SDK项目,所以也没法看pipeline什么的。

所以现在总结一下体验过程中的建议:

(1)编译的时候报 memset_s错,其实是缺 /usr/lib64/libc_sec.so。需要修改 CMakeLists.txt文件,可以考虑将/usr/lib64库加入LD_LIBRARY_PATH试试能不能行。

(2)使用MindStudio模型转换的时候全到后台去找pb文件和aipp配置文件,这点是不对的。按理说,既然是Windows代码,那么所有的文件应该是Windows端提供好才对。MindStudio Windows版本应该负责将相关的windows端的文件传输到后台进行远程atc命令执行。(与此对应的,MindStudio Linux版本是可以在Linux本地完成atc转换的,也就无需远程执行atc命令)

(3)MindStudio做模型转换的时候,命令能否被缓存。这样下一次重做模型转换的时候不要费劲选那么多参数了。不然很累的,不如使用后台atc了!(这点有专家回答说其实是有的,只是要在 模型转换的第一个界面 选择导入配置文件 即可。但是这点张小白不是很认可,什么叫做 导入配置文件,那就是你原来导出过了?张小白之所以没有点击那个按钮,就是因为自己认为这个命令不是我想要的命令,如果你把按钮改为 “使用上次模型转换配置”,张小白还可以理解。)

(4)卡通风格迁移原有代码做了异步拷贝,报错了。虽然技术人员解决了问题,但是最好还是深度解决一下。

(5)代码现在变长了。张小白也越来越看不懂了。(能不能在代码里面多加点注释?)

好了,不管如何,卡通风格迁移是张小白一直想用200DK复现的项目,终于在好多天之后完成了初体验,也算不容易。为此感谢又此被打扰到的各位昇腾 MindStudio和MindX SDK的同学们。

如果有空,我。。。

——我还会骚扰你们的。毕竟张小白是个超级细心的MindStudio体验官,对不对?

(全文完,谢谢阅读)

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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