ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TVM 微控制器实战:在 Arm Cortex-M55 与 Ethos-U55 NPU 裸机环境运行 Mobilenet v2

TVM 微控制器实战:在 Arm Cortex-M55 与 Ethos-U55 NPU 裸机环境运行 Mobilenet v2 编译器深度学习模型优化【免费下载链接】tvmOpen deep learning compiler stack for cpu, gpu and specialized accelerators项目地址https://gitcode.com/gh_mirrors/tvm7/tvm点击查看免费下载本指南围绕 Apache TVM 官方示例目录 apps/microtvm/ethosu 展开完整讲解如何在无操作系统的裸机bare metal环境下把量化int8MobileNet v2 图像分类模型部署到基于 Arm Corstone-300 平台的Cortex-M55 CPU Ethos-U55 NPU CMSIS-NN异构目标上从环境准备、TVM 编译选项、tvmc 命令行配置到 C 运行时桥接、链接脚本与 FVP 仿真验证的完整链路。读完本文你将掌握用 TVM 的ethos-u/cmsis-nn/c多目标编译能力生成 AOT 模型库MLF并在 Fixed Virtual PlatformFVP上驱动 NPU 完成真实推理与分类输出的整套方法。一、示例概述一次完整的微控制器 NPU 部署该示例位于仓库的 apps/microtvm/ethosu 目录展示了 TVM 微控制器microTVM工具链的典型工作流下载一个量化后的 int8 MobileNet v2 TFLite 模型使用tvmc将模型编译为面向Cortex-M55 CPU、Ethos-U55 NPU 与 CMSIS-NN的代码AOT 执行器 CRT 运行时下载一张企鹅图片将其转换为 C 头文件中的字节数组构建 Ethos-U55 核心驱动core driver、CMSIS 启动代码与演示应用在基于 Arm Corstone-300 的 FVP 仿真器上运行并在 UART 输出分类结果例如The image has been classified as king penguin。示例目录中的关键文件可对照阅读文件作用run_demo.sh一键式演示脚本下载模型与图片、调用 tvmc 编译、生成头文件、构建并运行 FVPMakefile使用arm-none-eabi-gcc交叉编译裸机/FreRTOS 演示程序并链接 Ethos-U 驱动convert_image.py把输入图片转换为inputs.h/outputs.hC 数组头文件convert_labels.py把 ImageNet 标签转换为labels.h并复制 CRT 配置头文件src/demo_bare_metal.c裸机演示主程序调用tvmgen_default_run执行推理src/demo_freertos.c基于 FreeRTOS 任务与队列的演示主程序src/tvm_ethosu_runtime.cTVM 运行时与 Ethos-U 驱动之间的桥接层arm-none-eabi-gcc.cmake交叉编译工具链文件指定 Cortex-M 目标corstone300.ldCorstone-300 平台的内存布局链接脚本二、前置条件与依赖安装2.1 在 CI Docker 容器中运行TVM 仓库自带的ci_cpuDocker 镜像已经预装本示例所需的全部软件是最省事的运行方式。若使用该容器可跳过本节剩余步骤。2.2 手动安装依赖若在本地环境运行需要先安装以下软件TVM 提供了自动化安装脚本 docker/install/ubuntu_install_ethosu_driver_stack.sh一条命令即可装齐Arm Corstone-300 的 Fixed Virtual PlatformFVP用于仿真 Corstone-300 子系统Cortex-M55 Ethos-U55是运行裸机镜像的虚拟机cmake 3.19.5构建 Ethos-U 驱动栈需要Arm GCC 工具链gcc-arm-none-eabi-10-2020-q4-major用于交叉编译 Cortex-M 目标Arm Ethos-U NPU 驱动栈core driver提供ethosu_init/ethosu_invoke/ethosu_reserve_driver等 NPU 操作接口CMSISCMSIS_5提供 Cortex-M55 设备头文件如ARMCM55.h与启动代码CMSIS-NN提供 Cortex-M 上的神经网络内核实现示例中 Softmax 直接使用 CMSIS-NN 实现。此外还需安装本目录 requirements.txt 中列出的 Python 库包括ethos-u-velaEthos-U 神经网络编译器、Pillow图片处理、numpy、tfliteTFLite 模型解析等。在示例目录下执行pip install -r ./requirements.txt2.3 TVM 本身的安装方式二选一从源码构建参考 TVM 官方安装文档。构建时必须在config.cmake中开启以下四个开关set(USE_ETHOSU ON) # 启用 Ethos-U 编译器后端 set(USE_CMSISNN ON) # 启用 CMSIS-NN 代码生成 set(USE_MICRO ON) # 启用 microTVM / CRT 运行时 set(USE_LLVM ON) # 启用 LLVM 代码生成其中USE_ETHOSU在 CMake 侧的开关逻辑可见 cmake/modules/contrib/EthosU.cmake开启后会把src/relay/backend/contrib/ethosu、src/contrib/ethosu/cascader与src/tir/contrib/ethosu的源码编入编译器关闭时仅保留 Python 侧 Object 定义所需的utils.cc与 cascader 代码。使用 TLCPack 预编译包直接安装现成的二进制 wheel。2.4 配置 PATH 环境变量需要把cmake 3.19.5与FVP加入PATH。假设二者都安装在/opt/arm下export PATH/opt/arm/FVP_Corstone_SSE-300/models/Linux64_GCC-6.4:/opt/arm/cmake/bin:$PATH其中FVP_Corstone_SSE-300/models/Linux64_GCC-6.4是 FVP 可执行文件的目录/opt/arm/cmake/bin是 cmake 的目录。三、运行演示应用3.1 裸机演示在示例目录下直接执行./run_demo.sh3.2 FreeRTOS 演示run_demo.sh支持--freertos_path参数指定 FreeRTOS 源码路径后将改用 src/demo_freertos.c 作为主程序用任务task与队列queue实现数据采集任务 → 推理任务的流水线./run_demo.sh --freertos_path /opt/freertos/FreeRTOSv202112.00/从脚本源码看run_demo.sh该路径会转换为FREERTOS_PATH环境变量传给 MakefileMakefile 检测到FREERTOS_PATH后会自动编译 FreeRTOS 内核源码tasks.c、list.c、queue.c、timers.c、event_groups.c及 ARM_CM33_NTZ 移植层的port.c/portasm.c/heap_3.c并链接src/demo_freertos.c。3.3 自定义依赖路径如果 Ethos-U 驱动或 CMSIS 未安装在默认位置/opt/arm/ethosu可以用脚本参数显式指定./run_demo.sh --ethosu_driver_path /home/tvm-user/ethosu/core_driver \ --cmsis_path /home/tvm-user/cmsis \ --ethosu_platform_path /home/tvm-user/ethosu/core_platformrun_demo.sh支持的完整参数来自脚本内show_usage见 run_demo.sh参数说明-h, --help显示帮助信息--ethosu_driver_pathEthos-U core driver 路径--cmsis_pathCMSIS 路径--ethosu_platform_pathEthos-U core platform 路径提供 UART 驱动与 Corstone-300 目标文件--fvp_pathFVP 根路径脚本会追加models/Linux64_GCC-6.4到PATH--cmake_path指定 cmake 可执行文件路径--freertos_path启用 FreeRTOS 演示并指定其源码路径3.4 脚本自动完成的完整流水线./run_demo.sh一次完成下列全部步骤可对照 run_demo.sh 逐行阅读make cleanall清理旧构建产物并新建build/目录从 Arm ML-zoo 下载mobilenet_v2_1.0_224_INT8.tflite调用tvmc将模型编译为 Cortex-M55 Ethos-U55 CMSIS-NN 目标产物格式为MLFModel Library Format解包得到 CRT 运行时与生成的 C 代码下载 ImageNet 标签文件labels_mobilenet_quant_v1_224.txt下载一张企鹅图片kitten.jpg同为默认测试图之一运行 convert_image.py 生成include/inputs.h输入图像数据与include/outputs.h输出缓冲区运行 convert_labels.py 生成include/labels.h并把 CRT 配置头文件复制到build/crt_config/make交叉编译生成裸机可执行文件build/demo启动FVP_Corstone_SSE-300_Ethos-U55仿真运行./build/demoUART 输出分类结果收到EXITTHESIM后仿真自动退出。四、tvmc 编译命令行逐项解析脚本核心是这条编译命令见 run_demo.sh它决定了整条部署链路的编译策略python3 -m tvm.driver.tvmc compile --targetethos-u,cmsis-nn,c \ --target-ethos-u-accelerator_configethos-u55-256 \ --target-cmsis-nn-mcpucortex-m55 \ --target-c-mcpucortex-m55 \ --runtimecrt \ --executoraot \ --executor-aot-interface-apic \ --executor-aot-unpacked-api1 \ --pass-config tir.usmp.enable1 \ --pass-config tir.usmp.algorithmhill_climb \ --pass-config tir.disable_storage_rewrite1 \ --pass-config tir.disable_vectorize1 \ ./mobilenet_v2_1.0_224_INT8.tflite \ --output-formatmlf参数含义与底层原理--targetethos-u,cmsis-nn,c声明三段式异构编译目标。TVM 会先让ethos-u后端Vela 编译器 TVM 的 Ethos-U 代码生成源码见 src/relay/backend/contrib/ethosu接管图中适合 NPU 加速的算子卷积等其余算子由cmsis-nn后端调用 CMSIS-NN 内核、最后落到c目标生成 C 代码--target-ethos-u-accelerator_configethos-u55-256指定 Ethos-U 加速器配置为U55 且 MAC 数为 256对应 FVP 启动参数ethosu.num_macs256两者必须一致--target-cmsis-nn-mcpucortex-m55与--target-c-mcpucortex-m55为 CMSIS-NN 和通用 C 代码指定 CPU 为 Cortex-M55--runtimecrt使用 microTVM 的 C RuntimeCRT让生成的代码可以在无操作系统、无标准库依赖的裸机上运行--executoraot采用 Ahead-of-Time 图执行器编译期生成tvmgen_default_run()入口函数--executor-aot-interface-apic以纯 C 结构体tvmgen_default_inputs/outputs/devices传递输入输出--executor-aot-unpacked-api1生成非打包unpackedAPI即每个算子对应独立的函数签名便于裁剪与静态分析--pass-config tir.usmp.enable1启用 USMPUnified Static Memory Planning统一静态内存规划在编译期确定所有中间张量的内存池布局--pass-config tir.usmp.algorithmhill_climb选择爬山算法进行内存池分配优化--pass-config tir.disable_storage_rewrite1禁用存储重写 pass配合 USMP 使用--pass-config tir.disable_vectorize1禁用向量化Cortex-M55 的 MVE 向量化在此示例中不启用--output-formatmlf输出 Model Library Format一个包含运行时、生成代码与元数据的标准目录结构打包为module.tar脚本随后tar -xf module.tar解包。五、输入数据与标签的 C 头文件生成5.1 图片 → C 数组convert_image.py 接收一个命令行参数图片路径完成以下转换使用 Pillow 把图片缩放为224×224MobileNet v2 的标准输入尺寸转为 numpy 数组并增加 batch 维度得到 NCHW 四维输入执行量化预处理每个像素减去 128再转为int8对应 TFLite 模型输入量化参数 zero point 为 -128 的情形生成include/inputs.h声明input[]数组16 字节对齐放置在ethosu_scratch段供 NPU 直接访问内容以\x..十六进制转义序列写入生成include/outputs.h声明长度为1001ImageNet 1000 类 1 个背景类的int8_t output[]放置在output_data_sec段。调用方式脚本第 170 行实际执行的命令python3 ./convert_image.py ./build/kitten.jpg5.2 标签 → C 字符串数组convert_labels.py 把 ImageNet 标签文件逐行转为char* labels[]字符串数组同样放置在ethosu_scratch段并调用tvm.micro.copy_crt_config_header把 CRT 配置头文件复制到build/crt_config/供 Makefile 使用python3 ./convert_labels.py ./build/labels_mobilenet_quant_v1_224.txt5.3 使用你自己的图片要换用自定义图片只需修改 run_demo.sh 中的下载与转换两行指向你的图片文件即可curl -sS https://upload.wikimedia.org/wikipedia/commons/1/18/Falkland_Islands_Penguins_29.jpg -o penguin.jpg python3 ./convert_image.py ./build/penguin.jpg注意convert_image.py只接受单个图片路径参数且图片会被强制缩放到 224×224因此任意分辨率图片均可使用。六、裸机运行时与 NPU 驱动的桥接6.1 应用主程序如何调用模型编译产物中TVM 的 AOT 执行器生成了tvmgen_default_run(inputs, outputs, devices)入口。裸机主程序 src/demo_bare_metal.c 的调用流程为UartStdOutInit(); // 初始化 Corstone-300 UART输出 printf EthosuInit(); // 初始化 Ethos-U NPU 驱动 struct tvmgen_default_inputs inputs { .tfl_quantize input, // 来自 inputs.h 的图像数据 }; struct tvmgen_default_outputs outputs { .MobilenetV2_Predictions_Reshape_11 output, // 来自 outputs.h }; struct ethosu_driver* driver ethosu_reserve_driver(); // 独占 NPU struct tvmgen_default_devices devices { .ethos_u driver, // 把 NPU 驱动句柄交给运行时 }; tvmgen_default_run(inputs, outputs, devices); ethosu_release_driver(driver); // 在 1001 个输出中找最大值的索引即为预测类别 printf(The image has been classified as %s\n, labels[max_index]); printf(EXITTHESIM\n); // FVP 收到该字符串后结束仿真6.2 NPU 初始化与中断NPU 的初始化位于 apps/microtvm/ethosu/include/ethosu_mod.hif (ethosu_init(ethosu0_driver, (void*)ETHOSU_BASE_ADDRESS, NULL, 0, 1, 1)) { printf(Failed to initialize NPU.\n); return -1; } NVIC_SetVector(ETHOSU_IRQ, (uint32_t)ethosuIrqHandler0); NVIC_EnableIRQ(ETHOSU_IRQ);而 Ethos-U55 的硬件地址与中断号定义在 include/ethosu_55.h#define ETHOSU_IRQ ((IRQn_Type)56) #define ETHOSU_BASE_ADDRESS ((void*)0x48102000)即 NPU 寄存器基地址为0x48102000中断号为 56这与 Corstone-300 SSE-300 子系统的硬件映射一致。6.3 TVM 运行时与 Ethos-U 驱动的桥接层AOT 生成的 C 代码会调用形如TVMEthosULaunch(...)的设备回调其实现位于 src/tvm_ethosu_runtime.c核心是把 TVM 传入的 NPU command stream 与张量基地址直接转交 Ethos-U 驱动的ethosu_invokeint32_t TVMEthosULaunch(tvm_device_ethos_u_t* context, void* cms_data, size_t cms_data_size, uint64_t* base_addrs, size_t* base_addrs_size, int num_tensors) { struct ethosu_driver* driver (struct ethosu_driver*)context; int32_t result ethosu_invoke(driver, cms_data, cms_data_size, base_addrs, base_addrs_size, num_tensors); if (result ! 0) return -1; return 0; }此外还提供了TVMDeviceEthosUActivate/Open/Close/Deactivate四个空实现返回 0保持设备生命周期接口完整。从源码结构可以推断ethosu_scratch/output_data_sec/rodata.tvm这些段正是为了让 TVM 生成的 command stream.rodata.tvm与输入输出数据落在NPU 可访问的 DDR/SRAM中。6.4 FreeRTOS 版本的差异src/demo_freertos.c 采用经典的生产者-消费者模式数据采集任务prvDataCollectionTask延迟 100ms 后将input指针通过xQueueSend发送到队列推理任务prvInferenceTaskxQueueReceive阻塞等待数据收到后构造tvmgen_default_inputs并执行tvmgen_default_run最后同样打印分类结果与EXITTHESIM。队列长度为 1推理任务优先级高于数据任务tskIDLE_PRIORITY 3vs 2推理任务栈大小 4096 字。由于 Ethos-U 驱动是不可重入的共享资源两个任务间通过队列串行化推理访问。七、构建系统与内存布局7.1 交叉编译工具链arm-none-eabi-gcc.cmake 是面向 Cortex-M 的 CMake 工具链文件关键点默认目标cortex-m55可通过CMAKE_SYSTEM_PROCESSOR覆盖根据目标自动推导硬浮点/软浮点cortex-m33、cortex-m55默认-mfloat-abihard统一添加-mcpu/-mfloat-abi编译与链接选项并默认生成output.map链接映射文件C 标准为 C99、C 标准为 C14。7.2 Makefile 的构建组成Makefile 默认路径约定Ethos-U 驱动、CMSIS、core platform 默认都在/opt/arm/ethosu下对应脚本参数--ethosu_driver_path等最终可执行文件build/demo由以下部分链接而成AOT 生成的 C 代码build/codegen/host/src/*.c打包为libcodegen.aCRT 运行时stack_allocator.c、crt_backend_api.c来自 MLF 解包出的 CRTCMSIS 启动代码CMSIS/Device/ARM/ARMCM55/Source/*.cCMSIS-NN SoftmaxCMSIS-NN/Source/SoftmaxFunctions/*.c模型的最后分类层Ethos-U core driver通过 CMake 工具链文件构建为静态库UART 驱动core_platform/drivers/uartCorstone-300 平台代码core_platform/targets/corstone-300/*.c演示主程序默认src/demo_bare_metal.c传入FREERTOS_PATH时替换为src/demo_freertos.c并加入 FreeRTOS 内核源码。CPU 编译选项为-mcpucortex-m55 -mthumb -mfloat-abihard -stdgnu99链接选项为-lm -specsnosys.specs -static -T corstone300.ld。7.3 Corstone-300 内存布局corstone300.ld 定义了五块内存区域内存基地址大小说明ITCM0x00000000512KB存放代码.textCPU 只读NPU 不可访问DTCM0x20000000512KB数据与栈/堆SSE-300 SRAM0x210000002MBCPU 与 NPU 均可读写.sram段存放 fast memoryData SRAM0x010000002MBCPU 与 NPU 均可读写DDR0x6000000032MBCPU 与 NPU 均可读写.ddr段链接脚本的核心段划分.ddr段依次放置ethosu_scratch输入数据、标签、output_data_sec输出与*.rodata.tvmNPU command stream全部落在DDR这是 NPU 可访问的共享内存.sram段放置*.bss.ethosu_fast_memory与*.data.tvm落在 SSE-300 SRAM供 NPU 快速访问栈与堆各 32KB__STACK_SIZE/__HEAP_SIZE0x8000位于 DTCM并在脚本末尾用ASSERT检查栈不溢出 DTCM。八、FVP 仿真与结果验证run_demo.sh最后一行启动仿真器见 run_demo.shFVP_Corstone_SSE-300_Ethos-U55 -C cpu0.CFGDTCMSZ15 \ -C cpu0.CFGITCMSZ15 -C mps3_board.uart0.out_file- -C mps3_board.uart0.shutdown_tagEXITTHESIM \ -C mps3_board.visualisation.disable-visualisation1 -C mps3_board.telnetterminal0.start_telnet0 \ -C mps3_board.telnetterminal1.start_telnet0 -C mps3_board.telnetterminal2.start_telnet0 -C mps3_board.telnetterminal5.start_telnet0 \ -C ethosu.extra_args--fast \ -C ethosu.num_macs256 ./build/demo关键 FVP 参数说明cpu0.CFGDTCMSZ15/cpu0.CFGITCMSZ15把 DTCM/ITCM 配满2^15 32KB对应 512KB 需要结合平台默认值理解此处是 Corstone-300 的标准配置mps3_board.uart0.out_file-UART 输出到终端便于观察 printf 结果mps3_board.uart0.shutdown_tagEXITTHESIMUART 收到EXITTHESIM字符串即关闭仿真——这正是 demo 程序最后打印该串的原因mps3_board.visualisation.disable-visualisation1关闭可视化窗口无头运行ethosu.num_macs256Ethos-U55 配置为 256 MAC必须与编译时accelerator_configethos-u55-256保持一致否则 NPU 执行可能出错。成功运行时终端会依次输出Starting Demo Running inference The image has been classified as king penguin EXITTHESIM随后仿真器自动退出证明整条TVM 编译 → 交叉编译 → NPU 驱动 → 推理 → 结果输出链路完全打通。九、总结一条可复用的 microNPU 部署范式从 apps/microtvm/ethosu 示例可以提炼出在 TVM 中部署CPU Ethos-U NPU CMSIS-NN异构微控制器目标的通用范式环境层FVP 仿真 arm-none-eabi-gcc工具链 Ethos-U core driver CMSIS/CMSIS-NN保证编译与运行目标一致编译层tvmc compile用--targetethos-u,cmsis-nn,c做算子级异构切分--executoraot--runtimecrt生成无 OS 依赖的静态入口tir.usmp系列 pass 负责统一静态内存规划数据层convert_image.py/convert_labels.py把图片与标签固化为放置在 NPU 可访问内存段的 C 数组运行时桥接层TVMEthosULaunch把 TVM 的 command stream 交给ethosu_invoke通过ethosu_reserve_driver/ethosu_release_driver管理 NPU 独占访问验证层FVP 以--fast模式加速 NPU 仿真通过 UART 输出分类结果并自动关机。基于这一范式你可以替换模型任意 TFLite 量化模型、替换图片convert_image.py单参数即可、甚至替换操作系统裸机 / FreeRTOS 双版本主程序快速在 Corstone-300 平台上验证自己的嵌入式 AI 方案。赞分享编译器深度学习模型优化【免费下载链接】tvmOpen deep learning compiler stack for cpu, gpu and specialized accelerators项目地址https://gitcode.com/gh_mirrors/tvm7/tvm点击查看免费下载相关推荐基于 TVM 与 Arm Virtual Hardware 在 Cortex(R)-M55 裸机环境运行 PaddleOCR 文本识别模型实战指南基于 TVM 与 Arm Virtual Hardware 在 Cortex R M55 裸机环境运行 PaddleOCR 文本识别模型实战指南 导读本文以人工智能计算机视觉OCR深度学习大模型RAGPaddleOCR 裸机部署实战用 TVM 与 Arm Virtual Hardware 在 Cortex-M55 上运行 PP-OCRv3 英文文字识别PaddleOCR 裸机部署实战用 TVM 与 Arm Virtual Hardware 在 Cortex M55 上运行 PP OCRv3 英文文字识别 本人工智能计算机视觉深度学习PaddleOCR 边缘部署实战基于 TVM 与 Arm 虚拟硬件在 Cortex-M55 裸机上运行文本识别模型PaddleOCR 边缘部署实战基于 TVM 与 Arm 虚拟硬件在 Cortex M55 裸机上运行文本识别模型 本篇技术指南围绕 PaddleOCR 仓库人工智能计算机视觉OCR深度学习大模型RAG上一篇DJITelloPy安装与配置指南下一篇Ruff VSCode 扩展插件使用教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表