当前位置: 首页 > news >正文

A1000学习笔记

记录自己学习A1000的时候的笔记


一、ubuntu安装bstnnx docker环境

1.导入镜像

从BST项目空间中下载文件,将bsnn_release_4.2.0中的所有文件下载到主目录中的toolchain文件夹中,进入终端导入image

docker load -i ./bsnn_tools_docker_4.2.0.tar

2.创建容器

创建container

方法一(黑芝麻):

./run_docker_container.sh --root --keep --network=host

方法二:

docker exec -it bsnn-tools-container-stk-4.2.0 /bin/bash

可选(容器改名):

docker rename old_container new_container

3.使用jupyter

打开jupyter服务,可视化查看方便一点

jupyter notebook list

4.申请并部署license文件

ubuntu查看MAC地址:ifconfig

用企业邮箱,联系黑芝麻技术人员,提供MAC地址得到license文件。

部署license文件:

docker cp license.lic bsnn-tools-container-stk-4.2.0:/workspace/license.lic

修改/workspace/tools/Net-FW/utilities/script/xtensa_setup.sh文件的license地址

export XTENSAD_LICENSE_FILE='/workspace/license.lic'

至此,基于toolchain docker 转换工具链bsnn_release_4.2.0的bstnnx docker环境就安装完成。

二、yolov5训练onnx转换 

使用代码为黑芝麻网站中的 yolov5 float 文件。其中的bst_yolov5工程已经修改了训练方式和激活函数,并且添加了opt优化

1.环境与数据集检查

datasets路径中有coco128数据集

环境按照requirements.txt中的配置(清华源:-i https://pypi.tuna.tsinghua.edu.cn/simple)

2.模型训练

python train.py --data coco128.yaml --weights yolov5n.pt --img 640 --epochs 300

结果会保存在  runs/trian/exp  中。将weights中的 best.pt 拷贝到 bst_yolov5/yolov5中,并重命名yolov5n.pt

可能遇到的问题:训练出现AttributeError: 'FreeTypeFont' object has no attribute 'getsize'报错

原因:新版本的 Pillow删除了该getsize 功能,降级到 Pillow 9.5 就可以解决

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple Pillow==9.5

3.onnx转换 并 验证

yolov5 float中的export.py代码与官网中的有所改动。

转换代码:

python export.py --weights yolov5n.pt --include=onnx

验证代码(保存路径 yolov5/runs/val/exp2):

python val.py --weights yolov5n.onnx --data coco128.yaml --img 640

测试代码(保存路径 yolov5/runs/detect/exp ):

python detect.py --weights yolov5n.onnx --source test.jpg

三、toolchain模型转换

1.准备toolchain工具模型转换所需的文件

新建一个yolov5_bstnnx文件夹,要包含下列文件

1)inputs_jpg

2)image_process_config

{
    "source_image_format": "RGB",   // 输入图像的颜色格式
    "target_image_format": "RGB",   // 目标图像的颜色格式
    "mean": [0, 0, 0],              // 均值 (mean),通常用于归一化
    "scale": [0.00390625, 0.00390625, 0.00390625]  // 缩放因子 (scale)
}

3)run.yaml

# 目标推理设备(比如 AI 加速器)
device_engine: A1000B0 

# 量化后的模型名称
model_name: yolov5n

# ONNX 格式的浮点模型路径
model_path: /workspace/models/yolov5_bstnnx/yolov5n.onnx

# 量化校准数据集(用于 PTQ 量化)
input_data_set_path: /workspace/models/yolov5_bstnnx/inputs_jpg

# 数据读取方法
data_reader_method: image_folder_data_reader

# 归一化计算方式
# mean = mean; scale = np.floor(std/2**-12 + 0.5) * 2**-12 -> std=1/255 -> scale = 0.00390625
image_process_config: /workspace/models/yolov5_bstnnx/image_process_config.json


# 量化时使用的校准数据量
size_limit: 500

# 是否启用自动 PTQ(Post Training Quantization)
auto_ptq: /workspace/models/yolov5_bstnnx/task_info_for_autoptq.yaml

