
前几篇跑的都是现成模型:Qwen3、MobileNet、Model Zoo 里下载就有。但做自己的应用,迟早会遇到"我的模型怎么上板"------这篇讲模型转换:把 PyTorch / ONNX 模型转成 RK1828 能跑的 RKNN 格式。
先看 wiki 给的全景:
PC (x86_64 Ubuntu) 板端 (aarch64)
────────────────── ─────────────
PyTorch / ONNX / HuggingFace rknn3-toolkit-lite
│ │
▼ │
rknn-toolkit3 (pip) │
rknn.config + rknn.build + rknn.export_rknn
│ │
▼ ▼
.rknn + .weight + .tokenizer.gguf + .embed.bin
│ │
▼ ▼
scp ─────────────────────────────────────► rknn3-toolkit-lite.load_rknn()
rkllm3-server / rknn3_cnn_demo
本章完整文档:《模型转换》
(一)、工具链铁律:PC 转、板端跑
第一件事分清两套工具,装错了报错都不知道哪来的:

说明:板端只能推理,不能转换,转换必须在 PC 上完成;Python 版本只支持 3.10 和 3.12,不支持 3.11------当前板端系统 Python 是 3.11.2,需要额外装 3.10 / 3.12 才能跑 toolkit。
(二)、省事路径:官方预转换模型
能不转就不转。RKNN3 Model Zoo 提供官方预转换模型,SDK 里已经带了一批:
ls /userdata/RK1820_RK1828_AI_SDK/rknn/rknn3-model-zoo/examples/
输出:
FastVLM glm_edge GME-Qwen2-VL HY_MT_1_5
InternVLM Janus_Pro MiniCPM_V_4 mobilenet_v1
mobilenet_v2 Qwen2_5 Qwen2_5_Omni Qwen2_5_VL
Qwen3 Qwen3_Embedding Qwen3_VL resnet
SmolVLM yolov5 yolov6 yolov8
GitHub 仓库可以拉最新的:
git clone https://github.com/airockchip/rknn3-model-zoo.git
转好的模型传上板:
scp -r model/ root@<设备IP>:/userdata/models/Qwen3-1.7B/
部署完确认一下,Qwen3-1.7B 的四件套(wiki 实测):
ls -lh /userdata/models/Qwen3-1.7B/
输出:
总计 1.7G
-rw-r--r-- 1 linaro linaro 594M 8月20日 11:33 Qwen3-1.7B.embed.bin
-rw-r--r-- 1 linaro linaro 24M 8月20日 11:34 Qwen3-1.7B.rknn
-rw-r--r-- 1 linaro linaro 5.9M 8月20日 11:33 Qwen3-1.7B.tokenizer.gguf
-rw-r--r-- 1 linaro linaro 1.1G 8月20日 11:33 Qwen3-1.7B.weight
(三)、自行转换 LLM:以 Qwen3-1.7B 为例
3.1 前置条件
PC 一台(GRQ 量化需 NVIDIA GPU,显存 ≥ 16GB);
Python 3.10 或 3.12;

PC 上装好完整转换包:
pip install rknn-toolkit3
python -c "from rknn.api import RKNN; print('RKNN Toolkit installed')"
输出:
RKNN Toolkit installed
3.2 方式 A:Model Zoo 转换脚本(推荐)
git clone https://github.com/airockchip/rknn3-model-zoo.git
cd rknn3-model-zoo
pip install -r requirements.txt
export PYTHONPATH=./
cd examples/Qwen3/python/
两步走:先导出 ONNX(GRQ 量化),再转 RKNN:
python export_llm.py --quant --model_path Qwen/Qwen3-1.7B
python export_rknn.py
即使启用 --quant,
GRQ 量化仍需数据集 ../../../datasets/CMMLU/dataset.json。
脚本背后实际执行的 RKNN 配置(来自 export_rknn.py):
rknn.config(target_platform='rk1820', # ← 不是 'rk1828'
quantized_dtype='w4a16',
quantized_algorithm='grq',
quantized_method='group32')
rknn.load_llm(model=onnx_path, config=config_path)
rknn.build(do_quantization=True, dataset=dataset_path)
rknn.export_rknn(rknn_path)
3.3 方式 B:Python API
from rknn.api import RKNN # ← PC 端真实 API
rknn = RKNN(verbose=True)
rknn.config(target_platform='rk1820', # 不是 'rk1828'
quantized_dtype='w4a16',
quantized_algorithm='grq',
quantized_method='group32')
rknn.load_llm(model='Qwen3-1.7B.onnx', config='Qwen3-1.7B.config.pkl')
rknn.build(do_quantization=True, dataset='./dataset.txt')
rknn.export_rknn('./Qwen3-1.7B.rknn')
转换产出四件套:
Qwen3-1.7B/
├── Qwen3-1.7B.rknn # 模型结构
├── Qwen3-1.7B.weight # 模型权重 (~1.1 GB)
├── Qwen3-1.7B.tokenizer.gguf # 分词器
└── Qwen3-1.7B.embed.bin # Embedding (~594 MB)
(四)、自行转换 CNN:以 MobileNet V2 为例
CNN 转换比 LLM 简单,PyTorch 导出 ONNX 后直接转:
import torch
import torchvision.models as models
# 第一步:导出 ONNX
model = models.mobilenet_v2(pretrained=True)
model.eval()
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(model, dummy_input, "mobilenet_v2.onnx",
input_names=["input"], output_names=["output"])
from rknn.api import RKNN
rknn = RKNN(verbose=True)
rknn.config(target_platform='rk1820', # 不是 'rk1828'
mean_values=[[0, 0, 0]],
std_values=[[255, 255, 255]])
rknn.load_onnx(model='./mobilenet_v2.onnx')
rknn.build(do_quantization=True, dataset='./dataset.txt')
rknn.export_rknn('./mobilenet_v2.rknn')
产出两个文件:
mobilenet_v2/
├── mobilenet_v2.rknn # 模型结构 (~60KB)
└── mobilenet_v2.weight # 模型权重 (~6.8MB)
(五)、关键参数,一个都不能错

两个最容易翻车的点:
target_platform 写 'rk1820',不是 'rk1828'------芯片叫 RK1828,平台参数却是 rk1820,写错直接报不支持;
max_context_len 在转换时写死到模型里,运行时改不了,rkllm3-server 的 -c 不能超过此值(而且 -c 实际是 core mask,不是上下文------篇③细讲)。
(六)、部署验证
传到板端之后,验两件事。
文件完整性:
file /userdata/models/Qwen3-1.7B/Qwen3-1.7B.rknn
md5sum /userdata/models/Qwen3-1.7B/Qwen3-1.7B.rknn
板端可加载性(用 toolkit-lite 实际 load 一次):
python3 -c "
from rknn3lite.api import RKNN3Lite
rknn = RKNN3Lite()
rknn.load_rknn(
'/userdata/models/Qwen3-1.7B/Qwen3-1.7B.rknn',
'/userdata/models/Qwen3-1.7B/Qwen3-1.7B.weight'
)
print('Model loaded successfully')
"
输出:
Model loaded successfully
weight_path 是必填参数,缺省会报 TypeError: missing 1 required positional argument: 'weight_path'。

(七)、常见的坑

(八)、写在最后
到这里,开发指南的主线走完了:Agent 平台跑起来(篇①)、九个技能即说即用(篇②)、模型调用与转换(篇③④)------从用现成的,到做自己的。
模型能转能跑之后,就该看真实场景了。系列下一篇进案例演示:工业异常检测,PatchCore 算法检测瓶体气泡、金属划痕这类表面缺陷。