Rockchip NPU 가이드 (RKNN/RKLLM)

FriendlyElec의 Rockchip NPU 위키 내용을 바탕으로, 보드 선택부터 RKNN 변환, RKLLM 실행, 측정/튜닝, 장애 대응까지 실무 절차를 한 번에 따라갈 수 있도록 정리했습니다.

개요

Rockchip NPU는 RK35xx 계열 SoC에서 신경망 추론을 전용 하드웨어로 가속하는 구성 요소입니다. 일반적인 운영 흐름은 개발 PC에서 모델 변환을 수행하고, 보드에서 런타임과 드라이버를 맞춘 뒤 추론하는 방식입니다.

실무에서 자주 겪는 문제는 대부분 세 지점에서 발생합니다.

  • 모델 변환 시 전처리/양자화 설정 불일치로 인한 정확도 저하
  • 보드 배포 시 드라이버와 런타임 버전 불일치
  • 실행 후 성능 점검 없이 체감 속도만으로 판단하여 병목 원인 누락

이 문서는 위 문제를 줄이기 위해 선택 기준, 변환 체크리스트, 배포 절차, 성능 검증 기준을 연결해서 설명합니다.

Rockchip NPU 기본 운영 4단계 모델 준비, RKNN 변환, 배포 패키지 구성, 보드 실행과 모니터링 순서를 나타낸 흐름도 모델 준비 ONNX / PyTorch 입력/전처리 정의 RKNN 변환 양자화 / 빌드 model.rknn 생성 배포 패키지 model.rknn rknn_server / rknnrt 보드 실행 NPU 추론 load/freq 모니터링 변환 패키징 실행

Rockchip NPU 기본 운영 흐름: 모델 준비 → RKNN 변환 → 배포 패키지 → 보드 추론/모니터링

지원 SoC와 환경

FriendlyElec 위키 기준으로 RK3576/RK3588 계열과 RK3568 계열이 주요 대상입니다. 일반적으로 상위 계열은 고성능 비전/멀티스트림 처리에 유리하고, 중급 계열은 경량 모델과 저전력 운영에 적합합니다.

SoC 계열 NPU 성능(위키 기준) 비고
RK3576 / RK3588 / RK3588S 약 6 TOPS 고성능 비전/LLM 추론에 유리
RK3568 / RK3566 / RK3556 약 0.8 TOPS 경량 모델, 저전력 엣지 워크로드

장비를 고를 때는 TOPS 숫자만 보지 말고 아래 항목을 함께 확인해야 합니다.

  • 목표 모델의 입력 크기와 FPS 목표치(예: 640x640 객체 탐지, 30 FPS)
  • 동시 작업 수(카메라 스트림 수, 후처리 연산, 네트워크 송수신)
  • 열 설계와 전원 여유(밀폐형 케이스, 팬 유무, 장시간 연속 부하)
  • 메모리 용량과 대역폭(LLM 계열은 메모리 병목 영향이 큼)

런타임 호환성 체크

NPU 추론은 커널 드라이버, librknnrt.so, rknn_server, 데모/앱 바이너리 조합이 맞아야 안정적으로 동작합니다. 한 요소라도 다른 릴리스에서 가져오면 초기화 실패나 성능 저하가 발생할 수 있습니다.

점검 항목 확인 방법 기대 결과
커널/이미지 버전 uname -a, 배포 이미지 릴리스 노트 보드 제조사 권장 조합과 일치
런타임 라이브러리 strings librknnrt.so | head 드라이버 계열과 동일 세대 버전
서버 바이너리 ./rknn_server 실행 로그 초기화 오류 없이 기기 인식
모델 파일 변환 로그/모델 메타 정보 대상 SoC 플랫폼으로 변환됨
주의: 보드 이미지(커널/드라이버)와 런타임 버전이 맞지 않으면 NPU가 초기화되지 않거나 성능이 크게 떨어질 수 있습니다. 위키의 SoC별 가이드를 먼저 맞추고 진행하세요.

RKNNToolkit2로 모델 변환

모델 변환은 단순히 파일 확장자를 바꾸는 작업이 아닙니다. 입력 사양 확정 → 전처리 고정 → 양자화 데이터셋 준비 → 정확도 검증 순서로 진행해야 결과가 안정적입니다.

