Ascend 310 推理
第一次参加华为的Ascend众智开发计划,负责DLinkNet的推理部分,一开始对整体环境和任务目标都比较迷茫,但是华为的老师讲解挺耐心的,慢慢的对项目也熟悉了起来。总体来说310的推理核心就是写main.cc推理文件和postprocess.py的后处理+精度计算文件,总目标就是拿到训练后的mindir文件在你写的main.cc上跑出结果,把结果拿到postprocess.py进行后处理+精度计算,精度一定要达标才行。以后参加离线推理的同学可以参考一下下面的讲解。
一、整体结构
├── ascend310_infer
│ ├──inc
└──utils.h //头文件
│ └──src
├──CMakeLists.txt //编译文件
├──build.sh //编译运行
├──main.cc //推理文件
└──utils.cc //工具方法
├── scripts
└── └──run_infer_310.sh // Ascend 310 推理脚本
二、CMakeLists.txt
此处与modelzoo上大部分是一样的(只不过我生成的可执行文件是自己命名的),路径如果修改的话一定要注意,因为修改错了会报奇奇怪怪的错误。
cmake_minimum_required(VERSION 3.14.1)
project(Dlinknet[CXX])
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -g -std=c++17 -Werror -Wall -fPIE -Wl,--allow-shlib-undefined")
set(PROJECT_SRC_ROOT ${CMAKE_CURRENT_LIST_DIR}/)
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
include_directories(${PROJECT_SRC_ROOT}/../inc)
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)
add_executable(dlinknet main.cc utils.cc)
target_link_libraries(dlinknet ${MS_LIB} ${MD_LIB} gflags)
三、build.sh
cmake . -DMINDSPORE_PATH="`pip show mindspore-ascend | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`"
make
四、utils.cc
根据自己的需要去修改或者编写自己的工具方法,大体有这么几个函数:
1.GetAllFiles(得到文件夹下的所有文件名)
2.RealPath(得到文件的真实路径)
3.OpenDir(打开文件夹)
4.ReadFile(读取数据)
5.WriteResult(把推理结果写写入某文件或者文件夹)
五、main.cc
这个部分每个模型差异都比较大,需要按照自己的模型去写。可以去官网找与自己模型类似的模型参考:modelzoo
前处理部分可以参考华为mindspore提供的API
大体步骤:
- 构建环境
- 定义前处理过程
- 构建模型
- 获取文件数据
- 经过前处理送入模型推理运行
- 获取推理性能
- 保存结果
六、run_infer_310.sh
这是310推理的总执行脚本文件,需要把编译,推理,计算精度依次执行。
以我的推理脚本为例:
1.编译
function compile_app()
{
cd ../ascend310_infer/src || exit
if [ -f "Makefile" ]; then
make clean
fi
bash build.sh &> build.log
}
2.推理执行
function infer()
{
cd - || exit
if [ -d result_Files ]; then
rm -rf ./result_Files
fi
if [ -d time_Result ]; then
rm -rf ./time_Result
fi
mkdir result_Files
mkdir time_Result
../ascend310_infer/src/dlinknet --mindir_path=$model --dataset_path=$data_path --device_id=$device_id &> infer.log
}
3.计算精度
function cal_acc()
{
python ../postprocess.py result_Files $label_path &> acc.log &
}
七、遇到的问题
1.各种路径问题:
CMakeList,utils.cc,main.cc,run_infer_310.sh这些文件都会涉及到路径,如果不太小心改错或者记错了路径就会出现很多奇
奇怪怪的bug,大部分bug都是路径错的。
2.环境激活:
运行310一定不要忘了source /home/env.sh
3.有可能会损失精度的地方
我在推理的时候一开始,自以为的在归一化函数的地方随便设置了6个数字参数,但是这个错误使得310推理的准确率损失了2个
百分点建议大家如下设置归一化。
std::shared_ptr<ds::TensorTransform> normalize(new ds::vision::Normalize({103.53, 116.28, 123.675},
{57.375, 57.120, 58.395}));