RKNN Model Zoo Example Deployment
1. rknn_model_zoo Example Workflow
rknn_model_zoo is an official repository provided by Rockchip, containing deployment examples of various mainstream AI algorithms supported by the RKNPU. The latest examples include deployments for models such as MobileNet and YOLO. In this chapter, YOLOv10 is used as an example to demonstrate how to use the rknn_model_zoo. This workflow demonstrates the complete process from ONNX model conversion to inference on the development board, covering key steps such as model conversion, deployment, and execution.
On the device side, two inference approaches are available:
- High-performance inference using a C program
- Rapid development and validation using Python (RKNN-Toolkit-Lite2)
2. Convert ONNX Model to RKNN in RKNN-Toolkit2 Environment
-
Download rknn_model_zoo.
git clone https://github.com/airockchip/rknn_model_zoo.git -
Download the YOLOv10 ONNX model.
cd <rknn_model_zoo Path>/rknn_model_zoo/examples/yolov10/modelchmod a+x download_model.sh./download_model.sh -
Convert the model to RKNN format. Run the conversion script convert.py located in the rknn_model_zoo/examples/yolov10/python directory.
conda activate RKNN-Toolkit2cd <rknn_model_zoo Path>/rknn_model_zoo/examples/yolov10/pythonpython3 convert.py ../model/yolov10n.onnx rv1126b# output model will be saved as ../model/yolov10.rknnpython3 convert.py <onnx_model> <TARGET_PLATFORM> <dtype(optional)> <output_rknn_path(optional)>Parameter Description:
<onnx_model>: Path to the ONNX model<TARGET_PLATFORM>: Target NPU platform (e.g., rv1126b)<quant_dtype>: Optional. Can be set to i8 or fp- i8: Enable quantization (default)
- fp: Disable quantization
<output_rknn_path>: Optional. Specifies the output path of the RKNN model. By default, the model is saved in the same directory as the ONNX model with the name yolov10n.rknn.
3. Model Inference (C)
3.1 Cross-compiling the C Inference Demo on x86_64 Linux
-
After successfully converting the ONNX model to an RKNN model, the next step is to cross-compile the demo located in the rknn_model_zoo/examples/yolov10 directory. Before building, set the following environment variable:
export GCC_COMPILER=/home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu -
Run the build-linux.sh script in the rknn_model_zoo directory. This script will compile the demo:
chmod +x ./build-linux.sh./build-linux.sh -t rv1126b -a aarch64 -d yolov10- Build process:
(RKNN-Toolkit2) luckfox@xt:~/conda/rknn_model_zoo$ ./build-linux.sh -t rv1126b -a aarch64 -d yolov10./build-linux.sh -t rv1126b -a aarch64 -d yolov10/home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu===================================BUILD_DEMO_NAME=yolov10BUILD_DEMO_PATH=examples/yolov10/cppTARGET_SOC=rv1126bTARGET_ARCH=aarch64BUILD_TYPE=ReleaseENABLE_ASAN=OFFDISABLE_RGA=OFFDISABLE_LIBJPEG=OFFINSTALL_DIR=/home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demoBUILD_DIR=/home/luckfox/conda/rknn_model_zoo/build/build_rknn_yolov10_demo_rv1126b_linux_aarch64_ReleaseCC=/home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu-gccCXX=/home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu-g++===================================-- The C compiler identification is GNU 12.4.0-- The CXX compiler identification is GNU 12.4.0-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Check for working C compiler: /home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu-gcc - skipped-- Detecting C compile features-- Detecting C compile features - done-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Check for working CXX compiler: /home/luckfox/Luckfox/rv1126b/sdk-251224/tools/linux/toolchain/aarch64-rockchip1240-linux-gnu/bin/aarch64-rockchip1240-linux-gnu-g++ - skipped-- Detecting CXX compile features-- Detecting CXX compile features - done-- !!!!!!!!!!!CMAKE_SYSTEM_NAME: Linux-- Looking for pthread.h-- Looking for pthread.h - found-- Performing Test CMAKE_HAVE_LIBC_PTHREAD-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success-- Found Threads: TRUE-- Configuring done-- Generating done-- Build files have been written to: /home/luckfox/conda/rknn_model_zoo/build/build_rknn_yolov10_demo_rv1126b_linux_aarch64_Release[ 16%] Building C object utils.out/CMakeFiles/imageutils.dir/image_utils.c.o[ 16%] Building C object utils.out/CMakeFiles/imagedrawing.dir/image_drawing.c.o[ 25%] Building C object utils.out/CMakeFiles/audioutils.dir/audio_utils.c.o[ 33%] Building C object utils.out/CMakeFiles/fileutils.dir/file_utils.c.o[ 41%] Linking C static library libfileutils.a.........[100%] Linking CXX executable rknn_yolov10_demo[100%] Built target rknn_yolov10_demoConsolidate compiler generated dependencies of target imagedrawing[ 16%] Built target imagedrawingConsolidate compiler generated dependencies of target imageutils[ 33%] Built target imageutilsConsolidate compiler generated dependencies of target fileutils[ 50%] Built target fileutilsConsolidate compiler generated dependencies of target rknn_yolov10_demo[ 83%] Built target rknn_yolov10_demoConsolidate compiler generated dependencies of target audioutils[100%] Built target audioutilsInstall the project...-- Install configuration: "Release"-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/./rknn_yolov10_demo-- Set runtime path of "/home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/./rknn_yolov10_demo" to "$ORIGIN/../lib"-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/model/bus.jpg-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/model/coco_80_labels_list.txt-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/model/yolov10.rknn-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/lib/librknnrt.so-- Installing: /home/luckfox/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo/lib/librga.so
- Build process:
-
After cross-compilation is completed, an install directory will be generated under the rknn_model_zoo path. This directory contains the compiled binaries and required library files.
(RKNN-Toolkit2) ubuntu@ubuntu:~/conda/rknn_model_zoo/install/rv1126b_linux_aarch64/rknn_yolov10_demo$ lslib model rknn_yolov10_demo
3.2 Deploy the install directory to the Luckfox Aura board for inference
-
Transfer the entire rknn_yolov10_demo directory to the development board, then run the following command:
scp -r rv1126b_linux_aarch64/rknn_yolov10_demo/ luckfox@192.168.253.105:/home/aura./rknn_yolov10_demo ./model/yolov10.rknn ./model/bus.jpg -
After inference is completed, an output image out.png will be generated.
(base) root@aura:/home/aura/rv1126b_linux_aarch64/rknn_yolov10_demo# ./rknn_yolov10_demo ./model/yolov10.rknn ./model/bus.jpgload lable ./model/coco_80_labels_list.txtmodel input num: 1, output num: 6input tensors:index=0, name=images, n_dims=4, dims=[1, 640, 640, 3], n_elems=1228800, size=1228800, fmt=NHWC, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003922output tensors:index=0, name=470, n_dims=4, dims=[1, 64, 80, 80], n_elems=409600, size=409600, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-38, scale=0.114574index=1, name=484, n_dims=4, dims=[1, 80, 80, 80], n_elems=512000, size=512000, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.002001index=2, name=491, n_dims=4, dims=[1, 64, 40, 40], n_elems=102400, size=102400, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-57, scale=0.095044index=3, name=505, n_dims=4, dims=[1, 80, 40, 40], n_elems=128000, size=128000, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003505index=4, name=512, n_dims=4, dims=[1, 64, 20, 20], n_elems=25600, size=25600, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-58, scale=0.061253index=5, name=526, n_dims=4, dims=[1, 80, 20, 20], n_elems=32000, size=32000, fmt=NCHW, type=INT8, qnt_type=AFFINE, zp=-128, scale=0.003792model is NHWC input fmtmodel input height=640, width=640, channel=3origin size=640x640 crop size=640x640input image: 640 x 640, subsampling: 4:2:0, colorspace: YCbCr, orientation: 1scale=1.000000 dst_box=(0 0 639 639) allow_slight_change=1 _left_offset=0 _top_offset=0 padding_w=0 padding_h=0rga_api version 1.10.1_[0]184 im2d_rga_impl rga_get_info(718): Can not get the correct RGA version, please check the driver, version=4.1.34669184 im2d_rga_impl rga_check(1280): rga im2d: rga2 get info failed!Error on improcess STATUS=0RGA error message: Fatal error: rga im2d: rga2 get info failed!try convert image use cpufinishrknn_runbus @ (88 137 556 437) 0.937person @ (109 234 226 536) 0.906person @ (210 240 284 511) 0.899person @ (478 233 560 519) 0.800person @ (79 331 114 518) 0.351write_image path: out.png width=640 height=640 channel=3 data=0x7f864a7010(base) root@aura:/home/aura/rv1126b_linux_aarch64/rknn_yolov10_demo# lslib model out.png rknn_yolov10_demo- Inference Result:


