5.3 KiB
5.3 KiB
Déploiement ExecuTorch + QNN NPU — OnePlus Pad 3
Procédure validée le 28 mars 2026
Prérequis
- Tablette rootée (Magisk)
- SELinux permissive (
su -c 'setenforce 0') - DSP permissions ouvertes (boot script
/data/adb/service.d/kazeia_dsp.sh) - QNN SDK 2.42 installé sur le PC :
/opt/Kazeia/qnn_sdk_242/qairt/2.42.0.251225/ - ExecuTorch compilé pour Android ARM64 :
/opt/Kazeia/executorch/build-android/
Fichiers requis (TOUS obligatoires)
| Fichier | Source | Rôle |
|---|---|---|
qnn_llama_runner |
executorch/build-android/examples/qualcomm/oss_scripts/llama/ |
Runner LLM |
libqnn_executorch_backend.so |
executorch/build-android/backends/qualcomm/ |
Backend ExecuTorch ↔ QNN |
libQnnHtp.so |
qnn_sdk_242/.../lib/aarch64-android/ |
QNN HTP runtime |
libQnnHtpV79Stub.so |
qnn_sdk_242/.../lib/aarch64-android/ |
Stub CPU → DSP |
libQnnHtpV79Skel.so |
qnn_sdk_242/.../lib/hexagon-v79/unsigned/ |
Skel DSP (hexagon) |
libQnnHtpPrepare.so |
qnn_sdk_242/.../lib/aarch64-android/ |
Préparation graphe HTP |
libQnnSystem.so |
qnn_sdk_242/.../lib/aarch64-android/ |
Système QNN |
libQnnModelDlc.so |
qnn_sdk_242/.../lib/aarch64-android/ |
Chargement modèles DLC |
libQnnHtpNetRunExtensions.so |
qnn_sdk_242/.../lib/aarch64-android/ |
Extensions réseau HTP |
hybrid_llama_qnn.pte |
models_qnn/qwen3-*-executorch/ |
Modèle ExecuTorch |
tokenizer.json |
models_qnn/qwen3-*-executorch/ |
Tokenizer HuggingFace |
IMPORTANT : Les libs Skel DOIVENT venir du même SDK que celui utilisé pour compiler le .pte. Ne PAS utiliser les libs vendor de la tablette (/vendor/lib64/hw/audio/).
Script de déploiement
#!/bin/bash
QNN="/opt/Kazeia/qnn_sdk_242/qairt/2.42.0.251225"
ET="/opt/Kazeia/executorch"
DIR="/data/local/tmp/kazeia-et"
MODEL_DIR="/opt/Kazeia/models_qnn/qwen3-0_6b-executorch" # ou qwen3-1_7b-executorch
# Créer répertoire
adb shell "rm -rf $DIR && mkdir -p $DIR/outputs"
# Libs QNN SDK 2.42
adb push $QNN/lib/aarch64-android/libQnnHtp.so $DIR/
adb push $QNN/lib/aarch64-android/libQnnHtpV79Stub.so $DIR/
adb push $QNN/lib/hexagon-v79/unsigned/libQnnHtpV79Skel.so $DIR/
adb push $QNN/lib/aarch64-android/libQnnHtpPrepare.so $DIR/
adb push $QNN/lib/aarch64-android/libQnnSystem.so $DIR/
adb push $QNN/lib/aarch64-android/libQnnModelDlc.so $DIR/
adb push $QNN/lib/aarch64-android/libQnnHtpNetRunExtensions.so $DIR/
# ExecuTorch
adb push $ET/build-android/backends/qualcomm/libqnn_executorch_backend.so $DIR/
adb push $ET/build-android/examples/qualcomm/oss_scripts/llama/qnn_llama_runner $DIR/
# Modèle + Tokenizer
adb push $MODEL_DIR/hybrid_llama_qnn.pte $DIR/
adb push $MODEL_DIR/tokenizer.json $DIR/
# Permissions
adb shell "chmod +x $DIR/qnn_llama_runner"
Exécution
adb shell "su -c 'cd /data/local/tmp/kazeia-et && \
export LD_LIBRARY_PATH=/data/local/tmp/kazeia-et && \
export ADSP_LIBRARY_PATH=/data/local/tmp/kazeia-et && \
./qnn_llama_runner \
--model_path hybrid_llama_qnn.pte \
--tokenizer_path tokenizer.json \
--decoder_model_version qwen3 \
--output_path outputs/outputs.txt \
--performance_output_path outputs/perf.txt \
--shared_buffer \
--prompt \"Votre prompt ici\" \
--system_prompt \"Tu es Kazeia, compagnon écoute émotionnelle.\" \
--temperature 0.7 \
--seq_len 256 \
--eval_mode 1'"
Paramètres clés
| Paramètre | Valeur | Description |
|---|---|---|
--decoder_model_version |
qwen3 |
Template de chat Qwen3 |
--eval_mode |
1 |
Mode hybride (prefill + KV cache) |
--shared_buffer |
(flag) | OBLIGATOIRE — mémoire partagée CPU↔DSP |
--output_path |
chemin | Fichier de sortie texte |
--temperature |
0.0-1.0 | 0 = déterministe, 0.7 = créatif |
--seq_len |
128-4096 | Longueur max (prompt + réponse) |
Performances mesurées
Qwen3-0.6B (660 MB)
- Chargement : 0.86s
- Prefill : 31ms (451 tok/s)
- Génération : 93.15 tok/s
- Temps au premier token : 31ms
- RAM : ~698 MB
Qwen3-1.7B (1.7 GB)
- Génération : ~25.7 tok/s (benchmark mars 2026)
Mistral-Nemo 12B (7.4 GB)
- Génération : ~5.1 tok/s (benchmark mars 2026)
Modèles disponibles
| Modèle | Fichier .pte | Taille | Qualité FR |
|---|---|---|---|
| Qwen3-0.6B | qwen3-0_6b-executorch/hybrid_llama_qnn.pte |
660 MB | Basique |
| Qwen3-1.7B | qwen3-1_7b-executorch/hybrid_llama_qnn.pte |
1.7 GB | Bonne |
| Mistral-Nemo 12B | mistral-nemo-executorch/hybrid_llama_qnn.pte |
7.4 GB | Excellente |
Erreurs courantes
loadRemoteSymbols failed with err 4000
- Cause : Libs Skel manquantes ou incompatibles
- Fix : Vérifier que
libQnnHtpV79Skel.sovient du SDK 2.42 (hexagon-v79/unsigned/), pas du vendor
SoC model (SnapdragonModel) is unknown
- Cause : Utilisation des libs vendor au lieu des libs SDK
- Fix : Ne PAS utiliser
/vendor/lib64/hw/audio/libQnn*.so
Runner se termine sans générer de texte
- Cause :
--shared_bufferet--output_pathmanquants - Fix : Ajouter les deux paramètres
Failed to create transport for device
- Cause :
libQnnModelDlc.somanquant - Fix : Copier depuis
qnn_sdk_242/.../lib/aarch64-android/
Projet Kazeia — Damien Micottis & Richard Loyer