怎么在 RK3576 上运行 LLM 模型

在 Ubuntu x86_64 PC 将 DeepSeek-R1-Distill-Qwen-1.5B 转为 RKLLM,使用 SSH/SCP 部署到 RK3576 并运行官方 C++ 示例。


快速入门:怎么在 RK3576 上运行 LLM 模型

项目本次验证环境
PCUbuntu 20.04.6 LTS,x86_64,Python 3.11,NVIDIA GTX 1070 8 GB
板卡reComputer RK3576,Debian 12 / Armbian 26.05.0-trunk
板端内核6.1.115-vendor-seeed-rk3576
RKNPU 驱动v0.9.8
SDKRKLLM-Toolkit / Runtime 1.3.0,仓库提交 878f936
示例账户与地址BOARD_USER@BOARD_IP

板端本地终端执行:

bash
sudo apt update
sudo apt install -y openssh-server git
sudo systemctl enable --now ssh

PC 执行:

bash
sudo apt update
sudo apt install -y git wget openssh-client
ssh BOARD_USER@BOARD_IP

#1. 缺少 RKNPU 驱动时如何解决

板端执行:

bash
uname -m
uname -r
mountpoint -q /sys/kernel/debug || sudo mount -t debugfs debugfs /sys/kernel/debug
sudo cat /sys/kernel/debug/rknpu/version
sudo cat /sys/kernel/debug/rknpu/load
grep "^CONFIG_ROCKCHIP_RKNPU=" /boot/config-$(uname -r)
sudo dmesg | grep -i rknpu | tail -n 20
for node in /sys/class/drm/renderD*; do
  printf '%s -> ' "$node"
  readlink -f "$node/device/driver"
done

本机实测输出节选:

text
RKNPU driver: v0.9.8
NPU load:  Core0:  0%, Core1:  0%
/sys/class/drm/renderD129 -> /sys/bus/platform/drivers/RKNPU
CONFIG_ROCKCHIP_RKNPU=y

renderD129 是本机节点,不是固定编号。SDK 1.3.0 要求驱动至少 v0.9.8;CONFIG_ROCKCHIP_RKNPU=y 表示驱动编入内核,lsmod 不显示也属正常。若版本文件不存在,结合 dmesg 与驱动绑定检查。

在本文对应的 reComputer RK3576 Seeed/Armbian Debian 系统上,先确认配套内核和设备树包:

bash
sudo apt update
apt-cache policy linux-image-vendor-seeed-rk3576 linux-dtb-vendor-seeed-rk3576

确认两个包的候选版本均来自本板的软件源后,缺失或低于 0.9.8 时安装/重装配套包:

bash
sudo apt install --reinstall linux-image-vendor-seeed-rk3576 linux-dtb-vendor-seeed-rk3576
sudo reboot

#2. 安装并验证 RKLLM Runtime 与 RKLLM-Toolkit

组件安装位置作用
RKNPU 内核驱动板端内核访问 NPU 硬件
RKLLM Runtime librkllmrt.so板端 aarch64加载 .rkllm 并提供 C/C++ 推理接口
RKLLM-Toolkit rkllm_toolkitUbuntu x86_64 PC转换、量化并导出 .rkllm

#2.1 两端获取相同版本的 SDK

PC 执行:

bash
mkdir -p ~/RKLLM_Project
cd ~/RKLLM_Project
git clone --branch release-v1.3.0 --depth 1 https://github.com/airockchip/rknn-llm.git

板端执行: 本例只取编译和运行所需文件,减少板端占用。

bash
mkdir -p ~/RKLLM_Project
cd ~/RKLLM_Project
git clone --filter=blob:none --sparse --depth 1 --branch release-v1.3.0 \
  https://github.com/airockchip/rknn-llm.git
cd rknn-llm
git sparse-checkout set examples/rkllm_api_demo/deploy rkllm-runtime/Linux

#2.2 板端验证 Runtime

板端执行:

bash
cd ~/RKLLM_Project/rknn-llm
file rkllm-runtime/Linux/librkllm_api/aarch64/librkllmrt.so
ldd rkllm-runtime/Linux/librkllm_api/aarch64/librkllmrt.so

file 应显示 AArch64 ELF;ldd 不应出现 not found。Runtime 不需要 pip install。第 4 节编译示例时,CMake 会把同版 librkllmrt.so 复制到部署目录的 lib/,运行前设置 LD_LIBRARY_PATH 即完成板端使用。本机 ldd 能找到 libgomp.so.1 等依赖;若你的输出出现 not found,先安装对应的板端依赖库。

#2.3 PC 安装 Toolkit

以下以 Ubuntu x86_64、Python 3.11 为例,使用独立 Conda 环境。已有 Miniforge 时可从 source 一行开始。

PC 执行:

bash
cd ~/RKLLM_Project
wget -O Miniforge3-Linux-x86_64.sh \
  https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
bash Miniforge3-Linux-x86_64.sh -b -p "$HOME/miniforge3"
source "$HOME/miniforge3/etc/profile.d/conda.sh"
conda create -n rkllm-1.3.0 python=3.11 -y
conda activate rkllm-1.3.0
python -m pip install --upgrade pip
python -m pip install ./rknn-llm/rkllm-toolkit/packages/rkllm_toolkit-1.3.0-cp311-cp311-linux_x86_64.whl
python -m pip install huggingface_hub
python -m pip check
python -c 'from rkllm.api import RKLLM; print("RKLLM-Toolkit import OK")'
nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
python -c 'import torch; print("CUDA available:", torch.cuda.is_available())'

