轻松学习 TFLM Day 4:手把手设计your_chip后端目录结构
从最小可跑通到完整产品化逐步演进
摘要:本文面向 AI 芯片设计商,系统讲解如何为 TFLM 设计一个可维护、可逐步演进的
your_chip后端目录结构。文章先厘清后端通常包含的 5 层(平台移植、优化 kernel、adapter/common、外部 NN library、构建/测试),再给出最小目录与完整目录两套方案,并从 5 个维度对比帮助读者按阶段决策。随后逐一说明各目录职责、your_chip_common的胶水定位、NN library 的边界设计、optimized kernel 文件组织、支持矩阵、内存设计、Fallback 三模式、测试与 benchmark 安排、Bazel 建议及文件命名规范。最后给出从 0 到 1 的 5 阶段推荐路线(平台跑通 → 第一个优化算子 → CNN 算子 → 工程化 → CI 发布)和一份最终推荐目录树,帮助读者从最小可跑通版本平滑演进到产品化后端。
这里的your_chip是一个占位名,实际项目可以替换成芯片或 IP 名称,例如:
abc_npuxyz_dspmycompany_aiyour_chip
本文目标是设计一个清晰、可维护、可逐步演进的后端结构。
1. 先明确:TFLM 后端通常包含哪些东西
一个芯片后端不只是几个conv.cc文件。完整一点看,它通常有 5 层:
应用 examples / 用户工程 | v TFLM runtime | v TFLM optimized kernels | v your_chip adapter / common glue | v your_chip NN library / driver / firmware | v 硬件 NPU / DSP / AI accelerator所以目录结构也要对应这几层:
| 层 | 放什么 |
|---|---|
| 平台移植层 | debug_log.cc、micro_time.cc、system_setup.cc。 |
| 优化 kernel 层 | conv.cc、fully_connected.cc、softmax.cc等。 |
| adapter/common 层 | tensor 转换、shape 转换、量化参数转换、错误码转换。 |
| 外部库层 | 你们自己的 NN library、driver、固件头文件。 |
| 构建/测试层 | Make/Bazel 配置、单测、benchmark、CI。 |
2. 推荐的最小目录结构
如果你想先跑通,不要一开始就建得太复杂。最小版可以这样:
tensorflow/lite/micro/ ├── your_chip/ │ ├── debug_log.cc │ ├── micro_time.cc │ ├── system_setup.cc │ └── README.md │ └── kernels/ └── your_chip/ ├── README.md ├── your_chip_common.h ├── your_chip_common.cc ├── fully_connected.cc ├── conv.cc ├── depthwise_conv.cc └── softmax.cc这已经能覆盖第一阶段目标:
- 平台能启动。
- 日志能打印。
- 时间能测量。
- 关键 int8 算子能走硬件。
- 其他算子继续走 reference。
3. 推荐的完整目录结构
产品化后端建议这样组织:
tensorflow/lite/micro/ ├── your_chip/ │ ├── README.md │ ├── debug_log.cc │ ├── debug_log_callback.h │ ├── micro_time.cc │ ├── system_setup.cc │ ├── memory_map.h │ ├── platform_config.h │ └── startup_notes.md │ ├── kernels/ │ └── your_chip/ │ ├── README.md │ ├── your_chip_common.h │ ├── your_chip_common.cc │ ├── your_chip_status.h │ ├── your_chip_quantization.h │ ├── your_chip_tensor_utils.h │ ├── your_chip_scratch.h │ ├── your_chip_profiler.h │ ├── add.cc │ ├── conv.cc │ ├── depthwise_conv.cc │ ├── fully_connected.cc │ ├── pooling.cc │ ├── mul.cc │ ├── softmax.cc │ ├── reshape.cc │ └── transpose.cc │ └── tools/ └── make/ ├── targets/ │ ├── your_chip_makefile.inc │ └── your_chip/ │ ├── your_chip.lds │ ├── download_toolchain.sh │ └── README.md │ └── ext_libs/ ├── your_chip_nnlib.inc ├── your_chip_nnlib_download.sh └── your_chip_driver.patch如果你们的 NN library 不适合放进 TFLM 仓库,可以只放.inc和下载脚本,实际源码作为外部依赖管理。
3.1 最小目录 vs 完整目录:怎么选
上面给了最小版和完整版两套结构,很多读者会纠结“到底该建哪套”。这里从 5 个维度做个对比,帮你按项目阶段快速决策:
| 对比维度 | 最小目录结构 | 完整目录结构 |
|---|---|---|
| 目录层级 | 2 层:your_chip/(平台适配)+kernels/your_chip/(优化算子)。 | 3 层:平台适配 + 优化算子 +tools/make/(构建配置、链接脚本、外部库)。 |
| 文件数量 | 约 10 个文件,只保留跑通必需项。 | 约 30+ 个文件,含your_chip_status.h、your_chip_quantization.h、your_chip_tensor_utils.h、your_chip_scratch.h、your_chip_profiler.h、Make target、ext_libs 等。 |
| 适用阶段 | 阶段 1-2:平台跑通、第一个优化算子(如fully_connected)。 | 阶段 3-5:CNN 算子铺开、工程化、CI 发布。 |
| 维护成本 | 低:文件少、依赖少,改起来快,适合快速验证。 | 高:文件多、职责划分细,需要团队约定和文档支撑。 |
| 推荐场景 | 个人探索、demo、评估芯片可行性、早期 bring-up。 | 产品化、多人协作、长期维护、需要 benchmark 和 CI 的后端。 |
一句话建议:先按最小目录跑通,再按完整目录演进。不要一上来就建全套,也不要一直停留在最小版——当算子数量超过 5 个、或开始接 CI 时,就该往完整目录迁移了。
4. 各目录职责
4.1tensorflow/lite/micro/your_chip/
这是平台适配目录,解决“代码怎么在你的板子上跑”。
建议文件:
| 文件 | 作用 |
|---|---|
README.md | 平台说明、工具链版本、构建命令、已知限制。 |
debug_log.cc | 把MicroPrintf接到 UART、RTT、semihosting 或系统 log。 |
debug_log_callback.h | 如果希望用户自定义 log callback,可以放这里。 |
micro_time.cc | 提供计时函数,用于 profiler 和 benchmark。 |
system_setup.cc | 芯片启动后 TFLM 运行前的初始化,如 cache、clock、NPU。 |
memory_map.h | SRAM、TCM、NPU memory、DMA buffer 地址规划。 |
platform_config.h | 平台宏、cache line、alignment、feature 开关。 |
startup_notes.md | 记录启动、链接脚本、SDK 注意事项。 |
参考现有目录:
tensorflow/lite/micro/cortex_m_generic/tensorflow/lite/micro/hexagon/tensorflow/lite/micro/ceva/tensorflow/lite/micro/riscv32_generic/
4.2tensorflow/lite/micro/kernels/your_chip/
这是优化 kernel 目录,解决“每个算子怎么调用你的硬件”。
建议文件:
| 文件 | 作用 |
|---|---|
README.md | 支持哪些 op、数据类型、shape、量化方式、fallback 策略。 |
your_chip_common.h/.cc | 通用转换函数、错误处理、硬件初始化检查。 |
your_chip_status.h | 把芯片库错误码映射为TfLiteStatus。 |
your_chip_quantization.h | 量化参数转换,如 multiplier/shift/zero point。 |
your_chip_tensor_utils.h | 从TfLiteEvalTensor取 shape/data 并转成芯片 API 参数。 |
your_chip_scratch.h | scratch buffer 管理辅助。 |
your_chip_profiler.h | 可选,用于记录硬件执行时间或 cycle。 |
<op>.cc | 每个算子的 TFLM wrapper。 |
第一批最值得优化的文件:
| 算子文件 | 为什么优先 |
|---|---|
conv.cc | CNN 模型主要耗时来源。 |
depthwise_conv.cc | MobileNet 类模型大量使用。 |
fully_connected.cc | 分类头、dense 层、RNN 里常见。 |
softmax.cc | 分类输出常见,虽不一定最耗时,但容易闭环。 |
pooling.cc | CNN 常见,接口相对简单。 |
add.cc/mul.cc | residual、elementwise 融合常见。 |
4.3tensorflow/lite/micro/tools/make/targets/your_chip_makefile.inc
这是 Make target 配置,解决“用什么编译器、什么 flags、怎么链接”。
建议内容:
TARGET_ARCH := your_chip TARGET_TOOLCHAIN_ROOT := ... CXX := your-chip-g++ CC := your-chip-gcc AR := your-chip-ar CXXFLAGS += -DYOUR_CHIP CXXFLAGS += -I$(MAKEFILE_DIR)/downloads/your_chip_nnlib/include LDFLAGS += -T tensorflow/lite/micro/tools/make/targets/your_chip/your_chip.lds可以参考:
tensorflow/lite/micro/tools/make/targets/cortex_m_generic_makefile.inctensorflow/lite/micro/tools/make/targets/ceva_makefile.inctensorflow/lite/micro/tools/make/targets/xtensa_makefile.inctensorflow/lite/micro/tools/make/targets/hexagon_makefile.inc
4.4tensorflow/lite/micro/tools/make/ext_libs/your_chip_nnlib.inc
这是外部库配置,解决“怎么把你们 NN library 加进来”。
建议内容:
YOUR_CHIP_NNLIB_ROOT := $(MAKEFILE_DIR)/downloads/your_chip_nnlib MICROLITE_CC_INCLUDES += \ -I$(YOUR_CHIP_NNLIB_ROOT)/include MICROLITE_LIBS += \ $(YOUR_CHIP_NNLIB_ROOT)/lib/libyour_chip_nnlib.a