# 量化和优化后的输出目录
result_dir: /workspace/models/yolov5_bstnnx/auto_ptq_yolov5n

# 量化 & 编译的优先级范围
priority_range: 100-1200

# General stage settings
stage:
  - stage_name: pre_processing_stage
    priority: 100
  - stage_name: graph_optimization_stage
    priority: 200
  - stage_name: quantization_stage
    priority: 300
  - stage_name: graph_partition_stage
    priority: 400
  - stage_name: section_binding_stage
    priority: 500
  - stage_name: code_generation_stage
    priority: 600
  - stage_name: code_compilation_stage
    priority: 700
  - stage_name: run_emulation_stage
    profiling_mode: 2
    priority: 800
  - stage_name: hardware_testing_stage
    XTSC_NET_SIM: True
    generate_rbf_only: True
    priority: 1100
  - stage_name: report_generation_stage
    priority: 1200
  - stage_name: userland_stage
    priority: 1500

4)task_info_for_autoptq.yaml

task_settings:
  # 设置量化方式,使用 per-channel KL 量化:
  # - per-channel: 每个通道独立量化,提升精度
  # - KL(Kullback-Leibler 散度): 计算最优量化范围,使量化数据与原数据分布最接近
  quantization_method: ["weight_perchannel_kl"]

  # 是否将部分 int8 卷积转换为 int16,提升计算精度,但会增加计算量
  # - [[]] 表示不转换,全部保持 int8
  # - 例如: [[], ["/model.24/m.0/Conv", "/model.24/m.1/Conv"]] 可指定某些层用 int16
  convert_int8conv_to_int16: [[]]

  # 量化过程中,不可调整的激活层范围(-1, 0, 1),默认值不变
  unadjustable_activations_last_n: [-1, 0, 1]

  # 设置激活量化校准方法(决定如何计算 scale & zero-point):
  # - minmax: 直接取最小-最大值,可能受异常值影响
  # - kl: 使用 KL 散度优化量化范围,适用于复杂模型
  # - percentile_0.999: 99.9% 分位数截断,忽略 0.1% 极端值,减少异常值影响
  calibration_method: ["minmax", "kl", "percentile_0.999"]

  # 下面是其他可选的校准方法(已注释掉),可以尝试不同分位数:
  # calibration_method: ["minmax", "kl", "percentile_0.999", "percentile_0.998", "percentile_0.997", "percentile_0.996", "percentile_0.995"]

# 是否自动更新任务:
# - false(默认): 需要手动调整任务队列
# - true: 允许自动调整 `task_order` 并追加新任务,适用于实验调优
auto_update: false

# 任务队列的模式(已注释),可用于自定义量化任务顺序:
# task_order_schema:
# ["index", "quantization_method", "convert_int8conv_to_int16",
# "unadjustable_activations_last_n", "calibration_method"]

5)yolov5n.onnx文件

2.将yolov5_bstnnx文件夹 复制到 模型转换容器

运行bsnn-tools-container-stk-4.2.0容器,将yolov5_bstnnx拷贝到bsnn-tools-container-stk-4.2.0容器中,我已将bsnn-tools-container-stk-4.2.0容器改名为bsnn_4.2(更简洁):

docker cp yolov5_bstnnx bsnn_4.2:/workspace/models/

3.进行模型转换

在容器中运行指令:

bstnnx_run --config models/yolov5_bstnnx/run.yaml

把结果/workspace/auto_ptq_yolov5n/1100_HardwareTestingStage/yolov5n.hw_test_config拷贝回ubuntu中:

docker cp bsnn_4.2:/workspace/auto_ptq_yolov5n/1100_HardwareTestingStage/yolov5n.hw_test_config /home/chy/文档/BSNN相关

四、基于转换后的模型文件,创建编译cmake工程

1.查看黑芝麻cmake工程demo

其中:
1)3rdparty和usr两个文件夹是bst-bsnn相关库文件等;
2)yolov5model是通过toolchain转换后1100_HardwareTestingStage 后缀.hw_test_config中 得到的weights.bin、.meta、.lib三个文件;
3)src中就是检测程序;
4)start_yolov5m.sh是后面在开发板上运行用到的运行脚本。

