娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

【TVM系列八】microTVM在ESP32上調(diào)優(yōu)算子

發(fā)布者:trendsetter9最新更新時間:2025-06-06 來源: jianshu關(guān)鍵字:ESP32 手機看文章 掃描二維碼
隨時隨地手機看文章

一、前言

本文主要介紹如何基于ESP32的開發(fā)板通過microTVM進行一個卷積算子的調(diào)優(yōu)。

二、microTVM

microTVM是TVM 編譯器的擴展,它能夠使TVM應用于微控制器,提供了在設備上運行 TVM RPC 服務以完成自動調(diào)優(yōu)的方法,同時也提供了一套最小化 C 語言的runtime,使得裸機邊緣設備可以獨立完成模型推理。

  • 基于TVM RPC服務
    需要host端與設備端同時參與,由host端與設備端通過串口或USB等進行連接通信,host端將交叉編譯完的固件程序燒錄到設備端,該固件程序包括了TVM編譯完成的模型設備端代碼,TVM C runtime,設備的初始化操作以及TVM RPC server。而host端負責GrpahExecutor實例的創(chuàng)建,它會通過串口或USB等物理連接發(fā)送RPC命令到設備端進行模型推理。

    基于TVM RPC服務

  • 獨立運行
    只需要設備端參與,與基于RPC服務的區(qū)別是GraphExecutor實例是由設備自己獨立完成。

    獨立運行


三、在ESP32上運行microTVM進行autotune

1、Zephyr安裝與配置

1.1 配置zephyr sdk

Zephyr sdk的release地址在:https://github.com/zephyrproject-rtos/sdk-ng

需要下載最新的0.14.1版本,提供了esp相關(guān)的toolchain,如果使用west espressif進行安裝會遇到newlibc的編譯問題。


cd ~/

wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.14.1/zephyr-sdk-0.14.1_linux-x86_64.tar.gz

tar -xvf zephyr-sdk-0.14.1_linux-x86_64.tar.gz

cd zephyr-sdk-0.14.1

./setup.sh

. environment-setup-x86_64-pokysdk-linux

我們需要的toolchain目錄為 xtensa-espressif_esp32_zephyr-elf


1.2 安裝依賴

這個按照Zephyr官方文檔進行:


sudo apt install --no-install-recommends git cmake

ninja-build gperf ccache dfu-util device-tree-compiler wget

python3-dev python3-pip python3-setuptools python3-tk

python3-wheel xz-utils file make gcc gcc-multilib

g++-multilib libsdl2-dev


pip3 install -- user -U west

echo 'export PATH=~/.local/bin:'$PATH'' >> ~/.bashrc

source ~/.bashrc

zephyr對cmake版本有要求,如果需要升級,可以執(zhí)行:


wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main'sudo apt update

sudo apt install cmake

1.3 初始化zephyr工程

west init ~/zephyrproject

cd ~/zephyrproject

west update

west zephyr-export

1.4  ESP32 newlibc支持

cd ~/zephyrproject/zephyr

git remote add upstream https://github.com/sylvioalves/zephyr.git

git fetch upstream

git checkout upstream/feature/newlibc_cpp_support

west update

雖然這個feature還沒有入到主分支,但是不加這個支持的話,不出意外應該會遇到的錯誤應該是這樣的:


In file included from ~/zephyrproject/zephyr/lib/posix/pthread_common.c:10:

~/zephyrproject/zephyr/include/posix/time.h:90:15: error: static declaration of 'clock_gettime' follows non-static declaration

__syscall int clock_gettime(clockid_t clock_id, struct timespec *ts);

^~~~~~~~~~~~~

In file included from ~/zephyrproject/zephyr/include/posix/time.h:12,

from ~/zephyrproject/zephyr/lib/posix/pthread_common.c:10:

/home/zgs/.espressif/tools/zephyr/xtensa-esp32-elf/xtensa-esp32-elf/sys-include/time.h:187:5: note: previous declaration of 'clock_gettime' was here

int clock_gettime (clockid_t clock_id, struct timespec *tp);

^~~~~~~~~~~~~