변환 전 체크리스트

  • 입력 텐서 형태: NCHW/NHWC, RGB/BGR, 정규화 방식
  • 지원 연산자 확인: 원본 모델의 특수 연산이 대상 툴킷에서 지원되는지 점검
  • 양자화 데이터셋: 실제 서비스 입력 분포를 반영한 샘플 구성
  • 기준 정확도: 변환 전 PC 추론 결과를 기준으로 저장
# 1) PC 환경 준비 (예시)
git clone https://github.com/airockchip/rknn-toolkit2.git
cd rknn-toolkit2/rknn-toolkit2/packages/x86_64
pip3 install rknn_toolkit2-*.whl

# 2) ONNX 로드 + 양자화 + RKNN 내보내기 (개념 예시)
rknn.load_onnx(model="model.onnx")
rknn.build(do_quantization=True, dataset="./dataset.txt")
rknn.export_rknn("model.rknn")
# 3) 변환 후 검증 포인트 (개념 예시)
# - 동일 입력 샘플로 원본 모델 vs RKNN 결과를 비교
# - 허용 오차를 벗어나면 전처리/양자화부터 재점검
orig = run_baseline("model.onnx", image)
rknn = run_rknn("model.rknn", image)
diff = compare_outputs(orig, rknn)
if diff > threshold:
    raise ValueError("정확도 편차가 큽니다. 전처리/양자화 재검토 필요")

핵심은 변환 성공 여부가 아니라 품질 보존 여부입니다. 로그에 오류가 없더라도 추론 결과가 기준선에서 벗어나면 배포하면 안 됩니다.

RKNN 변환 품질 검증 루프 원본 모델 준비부터 RKNN 출력까지 진행하고 검증 실패 시 설정 조정으로 되돌아가는 반복 흐름 원본 모델 준비 ONNX / PyTorch 전처리 고정 해상도 / 정규화 / 채널 양자화 빌드 dataset 기반 calibrate RKNN 출력 model.rknn 정확도 검증 루프 동일 샘플로 기준 모델과 RKNN 출력을 비교 허용 오차를 넘으면 전처리/양자화 설정을 다시 조정 검증 통과 후 보드 배포 단계로 이동 검증 실패 설정 조정

RKNN 변환 품질 루프: 성공 로그보다 정확도 검증 결과를 우선

보드 배포와 런타임 실행

배포 단계에서는 파일 배치, 실행 권한, 라이브러리 경로, 로그 확보를 먼저 고정해 두면 장애 대응이 빨라집니다.

# 권장 디렉터리 예시
/userdata/rknn/
  ├── model/
  │   └── detector.rknn
  ├── bin/
  │   ├── rknn_server
  │   └── rknn_yolov5_demo
  ├── lib/
  │   └── librknnrt.so
  └── logs/
# 예시: RK3576 보드에서 서버 실행
adb push rknn_server /userdata/
adb shell
cd /userdata
chmod +x rknn_server
./rknn_server

# 예시: 데모 실행
./rknn_yolov5_demo model.rknn test.jpg

서비스 운영에서는 수동 실행 대신 시작 스크립트를 두는 편이 안정적입니다.

#!/bin/sh
# /userdata/rknn/start_npu.sh
export LD_LIBRARY_PATH=/userdata/rknn/lib:$LD_LIBRARY_PATH
cd /userdata/rknn/bin
./rknn_server > /userdata/rknn/logs/rknn_server.log 2>&1
실무 팁: rknn_server 버전과 librknnrt.so 버전을 한 세트로 관리하세요. 이미지 업데이트 뒤 이전 런타임을 그대로 쓰면 오류가 자주 납니다.

RKLLM 실행 흐름 (LLM 추론)

RKLLM 영역은 비전 모델과 달리 컨텍스트 길이, 토큰 생성 속도, 메모리 사용량이 핵심 지표입니다. 따라서 단순 FPS 대신 토큰/초, 첫 토큰 지연, 장시간 안정성을 함께 봐야 합니다.

