算能BM1684X部署手写数字识别模型

大致流程---------------------------------------------------------------

参考《sophon-sail_zh》

移植步骤------------------------------------------------------------------------

首先搭建好自己的网络模型,并导出为onnx格式--具体可以参照-->

GitHub - warren-wzw/MNIST-pytorch

  1. 将onnx模型使用tpu-mlir工具转化为bmodel格式--具体可以参照---> https://kdocs.cn/l/cdwzqT3Hbyje

拷贝至板端:scp test_output_fp* linaro@10.12.13.66:/data

远程连接另一台linux--->ssh -p 22 linaro@10.12.13.66

  1. 在板端搭建好sophon-sail环境----> https://kdocs.cn/l/ce7T9GNtS3D3

python版----------------------------------------------------------------------------------------

在板端新建一个MNIST文件夹,文件目录如下,其中datasets存放测试数据集train-images-idx3-ubyte,test_output_fp16_1b.bmodel以及test_output_fp32_1b.bmodel为onnx转化后的bmodel模型,test.py为测试代码。

  1. 主要的原理就是使用sophon提供的api加载能够适配于BM1684X的bmodel类型的模型,并使用他们的api进行模型的推理,官方sail的API可以参考-->

3. API 参考 — sophon-sail v23.03.01 文档

  1. 下面讲解一下测试代码
#import cv2
import numpy as np
import sophon.sail as sail
import timenum = -1 
inference_time =[0]
print("--0-5 1-0 2-4 3-1 4-9 5-2 6-1 7-3 8-1 9-4 for example:if num =9 the pic's num is 4")engine = sail.Engine("./test_output_fp32_1b.bmodel",0,sail.IOMode.SYSIO) #load model-use FP32model on tpu-0 and use sys memery
#engine = sail.Engine("./test_output_fp16_1b.bmodel",0,sail.IOMode.SYSIO) #load model-use FP16 on tpu-0 and use sys memerygraph_name =engine.get_graph_names()[0]                      #get_graph_names-test_output
input_tensor_name = engine.get_input_names(graph_name)[0]    #get_input_names-input.1
output_tensor_name = engine.get_output_names(graph_name)[0]  #get_output_names-25_LogSoftmaxbatchsize,channel,height,width = engine.get_input_shape(graph_name,input_tensor_name) #get batchsize-1,channel-1,input image's height-28 & width-28#read image
with open("./datasets/train-images-idx3-ubyte","rb") as f:file = f.read()
for i in range(8000): num =num +1  i = 16+784*numimage1 = [int(str(item).encode('ascii'),16) for item in file[i:i+784]]#reshap input datainput_data = np.array(image1,dtype=np.float32).reshape(1,1,28,28)  #reshape the image to 1 1 28 28input_data_final = {input_tensor_name:input_data}     #because the process's parmeter(input_data)  must be dictionary so use{}start_time = time.time()outputs = engine.process(graph_name,input_data_final) #model inferenceend_time = time.time()inference_time.append(end_time - start_time)  result = outputs[output_tensor_name]  #use output_tensor_name to get the tensormax_value=np.argmax(result)           #get the index of the best scoreprint("----------------------------------the result is ",max_value,"the time is ",inference_time[num]*1000,"ms")mean = (sum(inference_time) / len(inference_time))*1000
print("-----FP32--","loop ",num+1,"times","average time",mean,"ms")

  1. 测试结果

FP32

FP16

基本稳定在4%峰值可达8%

C++版本---------------------------------------------------------------------------------------------------------

首先安装好c++交叉编译环境

--> https://kdocs.cn/l/cbe77SdEwLKm

1:采用交叉编译的方式进行编译,新建文件夹MNIST

文件结构

CMakeFile.txt

main.cpp