In file included from ~/zephyrproject/zephyr/lib/posix/pthread_common.c:10:

~/zephyrproject/zephyr/include/posix/time.h:94:5: error: conflicting types for 'timer_create'

int timer_create(clockid_t clockId, struct sigevent *evp, timer_t *timerid);

....

make[2]: *** [zephyr/lib/posix/CMakeFiles/lib__posix.dir/build.make:76: zephyr/lib/posix/CMakeFiles/lib__posix.dir/pthread_common.c.obj] Error 1

make[1]: *** [CMakeFiles/Makefile2:2950: zephyr/lib/posix/CMakeFiles/lib__posix.dir/all] Error 2

make[1]: *** Waiting for unfinished jobs....


1.5 導出環(huán)境變量

export ZEPHYR_BASE='${HOME}/zephyrproject/zephyr'

export ZEPHYR_TOOLCHAIN_VARIANT='espressif'

export ESPRESSIF_TOOLCHAIN_PATH='${HOME}/zephyr-sdk-0.14.1/xtensa-espressif_esp32_zephyr-elf'

export PATH=$PATH:$ESPRESSIF_TOOLCHAIN_PATH/bin

1.6 修改toolchain名稱

下載的zephyr-sdk 0.14.1中的toolchain名稱跟esp32所使用的默認名稱不一致,需要修改編譯腳本的默認值:


diff --git a/cmake/toolchain/espressif/target.cmake b/cmake/toolchain/espressif/target.cmake

index 5245bf9d08..f677bc9024 100644

--- a/cmake/toolchain/espressif/target.cmake

+++ b/cmake/toolchain/espressif/target.cmake

@@ -8,7 +8,7 @@ set(COMPILER gcc)

 set(LINKER ld)

 set(BINTOOLS gnu)

 

-set(CROSS_COMPILE_TARGET_xtensa_esp32    xtensa-esp32-elf)

+set(CROSS_COMPILE_TARGET_xtensa_esp32    xtensa-espressif_esp32_zephyr-elf)

 set(CROSS_COMPILE_TARGET_xtensa_esp32s2  xtensa-esp32s2-elf)

 set(CROSS_COMPILE_TARGET_riscv_esp32c3   riscv32-esp-elf)

2、TVM配置

2.1  使能 microTVM 編譯

修改 config.cmake


set(USE_MICRO ON)

重新編譯tvm。


2.2 增加esp32支持

在 ~/github/tvm/apps/microtvm/zephyr/template_project/boards.json 增加:


diff --git a/apps/microtvm/zephyr/template_project/boards.json b/apps/microtvm/zephyr/template_project/boards.json

index aae764a82..19a80397a 100644

--- a/apps/microtvm/zephyr/template_project/boards.json

+++ b/apps/microtvm/zephyr/template_project/boards.json

@@ -95,5 +95,13 @@

         'fpu': true,

         'vid_hex': '0483',

         'pid_hex': '374b'

+    },

+    'esp32': {

+        'board': 'esp32',

+        'model': 'esp32',

+        'is_qemu': false,

+        'fpu': true,

+        'vid_hex': '',

+        'pid_hex': ''

     }

 }

2.3 增加esp32 flash runner串口獲取方式

在~/github/tvm/apps/microtvm/zephyr/template_project/microtvm_api_server.py增加:


diff --git a/apps/microtvm/zephyr/template_project/microtvm_api_server.py b/apps/microtvm/zephyr/template_project/microtvm_api_server.py

index 059e76048..7e7b6e888 100644--- a/apps/microtvm/zephyr/template_project/microtvm_api_server.py+++ b/apps/microtvm/zephyr/template_project/microtvm_api_server.py

