Community코딩 & 개발github.com

qnn-npu-compile

ONNX 모델을 Qualcomm NPU(Hexagon HTP)용으로 컴파일하여 Android 앱에서 sherpa-onnx 또는 ONNX Runtime으로 실행합니다. 사용자가 Snapdragon 폰의 NPU에서 음성, 오디오, 비전, 소형 트랜스포머 모델을 속도나 배터리 향상을 위해 사용하거나 QNN, HTP, Hexagon, Snapdragon, 'NPU'에 모델을 컴파일/변환/양자화하는 방법을 물을 때 사용하세요.

qnn-npu-compile란 무엇인가요?

이 스킬은 ONNX 모델을 Qualcomm NPU(Hexagon HTP)에서 실행할 수 있도록 컴파일하는 단계별 절차를 제공합니다. sherpa-onnx에서 공개한 NPU 모델의 실제 CI 워크플로우를 기반으로 하며, 각 모델마다 고유한 내보내기와 검증이 필요합니다. 주요 단계는 다음과 같습니다: (1) NPU 사용 여부 결정 (정적 크기, 칩 호환성, 크기 제한 확인), (2) ONNX 모델을 NPU에 맞게 내보내기 (고정 배치, 고정 입력 길이, int32 입력), (3) QNN SDK 도구(qnn-onnx-converter, qnn-context-binary-generator)로 변환 및 컴파일, (4) Android 폰에서 실행 (QNN 런타임 라이브러리 탑재, sherpa-onnx의 QnnConfig 사용 또는 ONNX Runtime의 QNN 실행 제공자), (5) 출력 정확도, 속도, 전력 소모 검증. 지원 플랫폼: Linux x86-64 호스트 (QNN SDK), Android aarch64 타겟. Docker로 macOS도 가능하나 에뮬레이션으로 느림. 칩: Snapdragon 8 Gen 2(v73), 8 Gen 3(v75), 8 Elite(v79) 등. 주의사항: 동적 크기 금지, 컨텍스트 바이너리는 SDK 버전과 칩 아키텍처에 종속, CPU 폴백 항상 준비.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/chencohensolutions/claude-skills/tree/HEAD/plugins/qnn-npu-compile/skills/qnn-npu-compile

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Qualcomm NPU(QNN HTP)용 모델 컴파일

절차이지 스크립트가 아닙니다: 모든 모델은 자체 내보내기와 검증이 필요합니다. sherpa-onnx가 공개 NPU 모델을 컴파일하는 방식(k2-fsa/sherpa-onnx, .github/workflows/export-*-qnn.yaml, .github/scripts/export-qnn/, scripts/qnn/)을 따르며, 이 방식은 실제로 작동하는 것으로 알려져 있습니다. 시작하기 전에 해당 워크플로우를 읽고, 상황에 맞게 적응하고 새로 만들지 마십시오.

0. NPU의 가치 판단

  • 먼저 측정: 대상 폰에서 현재 모델의 CPU 사용률 및 소요 시간(/proc/<pid>/stat 2초마다 틱, top -H -p <pid> 스레드별), 전력이 목표라면 고정 작업에서 배터리 소모를 측정하십시오. NPU는 크고 일정한 매트릭스 작업(인코더, 긴 배치)에서 효과적입니다. 1-2개 스레드의 작은 모델에서는 이득이 적을 수 있습니다.
  • 정적 크기만 지원: NPU는 고정 크기 그래프(고정 배치 1, 고정 입력 길이: 청크 크기 또는 Whisper 인코더의 경우 30초)를 실행합니다. 입력 길이가 변하는 모델은 고정 청크, 패딩 또는 여러 그래프가 필요합니다.
  • 빌드당 하나의 칩 제품군: 컨텍스트 바이너리는 하나의 Hexagon 아키텍처(v73, v75, v79, v81…)용으로 컴파일되며 해당 아키텍처에서만 실행됩니다. 다른 폰(및 Exynos / Tensor / MediaTek)은 CPU 경로를 유지하십시오. 항상 CPU 폴백을 계획하십시오.
  • 크기 제한: 매우 큰 모델(fp16에서 약 10억 파라미터 초과)은 하나의 컨텍스트에 맞지 않을 수 있습니다. 8비트 가중치(w8a16) 및/또는 여러 그래프로 분할이 필요합니다. sherpa-onnx 자체 Whisper 빌드는 medium(769M)에서 멈춥니다.

