边缘设备使用记录--阿加犀AIBox 6490

设备介绍

阿加犀AIBox 6490是一款基于高通QCS6490平台的高性价比智能边缘计算终端,具有14TOPS AI算力,可独立运行Android、Linux、Ubuntu操作系统,或选择Android+Linux双系统原生融合并行,带来更加高效的使用体验。 详情可以参考官网链接,我手中的这块板子是单独的Ubuntu 20.04系统。

设备连接

6490自己是有HDMI out输出的,所以最简单的办法就是直接插上鼠标键盘还有显示器,当正常的电脑用,不过这里的桌面应该是简化过的,只有左上角有个终端的按钮,别的什么都没有

在这里插入图片描述

单纯这么使用的话应该是有点麻烦的,所以这里还是选择和之前树莓派,以及Nvidia Orin nx一样的方法,使用SSH远程开发。 然后这里就有新的问题了,这个目前似乎是没有开机自动WiFi连接的方法的,按之前给树莓派配WiFi的方法试了下也没成功,所以这里就退而求其次,选择用网线和主机连接,再把主机的网络共享给6490板子,实现的效果也是一样的。在连上网线之后,可以在网络设备里看到刚刚插入的网口
在这里插入图片描述

这个未识别的网络指的就是刚刚连上的了,接下来只需要再设置下WiFi的网络共享以及对应以太网的IP地址就可以了
在这里插入图片描述

然后再根据arp -a命令可以查到当前设备的IP地址,之后只需要用自己习惯的方式连上就可以,我这里配的是tabby和vscode
在这里插入图片描述
之后就可以进行愉快的coding了

  • 这里有一个小问题,就是板子每次重启后,虽然我连的网口没变,但IP还是会发生改变,这样其实倒也没什么问题。。就是后边用的次数多了可能会增加找到这个IP的难度。目前还没想到什么好办法解决,之后看看有没有办法能解决吧

glog && gflags

因为个人的习惯问题,还是把glog,gflags日志库安装了一下,这里还是源码编译,之前也源码编译安装了很多次了,首先要注意一定要先安装gflags

git clone https://github.com/gflags/gflags.git
cd gflags
mkdir build && cd build
cmake .. -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC ..
make -j4
sudo make install

然后再安装glog,不过这里直接拉最新的代码是不行的,主要报错是在CMake文件里,虽然感觉应该不难改,但这里还不如降低一下版本。。所以直接换成了0.5.0的版本,安装没什么问题

git clone -b v0.5.0 https://github.com/google/glog
cd glog
mkdir build && cd build
cmake -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_SHARED_LIBS=ON ..
make -j4
sudo make install

然后就在自己的程序里链接到这两个库就能愉快的使用了

onnx2tflite

我比较常用的模型都是onnx,之前在看autoware的时候有了解过TensorRTtvm两种部署方式,里面是通过加载onnx然后生成engine引擎文件实现的。在Aidlux自带的AI包中,支持的模型种类没有onnx,所以这里是稍微搜了下,发现了onnx2tflite这个库,所以这里把这个库先安装一下。第一步还是经典的依赖问题,直接pip install网络估计还是会报错,所以这里直接指定清华源了

sudo pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

安装之后其实报了版本冲突的警告,但是不知道后边会不会有影响,先运行下试试

  • 然后果然就出问题了,运行的时候一直会提示The TensorFlow library was compiled to use AVX instructions, but these aren’t available on your machine.这个错误,然后直接段错误,上网搜了下我的CPU应该是不支持AVX,所以要使用SSE版本的Tensorflow才行。。这里参考Tensorflow针对CPU的编译优化加速这篇文章进行了Tensorflow的重新安装

