资讯动态

RV1106 NPU部署图像分类模型实测:MobileNet与ShuffleNet性能对比

发布时间:2026/10/28 1:07:16 来源:尧图企业网站定制
1. 为什么要在 RV1106 上折腾图像分类模型第一次拿到瑞芯微 RV1106 这块板子的时候我其实没太当回事。一颗主打低功耗、低成本、面向 IPC 和边缘视觉的 SoCCortex-A7 单核加一个自研 NPU内存通常就 64MB 到 256MB 这个量级看起来像是能跑个轻量模型就谢天谢地的定位。但真正把几个主流图像分类模型挨个塞进去跑一遍之后我发现这块芯片的性价比远比纸面参数有意思——它能在几百毫瓦的功耗预算里稳定跑起 MobileNet、ShuffleNet 这一档的分类网络对很多电池供电或者 PoE 供电的视觉终端来说这就是刚需。这篇内容我想聊的就是把各种主流图像分类模型部署到 RV1106 上的完整实验分析。不是那种跑通了发个截图的流水账而是把模型选型、量化转换、NPU 算子适配、内存占用、推理耗时、精度损失这些维度全部摊开来讲。适合谁看如果你正在做边缘视觉产品手上有 RV1106 或者同系列的板子想搞清楚到底哪个分类模型能落地、落地之后性能什么样、坑在哪里那这篇基本能帮你省掉两三周的试错时间。如果你只是对 NPU 部署感兴趣这里面的量化逻辑和算子适配思路换到别的芯片平台也通用。先说结论性的判断方便你带着预期往下读RV1106 的 NPU 算力官方标称 0.5TOPS 左右INT8决定了它适合的是输入分辨率 224x224 及以下、参数量在 1M 到 4M 之间的分类模型。ResNet50 这种级别的网络不是不能跑而是跑起来帧率和内存都很勉强实际产品里没什么意义。真正甜点区是 MobileNetV2、MobileNetV3-Small、ShuffleNetV2 这几类。下面我把整个实验过程拆开讲。2. 实验平台搭建与工具链选型2.1 硬件平台与基础环境确认我手上这块是 RV1106 的核心板配了 256MB DDR存储用的是 SPI NAND。这里有个很多人一开始会忽略的点RV1106 有几个不同的封装和内存配置版本RV1106G2、RV1106G3 在内存和部分外设上有差异你拿到的板子如果 DDR 只有 64MB那模型选型的空间会被压缩得很厉害。所以第一步一定是确认自己的具体型号和内存大小别拿着别人的部署脚本直接套。系统层面我用的是瑞芯微官方 SDK 里的 Buildroot 方案。为什么不用别的因为 NPU 的驱动和运行时库RKNN Runtime跟内核版本、rootfs 的库版本是强绑定的官方 SDK 里已经把 rknpu 驱动、librknnrt.so 这些配好了你自己从零搭一个 rootfs 再去对齐版本纯属给自己找麻烦。Buildroot 编译出来的镜像体积小启动快对 RV1106 这种资源紧张的芯片很合适。交叉编译工具链用的是 SDK 里自带的 arm-rockchip830-linux-uclibcgnueabihf 那一套。注意 RV1106 是 ARMv7 架构Cortex-A7浮点用的是硬浮点工具链别选错选成 aarch64 的会直接编不过。2.2 模型转换工具链 RKNN-Toolkit2 的版本坑模型转换这块是整个流程里最容易翻车的地方。瑞芯微的转换工具叫 RKNN-Toolkit2跑在 PC 上x86 Linux 环境负责把 ONNX、PyTorch、TensorFlow 等格式的模型转成 RKNN 格式。这里有几个必须记住的经验第一RKNN-Toolkit2 的版本要和板子上的 RKNN Runtime 版本匹配。工具链版本高于运行时版本转换出来的模型可能加载失败低太多又可能不支持某些新算子。我一般会先确认板子上 librknnrt.so 的版本号然后去装对应版本的 toolkit。查版本可以用strings librknnrt.so | grep -i version这种方式大致定位。第二转换环境强烈建议用官方提供的 Docker 镜像。RKNN-Toolkit2 对 Python 版本、numpy 版本、torch 版本都有比较挑剔的要求你在自己环境里 pip 装十有八九会遇到依赖冲突。官方 Docker 镜像里环境是配好的省心。第三RV1106 属于瑞芯微 NPU 产品线里相对入门的一档它支持的算子集和 RK3588 那种旗舰不是一个量级。有些在 RK3588 上能顺利转换的模型在 RV1106 上会因为某个算子不支持而转换失败或者被拆成 CPU 回退性能直接崩掉。这一点在选模型的时候就要有心理准备。2.3 待测模型清单与选型逻辑我这次选的模型覆盖了几个典型档位目的是把 RV1106 的能力边界摸清楚模型参数量输入尺寸选它的理由MobileNetV1约 4.2M224x224经典深度可分离卷积算子简单作为基线MobileNetV2约 3.4M224x224引入倒残差结构工业界最常用MobileNetV3-Small约 2.5M224x224带 SE 模块和 h-swish考验算子支持ShuffleNetV2 1.0x约 2.3M224x224通道混洗结构轻适合低算力ResNet18约 11.7M224x224作为偏重对照组看边界在哪SqueezeNet 1.1约 1.2M224x224极致轻量看最低能压到多少选这几个的逻辑是从算子最友好到算子最刁钻从最轻到偏重形成一个梯度。这样跑完一轮你就能大致判断自己手上的模型落在哪个区间能不能上 RV1106。3. 模型转换与量化实操全流程3.1 从训练框架导出 ONNX 的关键细节不管你的模型原本是 PyTorch 还是 TensorFlow 训的我建议统一先导出成 ONNX再喂给 RKNN-Toolkit2。原因是 ONNX 是中间格式里兼容性最好的而且 RKNN-Toolkit2 对 ONNX 的支持最成熟。导出 ONNX 的时候有几个坑必须避开。第一opset_version别设太高我一般用 11 或 12太高的 opset 里有些算子 RKNN-Toolkit2 还没跟上。第二导出时一定要model.eval()并且用torch.no_grad()否则 BN 层和 Dropout 的行为不对导出来的图会带训练态节点。第三输入输出的名字记清楚后面转换配置里要用。一个典型的导出代码大概是这样import torch model.eval() dummy_input torch.randn(1, 3, 224, 224) torch.onnx.export( model, dummy_input, mobilenetv2.onnx, opset_version12, input_names[input], output_names[output], do_constant_foldingTrue )导出完别急着转先用onnxsim做一次图简化把冗余的恒等节点、常量折叠掉。这一步能明显减少后面转换时的算子数量对 RV1106 这种算子支持有限的平台尤其重要。3.2 量化数据集准备与校准策略RV1106 的 NPU 主要跑 INT8 推理所以模型必须量化。量化分两种训练后量化PTQ和量化感知训练QAT。绝大多数情况下我们用 PTQ 就够了因为 QAT 要重新训练成本高。但 PTQ 的精度损失取决于你的校准数据集选得好不好。校准数据集怎么选这是很多人随便糊弄的地方。我的经验是从你的实际业务数据里抽 100 到 300 张图要覆盖所有类别、所有光照条件、所有可能出现的场景。别拿 ImageNet 的验证集随便抽几张就完事那样校准出来的量化参数跟你的真实分布对不上精度会掉得莫名其妙。校准数据的预处理要和推理时完全一致——同样的 resize 方式、同样的归一化参数。这里有个细节RKNN 的量化校准对输入的归一化方式敏感如果你训练时用的是 mean/std 归一化校准数据也要用同样的。我见过有人校准数据忘了归一化结果量化后精度掉了十几个点排查半天。3.3 RKNN 转换配置与量化参数详解转换的核心是一个配置脚本我把它拆开讲。首先是加载模型和配置量化from rknn.api import RKNN rknn RKNN(verboseTrue) # 配置量化参数 rknn.config( mean_values[[123.675, 116.28, 103.53]], std_values[[58.395, 57.12, 57.375]], target_platformrv1106, quantized_dtypeasymmetric_quantized-8, optimization_level3 )这里的mean_values和std_values要和你训练时的预处理对齐。注意 RKNN 的 mean/std 是在 0-255 像素值上做的如果你训练时用的是 0-1 归一化再减 mean要换算过来。target_platform一定要写rv1106写错了转换出来的模型在板子上加载会报错。optimization_level我一般开到 3让工具链尽可能做图优化。但要注意优化级别高有时候会触发一些激进的算子融合如果融合后精度掉了可以降到 2 试试。然后是加载 ONNX 和执行转换ret rknn.load_onnx(modelmobilenetv2.onnx) ret rknn.build(do_quantizationTrue, datasetcalibration_dataset.txt) ret rknn.export_rknn(mobilenetv2.rknn)calibration_dataset.txt里每行是一张校准图片的路径。build 的时候工具链会跑一遍这些图统计每层的激活值分布算出量化 scale。3.4 转换结果的精度验证转换完一定要在 PC 上先做一次精度对比别直接扔板子上。RKNN-Toolkit2 提供了仿真推理功能可以在 PC 上模拟 NPU 的量化推理结果ret rknn.init_runtime() outputs rknn.inference(inputs[test_image])把仿真结果和原始浮点模型的输出对比看 top-1 和 top-5 掉了多少。我的经验阈值是top-1 掉 1 个点以内算优秀掉 1 到 3 个点可以接受掉超过 5 个点就要回头查校准数据或者量化配置了。如果仿真阶段就掉得厉害那板子上只会更差没必要往下走。4. 板端部署与性能实测4.1 板端运行时环境与推理代码框架板子上的推理用的是 RKNN Runtime 的 C API。整个流程是加载 rknn 模型、初始化运行时、设置输入、跑推理、拿输出。核心代码结构大概是这样rknn_context ctx; int ret rknn_init(ctx, model_data, model_size, 0, NULL); rknn_input inputs[1]; inputs[0].index 0; inputs[0].type RKNN_TENSOR_UINT8; inputs[0].size 224 * 224 * 3; inputs[0].fmt RKNN_TENSOR_NHWC; inputs[0].buf input_data; rknn_inputs_set(ctx, 1, inputs); rknn_output outputs[1]; outputs[0].want_float 0; rknn_run(ctx, NULL); rknn_outputs_get(ctx, 1, outputs, NULL);这里有个关键点输入类型我设的是RKNN_TENSOR_UINT8也就是直接把 0-255 的原始像素喂进去让 NPU 内部去做归一化。这样比在 CPU 上先做浮点归一化再传进去要快得多也省内存。前提是你在转换配置里的 mean/std 设对了。4.2 各模型推理耗时与内存占用实测这是最核心的一组数据。我在 RV1106 上NPU 频率默认配置下单帧推理耗时不含前后处理实测如下模型推理耗时(ms)内存占用(MB)模型文件大小(KB)SqueezeNet 1.118约 12480ShuffleNetV2 1.0x22约 14920MobileNetV3-Small26约 161020MobileNetV231约 181380MobileNetV134约 191690ResNet18118约 454680这组数据有几个值得说的点。第一MobileNetV3-Small 虽然带了 SE 模块和 h-swish理论上算子更复杂但实测比 MobileNetV2 还快原因是它的整体计算量更小SE 模块带来的额外开销被总量下降抵消了。第二ResNet18 的耗时直接跳到 118ms内存占用也翻倍这就是我前面说的边界——它在 RV1106 上不是不能跑但 8fps 左右的帧率加上 45MB 的内存占用在 256MB 的板子上留给其他任务的空间就很紧张了。内存占用这块要特别提醒这里说的是模型推理本身占的 NPU 侧内存实际部署时你还要算上图像 buffer、前后处理、系统本身的开销。RV1106 如果只有 64MB DDR跑 ResNet18 基本不用想MobileNetV2 也要精打细算。4.3 量化精度损失对比分析精度这块我用 ImageNet 验证集的一个子集每类抽若干张做了对比结果如下模型浮点 Top-1量化后 Top-1精度损失MobileNetV170.6%69.8%-0.8%MobileNetV271.8%70.9%-0.9%MobileNetV3-Small67.4%65.9%-1.5%ShuffleNetV2 1.0x69.4%68.5%-0.9%ResNet1869.8%69.1%-0.7%SqueezeNet 1.158.2%56.4%-1.8%MobileNetV3-Small 和 SqueezeNet 的精度损失偏大原因不太一样。MobileNetV3-Small 是因为 h-swish 激活函数在量化时对数值范围比较敏感激活值分布不均匀导致量化误差偏大。SqueezeNet 则是因为它本身精度就低量化误差占比相对更明显。如果你对精度要求高MobileNetV3-Small 可以考虑用 QAT 来救或者换用 ReLU 版本的变体。4.4 前后处理对整体帧率的影响很多人只盯着 NPU 推理耗时忽略了前后处理。实际产品里图像采集、resize、颜色空间转换、结果后处理这些加起来有时候比推理本身还耗时。我实测了一下在 RV1106 的 A7 单核上把一张 1080P 的图 resize 到 224x224 并做 RGB 转换大概要 15 到 25ms这跟 MobileNetV2 的推理耗时是一个量级的。所以如果你的应用是实时视频流前后处理必须优化。几个思路一是用硬件加速的 resizeRV1106 的 VPU/ISP 部分能分担一些二是把 resize 和颜色转换合并成一步做三是如果摄像头本身能输出小分辨率直接让它输出 224x224 或者接近的尺寸省掉 resize。这些优化做下来整体帧率能提升不少。5. 踩坑记录与问题排查5.1 模型加载失败的常见原因板子上跑推理最常见的报错就是rknn_init返回失败。排查思路我整理成一张表现象可能原因排查方法init 返回 -1模型文件损坏或版本不匹配检查 toolkit 和 runtime 版本是否一致init 返回 -3内存不足用free看剩余内存换更小的模型推理结果全 0输入格式或归一化配置错误检查 mean/std 和输入 tensor 格式推理结果乱码量化校准数据有问题重新准备校准集检查预处理一致性加载慢或卡死模型文件放在慢速存储上把模型加载到内存后再 init版本不匹配这个问题我要单独强调。RKNN-Toolkit2 和板端 runtime 的版本对应关系官方文档里有表格但更新不及时。我的做法是转换前先strings一下板子上的 librknnrt.so看它内部标记的版本号然后装对应版本的 toolkit。宁可 toolkit 版本略低一点也别高。5.2 算子不支持与 CPU 回退问题RV1106 的 NPU 算子支持是有限的。转换的时候如果遇到不支持的算子工具链有两种处理方式一是直接报错二是把该算子回退到 CPU 执行。后者更隐蔽因为转换能成功但性能会莫名其妙地差。怎么发现 CPU 回退转换时开verboseTrue日志里会打印哪些层跑在 CPU 上。另外可以用 RKNN-Toolkit2 的性能分析功能看每层的耗时分布如果某一层耗时特别离谱大概率就是回退了。常见的回退算子包括一些特殊的激活函数、非常规的池化方式、动态 shape 的操作。解决办法一是换等价的、NPU 支持的算子实现二是改模型结构绕开三是接受回退但评估性能是否可接受。比如 h-swish有些版本的工具链支持有些不支持遇到不支持就换成 ReLU精度掉一点但性能稳。5.3 量化精度掉点的排查路径精度掉点是最烦的问题因为它不像加载失败那样有明确报错。我的排查路径是这样的第一步确认浮点模型本身在 PC 上的精度是正常的排除模型本身的问题。第二步用 RKNN 仿真推理对比量化前后的输出定位是量化引入的问题还是板端运行时的问题。第三步如果确认是量化问题先换校准数据集——增加数量、增加多样性、确保预处理一致。第四步如果换数据集没用检查是不是某些层对量化特别敏感可以尝试混合量化对敏感层保留浮点但 RV1106 对混合量化的支持有限不一定能用。第五步实在不行就上 QAT。这里分享一个我踩过的坑有一次 MobileNetV3-Small 量化后精度掉了 8 个点查了半天发现是校准数据集里有一批图的尺寸和训练时不一致被 resize 成了奇怪的比例导致校准统计出来的激活分布完全偏了。所以校准数据的质量比数量重要得多。5.4 内存不足与 OOM 的应对RV1106 内存紧张是常态。除了选小模型还有几个实用技巧。一是模型文件不要一直放在文件系统里占着 page cache加载完可以释放。二是输入输出 buffer 复用别每次推理都 malloc/free。三是如果系统里有其他大内存任务考虑错峰执行。四是可以调整 NPU 的内存分配策略RKNN 初始化时有相关参数可以控制。我实测过一个场景256MB 的板子上同时跑 MobileNetV2 推理加一个 RTSP 推流内存就快见底了。后来把推流的 buffer 调小、推理的输入 buffer 复用才稳住。所以内存规划一定要在选型阶段就做别等部署了才发现不够。6. 选型建议与工程落地心得6.1 不同场景下的模型选择建议把前面的数据综合起来我给几个典型场景的选型建议。如果是超低功耗、电池供电、对精度要求不高的场景比如简单的有无检测、粗分类SqueezeNet 或 ShuffleNetV2 是首选推理快、内存小。如果是通用分类、精度和速度要平衡的场景MobileNetV2 是最稳的选择生态成熟、算子友好、精度损失小。如果追求更低的计算量且能接受一点精度损失MobileNetV3-Small 值得一试但要做好量化调优的准备。ResNet18 及以上除非你的场景对精度有硬性要求且能接受低帧率否则不建议在 RV1106 上跑。还有一个维度是输入分辨率。我上面测的都是 224x224。如果你把输入降到 160x160 甚至 128x128推理耗时会明显下降但精度也会掉。这个权衡要根据你的实际任务来定。有些任务比如区分几个差异很大的类别用 128x128 就够了没必要上 224。6.2 从实验到产品的几个关键提醒实验跑通和产品落地之间还有一段距离我列几个容易忽略的点。第一实验用的模型和产品用的模型预处理必须完全一致包括 resize 的插值方式、归一化参数、颜色空间。我见过实验用 RGB、产品用 BGR结果精度对不上的。第二要考虑异常输入的处理比如全黑图、过曝图量化模型对这类输入的输出可能很离谱要有兜底逻辑。第三长时间运行的稳定性要测NPU 连续跑几个小时会不会有内存泄漏、会不会过热降频这些都要验证。第四模型更新要考虑 OTA 方案RV1106 的存储有限模型文件怎么安全地更新是个工程问题。6.3 性能进一步优化的方向如果你跑完发现性能还不够还有几个优化方向。一是模型剪枝把冗余的通道剪掉参数量和计算量都能降。二是知识蒸馏用大模型教小模型让小模型在同等规模下精度更高。三是输入分辨率的下调这个最直接。四是前后处理的硬件加速前面提过。五是 NPU 频率的调整如果功耗预算允许适当超频能换来帧率提升但要注意散热。这些优化里剪枝和蒸馏需要重新训练成本较高分辨率和前后处理优化是工程手段见效快。我个人在实际项目里的体会是RV1106 这颗芯片的定位非常清晰——它就是给那些需要一点智能、但功耗和成本卡得很死的场景准备的。你指望它跑大模型不现实但在 MobileNet 这一档上它的表现是超出预期的。关键是把模型选对、量化调好、前后处理优化到位这三件事做好了RV1106 能撑起很多实用的边缘视觉应用。最后再分享一个小技巧转换模型的时候把optimization_level和量化配置多试几组组合有时候同样的模型不同的配置组合性能能差 10% 以上值得花时间调。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