2.创建自己的cmake工程

新建一个yolov5demo文件夹,将demo中的3rdparty、usr、src、CMakeLists.txt直接拷贝进来,并新建一个yolov5n_model文件夹,将前面yolov5n.hw_test_config中weights.bin,及fw_integration中.meta.lib文件,拷贝到cmake工程yolov5demo/yolov5n_model中并重命名::

3.修改代码

如果用的是其他的yolov5模型,请去修改cmakelist.txt里的对应部分。

修改src/main.cpp ,五显示器,所以注释了cv显示部分,增加检测结果图片保存

#include <iostream>
#include <opencv2/opencv.hpp>
#include "bsnn_model_load.h"
#include "drmshow.h"
#include "image_process.h"
#include <string.h>

using namespace std;

int main(int argc, char* argv[])
{
    // std::string in_image_path = "./000000000139.jpg";
    std::string in_image_path = "./fad_video.avi";  // 默认输入视频路径
    std::string bsnn_model_path = "./model";        // 定义 BSNN 模型路径
    cv::Mat img, input_image;   // 定义 OpenCV 矩阵用于存储原始图像和处理后的输入图像

    // asic_type_check();
    // 如果命令行参数提供了输入文件路径,则覆盖默认路径
    if(2 <= argc) {
        in_image_path = argv[1];
    }
    // 如果命令行参数提供了模型路径,则覆盖默认路径
    if(3 <= argc) {
        bsnn_model_path = argv[2];
    }
    // 打开视频文件或图片
    cv::VideoCapture capture(in_image_path);
    BSNN_MODEL bsnn_model(bsnn_model_path); // 加载 BSNN 模型

    Timer time, fps;    // 定义计时器用于测量 FPS 和时间消耗
    while (true)
    {
    // step 1 图片预处理
    capture >> img; // 读取视频帧
    if(img.empty()) // 如果读取失败(视频播放结束)
    {
        printf("img.empty = %d\n",img.empty()); // 输出错误信息
        capture.release();  // 释放视频流
        capture.open(in_image_path);    // 重新打开视频文件
        continue;
    }
    // 重置计时器
    time.reset();
    fps.reset();

    preprocess(img, input_image);   // 对图像进行预处理
    
    size_t input_img_len = 3 * IMG_HEIGHT * IMG_WIDTH; // 计算输入图像的字节大小(RGB 三通道)

    // 更改图片在内存中的存储方式为WHD
    if (!input_image.isContinuous())
        printf("-> input image is not continuous in memory...");
    uchar input_buf[input_img_len] = {0};   // 创建存储输入图像数据的缓冲区
    // 调整输入图像数据的排列方式,从 HWC (height, width, channel) 转换为 CHW (channel, height, width)
    for (int c = 0; c < 3; c++)
    {
        for (int i = 0; i < IMG_HEIGHT; i++)
        {
            for (int j = 0; j < IMG_WIDTH; j++)
            {
                input_buf[c * IMG_HEIGHT * IMG_WIDTH + i * IMG_WIDTH + j] = input_image.data[3 * (i * IMG_WIDTH + j) + c];
            }
        }
    }
    cout << "-> preprocess time : " << time.elapsed() << endl; // 输出预处理时间

    // step 2 模型推理
    time.reset();
    bsnn_model.Run(input_buf, input_img_len);   // 运行模型推理
    auto bsnn_output = bsnn_model.GetModelOutput(); // 获取模型推理结果

    // 计算推理 FPS(帧率),并输出模型推理时间
    printf("-> lite engine inference FPS: %.2f\n", 1.0 / time.elapsed() * 1000);
    cout << "-> bsnn model inference time : " << time.elapsed() << endl;
    
    // step 3 后处理
    time.reset();
    std::vector<ObjInfo> result;    // 定义存储目标检测结果的向量
    process_output(bsnn_output.get(), result);  // 解析模型输出,提取检测到的目标信息
    // cout << "-> The number of objects detected: " << result.size() << endl;
    cout << "-> post process time : " << time.elapsed() << endl;

    draw_bboxes(img, result);
    cv::imwrite("./inferresult.jpg",img);
    bsnn_model.ReleaseOutputBuffer();

    // printf("-> full flow FPS: %.2f\n", 1.0 / fps.elapsed() * 1000);
    cv::Mat show_img;
    cv::resize(img, show_img, cv::Size(1280, 720));
    //cv::imshow("img", show_img);
    //cv::waitKey(1);
    }
    return 0;
}

