[NPU:rknn] Add initial rknn support for Rockchip NPUs, supporting traditional models. - #4524
[NPU:rknn] Add initial rknn support for Rockchip NPUs, supporting traditional models.#4524huangzhengxiang wants to merge 7 commits into
Conversation
wangzhaode
left a comment
There was a problem hiding this comment.
Review Summary
这个 PR 为 MNN 添加了 Rockchip RKNN NPU 后端支持,采用 Converter + Plugin 的架构设计。
架构评价
Converter + Plugin 的设计方案合理:
- Host 侧 MNNConvert --rknn 生成 wrapper .mnn + sidecar .rknn
- Device 侧通过 CPU Plugin 框架 dlopen librknnrt.so 执行
- 应用侧 Session backend 仍使用 MNN_FORWARD_CPU
- 部署简单,不需要在线逐算子构图
⚠️ 核心代码改动需要特别关注
这个 PR 修改了 MNN 核心公共头文件和基类:
-
include/MNN/Interpreter.hpp:新增了 RKNN_PROFILE (HintMode=19) 和 BACKEND_PROFILE (SessionInfoCode=5 / getInfo code=7)。枚举值需确认不与现有值冲突,RKNN_PROFILE=19 跳过了不少数字。
-
source/core/Backend.hpp:新增虚函数 onGetRuntimeInfo()。这会改变 Backend 虚表布局,属于 ABI 变更。虽然 MNN 不保证跨版本 ABI 兼容,但需要确认此影响可接受。
-
source/core/Pipeline.hpp:新增 mModelExternalDir 成员,影响较小。
-
source/core/Session.cpp / express/Executor.cpp:新增 BACKENDS_PROFILE 查询逻辑,遍历所有 runtime 尝试获取 profile 文本。需要确认其他 backend 返回 false 时不会有副作用。
RKNN Backend 实现
- RKNNBackend.cpp 通过 dlopen 动态加载 librknnrt.so,符号绑定清晰
- 环境变量驱动(MNN_RKNN_RUNTIME_LIB, MNN_RKNN_TARGET 等),避免硬编码
- Converter 侧用 system() 调外部 Python 脚本转 RKNN:这在 CI 和自动化场景中需要注意 PATH 和 Python 环境设置
- CMakeLists.txt 强制依赖 MNN_WITH_PLUGIN=ON
文档
- docs/inference/npu.md 和 source/backend/rknn/README.md 文档完善 ✅
建议
- 核心代码改动(Backend.hpp 虚函数、Interpreter.hpp 枚举)建议单独提 PR,便于更仔细地评审和测试
- 确认 HintMode 和 SessionInfoCode 的枚举值分配不冲突
- 需要在 RK3588 板上实际验证后再合入
|
Thanks for the substantial RKNN integration work. The wrapper MNN plus sidecar RKNN design is reasonable, but please address the following issues before merging.
Please also run clang-format on the files reported by the changed-lines check, update the three commit messages to the required |
|
已基本按要求解决 |
|
resolved. |
Description
Current design:
.mnnmodel containingPlugin(type="RKNN").rknnmodel plus bundle manifestPlugin("RKNN")through the MNN CPU Plugin framework.MNN_FORWARD_CPU.1. Host build for
MNNConvert --rknnBuild a host
MNNConvertwith plugin support and RKNN converter support enabled:2. Generate wrapper
.mnn+ sidecar.rknnBefore running
MNNConvert --rknn, export these environment variables:Example:
Expected outputs:
/path/to/model.mnn${MNN_RKNN_OUTPUT_DIR}/model_<target>.rknn${MNN_RKNN_OUTPUT_DIR}/model.rknn.bundle.jsonThe generated wrapper
.mnncontains:Inputops for original inputsPlugin(type="RKNN")opmodel_pathbundle_manifesttargetinputsoutputso_0,o_1, ... for output shape metadataImportant:
model_pathandbundle_manifestare emitted as relative file names..mnn, sidecar.rknn, and bundle.jsonin the same target directory.3. Cross compile runtime for Linux aarch64 / ARMv8
Example cross build using the system
aarch64-linux-gnutoolchain.This builds the target-side runtime libraries;
MNNConvertitself is usually only needed on the host.Notes:
MNN_WITH_PLUGIN=ONis required because RKNN is implemented as a Plugin op.MNN_RKNN=ONpulls in the RKNN Plugin kernels.RKNN_API_INCLUDE_DIRmust point to the directory containingrknn_api.h.dlopen, not linked as a hard dependency.4. Target runtime usage
On the target board, export the RKNN runtime library path:
export MNN_RKNN_RUNTIME_LIB=/path/to/librknnrt.soThe wrapper
.mnnshould be deployed together with its sidecar.rknnand bundle manifest in the same directory on target.Important:
sudo.Runtime behavior:
.mnnPlugin(type="RKNN")is created by the CPU Plugin framework.rknnsidecar using RKNN C APIMNN_FORWARD_CPUNHWCbut the incoming MNN tensor isNCHW, the plugin converts layout automaticallyNHWC, no extra layout conversion is doneInterpreter::setSessionHint(Interpreter::RKNN_PROFILE, 1)orRuntimeManager::setHint(Interpreter::RKNN_PROFILE, 1)getSessionInfo(..., Interpreter::BACKEND_PROFILE, &ptr)orRuntimeManager::getInfo(Interpreter::BACKEND_PROFILE, &ptr)5. Current limitations
NCHW -> NHWCcase for 4D tensors only, and only when the RKNN model explicitly expectsNHWC.Module
Backend. Add rknn backend.
Type
Checklist
[Module:Type] Descriptionformat