칩(sherpa-onnx scripts/qnn/device_info.py 기준): SM8550 Snapdragon 8 Gen 2 (v73), SM8650 8 Gen 3 (v75), SM8750 8 Elite (v79), SM8850 (v81), QCS9100 (v73). SM8350 (v68)에는 fp16이 없습니다: 건너뛰십시오. 폰의 칩은 adb shell getprop ro.soc.model로 확인하십시오.

1. 도구 (Linux x86-64 전용)

QNN SDK(QAIRT)는 Linux x86-64(또는 Windows)에서 실행되며 macOS는 지원하지 않습니다. Mac의 경우: Linux VM/클라우드 박스, 또는 --platform linux/amd64를 사용한 Docker(느림: 에뮬레이션). sherpa-onnx는 이를 위한 Docker 이미지를 빌드합니다(Dockerfile-2.40, qnn-sdk-docker-build.yaml).

  • QAIRT SDK, 예: 2.40.0.251030: Qualcomm(무료 계정 필요)에서 다운로드하거나 sherpa-onnx CI가 다운로드하는 복사본(huggingface.co/csukuangfj/qnn-toolkit, v2.40.0.251030.zip) 사용. 라이선스가 사용자의 용도를 허용하는지 확인하십시오.
  • source qairt/<version>/bin/envsetup.sh (QNN_SDK_ROOT 설정), 이후 sudo ${QNN_SDK_ROOT}/bin/check-linux-dependency.sh 및 python3 ${QNN_SDK_ROOT}/bin/check-python-dependency 실행.
  • numpy<2 onnx==1.17.0 onnxruntime onnxsim 및 모델 자체 내보내기 의존성이 포함된 Python 3.10 venv.
  • Android NDK를 PATH에 설정(ndk-build), aarch64 모델 라이브러리용; LDFLAGS="-Wl,-z,max-page-size=16384" (16KB 페이지, Android 15+에서 필수).

2. NPU용 ONNX 내보내기

CPU용으로 만든 ONNX가 아닌 원본 체크포인트(PyTorch)에서 다시 내보내기:

  • --dynamic-batch 0 (배치 1), ONNX에 int8 양자화 없음(--enable-int8-quantization 0: QNN에서 양자화), --use-int32-inputs 1 (int64 텐서 없음), 고정 청크/길이.
  • 단순화(onnxsim) 후 모든 입출력이 고정 크기인지 확인(sherpa-onnx scripts/pyannote/segmentation/show-onnx.py).
  • ONNX를 CPU(onnxruntime)에서 몇 가지 실제 입력으로 원본과 비교 실행: 동일한 출력(또는 동일한 텍스트).

예시: 스트리밍 Zipformer2 (icefall zipformer/export-onnx-streaming.py, sherpa-onnx scripts/zipformer-transducer/x-asr/qnn/export-streaming.sh 참조); Whisper (sherpa-onnx scripts/whisper/qnn/export_onnx.py, 인코더와 디코더를 별도 그래프로).

3. 변환, 빌드, 컴파일 (그래프별, 칩별)

각 ONNX 그래프 $m(예: encoder, decoder, joiner)에 대해:

# a) ONNX → QNN C++ 그래프 + 가중치. fp16 활성화: --act_bitwidth 16 --bias_bitwidth 32.
#    8비트 가중치(큰 모델)의 경우: 실제 입력의 --input_list로 보정 양자화 추가.
qnn-onnx-converter --input_network $m.onnx --output_path out/$m.cpp --act_bitwidth 16 --bias_bitwidth 32

