ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

香橙派RK3588部署yolov5s前必查:NPU驱动与runtime版本匹配指南

香橙派RK3588部署yolov5s前必查:NPU驱动与runtime版本匹配指南 1. 为什么第三步才查NPU驱动这一步到底在确认什么很多人拿到香橙派RK3588之后第一反应是赶紧把yolov5s的模型转过去跑起来结果卡在推理这一步报错信息翻来覆去就是那几行要么是librknnrt.so找不到要么是版本不匹配要么是NPU压根没被识别。折腾半天才发现问题根本不在模型转换上而在于板子上的NPU驱动和runtime版本跟你手头那套RKNN Toolkit2对不上。这一步在整个部署链路里的位置很关键。你可以把它理解成装修房子之前先验房——你得先知道这面墙能不能承重、水管电路通不通再决定怎么设计。NPU驱动和runtime版本就是RK3588这块板子跑神经网络推理的“地基”。驱动是内核层面的东西负责让系统认识NPU这个硬件runtime是用户态的库负责让上层程序调用NPU算力。两者版本必须匹配而且还要跟你PC端用来转换模型的RKNN Toolkit2版本对得上否则就会出现模型转出来了但板子跑不了、或者跑起来结果不对的尴尬局面。我见过太多人在这上面栽跟头。有个朋友用RKNN Toolkit2 1.5.0转了个yolov5s的模型拷到板子上死活加载失败报RKNN model version mismatch他以为是模型转换参数写错了反复重转了好几遍最后才发现板子上的runtime是1.4.0的版本差了一个大版本API接口都变了。这种问题你不提前查清楚后面每一步都是白费功夫。所以这一节的核心任务很明确搞清楚你手上这块香橙派RK3588当前运行的NPU驱动版本是多少、runtime版本是多少、它们之间是否匹配、以及跟你PC端的工具链版本是否兼容。只有这三者对齐了后面的模型转换和部署才有意义。提示不要跳过这一步直接去跑demo。我实测下来版本不匹配导致的问题占所有部署失败的六成以上而且报错信息往往具有误导性会让你以为是模型本身的问题。2. 三种查版本的方法从系统层到应用层逐个摸清查NPU驱动和runtime版本有好几种途径不同途径看到的信息维度和准确度不一样。我一般会从系统层往应用层逐层确认这样能交叉验证避免单一来源的信息有误。2.1 通过dmesg看内核启动时的NPU初始化日志系统启动的时候NPU驱动会往内核日志里打一堆初始化信息这里面就包含了驱动版本号。操作很简单打开终端输入dmesg | grep -i rknpu你会看到类似这样的输出[ 3.456789] rknpu: RKNPU driver version: 0.9.6 [ 3.457012] rknpu: NPU clock: 1000000000 Hz [ 3.457234] rknpu: NPU power domain enabled这里的0.9.6就是NPU驱动的版本号。不同批次的香橙派RK3588出厂固件可能预装了不同版本的驱动有的早期固件是0.8.x新一点的可能是0.9.x。这个版本号决定了你的驱动支持哪些特性比如是否支持多核调度、是否支持INT8量化加速等。如果这条命令没有任何输出说明两种情况要么NPU驱动根本没加载要么内核日志被覆盖了。这时候你可以试试dmesg | grep -i npu把搜索范围放宽一点。如果还是没有那就得检查驱动模块是否被正确加载了。2.2 用cat查看sysfs节点获取驱动详细信息除了dmesg系统还在sysfs里暴露了NPU的一些信息节点。你可以直接读这些节点cat /sys/kernel/debug/rknpu/version有些固件版本里这个节点路径是cat /sys/kernel/debug/rknpu/driver_version输出通常就是一行版本号比如0.9.6。这个方法的优点是信息直接、干净不像dmesg那样混在一堆启动日志里。但缺点是debugfs默认可能没挂载你需要先确认mount | grep debugfs如果没有输出手动挂一下sudo mount -t debugfs none /sys/kernel/debug然后再去读版本节点。这个方法我比较推荐因为它反映的是当前内核里实际加载的驱动版本比dmesg更实时。2.3 通过librknnrt.so确认runtime版本驱动版本查完了接下来是runtime版本。runtime是以动态库的形式存在的通常在/usr/lib/或者/usr/lib/aarch64-linux-gnu/目录下文件名是librknnrt.so。你可以用strings命令从库文件里提取版本信息strings /usr/lib/librknnrt.so | grep -i version输出可能长这样librknnrt version: 1.5.0 (c3b0c8c2023-08-15)这里的1.5.0就是runtime的版本号。括号里那串是编译时的commit hash和日期对于排查问题也很有参考价值。如果/usr/lib/下找不到试试find / -name librknnrt.so 2/dev/null找到之后再用strings去读。有时候系统里可能存在多个版本的librknnrt.so比如你之前手动装过一个系统自带又有一个这时候就要确认你的程序实际链接的是哪一个。可以用ldd命令看ldd your_program | grep rknn这样能看到程序运行时实际加载的库路径。注意strings命令读出来的版本号是库文件编译时写入的跟你实际运行环境是否一致还要看库文件是否被正确链接。有些情况下你更新了库文件但程序链接的还是旧版本这时候ldd的结果才是最终答案。3. 驱动版本和runtime版本之间的对应关系查到了两个版本号之后接下来的问题是它们匹配吗这个问题比看起来要复杂一些因为驱动和runtime之间不是简单的版本号相等就行的。3.1 版本兼容性的基本规则RK3588的NPU软件栈大致是这样的分层结构最底层是内核态的NPU驱动中间是用户态的librknnrt.so运行时库最上层是PC端的RKNN Toolkit2工具链。这三者之间的版本兼容性遵循以下规则驱动版本和runtime版本之间有一个最低匹配要求。一般来说runtime版本不能低于驱动要求的最低版本也不能高于驱动支持的最高版本。比如驱动0.9.6可能要求runtime至少1.4.0最高支持到1.5.2。runtime版本和RKNN Toolkit2版本之间要求更严格通常需要大版本号一致。比如Toolkit2是1.5.x那runtime也应该是1.5.x否则模型文件格式可能不兼容。驱动版本相对独立一些只要在支持范围内小版本差异通常不影响功能。我整理了一个常见的版本对应关系表供参考驱动版本推荐runtime版本兼容Toolkit2版本备注0.8.21.3.01.3.0早期固件功能有限0.9.21.4.01.4.0支持多核调度0.9.61.5.01.5.0当前主流稳定组合0.9.81.5.21.5.2支持动态shape这张表是基于我实际用过的几块板子总结的不同批次的香橙派RK3588出厂固件可能略有差异以你实际查到的为准。3.2 版本不匹配时的典型症状版本不匹配导致的问题往往不会直接告诉你“版本不对”而是以各种奇怪的方式表现出来。我遇到过的情况包括模型加载时报RKNN_ERR_MODEL_INVALID看起来像是模型文件坏了实际上是runtime版本太低不认识新格式。推理结果全是一堆乱码或者全零模型能加载但算出来的东西完全不对这是驱动和runtime之间的内存布局约定不一致导致的。程序直接segfault连报错都没有这种情况通常是runtime调用了驱动不支持的ioctl命令。性能远低于预期比如yolov5s推理一帧要几百毫秒正常应该是几十毫秒这可能是驱动没正确启用NPU的加速特性。如果你遇到了上述任何一种情况先别急着怀疑模型或者代码回头把驱动和runtime版本对一遍大概率问题就在这里。3.3 怎么确认PC端工具链版本板子上的版本查完了还得确认你PC上装的RKNN Toolkit2是什么版本。在PC的Python环境里执行from rknn.api import RKNN rknn RKNN() print(rknn.version())输出会告诉你Toolkit2的版本号。这个版本号必须跟板子上的runtime版本大版本一致。比如板子上runtime是1.5.0你PC上Toolkit2也应该是1.5.x最好是1.5.0避免用1.5.2转的模型拿到1.5.0的runtime上跑。如果版本不一致解决办法有两个要么升级板子上的runtime要么降级PC上的Toolkit2。我一般倾向于让板子上的runtime保持跟PC工具链一致因为升级runtime相对简单而降级Toolkit2可能会影响你已有的工作流。4. 版本不匹配时的升级与降级操作确认了版本不匹配之后就得动手调整了。这一节说说具体怎么操作以及操作过程中容易踩的坑。4.1 升级板子上的runtime升级runtime本质上就是替换librknnrt.so这个文件。步骤不复杂但有几个细节要注意。首先从官方渠道获取对应版本的runtime库文件。通常是一个压缩包解压后里面有librknnrt.so和相关的头文件。然后备份现有的库sudo cp /usr/lib/librknnrt.so /usr/lib/librknnrt.so.bak接着把新版本的库拷过去sudo cp librknnrt.so /usr/lib/librknnrt.so sudo ldconfigldconfig这一步很关键它会刷新动态链接器的缓存让系统识别到新的库文件。不做这一步的话程序可能还是链接到旧的库。升级完之后用前面说的strings方法再查一遍版本确认替换成功了。然后跑一个简单的推理demo验证功能正常。提示替换librknnrt.so之前确保没有正在运行的NPU相关程序否则可能出现文件被占用导致替换失败的情况。可以用lsof | grep rknn检查一下。4.2 驱动版本的升级路径驱动升级比runtime麻烦一些因为驱动是内核模块通常需要重新编译内核或者使用官方提供的驱动更新包。香橙派的官方固件更新包里一般会包含驱动更新你可以通过烧录新固件的方式来升级驱动。如果你不想重烧固件也可以尝试单独编译NPU驱动模块。这个过程需要你有内核源码和对应的交叉编译工具链。大致步骤是# 进入内核源码目录 cd kernel/drivers/rknpu # 配置编译选项 make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- modules # 安装模块 sudo make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- modules_install编译完成后用insmod加载新的驱动模块或者重启系统让系统自动加载。加载后用dmesg确认新驱动版本已经生效。不过说实话除非你有特殊需求必须用某个特定版本的驱动否则我建议直接烧录官方最新的固件省时省力而且驱动和runtime的版本匹配是官方验证过的不容易出问题。4.3 降级Toolkit2的注意事项如果选择降级PC端的Toolkit2来匹配板子用pip操作就行pip install rknn-toolkit21.5.0但降级之前要注意几点一是确认你之前的模型转换脚本用的API在目标版本里也存在不同版本的API可能有增减二是降级后重新转换模型不要用之前版本转好的模型文件因为格式可能不兼容三是如果同时装了多个版本注意Python环境的隔离建议用virtualenv或者conda创建一个干净的环境。我个人的习惯是每块板子配一个独立的Python虚拟环境环境里锁定Toolkit2的版本这样不同板子之间不会互相干扰。5. 验证版本匹配的实操检查清单光查到版本号还不够得实际验证一下这套组合能不能正常工作。我一般会走一遍下面这个检查清单确认整个链路是通的。5.1 用官方demo做最小验证香橙派官方或者RKNN官方仓库里通常会提供一些预编译的demo比如简单的图像分类或者目标检测示例。找一个跟yolov5s规模差不多的demo直接在板子上跑./rknn_yolov5_demo model.rknn test.jpg如果demo能正常跑出结果说明驱动和runtime的基本功能是正常的。如果demo都跑不起来那说明版本问题还没解决先别急着上自己的模型。跑demo的时候注意观察输出日志看看有没有warning信息。有些warning虽然不影响运行但可能暗示着潜在的兼容性问题比如“fallback to CPU”这种说明NPU没被真正用起来。5.2 检查NPU利用率确认硬件在工作demo跑起来之后确认一下NPU是不是真的在干活。可以通过sysfs节点查看NPU的负载cat /sys/kernel/debug/rknpu/load输出会显示各个NPU核心的利用率。如果跑推理的时候这个值明显上升说明NPU确实在工作。如果一直是0那可能推理跑在CPU上了性能会差很多。这个检查很有必要因为有些版本组合下runtime会静默地回退到CPU推理不报错但性能极差。你不主动查的话可能一直以为自己在用NPU。5.3 记录版本信息备查验证通过之后把你板子上的驱动版本、runtime版本、PC端Toolkit2版本记录下来最好写在一个文档里。后面如果遇到问题这些信息能帮你快速定位。我一般会在板子上建一个version_info.txt内容大概这样NPU Driver: 0.9.6 Runtime: 1.5.0 Toolkit2: 1.5.0 Firmware: OrangePi 5 RK3588 v1.2 Date: 2024-01-15这样下次再折腾的时候直接看这个文件就知道当前环境是什么状态不用重新查一遍。6. 几个容易搞混的版本概念在查版本的过程中有几个概念容易混淆我单独拎出来说一下。6.1 驱动版本和固件版本不是一回事香橙派的固件版本比如v1.2、v1.3是整包的系统镜像版本里面包含了内核、驱动、runtime、各种库和工具。固件版本更新了里面的驱动和runtime版本可能也跟着变但两者不是一一对应的。同一个固件版本可能因为编译时间不同而包含不同版本的驱动。所以查版本的时候要以实际查到的驱动和runtime版本为准不能只看固件版本号。6.2 rknn_server和librknnrt.so的关系有些教程里会提到rknn_server这个东西它是运行在板子上的一个服务进程用于配合PC端的联机调试。rknn_server本身也依赖librknnrt.so所以它的版本兼容性跟runtime是一致的。如果你用联机调试模式除了确认librknnrt.so版本还要确认rknn_server的版本是否匹配。不过对于yolov5s这种直接部署的场景通常用不到联机调试可以忽略rknn_server。6.3 Python包版本和C库版本的区别PC端的RKNN Toolkit2是一个Python包板子上的librknnrt.so是一个C库。两者版本号看起来可能一样比如都是1.5.0但它们是独立发布的更新节奏不一定同步。有时候Toolkit2更新了但板子上的runtime还没跟上或者反过来。所以查版本的时候要分别确认不能因为PC上Toolkit2是1.5.0就想当然认为板子上runtime也是1.5.0。7. 我在这上面踩过的坑和总结的经验说几个我实际踩过的坑都是查版本这一步没做到位导致的。有一次我拿到一块二手香橙派RK3588卖家说已经刷好了最新固件。我直接开始转模型部署结果yolov5s推理速度只有10帧不到远低于预期。查了半天代码和模型参数最后才发现板子上的runtime是1.4.0的而我的Toolkit2是1.5.0模型虽然能加载但跑的是兼容模式性能打了对折。升级runtime到1.5.0之后帧率直接翻倍。还有一次更隐蔽驱动版本和runtime版本都匹配但推理结果就是不对框的位置全是偏的。折腾了一整天最后发现是驱动的一个小版本差异导致的内存对齐问题。换了一个驱动版本就好了。这种问题你光看版本号是看不出来的只能通过实际跑demo来验证。我的经验是查版本这一步不能省而且不能只看一个地方。dmesg、sysfs、strings三个途径交叉验证确认信息一致。然后一定要跑官方demo做实际验证不要觉得版本号对上了就万事大吉。版本号只是必要条件不是充分条件。另外建议在开始任何模型转换之前就把版本信息确认好不要等到模型转完了、拷到板子上了才发现版本不对。那时候你面临的选择就很尴尬要么重新转模型要么升级板子环境两条路都要花时间。提前花十分钟查版本能省掉后面几个小时的折腾。最后说一个实用技巧如果你不确定该用哪个版本的组合去香橙派的官方论坛或者RKNN的GitHub仓库看看最近别人成功部署yolov5s的帖子看看他们用的什么版本组合。跟着大多数人的选择走踩坑的概率会小很多。毕竟这些版本组合是别人实际验证过的比你自己摸索要靠谱。
返回列表