점검 항목 질문 실무 기준 예시
모델 크기 보드 메모리에 여유 있게 올라가는가? 모델 로드 후 시스템 메모리 여유 20% 이상 확보
컨텍스트 길이 요구 프롬프트 길이를 감당하는가? 실사용 최대 입력의 1.2배 수준으로 테스트
출력 지연 첫 토큰까지 지연이 허용 범위인가? 대화형 인터페이스는 체감 지연 기준 설정
지속 부하 연속 요청에서 속도 하락이 없는가? 30분 이상 반복 질의로 평균 처리량 확인
# 예시: RKLLM 런타임 실행 개념
./rkllm_demo \
  --model /userdata/models/your-model.rkllm \
  --prompt "Rockchip NPU 상태를 요약해줘"

LLM 추론은 메모리 대역폭 영향을 크게 받습니다. NPU 점유율이 높아도 전체 응답이 느리다면 CPU 전처리, 토크나이저, 메모리 압박을 먼저 의심해야 합니다.

모니터링과 성능 튜닝

성능 튜닝은 감으로 하지 말고 단계별 시간 분해로 접근해야 합니다. 최소한 아래 네 구간을 분리해 측정하세요.

  • 입력 준비 시간(디코딩, 리사이즈, 정규화)
  • NPU 추론 시간
  • 후처리 시간(NMS, 임계값 필터, 포맷 변환)
  • 입출력 시간(파일/카메라/네트워크)

배포 직후에는 아래 체크리스트를 반복하면 문제를 빠르게 좁힐 수 있습니다.

  • NPU 장치 파일과 드라이버 로드 상태 확인
  • 추론 중 NPU 로드율과 주파수 상승 여부 확인
  • 온도 상승 시 스로틀링(주파수 제한) 발생 여부 확인
  • 전처리/후처리 시간이 NPU 연산 시간을 압도하지 않는지 측정
병목 주의: NPU가 빠르더라도 입력 변환, 이미지 리사이즈, 후처리가 CPU에서 오래 걸리면 전체 FPS는 거의 늘지 않습니다. 반드시 단계별 시간을 분리 측정하세요.
엔드투엔드 병목 분석 입력 전처리, NPU 추론, 후처리, 출력 전송 단계별 시간을 분리해 병목을 찾는 구조 1 입력 전처리 decode / resize 2 NPU 추론 rknn runtime 3 후처리 NMS / decode 4 출력 전송 UI / stream 병목 분석 원칙 NPU 구간이 전체 지연에서 차지하는 비율을 먼저 수치화 가장 긴 구간부터 순서대로 튜닝

엔드투엔드 지연 분석(1→4): 전처리→추론→후처리→출력 순서로 병목을 수치화

자주 겪는 문제

증상 가능 원인 우선 조치
모델 로드 실패 런타임/드라이버 버전 불일치 보드 이미지와 같은 릴리스의 rknnrt, rknn_server로 교체
정확도 급락 양자화 데이터셋/전처리 설정 불일치 PC 추론 전처리와 보드 전처리 파이프라인을 동일하게 맞춤
속도 저하 열 스로틀링, CPU 후처리 병목 온도/주파수 확인, 후처리 최적화 및 해상도 재조정
간헐적 크래시 메모리 부족, 장시간 누수 장시간 반복 실행 로그 수집, 요청 크기 제한, 프로세스 재시작 정책 적용
첫 응답 지연 과다 모델 초기화 지연, 저장소 I/O 병목 워밍업 요청 수행, 모델 파일 위치/스토리지 성능 점검

장애 대응 우선순위

  1. 재현 조건 고정: 동일 모델, 동일 입력, 동일 온도 조건으로 재실행
  2. 버전 확인: 이미지/드라이버/런타임/모델 변환 로그 버전 기록
  3. 시간 분해: 전처리, 추론, 후처리 시간을 분리해 비정상 구간 식별
  4. 완화 조치: 해상도/배치/동시 요청 수를 낮춰 안정 구간 확인
  5. 근본 조치: 변환 파이프라인 또는 런타임 조합 재정렬 후 재검증

실전 운영 체크리스트

개발 단계에서 동작한 모델이 운영 환경에서 동일하게 동작하도록 아래 기준을 배포 파이프라인에 포함하세요.

