6.3 KiB
BUG in-app .pte 7B/8B (err 5010) — RÉSOLU : mauvaise version de backend QNN chargée par l'app
Date : 17/06/2026 · Sévérité : bloquant in-app pour les .pte denses multi-context (≥7B, num_sharding=2)
Statut : cause isolée — ce n'est NI le .pte, NI le wrapper libkazeia_pte.so. C'est l'intégration app (résolution de lib QNN).
⚠️ Rétracte
BUG_pte_multicontext_offset_overflow.md(théorie « overflow int32 » du.pte) : réfutée par le test CLI ci-dessous. Le.pte8B (2ᵉ context group à 3,24 G > 2 GiB) charge et génère sans problème avec le bon runtime. Pas d'overflow.
1. TL;DR
L'erreur in-app Context group 1 does not exist / Error 5010 est la signature d'un backend QNN trop ancien (≠ QAIRT 2.42) qui ne sait pas désérialiser la structure multi-context (sharding=2) des .pte ≥7B. Le backend 2.42 (ship_runtime/) les charge parfaitement. L'app charge un autre libQnnHtp.so/backend que celui livré (collision de SONAME, très probablement avec la pile ORT-QNN du STT, ou une lib d'une autre version restée sur le chemin du linker).
Fix : garantir que c'est bien la pile QNN 2.42 qui est mappée dans le process app au moment du chargement .pte (pas la version du STT/Maven). Aucun changement de .pte ni de wrapper.
2. Preuve d'isolation (décisive)
Sur le même device, avec le ship_runtime/ 2.42 livré, sur le même .pte Qwen3-8B (le cas « échec » de la théorie overflow) :
| Test sur Qwen3-8B (5,5 G, 2ᵉ context group à 3,24 G > 2 GiB) | Résultat |
|---|---|
Runner CLI qnn_llama_runner + ship_runtime 2.42 |
✅ 313 tokens, 9,65 tok/s, FR cohérent, EOS propre |
Wrapper libkazeia_pte.so (notre JNI) + ship_runtime 2.42 |
✅ 41 tokens, 10,3 tok/s, cohérent |
Dans les deux cas, le log montre QnnContextCustomProtocol expected magic 0x5678abcd but get 0x2000000 ET génère quand même → ce message est un INFO bénin présent dans les chargements qui marchent, pas la cause de l'échec. L'app, elle, enchaîne sur Context group 1 does not exist / err 5010 : c'est un second symptôme, propre à l'app, qui ne sort PAS avec le backend 2.42.
Conclusion logique : si c'était un overflow d'offset dans le .pte ou dans notre backend, le CLI et le wrapper échoueraient aussi. Ils réussissent. Donc l'app exécute un backend différent.
3. Cause racine — collision de version libQnnHtp / backend
libkazeia_pte.so ne NEEDED que libqnn_executorch_backend.so (le reste statique). Mais ce backend charge à son tour libQnnHtp.so / libQnnSystem.so par SONAME. Si l'APK contient plusieurs versions de ces libs — typiquement :
- la pile ORT-QNN du STT (qui embarque sa propre
libQnnHtp.so, possiblement une autre version QAIRT), - d'anciennes libs LLM (ère 2.32/2.37) restées dans
jniLibs, - une AAR QNN Maven,
…le linker Android n'en mappe qu'une seule par SONAME. Si la version gagnante n'est pas 2.42, le backend ExecuTorch reçoit un libQnnHtp incompatible → Context group N does not exist / err 5010 sur les .pte multi-context.
Pourquoi 4B marche et 7B/8B non : un backend trop ancien gère encore le layout de contexte simple du 4B, mais pas la structure multi-context (2 groups) des modèles plus gros. La forensique avait raison de voir « 2 context groups » sur les 7B/8B — mais la cause n'est pas un overflow dans le .pte, c'est le backend de l'app qui ne sait pas les parser. Le 2.42 les parse (prouvé §2).
4. Diagnostic à faire côté dev (confirme la cause en 2 min)
Quelle version de libQnnHtp est RÉELLEMENT mappée dans le process app ?
PID=$(adb shell pidof com.kazeia)
adb shell run-as com.kazeia cat /proc/$PID/maps | grep -iE 'libQnnHtp|libqnn_executorch_backend|libQnnSystem' | awk '{print $NF}' | sort -u
# puis pour chaque .so mappé :
adb shell run-as com.kazeia strings <chemin_mappé>/libQnnHtp.so | grep -m1 AISW_VERSION # doit être 2.42.0
Si la version mappée ≠ 2.42.0, la cause est confirmée.
Vérifier les doublons de QNN dans l'APK :
unzip -l app-release.apk | grep -iE 'libQnnHtp|libQnnSystem|libqnn' # ne doit PAS y avoir 2 origines/versions
SHA256 attendus (libs 2.42 de ship_runtime/) — ceux livrés dans jniLibs/arm64-v8a/ DOIVENT matcher :
95d01368b556f0c6… libqnn_executorch_backend.so
10eb1923b34ac9a7… libQnnHtp.so
a69cfc4350c16b22… libQnnSystem.so
a08fb34747345125… libQnnHtpV79Stub.so
7ee72b438c97c13c… libQnnHtpV79Skel.so
2daafb376fe6904a… libQnnHtpPrepare.so
a3bc48674377a042… libQnnHtpNetRunExtensions.so
5. Fix
- Une seule version de QNN dans l'app = 2.42 (celle de
ship_runtime/), pour le STT et le LLM.pte. Concrètement :- Retirer de
jniLibstoutelibQnnHtp*.so/libQnnSystem.soqui n'est pas du build 2.42 (anciennes libs LLM, AAR Maven d'une autre version). - Si le STT (ORT-QNN) impose une version QNN différente, aligner les deux sur 2.42 (le STT marche sur 2.42 ; ORT-QNN EP est tolérant à la version de
libQnnHtptant qu'elle ≥ celle de compilation). À défaut, isoler (process séparé) — mais l'alignement sur 2.42 est le plus simple.
- Retirer de
- Re-vérifier le
/proc/pid/maps:libQnnHtp.somappé = 2.42.0. - Aucun ré-export de
.pte, aucun rebuild delibkazeia_pte.sonécessaires.
6. Reproduction de la PREUVE (artefact sain)
# device, dossier avec le .pte 8B + tokenizer + ship_runtime/ 2.42 + prompt_ids.bin (uint64 LE)
ADSP_LIBRARY_PATH=. LD_LIBRARY_PATH=. ./qnn_llama_runner \
-model_path qwen3_8b.pte -tokenizer_path tokenizer.json \
-tokenized_prompt p8b_ids.bin -decoder_model_version qwen3 -eval_mode 1 -seq_len 512 -temperature 0
# Attendu : génère ~300 tokens à ~9-10 tok/s. PAS d'err 5010.
Le ship_runtime/ contient qnn_llama_runner + les 7 libs 2.42 : c'est l'oracle « bon backend ».
7. Données
.ptevalidés (génèrent avec 2.42) :qwen3_4b_seq1024/,qwen3_8b_seq512/,qwen2_5_7b_seq512/,kazeia-tablet-backup/llm/hybrid_llama_qnn_guard4b.pte.- Runtime de référence :
/opt/Kazeia/pte_prep_work/ship_runtime/(QAIRT 2.42,libQnnHtp= AISW_VERSION 2.42.0). - À fournir pour clore :
/proc/<pid>/mapsdu process app pendant un load 8B + listeunzip -ldeslibQnn*de l'APK.