前兩期中我們已經(jīng)把所有準(zhǔn)備工作一步步鋪墊到位:
Zephyr迎來AI加速時(shí)代:NPU驅(qū)動(dòng)集成從未如此簡(jiǎn)單
為Zephyr AI加速做好準(zhǔn)備:模型轉(zhuǎn)換
現(xiàn)在,是時(shí)候把準(zhǔn)備工作真正轉(zhuǎn)化為成果了!
今天,我們將正式在Zephyr中加入NPU軟件支持,讓模型不僅能“跑起來”,還能“跑得飛快”。是的,本期開始就是實(shí)戰(zhàn)環(huán)節(jié)!
本次的適配工作將以tflite_micro/hello_world工程為基礎(chǔ)展開。我們首先將其完整復(fù)制一份,并命名為hello_world_neutron。后續(xù)所有與Neutron NPU相關(guān)的移植步驟和配置修改,都將在這個(gè)新工程中進(jìn)行。
Zephyr的移植工作我們基于tfltie_micro/hello_world工程進(jìn)行,將其復(fù)制一份重命名為hello_world_neutron:

一、改造思路
整體改造大致分為三個(gè)主要步驟:
開啟C++/FPU/TFLM支持
添加NPU相關(guān)驅(qū)動(dòng)與接口層代碼
修改CMakeLists.txt讓工程真正“認(rèn)識(shí)” NPU
除此之外,還需要將模型文件替換為NPU可執(zhí)行的版本,并手動(dòng)注冊(cè)Neutron自定義算子,使TFLM能夠調(diào)用NPU。下面我們一步一步來。
二、工程配置
1.修改prj.conf文件,添加FPU與CXX的支持:
CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_FPU=y CONFIG_FPU_SHARING=y CONFIG_TENSORFLOW_LITE_MICRO=y CONFIG_MAIN_STACK_SIZE=2048 CONFIG_REQUIRES_FLOAT_PRINTF=y
三、加入NPU相關(guān)代碼
NPU 的組件大致可分為兩部分:
1. Neutron 與 TFLM 的接口層 2. Neutron 底層 Driver
3.1將NPU相關(guān)Driver從SDK中拷貝到工程目錄中
主要分為兩部分:NPU底層Driver以及NPU與TFLM的接口層代碼:
a) TFLM接口層代碼:
我們可以在SDK代碼中的eiq ensorflow-lite ensorflowlitemicrokernels eutron路徑下找到這兩個(gè)文件,
一定要注意:SDK版本要和轉(zhuǎn)換工具的版本一致,這里我們選擇的是2.16.0版本的SDK代碼以及針對(duì)于2.16.0 SDK版本的Neutron-converter.exe:

將這兩個(gè)文件拷貝到工程目錄中:

3.2NPU底層驅(qū)動(dòng):
可以在eiq ensorflow-lite hird_party eutron路徑找到:

將其同樣拷貝到工程目錄下,完整的目錄結(jié)構(gòu)如下:

四、修改CMakeLists,加入NPU依賴
我們需要讓工程能夠正確包含頭文件、鏈接NPU相關(guān)庫(kù),完整示例如下:
|
cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(tensorflow_hello_world) # These samples use local static initialization. Since Zephyr doesn't support the # C++ ABI for thread-safe initialization of local statics and the constructors don't # appear to require thread safety, we turn it off in the C++ compiler. set(NO_THREADSAFE_STATICS $ zephyr_compile_options($<$ #頭文件依賴 target_include_directories(app PRIVATE neutron/driver/include) target_include_directories(app PRIVATE neutron/common/include) target_include_directories(app PRIVATE neutron/source) #庫(kù)依賴 add_library(libneutron1 STATIC IMPORTED GLOBAL) set_target_properties(libneutron1 PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/neutron/libNeutronDriver.a) add_library(libneutron2 STATIC IMPORTED GLOBAL) set_target_properties(libneutron2 PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/neutron/libNeutronFirmware.a) add_library(libneutron INTERFACE) target_link_libraries(libneutron INTERFACE libneutron1 libneutron2) target_link_libraries(app PUBLIC libneutron) #添加源文件 file(GLOB app_sources src/*) target_sources(app PRIVATE ${app_sources}) target_sources(app PRIVATE neutron/source/neutron.cpp) |
到這里,工程已經(jīng)具備NPU支持能力。
五、替換模型文件
將src/目錄下的model.cpp替換為你通過xxd轉(zhuǎn)換得到的NPU版本模型。
模型來源應(yīng)為Neutron-converter轉(zhuǎn)換后的.bin,格式已經(jīng)適配NPU。

