Rockchip NPU 가이드 (RKNN/RKLLM)
FriendlyElec의 Rockchip NPU 위키 내용을 바탕으로, 보드 선택부터 RKNN 변환, RKLLM 실행, 측정/튜닝, 장애 대응까지 실무 절차를 한 번에 따라갈 수 있도록 정리했습니다.
개요
Rockchip NPU는 RK35xx 계열 SoC에서 신경망 추론을 전용 하드웨어로 가속하는 구성 요소입니다. 일반적인 운영 흐름은 개발 PC에서 모델 변환을 수행하고, 보드에서 런타임과 드라이버를 맞춘 뒤 추론하는 방식입니다.
실무에서 자주 겪는 문제는 대부분 세 지점에서 발생합니다.
- 모델 변환 시 전처리/양자화 설정 불일치로 인한 정확도 저하
- 보드 배포 시 드라이버와 런타임 버전 불일치
- 실행 후 성능 점검 없이 체감 속도만으로 판단하여 병목 원인 누락
이 문서는 위 문제를 줄이기 위해 선택 기준, 변환 체크리스트, 배포 절차, 성능 검증 기준을 연결해서 설명합니다.
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 플랫폼으로 변환됨 |
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 변환 품질 루프: 성공 로그보다 정확도 검증 결과를 우선
보드 배포와 런타임 실행
배포 단계에서는 파일 배치, 실행 권한, 라이브러리 경로, 로그 확보를 먼저 고정해 두면 장애 대응이 빨라집니다.
# 권장 디렉터리 예시
/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 연산 시간을 압도하지 않는지 측정
엔드투엔드 지연 분석(1→4): 전처리→추론→후처리→출력 순서로 병목을 수치화
자주 겪는 문제
| 증상 | 가능 원인 | 우선 조치 |
|---|---|---|
| 모델 로드 실패 | 런타임/드라이버 버전 불일치 | 보드 이미지와 같은 릴리스의 rknnrt, rknn_server로 교체 |
| 정확도 급락 | 양자화 데이터셋/전처리 설정 불일치 | PC 추론 전처리와 보드 전처리 파이프라인을 동일하게 맞춤 |
| 속도 저하 | 열 스로틀링, CPU 후처리 병목 | 온도/주파수 확인, 후처리 최적화 및 해상도 재조정 |
| 간헐적 크래시 | 메모리 부족, 장시간 누수 | 장시간 반복 실행 로그 수집, 요청 크기 제한, 프로세스 재시작 정책 적용 |
| 첫 응답 지연 과다 | 모델 초기화 지연, 저장소 I/O 병목 | 워밍업 요청 수행, 모델 파일 위치/스토리지 성능 점검 |
장애 대응 우선순위
- 재현 조건 고정: 동일 모델, 동일 입력, 동일 온도 조건으로 재실행
- 버전 확인: 이미지/드라이버/런타임/모델 변환 로그 버전 기록
- 시간 분해: 전처리, 추론, 후처리 시간을 분리해 비정상 구간 식별
- 완화 조치: 해상도/배치/동시 요청 수를 낮춰 안정 구간 확인
- 근본 조치: 변환 파이프라인 또는 런타임 조합 재정렬 후 재검증
실전 운영 체크리스트
개발 단계에서 동작한 모델이 운영 환경에서 동일하게 동작하도록 아래 기준을 배포 파이프라인에 포함하세요.
| 영역 | 체크 항목 | 통과 기준 |
|---|---|---|
| 품질 | 원본 대비 정확도 편차 | 사전에 정의한 허용 오차 이내 |
| 성능 | 평균/최대 지연, 처리량 | 서비스 목표 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 흐름(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
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 정보가 함께 노출됩니다. 이 정보를 저장해두면 장애 분석 시 큰 도움이 됩니다.
참고 자료
- FriendlyElec Wiki: NPU
- FriendlyElec Wiki: NPU (Revision 27524)
- Rockchip RKNN-Toolkit2
- Rockchip RKNN-LLM
- Rockchip rknpu2 문서
- FriendlyElec 다운로드 센터 (RK3576)