영역 체크 항목 통과 기준
품질 원본 대비 정확도 편차 사전에 정의한 허용 오차 이내
성능 평균/최대 지연, 처리량 서비스 목표 SLA 충족
안정성 장시간 반복 실행 메모리 증가 추세 없이 연속 동작
관측성 로그/메트릭 수집 장애 시 원인 구간 역추적 가능
복구 프로세스 재시작/롤백 자동 복구 또는 빠른 수동 복구 가능
권장 운영 방식: 모델 파일, 런타임 라이브러리, 실행 바이너리를 하나의 배포 단위로 묶고 버전 태그를 붙이세요. 이 방식이면 문제 발생 시 조합 단위로 즉시 롤백할 수 있습니다.

NPU 드라이버/런타임 버전 확인

이 절의 핵심은 "실행 전에 버전을 먼저 확인"입니다. 아래 순서로 드라이버와 런타임 버전을 확인하면 문제 재현이 쉬워집니다.

# NPU 드라이버 버전 확인
sudo cat /sys/kernel/debug/rknpu/version

# rknn_server 빌드 정보 확인
strings /usr/bin/rknn_server | grep 'build@'

# librknnrt.so 버전 확인
strings /usr/lib/librknnrt.so | grep 'librknnrt version:'
확인 대상 파일/명령 의미
NPU 드라이버 /sys/kernel/debug/rknpu/version 커널 측 NPU 드라이버 버전
서버 바이너리 /usr/bin/rknn_server 유저 공간 NPU 서버 빌드 시점/해시
런타임 라이브러리 /usr/lib/librknnrt.so 앱이 직접 링크하는 런타임 버전

RKLLM 지원 모델과 성능 비교

FriendlyElec 문서 6.1에서는 RKLLM 지원 모델 목록을 제공합니다. 아래는 해당 목록에서 대표 모델군만 추린 버전입니다.

  • InternLM2-1.8B
  • TinyLlama-1.1B-Chat-v1.0
  • Qwen2.5-1.5B / Qwen2.5-3B
  • DeepSeek-R1-Distill-Qwen-1.5B / 7B
  • MiniCPM3-4B
  • Llama-3.2-1B-Instruct / Llama-3.1-8B
  • Gemma-2B / Gemma-2-9B-IT
  • ChatGLM3-6B

FriendlyElec 문서 6.2 성능표(NanoPi-M5, w4a16 기준)는 모델 선택 시 매우 유용합니다. 아래 표는 해당 열 구조를 유지해 재정리한 버전입니다.

하드웨어 모델 파라미터 Dtype Pre-fill Reasoning CPU 부하 NPU 부하 메모리
NanoPi-M5 TinyLlama 1.1B w4a16 166.61 token/s 17.90 token/s 24% 2*73% 0.58G
NanoPi-M5 DeepSeek-R1-Distill-Qwen 1.5B w4a16 111.84 token/s 11.75 token/s 23% 2*75% 1.01G
NanoPi-M5 DeepSeek-R1-Distill-Qwen 7B w4a16 38.05 token/s 4.12 token/s 18.625% 2*85% 3.76G
NanoPi-M5 Qwen2.5 1.5B w4a16 109.36 token/s 11.23 token/s 20.25% 2*75% 1.01G
NanoPi-M5 Qwen2.5 3B w4a16 70.06 token/s 8.17 token/s 20.875% 2*76% 1.78G
NanoPi-M5 InternLM2 1.8B w4a16 96.08 token/s 11.72 token/s 16.75% 2*79% 1.02G
NanoPi-M5 MiniCPM3 4B w4a16 39.29 token/s 4.11 token/s 25.875% 2*66% 2.34G
NanoPi-M5 Llama-3.2-Instruct 1B w4a16 180.33 token/s 14.51 token/s 17.125% 2*79% 0.87G
NanoPi-M5 Llama-3.1 8B w4a16 36.44 token/s 3.8 token/s 18.875% 2*85% 3.97G
NanoPi-M5 Gemma-2 2B w4a16 93.08 token/s 7.86 token/s 19.875% 2*83% 1.65G
NanoPi-M5 Gemma-2 9B w4a16 25.91 token/s 2.84 token/s 19.125% 2*80% 5.25G
NanoPi-M5 ChatGLM3 6B w4a16 47.13 token/s 4.03 token/s 19.75% 2*88% 3.04G