六、注冊(cè)Neutron自定義算子
注冊(cè)Neutron算子:
因?yàn)門FLM本身不支持Neutron算子,這里需要我們手動(dòng)添加,添加方式是修改src/main_functions.cpp:
|
/* This pulls in the operation implementations we need. * NOLINTNEXTLINE(runtime-global-variables) */ static tflite::MicroMutableOpResolver <1> resolver; resolver.AddCustom(tflite::GetString_NEUTRON_GRAPH(), tflite::Register_NEUTRON_GRAPH()); |
因Zephyr自帶的模型算子類型是FullyConnected,這里將他替換為NeutronGraph,同時(shí)在文件開頭添加頭文件引用:

至此,所有軟件工作就都完成了,接下來就是使用west工具進(jìn)行編譯:
| west build -b frdm_mcxn947/mcxn947/cpu0 |

七、編譯,下載運(yùn)行
使用west編譯工程,下載運(yùn)行:

當(dāng)我們看到正常輸出、并且沒有任何錯(cuò)誤時(shí),就說明:
模型成功轉(zhuǎn)換
Neutron NPU驅(qū)動(dòng)加載成功
TFLM已正確調(diào)度NPU推理
模型已順利跑在NPU上進(jìn)行加速!
八、完整鏈路走通
至此,小編跨越三期,帶大家完整走了一遍流程:
1. 自主訓(xùn)練模型
2. 使用轉(zhuǎn)換工具生成NPU 可執(zhí)行格式
3. 在ZephyrOS 中添加 Neutron NPU 驅(qū)動(dòng)支持
4. 讓模型真正跑在NPU 上加速推理
這條鏈路雖然步驟較多,但每一步都是構(gòu)建“嵌入式AI”所必需的關(guān)鍵環(huán)節(jié)。
也期待未來ZephyrOS能繼續(xù)完善AI支持,讓NPU適配更加自動(dòng)化,讓開發(fā)者可以更加專注于算法本身。
-
移植
+關(guān)注
關(guān)注
1文章
416瀏覽量
29414 -
AI
+關(guān)注
關(guān)注
91文章
39819瀏覽量
301481 -
模型
+關(guān)注
關(guān)注
1文章
3755瀏覽量
52118 -
NPU
+關(guān)注
關(guān)注
2文章
374瀏覽量
21108 -
Zephyr
+關(guān)注
關(guān)注
0文章
59瀏覽量
6584
原文標(biāo)題:微控制器也能跑AI: 在Zephyr OS上啟用NPU的實(shí)用方案
文章出處:【微信號(hào):NXP_SMART_HARDWARE,微信公眾號(hào):恩智浦MCU加油站】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
當(dāng)RA MCU遇見Zephyr系列(3)——在Vs code中配置Zephyr集成開發(fā)環(huán)境
如何在Zephyr OS中使用cyhal?
請(qǐng)問如何將Zephyr OS移植到KIT_PSOCE84_EVK?
請(qǐng)問如何在OpenVINO?工具包中啟用NPU設(shè)備?
如何在NXP MCU上啟用D-Cache?
在 VisionFive 2 上嘗試 Zephyr 時(shí)沒有輸出是怎么回事?
AIO-3399ProC NPU開發(fā)相關(guān)資料推薦
如何同時(shí)在Zephyr上運(yùn)行RT1170 EVK 1G和100M端口?
如何使用RT685的DSP搭配Zephyr OS?
μC/OS-II在EP7312上的移植
Chrome OS將獲Linux支持,可在Chrome OS 上運(yùn)行Linux?
淺析Zephyr在ESP32上的啟動(dòng)流程
泰凌微電子Zephyr編譯環(huán)境搭建
在Sitara MPU上啟用Matter
深入解析Zephyr RTOS的技術(shù)細(xì)節(jié)
在Zephyr OS上啟用NPU的實(shí)用方案
評(píng)論