Wheel 文件名中的 cp311 对应 Python 3.11,linux_x86_64 对应 PC 架构;板端不安装此 wheel。本次 PC 使用已有的 ~/miniconda3 创建环境,实测输出为 No broken requirements found.、RKLLM-Toolkit import OK、CUDA available: True。上面的从零安装命令使用 Miniforge;第 3 节还要求 PC 已安装可用的 NVIDIA 驱动。

#3. 在 Ubuntu PC 转换 LLM 模型

#3.1 下载原始模型

PC 执行:

bash
source "$HOME/miniforge3/etc/profile.d/conda.sh"
conda activate rkllm-1.3.0
mkdir -p ~/RKLLM_Project/models
hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B \
  config.json tokenizer.json tokenizer_config.json generation_config.json model.safetensors \
  --local-dir ~/RKLLM_Project/models/DeepSeek-R1-Distill-Qwen-1.5B
ls -lh ~/RKLLM_Project/models/DeepSeek-R1-Distill-Qwen-1.5B/model.safetensors

这里下载的是 Hugging Face 原始模型,不能直接交给板端 Runtime。转换使用官方示例目录自带的 data_quant.json 作为演示校准集;实际业务模型应换成覆盖目标场景的问答数据。

#3.2 生成 RK3576 模型

PC 执行: 本次使用 NVIDIA GTX 1070 的 CUDA 环境,按下面参数创建转换脚本。

bash
cat > ~/RKLLM_Project/convert_rk3576.py <<'PY'
from pathlib import Path
from rkllm.api import RKLLM

root = Path.home() / 'RKLLM_Project'
model = root / 'models/DeepSeek-R1-Distill-Qwen-1.5B'
dataset = root / 'rknn-llm/examples/rkllm_api_demo/export/data_quant.json'
output = root / 'models/DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm'

llm = RKLLM()
ret = llm.load_huggingface(model=str(model), model_lora=None,
                           device='cuda', dtype='float16',
                           custom_config=None, load_weight=True)
if ret != 0:
    raise RuntimeError(f'load_huggingface failed: {ret}')
ret = llm.build(do_quantization=True, optimization_level=1,
                quantized_dtype='W4A16', quantized_algorithm='normal',
                target_platform='RK3576', num_npu_core=2,
                extra_qparams=None, dataset=str(dataset),
                hybrid_rate=0, max_context=4096)
if ret != 0:
    raise RuntimeError(f'build failed: {ret}')
ret = llm.export_rkllm(str(output))
if ret != 0:
    raise RuntimeError(f'export_rkllm failed: {ret}')
print(output)
PY
python ~/RKLLM_Project/convert_rk3576.py
ls -lh ~/RKLLM_Project/models/DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm

RK3576 使用 W4A16 量化、normal 算法与 2 个 NPU 核;这是该平台支持的组合。max_context=4096 与后面的运行参数一致。本次 PC 转换成功,导出的 W4A16 模型约 1.4 GB。模型文件必须放到对应的 RK3576 板卡。

#4. 在板卡上部署并运行 C++ 示例

#4.1 板端编译官方 llm_demo

板端执行: 使用板卡本机的 aarch64 编译器,避免官方 build-linux.sh 中写死的 PC 交叉编译器路径。

bash
sudo apt update
sudo apt install -y cmake g++ make
cd ~/RKLLM_Project/rknn-llm
cmake -S examples/rkllm_api_demo/deploy \
  -B examples/rkllm_api_demo/deploy/build/native \
  -DCMAKE_BUILD_TYPE=Release
cmake --build examples/rkllm_api_demo/deploy/build/native -j2
cmake --install examples/rkllm_api_demo/deploy/build/native
ls -lh examples/rkllm_api_demo/deploy/install/demo_Linux_aarch64/llm_demo \
  examples/rkllm_api_demo/deploy/install/demo_Linux_aarch64/lib/librkllmrt.so

#4.2 传模型并运行

PC 执行:

bash
scp ~/RKLLM_Project/models/DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm \
  BOARD_USER@BOARD_IP:~/RKLLM_Project/rknn-llm/examples/rkllm_api_demo/deploy/install/demo_Linux_aarch64/
sha256sum ~/RKLLM_Project/models/DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm
ssh BOARD_USER@BOARD_IP

板端执行:

bash
cd ~/RKLLM_Project/rknn-llm/examples/rkllm_api_demo/deploy/install/demo_Linux_aarch64
sha256sum ./DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm
export LD_LIBRARY_PATH="$PWD/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
ldd ./llm_demo | grep -E 'librkllmrt|not found'
export RKLLM_LOG_LEVEL=1
./llm_demo ./DeepSeek-R1-Distill-Qwen-1.5B_W4A16_rk3576.rkllm 128 4096

PC 与板端的 SHA-256 应一致。本次两端均为 ce4412147c33c78eb1364458757fbc607acc0ad3ed1fed5cf6894e91506d2051。在 user: 后输入 1+1等于多少?请只回答数字。,RK3576 实测输出节选:

text
rkllm init start
I rkllm: rkllm-runtime version: 1.3.0, rknpu driver version: 0.9.8, platform: RK3576
I rkllm: rkllm-toolkit version: 1.3.0, max_context_limit: 4096, npu_core_num: 2, target_platform: RK3576, model_dtype: W4A16
rkllm init success
...
1+1等于\boxed{2}

模型回答的具体措辞可能变化。128 是本次生成的最大 token 数,4096 是上下文上限;输入 exit 退出。

如果 ldd 出现 not found,先修复缺失的共享库;若初始化失败,核对驱动版本、模型文件完整性、平台参数及 Toolkit/Runtime 版本。RK3576 与 RK3588 的 .rkllm 文件不能互换。

#参考资料