문서에는 RKLLM 변환 결과물 저장 위치 예시도 제시됩니다: 다운로드 센터 내 09_Other files/RKLLM models 경로.

RKLLM 모델 선택과 실행 흐름 Hugging Face 모델을 PC에서 변환하고 보드에서 실행하며 성능표를 해석하는 흐름 1 Hugging Face 모델 Qwen / DeepSeek / Llama 2 PC 변환 단계 rkllm-toolkit로 .rkllm 생성 3 보드 실행 단계 rkllm-runtime + llm_demo 4 성능표 해석 포인트 Pre-fill은 입력 처리 속도, Reasoning은 생성 속도 모델이 커질수록 메모리 사용량과 지연이 증가하는 경향 배포 전 동일 워크로드로 재측정해 기준선 고정

RKLLM 흐름(1→4): 모델 선택 → PC 변환 → 보드 실행 → 성능 검증

RKLLM 모델 변환 (PC 측)

FriendlyElec 문서 6.3은 Hugging Face 형식을 RKLLM으로 변환하는 절차를 설명합니다. 권장 OS는 Ubuntu 20.04이며, Docker 사용도 가능합니다.

RKLLM-Toolkit 설치

sudo apt-get update
sudo apt-get install -y python3-dev python3-numpy python3-opencv python3-pip
cd ~
git clone https://github.com/airockchip/rknn-llm
cd rknn-llm
git reset 8623edd0559a07e7127876d685f2b7ca8b83590c --hard
pip3 install rkllm-toolkit/packages/rkllm_toolkit-1.1.4-cp38-cp38-linux_x86_64.whl

모델 다운로드 및 변환

cd ~/rknn-llm/rkllm-toolkit/examples/
git lfs install
git clone https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B
sed -i 's|^modelpath\\s*=.*|modelpath = "./DeepSeek-R1-Distill-Qwen-1.5B"|' test.py
sed -i 's|^dataset\\s*=.*|dataset = None|' test.py
# RK3576 대상이면 플랫폼/코어 설정 수정
sed -i "s/target_platform='rk3588'/target_platform='rk3576'/g" test.py
sed -i "s/num_npu_core=3/num_npu_core=2/g" test.py

python3 test.py
mv qwen.rkllm DeepSeek-R1-Distill-Qwen-1.5B.rkllm
scp DeepSeek-R1-Distill-Qwen-1.5B.rkllm root@NanoPC-T6:/home/pi
실무 팁: 변환 로그에 tokenizer 경고나 진행률 메시지가 길게 출력될 수 있습니다. 완료 메시지와 생성 파일 존재 여부를 마지막에 반드시 확인하세요.

RKLLM 데모 컴파일/실행 (보드 측)

문서 6.4 절차는 보드에서 rkllm_api_demo를 빌드한 뒤, 생성된 .rkllm 파일을 인자로 실행하는 흐름입니다.

sudo apt-get update
sudo apt-get install -y gcc g++ make cmake

# rknn-llm 준비
cd ~
[ -d rknn-llm ] || git clone https://github.com/airockchip/rknn-llm
cd rknn-llm
git reset 8623edd0559a07e7127876d685f2b7ca8b83590c --hard
cd examples/rkllm_api_demo
chmod +x ./build-linux.sh
sed -i 's/^GCC_COMPILER_PATH=.*/GCC_COMPILER_PATH=aarch64-linux-gnu/' ./build-linux.sh
./build-linux.sh

# llm_demo 실행
cd ./build/build_linux_aarch64_Release/
export LD_LIBRARY_PATH=~/rknn-llm/rkllm-runtime/Linux/librkllm_api/aarch64:$LD_LIBRARY_PATH
ulimit -HSn 10240
taskset f0 ./llm_demo ~/DeepSeek-R1-Distill-Qwen-1.5B.rkllm 512 1024

출력 예시에서는 rkllm-runtime version, rknpu driver version, platform 정보가 함께 노출됩니다. 이 정보를 저장해두면 장애 분석 시 큰 도움이 됩니다.

참고 자료