 RKNN 量化实战:YOLO 转化到RKNN)
RK3588学习日记(二) RKNN 量化实战YOLO 转化到RKNN从 Ubuntu 22.04 环境搭建开始把 YOLOv8s-P2 裂缝检测模型一步步转换为 RK3588 NPU 可加载的.rknn并对比 INT8、FP16、混合精度三种方案。示例输入为 1024×1024每一步都标明「改哪里」和「看到什么算成功」便于逐项复现和排查。先看完整流程7 步第 0 步 装转换环境PC 端 Linux一次性 第 1 步 准备模型和校准集 第 2 步 导出 ONNX 第 3 步 转 INT8 模型 第 4 步 转 FP16 模型 第 5 步 三方对比验证 第 6 步 板端加载验证第 0~5 步在 PC 的 Linux 机器上完成使用 rknn-toolkit2第 6 步转到 RK3588 板端做加载验证。下面按顺序操作。第 0 步装转换环境转换在 PC 上做需要一台 Linux本文 Ubuntu 22.04 Python 3.10。装一次后面反复用。0.1 准备 Python 3.10sudoaptupdatesudoaptinstall-ypython3.10 python3.10-venv python3-pip python3--version# 期望输出Python 3.10.x建议建一个虚拟环境避免污染系统python3-mvenv ~/rknn_envsource~/rknn_env/bin/activate坑Python 版本必须和后面的 whl 包cp标签一致cp310 只能装 Python 3.10。本文按 3.10 写。0.2 下载 rknn-toolkit2 2.3.2从官方 GitHub 仓库拿clone 或下载源码包https://github.com/airockchip/rknn-toolkit2下载后packages/x86_64/目录下有两个文件要用rknn_toolkit2-2.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl ← 本体 requirements_cp310-2.3.2.txt ← 依赖清单0.3 装依赖pipinstall-rrknn-toolkit2/packages/x86_64/requirements_cp310-2.3.2.txt如果慢加清华镜像-i https://pypi.tuna.tsinghua.edu.cn/simple/两个必须注意的版本上限装错会报错或 import 失败numpy1.26.4不能装 numpy 2.xtorch2.4.0不能装 torch 2.5。0.4 装 ultralytics导出 ONNX 用pipinstallultralytics8.2.820.5 装 rknn-toolkit2 本体pipinstall./rknn_toolkit2-2.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl看到Successfully installed rknn-toolkit2-2.3.2就成功。0.6 验证装好了python3-cfrom rknn.api import RKNN; print(OK)期望输出I rknn-toolkit2 version: 2.3.2 OK看到版本号和OK环境就绪。第 1 步准备模型和校准集1.1 模型文件拿到训练好的.pt本文是mix20.ptYOLOv8s-P2检测裂缝类别 nc1输入 1024×1024。1.2 校准集INT8 量化需要FP16 不需要校准集是一堆有代表性的图片量化时用它统计每层的数值范围。准备步骤收集图片本文 400 张真实场景裂缝图放一个目录比如calib_images/建一个清单文件calibration.txt每行一张图的绝对路径/home/you/calib_images/0000.jpg /home/you/calib_images/0001.jpg /home/you/calib_images/0002.jpg ...坑清单里必须是当前机器真实存在的路径。如果清单是从别的机器拷来的路径会不对转换时直接报「找不到图片」。校准集要覆盖真实场景不同亮度、距离、目标大小。只用 1 张图也能跑通但量化精度会差。第 2 步导出 ONNXYOLO → ONNXrknn-toolkit2 不吃.pt先导成 ONNX。改哪里写一个export_onnx.py只有一处要改fromultralyticsimportYOLO mYOLO(mix20.pt)# ← 改成你的 .pt 路径m.export(formatrknn,imgsz1024,opset12,dynamicFalse,simplifyTrue,nmsFalse,halfFalse)运行python3 export_onnx.py看到什么算成功export success ... saved as .../mix20.onnx并生成mix20.onnx约 40.6 MB。为什么是formatrknn而不是formatonnxYOLOv8 检测头用了 DFL框的坐标是回归一个概率分布靠后处理解码formatonnx会把 DFL 在图内提前解码破坏检测头导出后报 REGTASK 错误formatrknn保留未解码的 DFL 输出交给 RKNN 后处理正确。这是新手最容易踩的坑检测模型导出 ONNX 一定要用formatrknn。第 3 步转换 INT8 RKNN 模型改哪里写convert_rknn.py有三处要改ONNX 路径、校准集路径、输出名fromrknn.apiimportRKNN rknnRKNN()rknn.config(mean_values[[0,0,0]],# 归一化减 0std_values[[255,255,255]],# 除以 255即 0~255 → 0~1target_platformrk3588,)rknn.load_onnx(modelmix20.onnx)# ← 改成你的 ONNX 路径rknn.build(do_quantizationTrue,datasetcalibration.txt)# ← 改成你的校准集清单路径rknn.export_rknn(mix20_int8.rknn)# ← 改成你要的输出名rknn.release()归一化mean/std是什么、怎么定模型训练时输入是归一化过的。转换时要用config告诉 rknn「训练时怎么归一化的」它会把归一化做进模型这样板端直接喂原始像素即可。公式是(input - mean) / std。本文mean0, std255即(x - 0) / 255 x / 255把 0~255 的像素变成 0~1。这是 YOLOv8 最常见的配置。坑归一化配错了不报错而是结果全乱框满天飞 / 什么都检不到。所以第 5 步一定要做三方对比验证。运行python3 convert_rknn.py看到什么算成功Quantizating 40/40: 100%|...| 194/194 ← 量化进度条走完 I rknn building done. OK: .../mix20_int8.rknn并生成mix20_int8.rknn约 12.8 MB。INT8 构建时间有时候会很长耐心等。一个关键 warning构建时会出现The default input dtype of images is changed from float32 to int8意思是输入从 float32 变成了 int8。这是正常的意味着板端部署时输入用 uint8 原始像素不要传 float。第 4 步转换 FP16 RKNN 模型同一个脚本只改build一行去掉量化rknn.build(do_quantizationFalse)# ← 不量化权重保持 FP16python3 convert_rknn.py看到什么算成功OK: .../mix20_fp16.rknn并生成mix20_fp16.rknn约 24.6 MB。FP16 构建快。FP16 模型比 INT8 大约 2 倍但精度最接近训练原模型是 INT8 的「精度上限对照」。第 5 步PT / ONNX / RKNN 三方对比验证转换完不要急着上板先在同一张图上对比 PT / ONNX / RKNN 三个模型确认转换没丢东西。比什么三个维度检测数量框数对不对置信度分数差多少框位置坐标偏多少。实测结果本文模型5 张验证图conf0.25NMS0.45PT 与 ONNX 完全一致数值差 9.7e-05 级→ 导出环节没丢东西RKNN INT8 框位置几乎一致≤3px但 5 图里 1 张少检 1 框 → 量化损失。30 张图 INT8 vs FP1628 张一致IoU0.8、置信度差0.082 张 INT8 漏检小目标临界框→ PTQ 固有损失。结果怎么定位问题PT 与 ONNX 不一致 → 导出问题查formatONNX 与 RKNN 不一致 → 转换/量化问题查归一化、布局、输出解析。第 6 步在 RK3588 板端加载 RKNN把.rknn拷到 RK3588用 rknnlite 加载确认能跑fromrknnlite.apiimportRKNNLite rknnRKNNLite()retrknn.load_rknn(mix20_int8.rknn)# ← 你的 .rknn 路径assertret0retrknn.init_runtime(core_maskRKNNLite.NPU_CORE_AUTO)assertret0看到什么算成功两个ret都是 0且日志里有模型信息。两个要看的警告版本不匹配本文真实出现W RKNN: RKNN Model version: 2.3.2 not match with rknn runtime version: 2.1.0模型是 toolkit 2.3.2 编译的板端 runtime 是 2.1.0。能跑但有警告建议升级板端 runtime 到 2.3.x。转换和部署的版本要尽量对齐。输入布局决定下一篇怎么喂数据framework layout: NCHWNCHW[Batch, Channel, Height, Width]通道优先NHWC[Batch, Height, Width, Channel]通道最后。模型要求哪种板端推理输入就得准备成哪种。配错不报错而是结果全乱。本文模型是 NCHW下一篇板端推理就按 NCHW 准备输入。INT8、FP16、混合精度怎么选方式NPU cycles结论PT训练基线—精度上限INT8少 31%推荐FP16—精度最接近 PT模型大 2 倍混合精度85 层 FP16多 31%比INT8 精度高但更慢给新手的建议先 INT8精度不够再考虑混合精度。混合精度的具体操作怎么改 85 层在下一篇单独讲。常见问题现象原因解决whl 装不上报not a supported wheelPython 版本和 cp 标签不匹配用对应 Python 版本如 cp310 配 Python 3.10import 报 numpy 相关错误numpy 装成了 2.xpip install numpy1.26.4formatonnx导出报 REGTASKDFL 被图内解码改用formatrknn转换报「找不到校准图」calibration.txt 里是旧路径改成当前机器真实路径结果全乱但不报错归一化或 NCHW/NHWC 配错先查归一化再查framework layout板端加载报版本不匹配模型 toolkit 版本 runtime升级 runtime或接受警告下一篇下一篇讲混合精度量化实战当 INT8 精度不够时怎么用hybrid_quantization_step1/step2手动把敏感层改成 float16——一步步操作含quantization.cfg怎么看、85 层怎么改。