@@ -669,6 +669,10 @@ class ZephyrSerialTransport:

     def _find_stm32cubeprogrammer_serial_port(cls, options):

         return generic_find_serial_port()

 +    @classmethod+    def _find_esp32_serial_port(cls, options):+        return generic_find_serial_port()+    

     @classmethod

     def _find_serial_port(cls, options):

         flash_runner = _get_flash_runner()@@ -685,6 +689,9 @@ class ZephyrSerialTransport:

         if flash_runner == 'stm32cubeprogrammer':

             return cls._find_stm32cubeprogrammer_serial_port(options)

 +        if flash_runner == 'esp32':+            return cls._find_esp32_serial_port(options)+        

         raise RuntimeError(f'Don't know how to deduce serial port for flash runner {flash_runner}')

 

     def __init__(self, options):

2.4 修改host_driven內(nèi)存分配及頭文件依賴

主要修改兩個地方:


zephyr從2.6.0開始power/reboot.h改成了sys/reboot.h


縮小tvm_heap分配的內(nèi)存,否則最終的編譯會出現(xiàn)region `dram0_1_seg' overflowed by xxxxx bytes的錯誤。


diff --git a/apps/microtvm/zephyr/template_project/src/host_driven/main.c b/apps/microtvm/zephyr/template_project/src/host_driven/main.c

index 44d656028..463f7e0d1 100644--- a/apps/microtvm/zephyr/template_project/src/host_driven/main.c+++ b/apps/microtvm/zephyr/template_project/src/host_driven/main.c

@@ -33,7 +33,7 @@ #include

 #include

 #include -#include +#include

 #include

 #include

 #include @@ -42,6 +42,7 @@ #include

 #include

 #include +#include

 

 #ifdef CONFIG_ARCH_POSIX

 #include 'posix_board_if.h'@@ -130,7 +131,7 @@ tvm_crt_error_t TVMPlatformGenerateRandom(uint8_t* buffer, size_t num_bytes) {

 }

 

 // Heap for use by TVMPlatformMemoryAllocate.-K_HEAP_DEFINE(tvm_heap, 216 * 1024);+K_HEAP_DEFINE(tvm_heap, 50 * 1024);

 

 // Called by TVM to allocate memory.

 tvm_crt_error_t TVMPlatformMemoryAllocate(size_t num_bytes, DLDevice dev, void** out_ptr) {

按這樣改完后,編譯最終得到的內(nèi)存區(qū)使用情況如下,可以看到dram0_1_seg的使用率已經(jīng)到了96.22%:

內(nèi)存區(qū)使用情況


3、算子調(diào)優(yōu)

3.1 按microtvm_autotune的例程編寫應用

import osimport jsonimport numpy as npimport pathlibimport shutilimport tvmfrom tvm.relay.backend import Runtime


BOARD = os.getenv('TVM_MICRO_BOARD', default='esp32')def create_module():

    data_shape = (1, 3, 10, 10)

    weight_shape = (6, 3, 5, 5)


    # 輸入數(shù)據(jù)

    data = tvm.relay.var('data', tvm.relay.TensorType(data_shape, 'float32'))

    weight = tvm.relay.var('weight', tvm.relay.TensorType(weight_shape, 'float32'))


    # relay卷積算子

    y = tvm.relay.nn.conv2d(

        data,

        weight,

        padding=(2,2),

        kernel_size=(5, 5),

        kernel_layout='OIHW',

        out_dtype='float32',

    )


    # 定義relay Function表達式

    f = tvm.relay.Function([data, weight], y)


    # 用卷積算子表達式構(gòu)建一個module

    relay_mod = tvm.IRModule.from_expr(f)

    # 表達式類型推理

    relay_mod = tvm.relay.transform.InferType()(relay_mod)


    # weight隨機值

    weight_sample = np.random.rand(

        weight_shape[0], weight_shape[1], weight_shape[2], weight_shape[3]

    ).astype('float32')


    params = {'weight': weight_sample}

    return relay_mod, paramsdef config_target():

    runtime = Runtime('crt', {'system-lib': True})

    boards_file = pathlib.Path(tvm.micro.get_microtvm_template_projects('zephyr')) / 'boards.json'

    with open(boards_file) as fp:

        boards = json.load(fp)


    target = tvm.target.target.micro(boards[BOARD]['model'])

    return runtime, target


relay_mod, params = create_module()runtime, target = config_target()# 配置優(yōu)化passpass_context = tvm.transform.PassContext(opt_level=3, config={'tir.disable_vectorize': True})with pass_context:

    tasks = tvm.autotvm.task.extract_from_program(relay_mod['main'], {}, target)assert len(tasks) > 0zephyr_base = os.getenv('HOME') + '/zephyrproject/zephyr'module_loader = tvm.micro.AutoTvmModuleLoader(

    template_project_dir=pathlib.Path(tvm.micro.get_microtvm_template_projects('zephyr')),

[1] [2]
關(guān)鍵字:ESP32 引用地址:【TVM系列八】microTVM在ESP32上調(diào)優(yōu)算子

上一篇:Zephyr 環(huán)境搭建 - ESP32 篇
下一篇:最后一頁

推薦閱讀最新更新時間:2025-06-06 13:39

玩轉(zhuǎn) ESP32 + Arduino (十二) 通過MQTT協(xié)議上傳數(shù)據(jù)至OneNet云平臺
這里我們使用了一個庫: PubSubClient 中移動ONENET平臺 IP地址: 183.230.40.39 舊版MQTT端口號: 6002 一. 在ONENET平臺添加MQTT設備(舊版) 1. 添加 找到多協(xié)議接入入口 添加舊版MQTT產(chǎn)品 添加產(chǎn)品 添加產(chǎn)品成功 然后添加設備 2. 舊版MQTT關(guān)鍵信息 接下來我們來找到舊版MQTT關(guān)鍵的信息: 產(chǎn)品ID(在產(chǎn)品頁面) 2.設備ID(在設備界面) 3.設備鑒權(quán)信息 二. ESP32連接ONENET舊版MQTT 思路: 1.連接網(wǎng)絡 2.登錄ONENET 3.發(fā)布主題信息 #include Arduino.h #include
[單片機]
玩轉(zhuǎn) ESP32 + Arduino (四) 電容按鍵 霍爾傳感器 外部中斷 延時 脈沖檢測
一. 電容輸入 touchRead(pin) 及電容輸入中斷touchAttachInterrupt(pin, TSR , threshold) ESP32專門提供了電容觸摸傳感器的功能, 共有T0,T2~T9 共 9個touch傳感器可用.分別對應引腳4、2、15、13、12、14、27、33、32. 無需設置PinMode touchRead(pin) 返回值 0~255. 觸摸強度 注意: 摸得越瓷實,數(shù)值越小 void setup(){ Serial.begin(9600);}void loop(){ Serial.printf( touch:%dn ,touchRead(4));} touchAttachInter
[單片機]
stm32系列簡介與stm32 esp32性能比較
STM32應該是比較熟悉的一個系列的單片機,而ESP32相對陌生一些。但是從名字看,兩者應該都是32位單片機。那么兩者之間到底有什么關(guān)聯(lián),或者性能哪個好一些,哪個差一些呢? STM32系列 意法半導體 (STMicroelectronics) 集團于1987年6月成立,是由意大利的SGS 微電子公司和法國Thomson 半導體公司合并而成。1998年5月,SGS-THOMSON Microelectronics 將公司名稱改為意法半導體有限公司,意法半導體是世界最大的半導體公司之一。 STM32系列專為要求高性能、低成本、低功耗的嵌入式應用設計的ARM Cortex?-M0,M0+,M3, M4和M7內(nèi)核(ST‘s produ
[單片機]
stm32<font color='red'>系列</font>簡介與stm32 <font color='red'>esp32</font>性能比較
小廣播
設計資源 培訓 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 东丰县| 武功县| 保康县| 红安县| 温宿县| 亚东县| 夹江县| 苗栗县| 太湖县| 乐至县| 尉犁县| 晋州市| 巩义市| 万源市| 宁津县| 大同县| 灯塔市| 九龙城区| 綦江县| 朝阳县| 渝北区| 武义县| 泾阳县| 昌图县| 茌平县| 中卫市| 宿迁市| 富源县| 扶余县| 井研县| 琼中| 通辽市| 永安市| 清丰县| 墨玉县| 苍山县| 垦利县| 崇州市| 怀仁县| 红桥区| 沙洋县|