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++ 推論 API を提供
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 での変換は成功し、約 1.4 GB の W4A16 モデルが生成されました。モデルは対応する RK3576 ボードに配置します。

#4. ボードに配置して C++ サンプルを実行

#4.1 ボードで公式 llm_demo をビルド

ボードで実行: 公式の build-linux.sh に固定された PC のクロスコンパイラーパスを避けるため、ボードの aarch64 ネイティブコンパイラーを使用します。

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 は今回生成する最大トークン数、4096 はコンテキスト上限です。終了するには exit を入力します。

ldd に not found が出たら、先に不足する共有ライブラリを修復します。初期化に失敗した場合は、ドライバーのバージョン、モデルの完全性、プラットフォーム引数、Toolkit/Runtime のバージョンを確認します。RK3576 と RK3588 の .rkllm ファイルは交換できません。

#参考資料