# b) 칩에 맞는 HTP 설정 (sherpa-onnx scripts/qnn/generate_config.py: soc_id, dsp_arch, vtcm).
python3 generate_config.py --soc SM8750 --graph-name $m --output-dir out/config-$m --qnn-sdk-root $QNN_SDK_ROOT

# c) 모델 라이브러리: x86_64 (호스트에서 컨텍스트를 컴파일하기 위해) 및 aarch64-android.
python3 $QNN_SDK_ROOT/bin/x86_64-linux-clang/qnn-model-lib-generator -c out/$m.cpp -b out/$m.bin -o out/model_libs

# d) 칩용 컨텍스트 바이너리: 폰이 로드하는 것.
$QNN_SDK_ROOT/bin/x86_64-linux-clang/qnn-context-binary-generator \
  --backend $QNN_SDK_ROOT/lib/x86_64-linux-clang/libQnnHtp.so \
  --model out/model_libs/x86_64-linux-clang/lib$m.so \
  --output_dir out/binary --binary_file $m \
  --config_file out/config-$m/htp_backend_extensions.json

변환기 및 생성기 로그를 보관하십시오: 지원되지 않는 연산과 양자화 경고가 여기에 나타납니다.

4. 폰에서 실행

  • Android aarch64용 QNN 런타임 라이브러리 제공(libQnnHtp.so, libQnnHtpV79Skel.so 및 칩용 스텁, libQnnSystem.so; sherpa-onnx는 이를 qnn-libs-<version>.tar.bz2로 배포). Skel 라이브러리는 DSP에서 실행됩니다: sherpa-onnx의 OnlineRecognizer.prependAdspLibraryPath(dir) (또는 ADSP_LIBRARY_PATH)가 해당 폴더를 가리켜야 합니다.
  • sherpa-onnx: 모델 설정(예: OnlineTransducerModelConfig(..., qnnConfig = ...))에 QnnConfig(backendLib = ".../libQnnHtp.so", contextBinary = ".../$m.bin", systemLib = ".../libQnnSystem.so"), provider = "qnn".
  • ONNX Runtime 대안: QNN 실행 제공자(QNNExecutionProvider, backend_path=libQnnHtp.so), 자체적으로 컨텍스트 바이너리를 캐시할 수도 있음.
  • 장치별 선택: ro.soc.model이 컴파일된 칩과 일치하고 라이브러리가 로드되면 NPU, 그렇지 않으면 CPU. 절대 가정하지 마십시오.

5. 검증

  1. 동일한 출력: 동일한 오디오/입력을 CPU와 NPU에서 실행; 음성의 경우 10개 이상의 실제 클립에서 단어 오류율 확인. 16비트 활성화는 일반적으로 무손실; 8비트 가중치는 반드시 확인.
  2. 속도: 폰에서 실시간 계수 및 첫 출력 지연 시간 측정.
  3. 전력: 프로세스의 CPU %, 고정 30-60분 작업 동안 CPU vs NPU의 배터리 소모, 화면 꺼짐, 동일 밝기 및 네트워크 조건에서 측정. 반복; 열 상태가 결과를 변화시킴.
  4. 결과(칩, SDK 버전, 모델 커밋, 양자화, 수치)를 모델 옆에 기록.

함정

  • 동적 크기, int64 입력, 지원되지 않는 연산(일부 attention 또는 제어 흐름 연산): QNN이 아닌 내보내기에서 수정(모델 래핑, 길이 수정).
  • 컨텍스트 바이너리는 SDK 버전 제품군에 종속됨: 런타임 라이브러리와 동일한 QAIRT 버전으로 빌드.
  • 일부 연산에서 CPU로 폴백되는 모델은 이득의 대부분을 조용히 잃음: CPU 파티션 로그 확인.
  • 라이선스: 모델(컴파일된 형태의 재배포는 모델 재배포) 및 QNN SDK.
  • 로컬 Linux 없는 대안: Qualcomm AI Hub(클라우드 컴파일 및 실제 장치에서 프로파일링; 계정 필요; 앱에 대한 조건 확인).

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