- Inference Result:
4. Model Inference (Python)
- Copy the rknn_model_zoo/examples/yolov10 directory to the development board. Then navigate to the model directory and implement a Python inference script based on RKNN-Toolkit-Lite2.
import numpy as npimport cv2from rknnlite.api import RKNNLiteMODEL_PATH = 'yolov10.rknn'IMG_PATH = 'bus.jpg'IMG_SIZE = 640OBJ_THRESH = 0.65NMS_THRESH = 0.35CLASSES = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light','fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow','elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee','skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard','tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple','sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch','potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone','microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear','hair drier', 'toothbrush']def sigmoid(x):return 1 / (1 + np.exp(-np.clip(x, -20, 20)))def softmax(x, axis=1):x_exp = np.exp(x - np.max(x, axis=axis, keepdims=True))return x_exp / np.sum(x_exp, axis=axis, keepdims=True)def main():rknn = RKNNLite()print(f"load rknn model: {MODEL_PATH}")if rknn.load_rknn(MODEL_PATH) != 0:print("load rknn failed!"); returnif rknn.init_runtime() != 0:print("init runtime failed!"); returntry:input_attrs = rknn.get_sdk_get_inputs_attrs()output_attrs = rknn.get_sdk_get_outputs_attrs()print(f"model input num: {len(input_attrs)}, output num: {len(output_attrs)}")print("input tensors:")for i, a in enumerate(input_attrs):print(f" index={i}, name={a['name']}, dims={a['dims']}, zp={a['zp']}, scale={a['scale']:.6f}")print("output tensors:")for i, a in enumerate(output_attrs):print(f" index={i}, name={a['name']}, dims={a['dims']}, zp={a['zp']}, scale={a['scale']:.6f}")except:passimg_src = cv2.imread(IMG_PATH)h_ori, w_ori = img_src.shape[:2]print(f"input image: {w_ori} x {h_ori}")img = cv2.resize(img_src, (IMG_SIZE, IMG_SIZE))img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)print("rknn_run")outputs = rknn.inference(inputs=[np.expand_dims(img, 0)])reg_layers = [o for o in outputs if o.shape[1] == 64]cls_layers = [o for o in outputs if o.shape[1] == 80]reg_layers.sort(key=lambda x: x.shape[2], reverse=True)cls_layers.sort(key=lambda x: x.shape[2], reverse=True)strides = [8, 16, 32]boxes_all, scores_all, ids_all = [], [], []for i in range(len(reg_layers)):reg = reg_layers[i].astype(np.float32)cls = cls_layers[i].astype(np.float32)stride = strides[i]scores = sigmoid(cls)b, c, h, w = reg.shapereg_dist = reg.reshape(1, 4, 16, h, w)reg_dist = softmax(reg_dist, axis=2)dist = (reg_dist * np.arange(16).reshape(1, 1, 16, 1, 1)).sum(2)grid_y, grid_x = np.indices((h, w))grid = np.stack([grid_x, grid_y], axis=0).astype(np.float32)x1 = (grid[0:1] + 0.5 - dist[:, 0:1]) * stridey1 = (grid[1:2] + 0.5 - dist[:, 1:2]) * stridex2 = (grid[0:1] + 0.5 + dist[:, 2:3]) * stridey2 = (grid[1:2] + 0.5 + dist[:, 3:4]) * stridebox = np.concatenate([x1, y1, x2, y2], axis=1).transpose(0, 2, 3, 1).reshape(-1, 4)prob = scores.transpose(0, 2, 3, 1).reshape(-1, 80)max_s = np.max(prob, axis=1)max_id = np.argmax(prob, axis=1)mask = max_s > OBJ_THRESHfor idx in np.where(max_id == 10)[0]:if max_s[idx] < 0.8:mask[idx] = Falsekeep = np.where(mask)if len(keep[0]) > 0:boxes_all.append(box[keep])scores_all.append(max_s[keep])ids_all.append(max_id[keep])if boxes_all:boxes_all = np.concatenate(boxes_all)scores_all = np.concatenate(scores_all)ids_all = np.concatenate(ids_all)indices = cv2.dnn.NMSBoxes(boxes_all.tolist(), scores_all.tolist(), OBJ_THRESH, NMS_THRESH)sw, sh = w_ori / IMG_SIZE, h_ori / IMG_SIZEif len(indices) > 0:for i in indices.flatten():b = boxes_all[i]x1, y1 = int(b[0]*sw), int(b[1]*sh)x2, y2 = int(b[2]*sw), int(b[3]*sh)cls_id = int(ids_all[i])label = CLASSES[cls_id] if cls_id < len(CLASSES) else f"ID:{cls_id}"conf = scores_all[i]print(f"{label} @ ({x1} {y1} {x2} {y2}) {conf:.3f}")cv2.rectangle(img_src, (x1, y1), (x2, y2), (0, 255, 0), 2)text = f"{label} {conf:.2f}"t_size = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)[0]cv2.rectangle(img_src, (x1, y1 - t_size[1] - 5), (x1 + t_size[0], y1), (0, 255, 0), -1)cv2.putText(img_src, text, (x1, y1 - 5),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, lineType=cv2.LINE_AA)cv2.imwrite("out.png", img_src)print(f"write_image path: out.png width={w_ori} height={h_ori}")rknn.release()if __name__ == '__main__':main()
- Ensure that the RKNN-Toolkit-Lite2 runtime environment is properly configured on the board, and execute the following command to run the program:
conda activate rknn-toolkit-lite2python test.py(rknn-toolkit-lite2) root@aura:/home/aura/test/yolov10/model# python test.pyload rknn model: yolov10.rknnI RKNN: [10:33:58.012] RKNN Runtime Information, librknnrt version: 2.3.2 (429f97ae6b@2025-04-09T09:09:27)I RKNN: [10:33:58.012] RKNN Driver Information, version: 0.9.8I RKNN: [10:33:58.014] RKNN Model Information, version: 6, toolkit version: 2.3.2(compiler version: 2.3.2 (e045de294f@2025-04-07T19:48:25)), target: RKNPU f3, target platform: rv1126b, framework name: ONNX, framework layout: NCHW, model inference type: static_shapeW RKNN: [10:33:58.040] query RKNN_QUERY_INPUT_DYNAMIC_RANGE error, rknn model is static shape type, please export rknn with dynamic_shapesW Query dynamic range failed. Ret code: RKNN_ERR_MODEL_INVALID. (If it is a static shape RKNN model, please ignore the above warning message.)input image: 640 x 640rknn_runbus @ (88 137 556 437) 0.718person @ (109 234 226 536) 0.712person @ (210 240 284 511) 0.711person @ (478 233 560 519) 0.690write_image path: out.png width=640 height=640
- Inference Result:

- Inference Result:
5. Summary
Python (RKNN-Toolkit-Lite2) Solution: Suitable for rapid validation and functional debugging. It offers high development efficiency and can be easily integrated with tools such as OpenCV to build the inference pipeline. However, it depends on the Python runtime environment, and preprocessing is mainly performed on the CPU, resulting in relatively limited overall performance and real-time capability.
C/C++ (Native API) Solution: More suitable for production deployment and high-performance scenarios. By directly invoking low-level RKNN APIs and leveraging hardware acceleration (such as RGA), it enables efficient inference and preprocessing with lower resource usage and better real-time performance. However, development and debugging are more complex, making it better suited for final product deployment.