前面的帖子把 RKNN3 工具链、RKLLM 板端运行时都过了一遍,这篇补一下 RK1828 上 NPU 本身的架构细节。主要是支持的精度模式、完整的开发流程、PC 端和板端的代码示例,还有我踩过的坑。
再次提醒: RK182X 系列用的是 RKNN3 Toolkit,RKNN-Toolkit2 是 RK3588 这些主控 SoC 用的,别搞混了。
一、整体开发框图
先把全局链路拉出来看一遍,心里有个数:
PC 端 设备端
┌──────────────────────┐ ┌──────────────────────┐
│ RKNN3-Toolkit (whl) │ 传输模型文件 │ RKNN3-Toolkit-Lite │
│ 1. export_llm.py │ ────────────► │ 4. rkllm3-server │
│ 2. export_rknn.py │ │ 5. rknn3_*_demo │
│ 3. .rknn/.weight 等 │ │ 6. 推理输出 │
└──────────────────────┘ └──────────────────────┘
一句话总结:PC 端转换模型,scp 拷到板子上,板端起服务或跑 demo,应用通过 API 调用。
二、NPU 支持的精度
基于 RKNN3 V1.0.0 Release Note,RK182X NPU 支持以下精度模式:
| 精度 | 说明 |
|---|---|
| INT8 | 峰值算力 20 TOPS(官方 datasheet 确认) |
| FP16 | 高精度推理,也是量化前的中间格式 |
| BF16 | Brain Float 16,和 FP16 是不同的格式,别搞混 |
日常使用中,CNN 模型走 INT8 量化跑量,LLM 模型走 w8a8 或 w4a16 量化。FP16/BF16 主要用在量化前的精度对比和调试阶段。
三、RKNN3 完整开发流程
| 步骤 | 在哪做 | 用什么工具 |
|---|---|---|
| 1. 导出 ONNX | PC | export_llm.py |
| 2. 转换为 RKNN | PC | rknn-toolkit3(from rknn.api import RKNN) |
| 3. 传输模型到板子 | PC → 板端 | scp / adb push |
| 4. 启动推理服务 | 板端 | rkllm3-server / rknn3_*_demo |
| 5. 应用调用 | 板端 | OpenAI 兼容 API 或 Python API |
整体就是"PC 端干活、板端跑活"的两步走模式。
四、PC 端模型转换示例
以 Qwen3-1.7B 为例,核心代码:
from rknn.api import RKNN
rknn = RKNN(verbose=True)
rknn.config(target_platform='rk1820', # ← 注意:写 '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='datasetsdataset.txt')
rknn.export_rknn('Qwen3-1.7B.rknn')
重点踩坑提醒: target_platform 必须写 'rk1820',不是 'rk1828'!虽然你手上拿的是 RK1828 的卡,但底层 target 标识就是 rk1820。写错了会直接报 unsupported target_platform。
五、板端 C API 推理示例
在板子上用 C 语言做推理的核心流程:
#include "rknn3_api.h" // 头文件需要找瑞芯微要
rknn3_init(&ctx, &ext); // 上下文指针 + 初始化扩展参数
rknn3_load_model_from_path(ctx, "model.rknn", "model.weight");
// 只传 3 个参数,core_mask 不在这里传
rknn3_config cfg = {0};
cfg.run_core_mask = 0xff; // LLM/VLM 用全部 8 核 (0xff);某些 CNN 模型用 0x01
rknn3_model_init(ctx, &cfg);
rknn3_run(ctx, inputs, n_inputs, outputs, n_outputs); // CNN 推理走这里
// LLM 推理走 rknn3_session_run(session, ...),是独立的 session API
rknn3_destroy(ctx);
几个要点:
rknn3_api.h头文件不在标准安装包里,需要单独找瑞芯微索取- core_mask 是核心坑点:LLM/VLM 模型需要
0xff(8 核全开),某些 CNN 只需要0x01(单核)。设错了会报core_mask X is not match with npu core number N! - CNN 推理用
rknn3_run,LLM 推理用rknn3_session_run,走的是不同的 API 路径
六、NPU 支持的算子
基于 V1.0.0 Release Note,NPU 针对以下算子做了优化实现:
exSDPA(缩放点积注意力)exMatMul(矩阵乘法)ResizeTranspose
完整的算子列表参考 RKNN3 Toolkit 官方文档。
七、性能数据(RKNN3 V1.0.0)
| 类别 | 能力 |
|---|---|
| LLM Decode 性能 | 整体提升 >15% |
| 多核多模型 | 支持同时推理(PCIe 卡有 8 核;模型编译时声明 core_mask — LLM/VLM 用 0xff,某些 CNN 用 0x01) |
| 新格式 | 支持 mRoPE、Function Call、YUV 格式输入 |
| rkllm3-server | 支持 embedding 模型和音频输入 |
LLM Decode 性能提升超过 15% 这个数据挺实在的,对端侧对话场景体感明显。
八、验证 NPU 状态
拿到板子后第一件事,确认 NPU 服务正常、设备能被识别:
systemctl is-active rknn3.service && lspci -d 1d87:182a
正常输出:
active
0004:41:00.0 Processing accelerators: Rockchip Electronics Co., Ltd Device 182a (rev 01)
如果 lspci 看不到 182a 设备,大概率是卡没插好或者供电不够,重新插拔一下然后看 dmesg 日志。
九、SDK 参考文档
SDK 里自带了 PDF 和 Markdown 文档,路径在 /userdata/RK1820_RK1828_AI_SDK/docs/,目录结构如下:
docs/
├── Examples/
├── Others/
├── Release/ # PDF 文档
│ ├── Rockchip_RK1820_RK1828_AI_SDK_Quick_Start_CN.pdf
│ ├── Rockchip_RK1820_RK1828_AI_SDK_Quick_Start_EN.pdf
│ ├── Rockchip_RK1820_RK1828_AI_SDK_Quick_Start_For_Android_CN.pdf
│ ├── Rockchip_RK1820_RK1828_AI_SDK_Quick_Start_For_Android_EN.pdf
│ ├── Rockchip_RK1820_RK1828_AI_SDK_RELEASE_CN.pdf
│ └── Rockchip_RK1820_RK1828_AI_SDK_RELEASE_EN.pdf
├── Tools/
├── RK1820_RK1828_AI_Release-Note_CN.md
└── RK1820_RK1828_AI_Release-Note_EN.md
Release Note V1.0.0 的关键更新(摘录):
- 新增 Docker 环境部署说明及示例
rockit_yolo_detect示例兼容 RKNN2 与 RKNN3 接口- 新增工业异常检测、
vi_yolo_venc示例 - RKNN-Console 新增多卡与 USB 设备支持
- RKNN-SMI 新增 NPU 负载、电流、电压、功耗等查询接口
- RKNN3 版本更新至 V1.0.0,LLM Decode 性能整体提升超过 15%
建议把 Release Note 和 Quick Start 都过一遍,能省不少试错时间。
差不多就这些。这篇把 NPU 的精度支持、完整开发流程、PC 端和板端代码、SDK 文档结构、FAQ 都理了一遍,配合前面几篇 RKNN3 Toolkit、RKLLM 的内容,基本上 RK1828 开发的全链路都覆盖了。
有遇到其他坑的欢迎评论区交流。