#define USE_FFMPEG 1
#define USE_OPENCV 1
#define USE_BMCV 1
#include <stdio.h>
#include <sail/cvwrapper.h>
#include <iostream>
#include <string>
#include <numeric>
#include <sys/time.h>#include "spdlog/spdlog.h"
#include "spdlog/fmt/fmt.h"
#include "engine.h"using namespace std;
using namespace sail;
const std::string& bmodel_path_fp32="./test_output_fp32_1b.bmodel";
const std::string& bmodel_path_fp16="./test_output_fp16_1b.bmodel";
const int MODEL_IN_WIDTH = 28;
const int MODEL_IN_HEIGHT = 28;
const int MODEL_CHANNEL = 1;
const int loop_count = 1000;
int num = -1;static inline int64_t getCurrentTimeUs()
{struct timeval tv;gettimeofday(&tv, NULL);return tv.tv_sec * 1000000 + tv.tv_usec;
}
void Load_data(int num,unsigned char * input_image)
{int j=16+784*num;FILE *file = fopen("./datasets/train-images-idx3-ubyte", "rb");if (file == NULL) {printf("can't open the file!\n");}fseek(file,j,SEEK_SET);fread(input_image,sizeof(char),784,file);
/*     for(int i=0;i<MODEL_IN_WIDTH;i++){for(int j=0;j<MODEL_IN_WIDTH;j++){printf("%4d",input_image[i*28+j]);}printf("\n");} */ fclose(file);
}void Array_change(float input_aray[][MODEL_CHANNEL][MODEL_IN_WIDTH][MODEL_IN_HEIGHT],unsigned char *input_image)
{int index=0;for (int i = 0; i < 1; i++) {for (int j = 0; j < MODEL_CHANNEL; j++) {for (int k = 0; k < MODEL_IN_HEIGHT; k++) {for (int l = 0; l < MODEL_IN_WIDTH; l++) {input_aray[i][j][k][l] = (float)input_image[index++];//cout<<input_aray[i][j][k][l]<<" ";}//cout<<endl;}}//cout<<endl;} 
}void Bubble_sort(float *buffer,int num)
{float temp;for(int i=0; i<num;i++){for(int j=0; j<num-i-1;j++){if(buffer[j]>buffer[j+1]){temp = buffer[j];buffer[j]=buffer[j+1];buffer[j+1]=temp;}}}
}void dump_shape(std::vector<int> shape)
{cout<<"[  ";for (const int& value : shape) {std::cout << value << " ";}cout<<"]"<<endl;
}
bool inference(int device_id)
{int64_t time[loop_count] = {};unsigned char input_image[784]={};float input_aray[1][MODEL_CHANNEL][MODEL_IN_HEIGHT][MODEL_IN_WIDTH]={};int64_t sum=0;float buffer_copy[]={};// init Enginesail::Engine engine(device_id);    // load bmodel without builtin input and output tensorsengine.load(bmodel_path_fp32);// get model infoauto graph_name = engine.get_graph_names().front();auto input_name = engine.get_input_names(graph_name).front();auto output_name = engine.get_output_names(graph_name).front();std::vector<int> input_shape = {1, 1, 28, 28};std::map<std::string, std::vector<int>> input_shapes;input_shapes[input_name] = input_shape;auto output_shape = engine.get_output_shape(graph_name, output_name);auto input_dtype = engine.get_input_dtype (graph_name, input_name);auto output_dtype = engine.get_output_dtype(graph_name, output_name);cout<<"----------------graph_name is "<<graph_name<<endl;cout<<"----------------input_name is "<<input_name<<endl;cout<<"----------------output_name is "<<output_name<<endl;cout<<"----------------input_dtype is "<<input_dtype<<endl;cout<<"----------------output_dtype is "<<output_dtype<<endl;cout<<"output shape is ";dump_shape(output_shape);cout<<"input shape is ";dump_shape(input_shape);// get handle to create input and output tensorssail::Handle handle = engine.get_handle();// allocate input and output tensors with both system and device memorysail::Tensor in(handle, input_shape, input_dtype, true, true);sail::Tensor out(handle, output_shape, output_dtype, true, true);std::map<std::string, sail::Tensor*> input_tensors = {{input_name, &in}};std::map<std::string, sail::Tensor*> output_tensors = {{output_name, &out}};// prepare input and output data in system memory with data type of float32float* input = nullptr;float* output = nullptr;int in_size = std::accumulate(input_shape.begin(), input_shape.end(),1, std::multiplies<int>());int out_size = std::accumulate(output_shape.begin(), output_shape.end(),1, std::multiplies<int>());if (input_dtype == BM_FLOAT32) {input = reinterpret_cast<float*>(in.sys_data());} else {input = new float[in_size];}if (output_dtype == BM_FLOAT32) {output = reinterpret_cast<float*>(out.sys_data());} else {output = new float[out_size];}//loop for(int times=0;times<loop_count;times++) {num++;Load_data(num,input_image);Array_change(input_aray,input_image);bool status=in.own_dev_data();cout<<"own_dev_data "<<status<<endl;status=in.own_sys_data();cout<<"own_sys_data "<<status<<endl;in.reset_sys_data(input_aray,input_shape);// set io_mode SYSO:Both input and output tensors are in system memory.engine.set_io_mode(graph_name, sail::  SYSIO);bm_data_type_t ret =in.dtype();printf("in.dtype is %d\n", ret);//inferenceint64_t start_time = getCurrentTimeUs();engine.process(graph_name, input_tensors, input_shapes, output_tensors);int64_t end_time = getCurrentTimeUs();time[times]=end_time-start_time;sum = sum+time[times];//post processauto real_output_shape = engine.get_output_shape(graph_name, output_name);float* output_data = reinterpret_cast<float*>(out.sys_data());for(int i = 0; i < 10;i++){buffer_copy[i]=output_data[i];//printf("output_data is %f \n",output_data[i]);}Bubble_sort(output_data,10);for(int i =0;i<10;i++){if(buffer_copy[i]==output_data[9]){printf("------------------------------------------the pic value is %d \n",i);}}/* cout<<"real_output_shape is "<<"[  ";dump_shape(real_output_shape);*/printf(": Elapse Time = %.3f ms \n", time[times] / 1000.f);}printf("--------loop %d times sum is %.4f ms average time is %.3f ms\n", loop_count,sum / 1000.f,(sum / 1000.f)/loop_count);return true;
}
int main()
{int device_id = 0;int tpu_num=get_available_tpu_num();printf("the tpu number is %d\n", tpu_num);bool status = inference(device_id);return 0;    
}

打印结果

fp32

fp16

int8

bm-smi

基本稳定在2%,峰值为4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/33004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型之一 Attention is all you need ---Transformer

大语言模型已经在很多领域大显身手&#xff0c;其应用包括只能写作、音乐创作、知识问答、聊天、客服、广告文案、论文、新闻、小说创作、润色、会议/文章摘要等等领域。在商业上模型即产品、服务即产品、插件即产品&#xff0c;任何形态的用户可触及的都可以是产品&#xff0c…

opencv基础46-图像金字塔02-拉普拉斯金字塔

前面我们介绍了高斯金字塔&#xff0c;高斯金字塔是通过对一幅图像一系列的向下采样所产生的。有时&#xff0c;我们希望通过对金字塔中的小图像进行向上采样以获取完整的大尺寸高分辨率图像&#xff0c;这时就需要用到拉普拉斯金字塔 前面我们已经介绍过&#xff0c;一幅图像在…

.Net C# 免费PDF合成软件

最近用到pdf合成&#xff0c;发现各种软件均收费啊&#xff0c;这个技术非常简单&#xff0c;别人写好的库一大把&#xff0c;这里用到了PDFsharp&#xff0c;项目地址Home of PDFsharp and MigraDoc Foundation 软件下载地址 https://download.csdn.net/download/g313105910…

网站SSL安全证书是什么及其重要性

网站SSL安全证书具体来说是一个数字文件&#xff0c;是由受信任的数字证书颁发机构&#xff08;CA机构&#xff09;进行审核颁发的&#xff0c;其中包含CA发布的信息&#xff0c;该信息表明该网站已使用加密连接进行了安全保护。 网站SSL安全证书也被称为SSL证书、https证书和…

Similarities:精准相似度计算与语义匹配搜索工具包,多维度实现多种算法,覆盖文本、图像等领域,支持文搜、图搜文、图搜图匹配搜索

Similarities&#xff1a;精准相似度计算与语义匹配搜索工具包&#xff0c;多维度实现多种算法&#xff0c;覆盖文本、图像等领域&#xff0c;支持文搜、图搜文、图搜图匹配搜索 Similarities 相似度计算、语义匹配搜索工具包&#xff0c;实现了多种相似度计算、匹配搜索算法&…

IDEA之Debug调试

资料来源于韩老师视频 &#xff08;一&#xff09;初探debug 1、打断点的话&#xff1a;直接在该行前面单击左键&#xff0c;出现小红点就是断点了。 想要取消断点的话&#xff0c;再单击小红点即可。 运行debug时&#xff0c;右键选择"Debug…"而不是选“Run…”…

【C++】开源:spdlog跨平台日志库配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍spdlog日志库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下…

​LeetCode解法汇总1572. 矩阵对角线元素的和

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 描述&#xff1a; 给你一个正…

配置vscode

配置vscode 设置相关 网址&#xff1a;https://code.visualstudio.com/ 搜索不要用百度用这个&#xff1a;cn.bing.com 1.安装中文包 Chinese (Simplified) (简体中文) 2.安装 open in browser 3.安装主题 Atom One Dark Theme 4. 安装图标样式 VSCode Great Icons 5.安装 L…

yum 安装本地包 rpm

有时直接yum install 有几个包死活下不下来 根据网址&#xff0c;手动下载&#xff0c;下载后上传至 centos 然后运行 sudo yum localinstall xxx.rpm 即可安装 参考 https://blog.csdn.net/weiguang1017/article/details/52293244

MachineLearningWu_16/P72-P77_Diagnostic

x.1 导数&#xff0c;计算图&#xff0c;大型网络 计算图就是根据链式法则求取偏导&#xff0c;大型网络就是多层网络堆叠而成。 x.2 Diagnostic 在我们对深度学习有了一些认知后&#xff0c;最重要的就是模型的诊断&#xff0c;以带有L1正则化的线性回归为例&#xff0c;我…

SQL | 排序检索的数据

3-排序检索的数据 使用order by语句排序检索到的数据。 3.1-排序数据 使用SQL语句返回一个数据表的列。 select prod_id from products; --------------------- | prod_name | --------------------- | 8 inch teddy bear | | 12 inch teddy bear | | 18 inch teddy bear |…

泊松损坏图像的快速尺度间小波去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C#调用百度翻译API自动将中文转化为英文,按行转换

我们可以使用百度翻译API获取到翻译结果 翻译API地址&#xff1a; http://api.fanyi.baidu.com/api/trans/vip/translate 一、新建窗体应用程序TranslatorDemo&#xff0c;将默认的Form1重命名为FormTranslator。 窗体FormTranslator设计器如图&#xff1a; 窗体设计器源代码…

Qt通过QSS设置QPushButton的样式

同时设置QPushButton的文字样式和图标的方法 为了美化界面&#xff0c;有时候需要修改QPushButton的样式&#xff0c;让一个QPushButton上面既要显示图标&#xff0c;又要显示文字内容 起初我的做法是重写QPushButton&#xff0c;这样做可以实现&#xff0c;但是有几个问题 实现…

[JAVAee]多线程环境下:HashTable, HashMap, ConcurrentHashMap之间的区别

HashMap在多线程环境下是不安全的,只能在单线程下使用. 多线程下安全的只有: HashTableConcurrentHashMap HashTable HashTable在多线程环境下安全的原因是,给其的get与put方法都使用synchronized修饰了,被锁的对象是整个HashTable,只要有线程对此HashTable操作就上锁,其他…

Von Maur, Inc EDI 需求分析

Von Maur, Inc 是一家历史悠久的卖场&#xff0c;成立于19世纪&#xff0c;总部位于美国。作为一家知名的零售商&#xff0c;Von Maur 主要经营高端时装、家居用品和美妆产品。其使命是为顾客提供优质的产品和无与伦比的购物体验。多年来&#xff0c;Von Maur 凭借其卓越的服务…

【STM32RT-Thread零基础入门】 3. PIN设备(GPIO)的使用

硬件&#xff1a;STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 文章目录 前言一、PIN设备介绍1. 引脚编号获取2. 设置引脚的输入/输出模式3. 设置引脚的电平值4. 读取引脚的电平值5. 绑定引脚中断回调函数6. 脱离引脚中断…

大语言模型之二 GPT发展史简介

得益于数据、模型结构以及并行算力的发展&#xff0c;大语言模型应用现今呈井喷式发展态势&#xff0c;大语言神经网络模型成为了不可忽视的一项技术。 GPT在自然语言处理NLP任务上取得了突破性的进展&#xff0c;扩散模型已经拥有了成为下一代图像生成模型的代表的潜力&#x…

【Unity细节】Unity打包后UI面板消失是怎么回事

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐关于物体的动画碰到其他碰撞器后停止播放的问题⭐ 文章目录 ⭐关于物体的动画碰…