这里也是废了半天劲,最后转换得到了一个yolox_nano.tflite文件,而且还不知道能不能用。。先继续往下看吧(后边试了一下,加载模型的时候会提示GATHER不支持GPU加速,但好像也没什么大问题?

在这里插入图片描述

  • 又在网上搜了半天,发现了YOLOX-ti-lite Object Detector in TFLite这样一个仓库,里面是一些在边缘设备部署YOLOx的代码,而且也有几个训练好的模型,这里也是下了几个别人训练好的模型准备后边拿来测试一下,至少创建模型是可以的

AidLite SDK for C++

本来还想着要装tvm呢,后来搜了搜发现阿加犀自己有对应的模型推理的一个SDK,而且使用文档写的相对还挺全的,这个文档的地址在AidLite SDK for C++,这里就参考这个文档依次来学习一下

模型输入输出的shape

在模型创建的代码中,我们发现里面对input_shapeoutput_shape进行了设置

// 创建Model实例对象,并设置模型相关参数
Model* model = Model::create_instance("./inceptionv3_float32.dlc");
if(model == nullptr){
    printf("Create model failed !\n");
    return EXIT_FAILURE;
}
std::vector<std::vector<uint32_t>> input_shapes = {{1,299,299,3}};
std::vector<std::vector<uint32_t>> output_shapes = {{1,1001}};
model->set_model_properties(input_shapes, DataType::TYPE_FLOAT32, 
    output_shapes, DataType::TYPE_FLOAT32);

像这里,我个人觉得第一个1代表的就是批次,然后输入后边对应的就是2992993的图像,下面输出的1000应该对应着1001种类别。 OK,因为我对各种网络其实不是很熟悉,所以这里还是以YOLOx为例,之前也有在autoware.universe源码略读(3.1)–perception:yolo初识这篇文章总结过,这里的输出应该是85*8400,所以设置的话应该设置成[1, 8400,85]?这里我暂时是这么设置的

  • 这里又看了下,YOLOx-nano和tiny应该是只支持416*416一种输入的,所以这里的输入输出都得跟着改成下面这样
std::vector<std::vector<uint32_t>> input_shapes = {{1, 416, 416, 3}};
std::vector<std::vector<uint32_t>> output_shapes = {{1, 3549, 85}};
model->set_model_properties(input_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32,
                            output_shapes, Aidlux::Aidlite::DataType::TYPE_FLOAT32);

还不知道这样对不对,还是一边写一边测试吧。然后是创建 Config 类型的对象,此对象用于记录模型推理相关的配置信息,推理框架运行过程中会使用到这些配置信息。

执行推断

这里其实照着文档来就可以了,不过值得注意的是,我本来以为这个板子是NPU,结果发现还是GPU(其实我也不是很了解两者的区别),因为在设置Config提示我tflite模型不能用NPU我才发现这个问题。还有和之前用到的TensorRT不同的一点是,因为这里指定了输入和输出的shapes,所以保存成cv::Mat就可以了

cv::Mat input_data;
preprocess(FLAGS_input_image, input_data);
result = fast_interpreter->set_input_tensor(0, static_cast<void*>(input_data.data));
if (result != 0)
{
    LOG(FATAL) << "interpreter set input tensor false!\n";
}

然后执行推理过程,稍微计时了一下,在我使用yolox_nano_ti_lite_float32.tflite模型的时候每次推理的耗时在20-30ms,不是很清楚这个算什么水平。然后我们在这里直接把输出再转成一个vector,这样应该会好处理一些

result = fast_interpreter->invoke();
if (result != 0)
{
    LOG(FATAL) << "invoke failed!\n";
}
time_end = std::chrono::system_clock::now();
auto time_cost = std::chrono::duration_cast<std::chrono::milliseconds>(time_end - time_begin);
LOG(INFO) << "invoke cost: " << time_cost.count() << "ms.\n";
float* out_data = nullptr;
uint32_t output_tensor_length = 0;
result = fast_interpreter->get_output_tensor(0, (void**)&out_data, &output_tensor_length);
assert(result == 0);
std::vector<float> out_data_vec(out_data, out_data + output_tensor_length / 4);
LOG(INFO) << "out data vec size: " << out_data_vec.size() << std::endl;

最后当然还有一步骤是输出的后处理,这个就要针对不同的模型进行不同的操作了,就不在这里说了

OpenCV使用

在板子里是有预先安装好OpenCV的,但是可以看到里面有不止一个
在这里插入图片描述
这里是有两个版本,4.9.0和4.2.0,其实我也不太清楚这两个版本具体有什么区别,但是因为之前自己用的都是4.2.0的,所以这里还是用4.2.0的进行后续的开发。在CMake里直接find_package的找到的是4.9.0的版本,所以这里只需要指定一下cmake文件的路径就好

find_package(OpenCV REQUIRED
             PATHS /usr/local/lib/aidlux_opencv/lib/cmake/opencv4
             NO_DEFAULT_PATH)
include_directories(${OpenCV_INCLUDE_DIRS})
# message(STATUS "OpenCV include path: ${OpenCV_INCLUDE_DIRS}")

其实不需要消息输出,因为会提示找到的OpenCV的版本

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值