4.编译工程

启动a1000b-sdk-fad-2.3.1.2容器(我改名为sdk_2.3.1.2),将yolov5demo拷贝到容器中:

docker cp yolov5demo sdk_2.3.1.2:opt/bstos/2.3.1.2/sysroots/aarch64-bst-linux/usr/include/src

容器中编译

cd yolov5demo
mkdir build
cd build
cmake ..
make

五、开发板运行

1.将编译好的yolov5demo从容器拷贝回ubuntu

docker cp sdk_2.3.1.2:opt/bstos/2.3.1.2/sysroots/aarch64-bst-linux/usr/include/src/yolov5demo /home/chy/文档/BSNN相关

2.整合运行文件

在yolov5demo中新建一个yolov5demo_run文件夹

1)app文件夹

将yolov5demo中的build文件夹中的可执行文件yolov5n拷贝到app文件夹

2)yolov5n文件夹

将yolov5n_model文件夹的三个文件拷贝到app文件夹

3)datasets文件夹

4)运行脚本文件

创建start_yolov5s.sh

#!/bin/sh
mkdir -p /run/user/1000
export XDG_RUNTIME_DIR="/run/user/1000"

echo 0 > /sys/devices/platform/vsp@1/enable && weston --tty=1 &

./app/yolov5n ./datasets/fad_video.avi ./yolov5n

3.运行

1)拷贝

把yolov5demo_run文件夹从ubuntu拷贝到开发板。并把yolov5demo中的 usr/lib64 文件夹下的文件,cp到开发板 /usr/lib 文件夹下

2)运行

cd /userdata/yolov5demo_run
chmod +x start_yolov5n.sh
./start_yolov5n.sh

相关文章:

  • Flask使用Blueprint注册管理路由
  • SQLMesh 系列教程:解锁SQLMesh的宏与变量魔法
  • 日志存储与分析
  • CSS3-流星雨
  • 大型语言模型与强化学习的融合:迈向通用人工智能的新范式——基于基础复现的实验平台构建
  • 办公自动化:使用 Python 生成 Word 文件:自动生成数据库文档 Word 文件
  • 从PDF文件中提取数据
  • 基于 Verilog 的时序设计:从理论到实践的深度探索
  • SpringMVC(七)数据校验+VO++脱敏
  • 五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测
  • 【sql靶场】第13、14、17关-post提交报错注入保姆级教程
  • C# WPF 基础知识学习(三)
  • 深度解析扣减系统设计:从架构到实践
  • 【Agent】OpenManus-Agent-Memory详细设计
  • 安装配置Anaconda,配置VSCode
  • 数据分析项目:基于LSTM的微博评论情感分析
  • 2.5[frontEnd]
  • Java 集合框架中 `List` 接口及其子类的详细介绍,并用 UML 图表展示层次结构关系,用表格对比各个类的差异。
  • Notepad++插件:快捷选择成对括号之间的内容
  • 代码随想录算法训练营第三十五天(20250303) |01背包问题 二维,01背包问题 一维,416. 分割等和子集 -[补卡20250316]
  • 哪里学网站建设与管理/运营推广怎么做
  • 组建个人网站/最近国家新闻
  • 沈阳哪家网站做的好/苏州seo关键词优化外包
  • 网站后台管理维护 不懂编程/一个完整的策划案范文
  • 餐饮团购网站建设/广州百度seo
  • 温州市建设工程质量安全管理总站/免费搭建网站的软件