Skip to content

hexagon: support for device discovery and create sessions on demand - #27785

Merged
ggerganov merged 3 commits into
ggml-org:masterfrom
qualcomm:hexagon-devices
Aug 30, 2026
Merged

hexagon: support for device discovery and create sessions on demand#27785
ggerganov merged 3 commits into
ggml-org:masterfrom
qualcomm:hexagon-devices

Conversation

@max-krasnyansky

Copy link
Copy Markdown
Member

Overview

Minor overhaul of how ggml-hexagon creates devices and sessions.

The original implementation created session early during backend init.
Since the number of supported sessions is limited it makes sense to create them only when actually needed for loading & running a model.
This change enables running llama-server in "router mode" without wasting available sessions.

This update also adds support for NPU discovery at run-time on on devices that support newer API
(like the IQ10, and the latest Android phones).
If the device discover is not supported we fallback to the original hardcoded NPU/CDSP domain values.

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: Yes, used Antigravity to review and refactoring.

@max-krasnyansky
max-krasnyansky requested a review from a team as a code owner August 27, 2026 04:38
@github-actions github-actions Bot added ggml changes relating to the ggml tensor library for machine learning Hexagon labels Aug 27, 2026
@max-krasnyansky

Copy link
Copy Markdown
Member Author

@CreaV here is the PR that adds auto-discovery (and on-demand sessions).
re: our discussions from #26501

@max-krasnyansky

Copy link
Copy Markdown
Member Author

Tested on:

  • Galaxy S24 (v75) -- discovery not supported
  • Galaxy S25 (v79) -- discovery not supported
  • Galaxy S26 (v81) -- discovery is supported, returns single domain
  • IQ9 EVK (dual v73) -- discovery not supported
  • WoS on X2 elite -- discovery not supported

(test results from IQ10 are coming a bit later)

max-krasnyansky and others added 3 commits August 27, 2026 10:01
…interfaces

Co-authored-by: Marco Colombo <mcolombo@qti.qualcomm.com>
Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com>
Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>
@CreaV

CreaV commented Aug 28, 2026

Copy link
Copy Markdown

@max-krasnyansky Thanks for the update. We rebased our SA8797P changes onto the latest version of this PR and successfully validated it on the Android guest.

Runtime FastRPC domain discovery now correctly identifies all four physical NSPs (nsp1000–nsp1003). Our previous local domain-discovery workaround is no longer required. Multi-NSP tensor split and streaming inference are both working correctly.

We found one separate Hexagon issue that may be worth discussing. ggml_hexagon_supported_mul_mat() currently rejects quantized matrix multiplications when src0->ne[1] > 32768. Qwen3-VL has a 151936-row output head, so the LM head otherwise falls back to the CPU.

We added an opt-in configurable row limit locally and verified that the larger LM-head matmul runs correctly on SA8797P. Would you prefer this limit to be exposed as a backend configuration option, or replaced with a capability/resource-based check?

We can prepare this as a separate PR if useful.

Thanks again for implementing the runtime domain discovery support.

@max-krasnyansky

max-krasnyansky commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

@max-krasnyansky Thanks for the update. We rebased our SA8797P changes onto the latest version of this PR and successfully validated it on the Android guest.

Runtime FastRPC domain discovery now correctly identifies all four physical NSPs (nsp1000–nsp1003). Our previous local domain-discovery workaround is no longer required. Multi-NSP tensor split and streaming inference are both working correctly.

Yep. Confirmed internally as well. Thank you for the update.
I'll mark this as read to merge.

We found one separate Hexagon issue that may be worth discussing. ggml_hexagon_supported_mul_mat() currently rejects quantized matrix multiplications when src0->ne[1] > 32768. Qwen3-VL has a 151936-row output head, so the LM head otherwise falls back to the CPU.

We added an opt-in configurable row limit locally and verified that the larger LM-head matmul runs correctly on SA8797P. Would you prefer this limit to be exposed as a backend configuration option, or replaced with a capability/resource-based check?

We can prepare this as a separate PR if useful.

Ha. I didn't even think of this in the multi-NPU context.
There is a MatMul PR coming shortly where I'm going to revisit the solver (it underestimates VTCM requirements for the new Nemotron models) and I'm revisiting the QKV and FFN MM fusion with HMX. We should be able to get rid of that hardcoded hack for ne[1] now. I'll include it in that PR and tag you for review/testing/updates.

@max-krasnyansky max-krasnyansky added the merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge. label Aug 28, 2026
@max-krasnyansky

Copy link
Copy Markdown
Member Author

@lhez please review/ack when you get a chance

@ggerganov
ggerganov merged commit 9e54e68 into ggml-org:master Aug 30, 2026
30 of 32 checks passed
@GaTmaNnes

Copy link
Copy Markdown

e: ggml_hexagon_supported_mul_mat() ne1 > 32768 → lm-head CPU fallback
We're hitting the exact same issue on the OnePlus 15 (Snapdragon 8 Elite Gen 5, SM8850, Hexagon HTP v81) with a Qwen3.5-9B (hybrid Mamba-2 + attention).
Our output.weight (lm-head) is [4096, 248320] — the vocab is 248k — so src0->ne[1] = 248320 > 32768 and the quantized matmul is rejected by ggml_hexagon_supported_mul_mat(), falling back to CPU.
Measured impact on our decode:

  • lm_head ≈ 26% of the total decode traffic (~795 MB/token of the ~4.53 GB/token total), and it runs on CPU because of this limit.
  • The whole decode is DDR-bandwidth-bound (~30 GB/s GGML, ~74 GB/s QAIRT), so keeping this single tensor on CPU adds a large fixed cost per token.
    We'd also prefer an opt-in configurable row limit (e.g. env GGML_HEXAGON_MAX_MUL_MAT_ROWS, default 32768) rather than a hardcoded cap, so we can test the 248k-row lm-head on HTP on v81 like you did on SA8797P. Happy to validate on our side and report back if that helps.

@max-krasnyansky

Copy link
Copy Markdown
Member Author

@CreaV @GaTmaNnes
Here is the MUL_MAT PR that removes the 32K limit #28202

@GaTmaNnes

Copy link
Copy Markdown

hanks Max. This is very relevant to what I have been measuring on an SM8850 device with Qwen3.5-9B-D2-A-MTP.

I have been profiling the Hexagon HTP path quite extensively, and one result seems particularly relevant to the solver/fusion changes you mention.

On the same model and HTP configuration, I selectively requantized the attention weights from Q8_0 to Q4_0:

model: 7.29 GiB → 5.07 GiB (~30% smaller)
DSP/MUL_MAT time: ~415 µs → ~345 µs (~17% reduction)
total DSP batch time: ~1.10 s → ~0.95 s (~14% reduction)
but decode throughput remained essentially unchanged (~6–7 tok/s).

I also confirmed from the backend code that activations are still dynamically quantized to Q8_0_TILED for these matmuls, so the weight reduction does not eliminate the activation quantization/repack path.

This makes me suspect that the remaining decode bottleneck is not simply the amount of weight data or raw MUL_MAT compute, but the surrounding execution pipeline: VTCM preparation, buffer management, op batching/queueing, synchronization and possibly fusion opportunities.

Your #28202 changes to QKV/FFN fusion, the VTCM solver, OPBATCH/OPQUEUE sizing and VA buffer fragmentation therefore look particularly relevant.

I am going to benchmark the same workload against #28202 and compare:

MUL_MAT count → fused ops → DSP time → VTCM usage → DMA events → OPQUEUE/OPBATCH → wall-clock decode

One additional observation: MXFP4 attention at essentially the same model size as Q4_0 gave ~6.6 tok/s versus ~5.9 tok/s for Q4_0 in one controlled run, despite very similar DMA event counts. So there may also be a kernel/data-layout effect beyond simple byte count.

If you have any specific profiling counters or traces that would be useful for validating whether the new fusion/solver path is actually removing pipeline overhead on SM8850, I would be happy to collect them

@GaTmaNnes

Copy link
Copy Markdown

NEXA / GENIEX ENQUÊTE
HISTORIQUE D’EXÉCUTION QUALCOMM HTP / HEXAGON / OPENCL / GGML / MTP
RAPPORT
TECHNIQUE REPRODUCTIBLE ======================================================================

Date :
01-09-2026

Portée :
SDK historique Nexa / lignée
exécutable Qualcomm GenieX / Nexa runtime
GGML / llama.cpp architecture
backend Exécution
HTP hexagonale OpenCL / Adreno exécution
MTP décodage
spéculatif du plan mémoire gallocr comportement
OPPOLL Placement

HTP<->GPU Investigation

de régression à l’exécution ======================================================================

  1. RÉSUMÉ
    EXÉCUTIF ======================================================================

L’enquête établit plusieurs faits indépendants.

  1. La lignée historique du SDK Nexa/exécutable est récupérable.

SourceForge héberge un miroir exact du projet Nexa SDK et identifie explicitement
le dépôt en amont comme :

https://github.com/NexaAI/nexa-sdk

Le miroir contient des archives sources historiques et des paquets exécutables.

  1. Le fork exécutable communautaire est réel et utile pour la comparaison médico-légale :

https://github.com/zhycheng614/nexa-sdk-executable

Il décrit Nexa SDK comme supportant à la fois GGML et ONNX ainsi que plusieurs
modalités d’inférence.

  1. Le dépôt Qualcomm moderne est désormais visible comme :

https://github.com/qualcomm/nexa-sdk

Cela est important car le dépôt historique NexaAI et la
lignée maintenue par Qualcomm ne doivent PAS automatiquement être considérés comme
des environnements d’exécution équivalents octet pour octet.

  1. Les expériences montrent que l’exécution HTP est fondamentalement différente de l’exécution
    pure GPU.

  2. Requantification d’attention sélective :

7,29 Gio -> 5,07 Gio
environ -30 % du

poids du modèle n’a PAS significativement amélioré le débit de décodage de l’horloge murale.

  1. Le placement mixte HTP/GPU a produit une légère amélioration du décodage lors d’une
    expérience JZ :

HTP0 : 7,68 t/s
HTP0->GPU : 8,11 t/s
GPU->HTP0 : 8,14 t/s
GPU seulement : 5,42 t/s

Cependant, ces mesures étaient thermiquement contaminées et
ne doivent donc PAS être utilisées comme chiffres définitifs de débit architecturaux.

  1. Le runtime JZ contient le diagnostic gallocr AXE-8.

Il a rapporté :

7 254 incompatibilités

plan/identité durant la diffusion du MTP.

Fait crucial, une série ultérieure hors MTP a également produit :

2 662 désaccords

LesÀ l’effet, le phénomène de décalage n’est PAS uniquement causé par le MTP.

  1. Le diagnostic de désappariement prouve néanmoins que ggml gallocr rencontre
    des changements d’identité tensorielle par rapport à un plan d’allocation précédemment construit
    .

Le diagnostic lui-même indique explicitement :

« possible corruption silencieuse si le plan est réutilisé ».

C’est un signal sérieux d’allocateur/validité du plan.

  1. L’acceptation du MTP était stable :

41 acceptés / 62 acceptés générés
= 66,129 %
longueur moyenne spéculative = 2,95

Cette stabilité est une preuve utile que le mécanisme du MTP lui-même fonctionne
de manière reproductible.

  1. L’OPPOLL n’a pratiquement pas apporté d’amélioration au runtime JZ.

Premier JZ A/B :
base ~8,28 t/s
OPPOLL ~8,71 t/s

Comparaison antérieure plus froide du JZ :
9,71 vs 9,62 t/s

La variation suit la température suffisamment fortement pour que ces différences
ne puissent pas être interprétées comme un gain OPPOLL significatif.

  1. L’exécution MTP JZ a montré environ 97 % d’utilisation du CPU pendant la
    génération alors que l’activité HTP/NPU était présente.

C’est une preuve solide que le chemin MTP contient un important composant de contrôle/orchestration côté
CPU.

  1. L’appareil est devenu saturé thermiquement :

environ 38-40 °C au début
environ 72-74 °C pendant la génération

. Par conséquent, l’état thermique est une variable expérimentale de première classe.

  1. La bonne étape suivante est de NE PAS continuer à optimiser le placement à l’aveugle.

La bonne étape suivante est :

RESTAURER / IDENTIFIER L’EXÉCUTION
HISTORIQUEMENT FONCTIONNANTE -> GELER LE BINAIRE EXACT + les bibliothèques
-> reproduire la base
de référence -> comparer le runtime JZ avec l’exécution historique
-> ensuite enquêter sur MTP / OPPOLL / ============================== de placement

==========
2. SOURCE / DÉPÔT DE PREUVES

2.1 Miroir

historique SourceForge indique explicitement que son projet est un miroir exact de :

https://github.com/NexaAI/nexa-sdk

SourceForge :

https://sourceforge.net/projects/nexa-sdk.mirror/files/

Evidence :

Le miroir contient des paquets versionnés et des archives sources historiques.

Par exemple, la version 0.2.72 contient :

la source v0.2.72 code.tar.gz
la code.zip
source
v0.2.72 ainsi que les paquets Linux, Windows et macOS.

Source :

https://sourceforge.net/projects/nexa-sdk.mirror/files/v0.2.72/

Ceci est précieux pour l’archéologie en temps exécutif car les instantanés historiques
des sources peuvent être comparés sans dépendre exclusivement du dépôt actuel.

2.2 Disponibilité

des versions historiques Le miroir contient une séquence comprenant :

v0.2.68,
v0.2.69,
v0.2.71
, v0.2.72,
v0.2.73

et versions ultérieures.

Source :

https://sourceforge.net/projects/nexa-sdk.mirror/files/

Le miroir actuel expose également des paquets plus récents tels que v0.4.0 et v0.5.0.

Sources :

https://sourceforge.net/projects/nexa-sdk.mirror/files/v0.4.0/

https://sourceforge.net/projects/nexa-sdk.mirror/files/v0.5.0/

Cela nous donne un axe
historique pratique :
l’ancienne Nexa
|
+-- v0.2.x
|
+-- v0.3.x
|
+-- v0.4.x
|
+-- v0.5.x / Geniex lineage

2.3 Fork
exécutable communautaire Fork
communautaire :

https://github.com/zhycheng614/nexa-sdk-executable

Le dépôt décrit Nexa SDK comme supportant :

GGML
ONNX
génération

d’images VLM
Mode

serveur
ASR TTS
Ceci est utile comme artefact supplémentaire car il préserve une vue
orientée exécutable du SDK plutôt que seulement l’historique source.

======================================================================
3. LIGNÉE
ACTUELLE QUALCOMM ======================================================================

La lignée actuelle des dépôts est visible sous :

https://github.com/qualcomm/ne les données du workflow GitHub de xa-sdk

exposent des versions telles que :

v0.2.73
v0.2.73-rc1
v0.2.72

et les commits associés au processus de compilation/publication.

Source :

https://github.com/qualcomm/nexa-sdk/actions

Cela est important car notre temps d’exécution expérimental doit être identifié par :

hachage exécutable date
de
compilation, commit/tag si disponible
, hachages de bibliothèques partagées
DSP/HTP, bibliothèques

OpenCL Variables
d’environnement
plutôt que de simplement l’appeler « Nesta ».

======================================================================
4. ARCHITECTURE
BACKEND GGML / LLAMA ======================================================================

L’architecture llama.cpp en amont confirme que GGML prend en charge les backends chargés dynamiquement
.

Le chargeur backend recherche les bibliothèques backend et inclut explicitement :

opencl hexagon
cpu
cuda
hip
vulkan
...

Source :

https://github.com/ggml-org/llama.cpp/blob/master/ggml/src/ggml-backend-reg.cpp

L’implémentation backend est centralisée dans :

ggml-backend.cpp

Source :

https://github.com/ggml-org/llama.cpp/blob/master/ggml/src/ggml-backend.cpp

Cela est important pour l’enquête car un seul exécutable de serveur
lama peut théoriquement exposer plusieurs backends d’exécution.

Le projet en amont documente également Hexagon en tant que backend Snapdragon et
prend en charge l’exécution hybride CPU/GPU.

Source :

https://github.com/ggml-org/llama.cpp

======================================================================
5. OPENCL / ADRENO EVIDENCE

Le backend OpenCL en amont prend explicitement en charge les noyaux spécifiques à Adreno.

Les options pertinentes incluent :

GGML_OPENCL_EMBED_KERNELS GGML_OPENCL_USE_ADRENO_KERNELS
GGML_OPENCL_USE_ADRENO_BIN_KERNELS

Source :

https://github.com/crc-org/llama.cpp/blob/main/docs/backend/OPENCL.md

Par conséquent, une compilation OpenCL+HTP n’est pas conceptuellement un temps d’exécution sur un seul dispositif.

Il peut contenir :

CPU
|
+-- OpenCL / Adreno
|
+-- Hexagon / HTP

La discussion sur la compilation d’Hexagon documente également une
véritable configuration dual-backend de Snapdragon impliquant Hexagon et OpenCL.

Source :

#23314

Cela soutient directement la stratégie expérimentale de comparaison :

HTP uniquement

OpenCL + OpenCL

uniquement au lieu de supposer que « temps d’exécution HTP » signifie « rien d’autre ne s’exécute sur GPU ».

======================================================================
6. MODÈLE EN COURS DE TEST

Modèle principal :

Qwen3.5-9B-D2-A-MTP

Quantification :

Q4_0 requantisation sélective de l’attention de base
Q8 -> Q4_0

Taille du modèle :

Original :
~7,29 Gio

Requantisation de l’attention :
~5,07 Gio

Réduction :

~30 %

La requantisation de l’attention était donc suffisamment importante pour tester si
la bande passante mémoire / le mouvement de poids était le goulot d’étranglement dominant.

======================================================================
7. RÉSULTAT
DE LA REQUANTISATION DE L’ATTENTION ======================================================================

Expérience :

Attention Q8 -> Q4_0

Observation :

modèle :
7,29 GiB -> 5,07 GiB

tg8 :
6,72 t/s -> 6,68 t/s

Par conséquent :

environ -30 % du poids du

modèle n’a PAS conduit à une amélioration significative du débit de décodage.

Le timing interne des DSP s’est néanmoins amélioré :

total DSP :
1 100 s -> 0,950 s

MUL_MAT :
414,8 us -> 344,9 us

C’est une distinction très importante.

Le calcul HTP de bas niveau est devenu plus rapide, tandis que la génération de jetons
de bout en bout ne l’a pas fait.

Interprétation :

l’arithmétique HTP n’est PAS le seul facteur limitant.

Le temps manquant est donc probablement dans un ou plusieurs des cas suivants :

synchronisation de l’orchestration
CPU
, synchronisation DMA / déplacement
de la mémoire,
planification du backend, transitions backend,
gestion
de graphes, décodage spéculatif, contrôle,
overhead

d’exécution ============================================================8 ==========
. EXPÉRIENCE
DE PLACEMENT HTP/GPU ======================================================================

Durée d’exécution :

JZ

Modèle :

attnQ4

Placement :

ngl=33

Test :

pp16 + tg16

Résultats :

Placement pp16 tg16

HTP0 pur 54.80 7.68
HTP0 -> GPU 60.10 8.11
GPU -> HTP0 42.23 8.14
GPU pur 35.84 5.42

Interprétation initiale :

placement mixte :
environ +5-6 % décoder

GPU uniquement :
GPU->HTP :

préremplissage

médiocre Cependant, des preuves thermiques ultérieures invalident le traitement de ces chiffres comme un
architecturale propre.

La température de l’appareil lors des essais ultérieurs atteignait :

~72-74 °C

, tandis que les relancements à froid produisaient un débit bien plus élevé.

Donc :

résultat de placement = résultat de placement intéressant
dans la direction = résultat de placement NON contrôlé
thermiquement = nécessite une réplication

à froid L’expérience établit néanmoins une hypothèse importante :

HTP + GPU peut potentiellement améliorer légèrement le décodage,
mais le GPU seul n’est pas compétitif dans cette configuration.

======================================================================
9. OPPOLL EXPERIMENT

Le temps d’exécution en amont avait auparavant démontré environ :

10,3-10,5 t/s

avec en amont + OPPOLL.

Le temps d’exécution JZ ne reproduisait pas ce gain.

Les comparaisons observées de JZ comprenaient :

~8,28 t/s base
~8,71 t/s OPPOLL

et une autre comparaison plus froide :

9,71 t/s
9,62 t/

s Les différences sont faibles par rapport à la variation thermique.

Conclusion :

OPPOLL ne démontre actuellement pas de gain
de performance significatif sur l’exécution JZ.

Cela suggère fortement que le mécanisme OPPOLL dépend du temps d’exécution et de la compilation.

Il ne doit donc PAS être considéré comme un commutateur universel garantissant
l’amélioration des performances en amont.

======================================================================
10. CONTAMINATION THERMIQUE

Le comportement thermique est l’un des facteurs de confusion les plus forts découverts.

Exemple MTP base :

start :
~38.4 C

serveur prêt :
~47.3 C

complétion :
~72.5 C

Exemple MTP OPPOLL :

start :
~38.7 C

serveur prêt :
~47.7 C

complétion :
~73.6 C

Cela signifie sequeLes comparaisons de benchmarks initiaux peuvent devenir invalides très rapidement.

Une différence de débit de plusieurs pourcentages peut être causée par :

la limitation
thermique
plutôt que :

la
quantification
backend
Placement

OPPOLL Par conséquent, chaque futur benchmark doit enregistrer :

température
de départ température prête
pour le serveur Température
terminale Fréquence
CPU Utilisation CPU Température

NPU Température GPU Température

DDR ======================================================================
11. CORRECTIF
DU SAMPLER DE TÉLÉMÉTRIE ======================================================================

Le premier échantillonneur de télémétrie a échoué car Android mksh ne prend pas en charge
la substitution de procédés Bash :

< <(...)

La construction défaillante a été remplacée par une méthode de fichier
temporaire compatible POSIX.

L’échantillonneur résultant fonctionne sur Android.

Exemple de sortie réussi :

cpu %=5
t_cpu=35900
t_gpu=35600
t_npu=34900
t_ddr=35600
freq0=787200
frequ0=883200

Pendant MTP :

cpu %=97
t_cpu=72700
t_npu=58900
frequ6=2438400

C’est une instrumentation puissante preuves.

======================================================================
12. SATURATION DU CPU PENDANT LE MTP

L’observation la plus importante à l’exécution est :

génération de MTP :
utilisation du CPU ~= 97 %

tandis que :

l’exécution HTP/NPU est active.

Cela signifie que le NPU ne fonctionne pas comme un moteur de calcul isolé.

Le temps d’exécution MTP dispose d’un important chemin de contrôle côté hôte.

Les candidats probables incluent :

préparation du graphe d’exécution
du brouillon, préparation

du graphe, vérification
du graphe, token de vérification de la comptabilité,
acceptation du traitement
, planificateur, activité
du planificateur backend,
synchronisation de l’allocation et gestion
du plan d’allocation, gestion

du tensor/vue Cela est cohérent avec l’observation selon laquelle réduire le temps de MUL_MAT HTP n’a
pas amélioré proportionnellement le décodage de bout en bout.

======================================================================
13 ans. AXE 8 GALLOCR ==============================

======================================================================

@GaTmaNnes

Copy link
Copy Markdown

================================================================================
GLOBAL EXPERIMENTAL CONTRIBUTION
MTP 9B - HTP/NPU - THERMAL - ALIGNMENT - REPACK - SCHEDULING
GGML Hexagon / GPU / NPU / QAIRT on Qualcomm SM8850

Status : CONSOLIDATED EXPERIMENTAL DOSSIER
Date : 31 August 2026
Platform : OnePlus 15 CPH2747
SoC : Qualcomm Snapdragon 8 Elite Gen 5 / SM8850
HTP : Hexagon HTP v81
GPU : Adreno 840 / OpenCL
Model : Qwen3.5-9B-D2-A-MTP
Backend : GGML Hexagon / llama.cpp lineage
Scope : MTP / HTP / GPU / CPU / thermal / NGL / repack /
scheduling / alignment / profiling / QAIRT

================================================================================
0. EXECUTIVE SUMMARY

This dossier consolidates the Qualcomm SM8850 experimental campaign,
including:

  • GGML/Hexagon HTP execution
  • CPU / GPU / HTP placement
  • MTP 9B execution
  • thermal behavior
  • NGL/offload sweeps
  • per-operation profiling
  • weight repacking
  • activation quantization
  • VTCM / DMA behavior
  • graph scheduling
  • HMX/HVX execution
  • QAIRT/GenieX reference experiments
  • padding/alignment hypotheses

The AMD XDNA2 experiments are kept separate from Qualcomm Hexagon
experiments because the architectures and software stacks are different.

The strongest result of the Qualcomm campaign is:

HTP0-only decode ~= 6.74 tok/s
HTP0 -> CPU, last 33 layers ~= 9.01 tok/s

This corresponds to:

(9.01 / 6.74 - 1) * 100
~= +33.7 %

Therefore:

MORE HTP OFFLOAD != ALWAYS MORE DECODE PERFORMANCE

The optimal decode configuration depends on:

  • graph placement
  • CPU/HTP split
  • scheduler behavior
  • graph splits
  • tensor geometry
  • weight repacking
  • activation quantization
  • DMA/VTCM transfers
  • kernel efficiency
  • CPU fallback
  • synchronization
  • thermal/DVFS state

The HTP is not intrinsically slow.

In E6:

HTP prefill ~= 301.9 tok/s
GPU prefill ~= 87.7 tok/s

Therefore HTP is approximately:

3.44x faster than OpenCL GPU

for the tested prefill configuration.

However, decode was only:

HTP ~= 5.73 tok/s
GPU ~= 5.57 tok/s

or approximately:

+2.8 % HTP advantage

This shows a major difference between compute-heavy prefill and
memory/control/scheduling-sensitive decode.

The current evidence therefore does NOT support a single bottleneck model.

The current working model is:

T_token =
T_CPU
+ T_HTP
+ T_repack
+ T_activation_quant
+ T_DMA
+ T_VTCM
+ T_sync
+ T_graph_split
+ T_fallback
+ T_KV
+ T_thermal/DVFS
+ T_other

The next decisive experiment is the controlled NGL sweep:

NGL = 0 / 33 / 40 / 50 / 60 / 66 / 75 / 90

followed by a local NGL refinement around the optimum.

================================================================================

  1. PLATFORM
    ================================================================================

Device:

OnePlus 15 CPH2747

SoC:

Qualcomm Snapdragon 8 Elite Gen 5
SM8850 / SM8850-AC

CPU:

ARM CPU

GPU:

Qualcomm Adreno 840
OpenCL

NPU / accelerator:

Qualcomm Hexagon HTP v81

HTP sessions/devices:

HTP0 and additional HTP devices depending on runtime/backend
Exact exposed device count must be recorded for each build.

IMPORTANT:

Do NOT automatically equate the physical/runtime-visible HTP device
count with the number of physical HTP blocks.

Previous campaigns observed multiple HTP sessions, with approximately
3.4-3.6 GiB addressable memory per session and approximately 10-11.4 GiB
aggregate addressable space in configurations exposing three sessions.

OS:

OxygenOS 16

Kernel:

6.12.x in the tested campaigns

QAIRT:

Bundle:
2.45.0.260326

Local SDK:
2.49.0.260730

GGML:

llama.cpp / ggml Hexagon fork
HTP v81 skel rebuild

Project:

C:\Users\videl\Desktop\geniex_harness

================================================================================
2. REPRODUCIBILITY RULES

For every A/B experiment keep constant:

  • device
  • firmware
  • runtime
  • binary
  • exact git commit
  • build flags
  • skel
  • GGUF
  • GGUF hash
  • model architecture
  • quantization
  • prompt
  • context
  • batch
  • ubatch
  • thread count
  • generation parameters
  • MTP configuration
  • GGML_HEXAGON_* variables
  • backend order
  • tensor split
  • warm-up sequence

Record:

  • temperature before run
  • temperature after run
  • maximum temperature
  • thermal zones
  • nsphvx-* counters
  • nsphmx-* counters
  • CPU frequency
  • HTP frequency when available
  • GPU state when available
  • complete stdout
  • complete stderr
  • exit code
  • crashes
  • tombstone/logcat for crashes

Never rely on:

adb ... | grep ...
adb ... | tail ...

for profiling output.

Write complete logs to device, pull them, and analyze offline.

================================================================================
3. IMPORTANT DEVICE STATE RULE

Fast repeated llama-bench executions can leave the CDSP/HTP in a bad state.

A previous CDSP offline state was observed.

A complete power-off restored the device.

Therefore:

CDSP offline != proof of OOM
CDSP offline != proof of HTP memory exhaustion
CDSP offline != proof of backend corruption

For sensitive experiments:

  1. stop old processes
  2. verify CDSP/HTP state
  3. run baseline
  4. avoid rapid process cascades
  5. power-cycle if the DSP enters an abnormal state
  6. record the event

================================================================================
4. MODEL

Primary model:

Qwen3.5-9B-D2-A-MTP

Baseline mixed-attention GGUF:

approximately 7.29 GiB

Selective attention Q4 experiment:

approximately 5.07 GiB

Modification:

attention Q8_0 -> Q4_0

Approximate file-size reduction:

~= 30 %

Important:

File size reduction does NOT automatically imply a proportional
reduction in decode time.

================================================================================
5. HEXAGON DATA PATH

The current backend distinguishes weight representation from
runtime activation representation.

Weight repacking:

GGML_TYPE_Q4_0
|
+--> repack_q4_0_tiled()
|
+--> Q4_0_TILED

GGML_TYPE_Q4_1
|
+--> repack_q4_1_tiled()
|
+--> Q4_1_TILED

GGML_TYPE_Q8_0
|
+--> repack_q8_0_tiled()
|
+--> Q8_0_TILED

GGML_TYPE_IQ4_NL
|
+--> Q4_0_TILED

GGML_TYPE_MXFP4
|
+--> repack_mxfp4_tiled()
|
+--> MXFP4_TILED

The backend does NOT generally promote Q4 weights to Q8 simply because
the HTP kernel is used.

Runtime activation path for the tested quantized matrix operations:

F32 activation
|
v
quantize_f32_q8_0_tiled()
|
v
Q8_0_TILED activation

For Q4_0 and Q8_0 weight paths:

activation = Q8_0_TILED

For Q4_1:

activation = Q8_1_TILED

Therefore the attention Q4 experiment means:

weights:
Q4_0_TILED

activations:
Q8_0_TILED

It does NOT mean:

weights = Q4
activations = Q4

================================================================================
6. INTERNAL TILED TYPES

Current Hexagon backend exposes internal tiled formats including:

Q4_0_TILED
Q4_1_TILED
Q8_0_TILED
MXFP4_TILED

Relevant block sizes include:

QK_Q4_0_TILED = 256
QK_Q8_0_TILED = 128
QK_MXFP4_TILED = 256

The backend also exposes profiling events associated with:

  • DMA
  • L2 flush
  • HVX
  • HMX

This makes a physical-layout hypothesis experimentally testable.

================================================================================
7. MM SELECT

GGML_HEXAGON_MM_SELECT:

3 = HMX -> Tiled -> Flat -> CPU
2 = Tiled -> Flat -> CPU
1 = Flat -> CPU

MM_SELECT changes the execution path.

It does NOT change the fact that the tested quantized activation path
uses Q8_0_TILED.

Therefore NGL experiments must keep MM_SELECT constant.

================================================================================
8. HTP MEMORY / VTCM

The Hexagon backend uses:

  • unified memory
  • VTCM
  • DMA
  • repacked weight buffers
  • temporary intermediate buffers

VTCM is used for:

  • intermediate data
  • dynamically quantized data
  • temporary weight chunks
  • tiled computation

Repacked buffers are intentionally handled differently from ordinary
host buffers to force the required HTP representation.

IMPORTANT:

NGL is NOT a direct measurement of HTP memory usage.

Always record actual:

  • HTP0-REPACK
  • CPU-REPACK
  • OpenCL buffers
  • VTCM
  • other backend allocations

================================================================================
9. HISTORICAL E1-E9 CAMPAIGN

E1 - CPU frequency

Large CPU cores were reduced from approximately:

4.6 GHz -> 2.3 GHz

At high NGL:

TG changed relatively little

while:

PP decreased

Interpretation:

Large CPU frequency is not the primary decode bottleneck at high HTP
offload.

However CPU remains important for:

  • low NGL
  • prefill
  • fallback
  • orchestration

E2 - ABBA NGL16 / NGL64

Example:

NGL16:
PP ~= 15.16 +/- 2.50
TG ~= 5.05 +/- 0.10

NGL64:
PP ~= 206.87 +/- 3.32
TG ~= 5.68 +/- 0.89

Second NGL64:

  PP ~= 205.05 +/- 6
  TG ~= 5.52 +/- 0.29

Second NGL16:

  PP ~= 11.92 +/- 0.55
  TG ~= 4.85 +/- 0.38

The first cold point was thermally confounded by prefill.

At comparable temperature, NGL64 remained approximately:

+13.8 %

ahead of NGL16.

Interpretation:

routing / placement matters.


E3 - Actual buffers

HTP0-REPACK:

NGL16:
~= 1.16 GiB

NGL48:
~= 2.43 GiB

NGL64:
~= 2.55 GiB

TG remained around:

~= 7 tok/s

in the associated run.

Therefore:

W_HTP alone does not predict decode throughput.

Simple regression models:

T ~ W_HTP
T ~ N

produced nonphysical/negative slopes in some measurements.

Those regressions must NOT be used as direct BW_eff estimates.


E4 - Dense NGL sweep

Representative results:

NGL PP TG ms/token

0 8.14 5.762 173.6
2 7.72 5.123 195.2
4 7.96 5.315 188.1
8 8.79 4.363 229.2
14 8.99 4.810 207.8
16 10.07 4.950 202.2
32 87.05 6.290 159.1
48 184.56 6.730 148.5
64 182.09 6.640 150.6

The most important observation:

NGL=8 was worse than NGL=0.

NGL8 -> NGL48:

TG +54.3 %

NGL16 -> NGL32:

approximately +27 %

Temperature during the relevant range:

approximately 61-65 C

Therefore temperature alone does not explain the non-monotonic curve.

Interpretation:

There is a low-NGL routing/scheduler valley.


E5 - Controlled thermal degradation

Fixed routing:

NGL48
PP512
N256

TG repetitions:

Run 1 6.70612 tok/s
Run 2 6.69056 tok/s
Run 3 6.64737 tok/s
Run 4 6.00266 tok/s
Run 5 5.47082 tok/s

Run 1 -> Run 5:

-18.4 %

Temperature:

start ~= 46.9 C
~= 86.8 C at t=118 s
final/peak ~= 93.8 C

Average heating:

~= 0.34 C/s

PP remained approximately:

~= 232.4 tok/s

Interpretation:

thermal degradation is directly observed under fixed routing.

Without simultaneous HTP frequency/voltage telemetry:

DO NOT claim direct HTP frequency throttling is proven.

Correct statement:

performance degradation is thermally correlated and compatible with
thermal/DVFS throttling.


E6 - GPU vs HTP

GPU OpenCL:

PP128 ~= 87.942 tok/s
TG32 ~= 5.561 tok/s

HTP0:

PP128 ~= 300.273 tok/s
TG32 ~= 5.785 tok/s

Second HTP order:

PP ~= 303.609
TG ~= 5.675

GPU second order:

PP ~= 87.485
TG ~= 5.587

Average:

HTP PP ~= 301.94
GPU PP ~= 87.71

Ratio:

~= 3.44x

Decode:

HTP ~= 5.730
GPU ~= 5.574

Ratio:

~= 1.028

Therefore:

HTP has a large compute advantage in prefill
but only a small decode advantage in this GGML configuration.


E7/E8 - Backend matrix

CPU:

A: 5.37 PP / 4.24 TG
B: 4.10 PP / 3.06 TG

GPU OpenCL:

A: 100.6 PP / 6.06 TG
B: 88.8 PP / 5.70 TG

HTP0:

A: 299.1 PP / 5.79 TG
B: 292.7 PP / 5.41 TG

AUTO:

A: 183.6 PP / 6.65 TG
B: 173.4 PP / 6.11 TG

GPU,NPU:

A: 6.02 TG
B: 5.78 TG

NPU,GPU:

A: 5.49-5.69 TG
B: 5.36-5.71 TG

Forced 1/99 and 99/1 splits did not outperform AUTO in the tested
9B configuration.

Important:

AUTO without explicit -dev produced the best decode measured in
that particular E8 campaign.

This does NOT prove that GPU+NPU hybrids are useless.

Previous smaller-model campaigns showed hybrid gains.

Therefore:

Hybrid benefit is likely workload-size / graph / synchronization
dependent.

This is a crossover hypothesis, not a universal rule.


E9 - QAIRT / GenieX

A standalone QAIRT configuration used:

perf_profile = burst
core_id = 0
shared_buffer
weight_sharing_enabled = true
5 context binaries

Plugin discovery succeeded.

QNN initialization succeeded.

Five shards were found.

The process then exited:

EXIT=139
SIGSEGV

at approximately:

48.8 C

Therefore this experiment measured:

NO valid burst throughput
NO valid sustained throughput

Next step:

tombstone + logcat crash analysis

before any thermal comparison.

================================================================================
10. MTP 9B FUNCTIONAL VALIDATION

A functional MTP configuration was obtained with a clean CDSP state.

Representative run:

predicted tokens = 16
draft tokens = 15
accepted tokens = 9

Acceptance:

9 / 15 = 0.600

Prompt:

~= 524 ms
~= 21.0 tok/s

MTP decode:

1820.6 ms / 16 tokens
~= 8.24 tok/s

Observed:

SPIN = 0
err46 = 0

Therefore:

MTP execution is functionally demonstrated.

This does NOT prove architectural optimality.

Acceptance is workload/configuration dependent.

================================================================================
11. MTP HOST CPU OBSERVATION

During MTP generation:

CPU utilization reached approximately 97 %

while:

HTP/NPU remained active.

This is strong evidence of substantial host-side activity.

However:

CPU utilization = 97 %

does NOT mean:

CPU = 97 % of token latency.

Possible contributors:

  • orchestration
  • graph scheduling
  • synchronization
  • RPC
  • tensor bookkeeping
  • memory planning
  • speculative verification
  • fallback
  • token sampling

This is therefore a major investigation target, not yet a causal proof.

================================================================================
12. GALLOCR PLAN / TENSOR IDENTITY OBSERVATIONS

Instrumented gallocr diagnostics observed:

MTP workload:
~= 7,254 plan/tensor identity mismatches

subsequent non-MTP workload:
~= 2,662 mismatches

Important interpretation:

This does NOT prove memory corruption.

Correct interpretation:

tensor identities differ from those expected by a previously constructed
allocation plan.

This is consistent with a possible:

  • plan lifetime problem
  • plan reuse problem
  • dynamic graph/allocation interaction
  • tensor identity instability

The fact that thousands of mismatches also appeared in a non-MTP workload
means:

the phenomenon is NOT exclusively caused by MTP.

MTP may expose or amplify it.

================================================================================
13. REBUILD / INSTRUMENTATION

Rebuild problems and resolutions:

P1:

CMake string(FIND)
PREBUILT_LIB_DIR absent

Fix:

-DPREBUILT_LIB_DIR=toolv19_v81

Status:

RESOLVED

P2:

__fp16 compilation issue

Cause:

host/x86_64 compilation instead of Android ARM64

Fix:

Android NDK r29
ARMv8.7a
FP16
dotprod
i8mm

Status:

RESOLVED

P3:

Svelte UI environment incomplete

Fix:

ignore UI target
build core/libs

Status:

NON-BLOCKING

P4:

WSL detached during close

Fix:

synchronous execution + long timeout

Status:

RESOLVED

P5:

OpenCL / OpenMP libraries absent

Fix:

separate JZ GPU runtime
copy libomp

Status:

PARTIALLY RESOLVED

P6:

modern CLI architecture

Fix:

use llama / llama-cli / llama-bench appropriately

Status:

RESOLVED

P7:

profiling absent

Cause:

DEBUG-level profiling filtered by default

Fix:

llama-bench -v
GGML_HEXAGON_PROFILE=3

Status:

RESOLVED

P8:

logs truncated

Cause:

adb pipe / grep / tail

Fix:

save complete log on device
adb pull
analyze offline

Status:

RESOLVED

================================================================================
14. PER-OP PROFILING

With:

GGML_HEXAGON_PROFILE=3
-v

the profiling output produced approximately:

9,333 profile-op lines

representing approximately:

8,982 operations

Representative run:

DSP time:
~= 1.100 s

DSP frequency:
~= 2035 MHz

MUL_MAT:
2,080 operations

MUL_MAT share:
~= 80.5 % of DSP time

average MUL_MAT:
~= 415 us

FFN 49152-column operation:
~= 816 us/op

HMX:
~= 14 %
~= 496 HMX-tiled events

HVX:
row-block dominant
~= 3,019 events

GATED_DELTA_NET:
264 operations
~= 3.19 %

Interpretation:

MUL_MAT is the dominant DSP operation class in the measured run.

But:

MUL_MAT = 80.5 % DSP time

does NOT prove:

MUL_MAT = 80.5 % wall-clock token latency.

The complete wall-clock token cost includes all host and data-movement
components.

================================================================================
15. IMPORTANT Q8_0 OBSERVATION

Profiling observed:

~= 616 Q8_0 operations

even though the GGUF was described as Q4_0.

The correct interpretation is NOT:

"the entire model became Q8"

Rather:

some operations use a Q8_0_TILED physical representation after
backend processing/repacking.

Other operations can remain Q4_0-based.

Therefore the following must be distinguished:

logical GGUF quantization
!=
physical HTP kernel representation

This distinction is critical when estimating memory traffic.

================================================================================
16. ATTENTION Q8 -> Q4 EXPERIMENT

Original:

Qwen3.5-9B-D2-A-MTP
~= 7.29 GiB

Selective attention requantization:

Q8_0 -> Q4_0

Result:

~= 5.07 GiB

Reduction:

~= 30 %

Attention weight example:

original:
35,651,584 bytes

Q4:
18,874,368 bytes

This changes weight representation.

It does NOT change the tested activation path:

activation = Q8_0_TILED

================================================================================
17. ATTENTION A/B/C RESULTS

A - Mixed Q8 attention

model ~= 7.29 GiB

PP8:
~= 43.61 tok/s
(other controlled run ~= 42.41)

TG8:
~= 6.72 tok/s
(other controlled run ~= 6.39)

DSP:
~= 1.100 s

MUL_MAT:
~= 415 us

B - Attention Q4_0

model ~= 5.07 GiB

PP8:
~= 39.01 tok/s
(other run ~= 39.50)

TG8:
~= 6.68 tok/s
(other run ~= 5.86)

DSP:
~= 0.950 s

MUL_MAT:
~= 345 us

C - Attention MXFP4

model ~= 5.03 GiB

PP8:
~= 39.18 tok/s

TG8:
~= 6.64 tok/s

DSP:
~= 0.957 s

MUL_MAT:
~= 349 us

Robust interpretation:

Q8 -> Q4:
approximately 30 % smaller model

DSP:
approximately -14 %

MUL_MAT:
approximately -17 %

wall-clock decode:
little or no consistent gain

Therefore:

reducing logical/physical weight volume does not automatically
translate into decode throughput.

This is strong evidence against a simple:

TG proportional to 1 / weight_bytes

model.

It does NOT disprove memory bandwidth as a first-order cost.

It indicates that other terms remain significant.

================================================================================
18. DMA EVENT OBSERVATION

DMA event counts:

Q8:
1,439,118

Q4:
1,438,798

MXFP4:
same as Q4 in the measured configuration

Q8 -> Q4 difference:

approximately -0.022 %

IMPORTANT:

These are DMA EVENT COUNTS.

They are NOT:

DMA byte counts.

Therefore:

DO NOT conclude that Q8 and Q4 transfer identical numbers of bytes.

The correct statement is:

event count remained almost unchanged.

================================================================================
19. MXFP4 OBSERVATION

Q4_0:

~= 5.07 GiB

MXFP4:

~= 5.03 GiB

Similar file size.

Measured TG:

Q4_0:
~= 5.86-6.68 tok/s depending on run

MXFP4:
~= 6.64 tok/s

In one controlled comparison MXFP4 was approximately:

+13.3 %

ahead of Q4_0.

Possible explanation:

MXFP4 QK = 256
Q4_0 QK = 128

The larger block granularity may change:

  • dequantization overhead
  • tile efficiency
  • vector utilization
  • kernel scheduling

This remains a hypothesis until cycle/stall/kernel-level profiling
confirms the mechanism.

================================================================================
20. NGL / PLACEMENT EXPERIMENT

A particularly strong placement result:

HTP0 only:
~= 6.74 tok/s

HTP0 -> CPU
last 33 layers on CPU:
~= 9.01 tok/s

Gain:

~= +33.7 %

Other measured placements:

HTP0 -> GPU:
~= 7.13 tok/s

HTP0 -> GPU -> CPU:
~= 7.41 tok/s

GPU -> HTP0:
~= 6.14 tok/s

This proves:

maximizing HTP offload is not equivalent to maximizing decode throughput.

It does NOT prove exactly why the last 33 CPU layers are beneficial.

Possible mechanisms:

  • CPU is better for particular tensor geometries
  • reduced HTP workload
  • reduced repacking
  • reduced synchronization
  • reduced VTCM pressure
  • improved memory locality
  • more efficient CPU fallback
  • scheduler behavior
  • kernel-specific inefficiency

================================================================================
21. NGL SWEEP - NEXT PRIMARY EXPERIMENT

The controlled sweep must test:

NGL = 0
NGL = 33
NGL = 40
NGL = 50
NGL = 60
NGL = 66
NGL = 75
NGL = 90

Primary metric:

decode tok/s

Secondary metrics:

ms/token
PP tok/s
CPU %
temperature
HTP utilization
HTP0-REPACK
CPU-REPACK
VTCM
DMA events
graph splits
MUL_MAT time
HMX/HVX time

The NGL sweep MUST NOT change:

GGML_HEXAGON_OPQUEUE
GGML_HEXAGON_OPBATCH
GGML_HEXAGON_OPFUSION
GGML_HEXAGON_OPSTAGE
GGML_HEXAGON_OPPOLL
GGML_HEXAGON_MM_SELECT
GGML_HEXAGON_NHVX
GGML_HEXAGON_NHMX
GGML_HEXAGON_VMEM
GGML_HEXAGON_MBUF

================================================================================
22. NGL SWEEP INTERPRETATION

Hypothesis H1:

PIPELINE / OFFLOAD BOUND

Expected shape:

       TG
        ^
        |        /\
        |       /  \
        |______/    \____
        +-----------------> NGL

Interpretation:

intermediate NGL is optimal.

Possible cause:

too much HTP offload increases:
- synchronization
- memory movement
- VTCM pressure
- repack
- graph overhead


Hypothesis H2:

HTP LIMITED

Expected shape:

       TG
        ^
        |              ______
        |          ___/
        |       __/
        |______/ 
        +-----------------> NGL

Interpretation:

increasing HTP offload continues to help until a high NGL.


Hypothesis H3:

BOTTLENECK ELSEWHERE

Expected shape:

       TG
        ^
        |  -----------------------
        |
        +-------------------------> NGL

Interpretation:

broad plateau.

Likely bottleneck:

  • memory system
  • synchronization
  • CPU orchestration
  • DMA
  • repack
  • scheduler
  • kernel overhead

================================================================================
23. NGL SWEET-SPOT DEFINITION

Sweet spot:

NGL maximizing reproducible decode throughput

subject to:

  • acceptable variance
  • no errors
  • no crashes
  • comparable temperature
  • reasonable CPU load
  • no obvious pipeline degradation

Do NOT define the sweet spot from one run.

Minimum:

3 repetitions per NGL

Preferred:

randomized or ABBA ordering

Record:

mean
standard deviation
min
max
temperature

================================================================================
24. NGL REFERENCE RESULTS

Previous historical attnQ4 observations:

NGL33:
~= 7.07 tok/s

NGL40:
~= 6.69 tok/s

NGL50:
~= 5.64 tok/s

NGL60:
~= 6.75 tok/s

NGL66:
~= 6.04 tok/s

These values are HISTORICAL.

They must NOT be mixed with the new controlled sweep.

They are useful only as prior evidence that the curve can be
non-monotonic.

If the new sweep reproduces this shape under controlled conditions,
the evidence for a scheduler/placement regime change becomes much
stronger.

================================================================================
25. SECONDARY NGL REFINEMENT

After identifying the best broad region:

Example:

NGL 40-50

perform:

NGL36
NGL38
NGL40
NGL42
NGL44
NGL46
NGL48
NGL50
NGL52

This second pass determines the actual local optimum.

Do NOT tune OPQUEUE or OPBATCH before this point.

================================================================================
26. GPU / NPU HYBRID CROSSOVER

Previous experiments on smaller models showed that GPU+NPU or
NPU+GPU configurations can improve decode.

The 9B campaign does NOT reproduce a clear advantage from forced
GPU+NPU splits.

Therefore the correct hypothesis is:

hybrid benefit = f(model_size, graph_shape, synchronization,
memory pressure, backend implementation)

Possible crossover:

small model:
hybrid gain > synchronization cost

large model:
synchronization/repack/split cost >= parallelism gain

This must be experimentally measured.

Recommended matrix for each model:

CPU
GPU
HTP
AUTO
GPU,HTP
HTP,GPU
GPU,HTP split 1/99
HTP,GPU split 99/1

Measure:

PP
TG
graph splits
buffers
temperature
CPU
HTP
GPU

Define:

hybrid_gain =
TG_best_hybrid / max(TG_GPU,TG_HTP) - 1

================================================================================
27. THERMAL EXPERIMENT

Controlled 2x5 COLD/HOT result:

n_predict COLD HOT Difference

 16       9.87       8.94       -9.4 %
 32       9.14       8.54       -6.6 %
 64       8.48       8.19       -3.4 %
128       9.11       8.40       -7.8 %
256       9.04       7.86      -13.1 %

Interpretation:

Thermal degradation is real.

The controlled experiment corrects the earlier interpretation of
approximately -21 %.

Correct conclusion:

approximately 10-13 % causal degradation in the controlled 2x5
experiment.

Do NOT use one universal thermal penalty.

Thermal effect depends on:

  • starting temperature
  • workload
  • duration
  • sustained power
  • thermal governor
  • DVFS state

At cold state:

decode remained close to 9 tok/s across 16-256 tokens.

Therefore token count itself was not a dominant intrinsic limiter
within this tested range.

================================================================================
28. THERMAL SUSTAINED RUN

Fixed:

NGL48
PP512
N256

Results:

Run 1:
6.70612 tok/s

Run 2:
6.69056 tok/s

Run 3:
6.64737 tok/s

Run 4:
6.00266 tok/s

Run 5:
5.47082 tok/s

Loss:

-18.4 %

Temperature:

start ~= 46.9 C
t=118s ~= 86.8 C
peak/final ~= 93.8 C

This is direct intra-process evidence of performance degradation
under sustained thermal load.

================================================================================
29. THERMAL COOLING

Heat burst:

256 tokens
start ~= 43 C
maximum ~= 68 C

Cooling observations:

t=0s:
56.2 C

t=8s:
51.2 C

t=14s:
48.0 C

t=16s:
47.3 C

Average heating:

~= 2.6 C/s

Cooling:

~= 0.62 C/s

Simplified thermal ratio:

~= 4x

A thermal scheduler was derived empirically.

Example policy:

40 C:
large burst

65 C:
reduced burst + idle

86 C:
cooldown

This is a:

empirical throughput/thermal policy

NOT:

proven tokens/joule optimum

because electrical power/energy has not been measured.

================================================================================
30. ALIGNMENT / PADDING / TILING

The backend contains explicit tiled representations.

It also contains:

  • PAD operations
  • tensor dimensions
  • strides
  • alignment helpers
  • VTCM tile buffers
  • DMA events
  • HVX/HMX profiling

Flash-attention paths include aligned dimensions.

Therefore:

tensor geometry
->
padding/alignment
->
tile shape
->
repack
->
DMA/VTCM
->
kernel efficiency

is a valid mechanistic hypothesis.

However:

hidden_size % 512 == 0

is NOT established as a universal HTP performance law.

It remains:

an experimental hypothesis.

================================================================================
31. ALIGNMENT EXPERIMENT

The next mechanistic experiment should isolate attention tensors.

For each MUL_MAT record:

logical_M
logical_K
logical_N

physical_M
physical_K
physical_N

padding_M
padding_K
padding_N

tile_K
stride
address alignment

input_type
weight_type
physical_type_after_repack

repack_bytes
repack_time

DMA_events
DMA_bytes if available

VTCM_occupancy
VTCM_transfer

HVX_cycles
HMX_cycles

MUL_MAT_us

Then test controlled K values such as:

K=4000
K=4032
K=4096

plus neighboring dimensions.

The objective:

determine whether there are discontinuities associated with
tile/alignment geometry.

A real discontinuity would be stronger evidence for a geometry-driven
effect than a simple correlation between model size and throughput.

================================================================================
32. Q4 / Q8 / MXFP4 DISCRIMINATING EXPERIMENT

Test:

A = attention Q4_0
B = attention Q8_0
C = attention MXFP4

Measure:

physical bytes
repack bytes
repack time
DMA events
DMA bytes
VTCM usage
HVX cycles
HMX cycles
MUL_MAT latency
total DSP
wall-clock TG

Interpretation:

CASE 1

bytes decrease
cycles decrease
TG increases

Supports:

memory / transfer contribution

CASE 2

bytes decrease
cycles remain stable
TG remains stable

Supports:

kernel / geometry / synchronization dominance

CASE 3

file size almost identical
kernel time changes significantly

Supports:

representation/tile/dequantization efficiency rather than raw
model size.

================================================================================
33. MODEL PERFORMANCE FUNCTION

Current working model:

T_token ~=

  W_effective / BW_effective

+ T_layout/repack

+ T_activation_quant

+ T_DMA

+ T_VTCM

+ T_graph_split

+ T_sync

+ T_kernel

+ T_fallback

+ T_KV

+ T_CPU

+ T_thermal/DVFS

This is intentionally richer than:

T_token ~= W_HTP / BW

because E1-E9 demonstrate that the latter is insufficient.

The objective is to progressively replace qualitative terms with
measured per-operation values.

================================================================================
34. QAIRT / GENIEX REFERENCE

Historical QAIRT Qwen3-8B W4A16:

approximately 14-16 tok/s decode

One campaign:

approximately 15.9 tok/s across nine prompts

Prefill:

approximately 1253-1438 tok/s depending on campaign

These results are NOT directly comparable to:

GGML Qwen3.5-9B Q4_0

because:

model differs
quantization differs
runtime differs
graph differs
thermal protocol differs

They are evidence that substantial runtime/software efficiency is
available on the same SoC family.

The comparison becomes causal only if:

same model
same quantization
same context
same thermal protocol
same token workload

are controlled.

================================================================================
35. QAIRT E9 NEXT PROTOCOL

After resolving the SIGSEGV:

A:
burst, cold

B:
sustained_high_performance, cold

C:
sustained_high_performance, hot

D:
burst, hot

Only change:

perf_profile

Keep constant:

dsp_arch
soc_model
core_id
rpc_control_latency
memory configuration
context binaries

Record:

nsphvx-*
nsphmx-*
max temperature
frequencies
throughput per window

Do not compare a crashed E9 run as a throughput result.

================================================================================
36. CURRENT NGL EXPERIMENTAL PROTOCOL

Primary models:

A:
Qwen3.5-9B-D2-A-MTP-attnQ4.gguf
~= 5.07 GiB

B:
baseline mixed-attention model
~= 7.29 GiB

NGL:

0
33
40
50
60
66
75
90

For each NGL:

minimum 3 repetitions

Primary:

TG tok/s

Secondary:

PP tok/s
ms/token
CPU %
temperature
HTP info

Do not change:

OPQUEUE
OPBATCH
OPFUSION
OPSTAGE
OPPOLL
MM_SELECT
NHVX
NHMX
VMEM
MBUF

================================================================================
37. NGL DATA TABLE

+------+-------+-----------+-----------+----------+----------+----------+
| Run | NGL | TTFT ms | TG tok/s | ms/token | CPU % | Temp C |
+------+-------+-----------+-----------+----------+----------+----------+
| 1 | 0 | | | | | |
| 2 | 33 | | | | | |
| 3 | 40 | | | | | |
| 4 | 50 | | | | | |
| 5 | 60 | | | | | |
| 6 | 66 | | | | | |
| 7 | 75 | | | | | |
| 8 | 90 | | | | | |
+------+-------+-----------+-----------+----------+----------+----------+

Additional columns recommended:

HTP utilization
HTP0-REPACK
CPU-REPACK
VTCM
DMA events
graph splits
MUL_MAT us
HMX cycles
HVX cycles

================================================================================
38. NGL REPETITION RECORD

NGL=0

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=33

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=40

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=50

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=60

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=66

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=75

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

NGL=90

Run 1: __________________________
Run 2: __________________________
Run 3: __________________________
Mean : __________________________
Std : __________________________

================================================================================
39. CPU / GPU / HTP PLACEMENT MATRIX

+----------------------+----------+----------+
| Placement | PP tok/s | TG tok/s |
+----------------------+----------+----------+
| CPU | 11.99 | 3.64 |
| GPU OpenCL | 29.94 | 6.71 |
| HTP0 | 40.91 | 6.74 |
| HTP0 -> CPU | 40.71 | 9.01 |
| HTP0 -> GPU | 39.08 | 7.13 |
| HTP0 -> GPU -> CPU | 36.45 | 7.41 |
| GPU -> HTP0 | 31.12 | 6.14 |
+----------------------+----------+----------+

This matrix is one of the strongest pieces of evidence in the dossier.

It demonstrates:

maximum HTP offload != maximum decode performance.

================================================================================
40. CURRENT PROOF LEVELS

MEASURED

MTP 9B works.

MEASURED

HTP0 is actively executing the tested MUL_MAT operations.

MEASURED

Per-operation Hexagon profiling works.

MEASURED

Approximately 80.5 % of DSP time was attributed to MUL_MAT in
the instrumented run.

MEASURED

HTP0-only ~= 6.74 tok/s.

MEASURED

HTP0 -> CPU ~= 9.01 tok/s.

MEASURED

HTP0 -> CPU is approximately +33.7 % over HTP0-only.

ESTABLISHED

Controlled thermal degradation is approximately 10-13 % in the
2x5 experiment.

ESTABLISHED

A sustained fixed-routing run reached approximately -18.4 % at
extreme thermal state.

ESTABLISHED

HTP prefill is approximately 3.44x GPU prefill in E6.

ESTABLISHED

HTP decode advantage is only approximately +2.8 % in E6.

ESTABLISHED

HTP/GPU placement materially changes performance.

ESTABLISHED

The backend implements tiled Q4/Q8/MXFP4 representations and
repacking.

ESTABLISHED

Runtime activations use Q8_0_TILED on the tested Q4_0/Q8_0 paths.

PROBABLE

Memory bandwidth is a first-order decode cost.

HYPOTHESIS

hidden_size % 512 is a useful performance/alignment predictor.

HYPOTHESIS

padding/alignment is a major cause of the observed performance
differences.

HYPOTHESIS

some NGL degradation is caused by pipeline/synchronization overhead.

HYPOTHESIS

Gallocr plan/tensor identity mismatches may indicate a plan lifetime
or plan reuse problem.

NOT DEMONSTRATED

actual memory corruption.

NOT DEMONSTRATED

HTP frequency throttling as the direct cause of every thermal drop.

NOT DEMONSTRATED

tokens/joule optimum of the thermal scheduler.

NOT DEMONSTRATED

universal superiority or inferiority of GPU+HTP hybrid execution.

================================================================================
41. IMPORTANT NEGATIVE RESULTS

The following conclusions must NOT be made:

"More HTP always means more TPS."

FALSE.

"Q4 is automatically faster because the model is smaller."

FALSE.

"80.5 % MUL_MAT DSP time means 80.5 % token latency."

FALSE.

"Q8_0_TILED means twice the DDR traffic."

NOT PROVEN.

"DMA event counts prove equal DMA byte volume."

FALSE.

"hidden_size % 512 is a universal HTP law."

NOT PROVEN.

"GPU+HTP is useless."

NOT PROVEN.

"HTP is slow."

FALSE as a general statement.

"CDSP offline proves OOM."

FALSE.

"Gallocr mismatch proves memory corruption."

FALSE.

"97 % CPU utilization means CPU consumes 97 % of latency."

FALSE.

"QAIRT 16 tok/s proves GGML should reach 16 tok/s."

FALSE.

================================================================================
42. CRITICAL DISTINCTION: LOGICAL VS PHYSICAL FORMAT

Always distinguish:

GGUF logical type
|
v
backend repack
|
v
physical tiled representation
|
v
HTP kernel
|
v
DMA / VTCM / HVX / HMX

For example:

GGUF:
Q4_0

does not imply:

physical HTP memory layout:
raw Q4_0

The backend can use:

Q4_0_TILED

Similarly:

GGUF Q8_0
->
Q8_0_TILED

Therefore all memory-traffic claims must use measured physical
representation, not merely the GGUF quantization label.

================================================================================
43. CURRENT SCIENTIFIC QUESTION

The key question is no longer:

"Is HTP fast?"

nor:

"Is the model too large?"

nor:

"Is the system memory-bound?"

The correct question is:

How does the total token cost change with graph placement,
and which individual cost terms dominate at each NGL?

Formally:

minimize T_token(NGL)

with:

T_token =
T_CPU
+ T_HTP
+ T_repack
+ T_activation_quant
+ T_DMA
+ T_VTCM
+ T_graph_split
+ T_sync
+ T_fallback
+ T_KV
+ T_thermal

================================================================================
44. PRIORITY EXPERIMENT ORDER

PHASE 1

Controlled NGL sweep:

0 / 33 / 40 / 50 / 60 / 66 / 75 / 90

PHASE 2

Local NGL refinement around best region.

PHASE 3

Compare:

baseline mixed attention
attention Q4_0

at identical NGL.

PHASE 4

Freeze best NGL.

PHASE 5

OPQUEUE sweep.

PHASE 6

OPBATCH sweep.

PHASE 7

OPSTAGE / profiling.

PHASE 8

per-MUL_MAT physical geometry.

PHASE 9

Q4 / Q8 / MXFP4 physical traffic comparison.

PHASE 10

alignment/padding controlled tensors.

PHASE 11

#28202 before/after comparison.

================================================================================
45. #28202 / HEXAGON MATMUL PR RELEVANCE

The Hexagon MUL_MAT/MUL_MAT_ID fusion work is directly relevant to
this investigation.

The changes include:

  • QKV / FFN MUL_MAT fusion
  • MUL_MAT_ID fusion
  • removal of the hardcoded 32K restriction
  • VTCM solver corrections
  • OPBATCH / OPQUEUE sizing changes
  • buffer ordering
  • VA fragmentation reduction
  • VA defragmentation
  • fast division optimizations

The 32K restriction is particularly important for the Qwen3.5-9B
lm_head:

logical shape:
approximately [4096, 248320]

The previous backend rejected quantized MUL_MAT operations above
the hardcoded 32K row/output restriction.

This caused CPU fallback.

The cost of this fallback is potentially significant.

However:

lm_head fallback != automatically the complete decode bottleneck.

It must be experimentally separated from the other pipeline costs.

================================================================================
46. #28202 BEFORE / AFTER EXPERIMENT

Recommended experiment:

              CURRENT MASTER
                   |
                   v
          NGL sweep / baseline
                   |
                   v
              #28202
                   |
                   v
          identical NGL sweep
                   |
                   v
                compare

Record:

TG
PP
CPU %
MUL_MAT count
MUL_MAT_ID count
fused operations
lm_head placement
CPU fallback time
HTP MUL_MAT time
VTCM
graph splits
OPQUEUE
OPBATCH
DMA
temperature

Interpretation:

CASE A

lm_head moves CPU -> HTP
TG increases strongly

Then:

32K fallback was a major bottleneck.

CASE B

lm_head moves CPU -> HTP
TG changes only slightly

Then:

fallback was real but not dominant.

CASE C

TG improves while MUL_MAT time barely changes

Then:

scheduling / fusion / VTCM / buffer management becomes more likely.

CASE D

MUL_MAT time decreases substantially
TG follows

Then:

kernel efficiency is implicated.

================================================================================
47. FASTRPC

Measured historical values:

allocation/send median:
~= 11.5 us

send -> response median:
~= 178.5 us

Observed overhead:

<10 % in the measured configuration.

Therefore FastRPC alone does not currently explain the entire
decode ceiling.

However RPC overhead must remain part of:

T_sync / T_CPU / T_other

until measured inside the complete token pipeline.

================================================================================
48. THERMAL SCHEDULER STATUS

Current thermal scheduler:

empirically useful

NOT proven energy optimal

Correct terminology:

"empirical throughput/thermal controller"

Incorrect terminology:

"tokens/joule optimum"

unless electrical power is measured.

For future energy experiments:

measure:

voltage
current
power
energy/token
temperature
throughput

================================================================================
49. AMD XDNA2 SEPARATION

AMD experiments:

Ryzen AI / Strix Point / XDNA2

Historical stack:

FastFlowLM
XRT
xclbin
proxy DLL
XDNA2 AIE

Historical result:

approximately 7.8 tok/s decode
approximately 46.3 tok/s prefill

The AMD experiments involved:

TDR 0xc01e0200
proxy versions
descriptor structures
padding/alignment
XDNA2 topology
column activation experiments

Those results must NOT be used as direct evidence about Qualcomm HTP.

The common research question is:

geometry + placement + memory + runtime

but:

XDNA2 != Hexagon HTP

================================================================================
50. ALIGNMENT HYPOTHESIS STATUS

Observed hypothesis:

hidden_size % 512 == 0

may correlate with good NPU behavior in some previous experiments.

Current status:

HYPOTHESIS

It is NOT established as:

  • a universal HTP requirement
  • a Qualcomm-published rule
  • a universal optimum
  • a direct cause of the 9B decode ceiling

To establish causality:

controlled dimensions
controlled weights
controlled K/M/N
identical quantization
identical runtime
identical scheduler

must be used.

================================================================================
51. RECOMMENDED DATASET FOR EACH MUL_MAT

For every significant MUL_MAT:

layer_id
op_id

logical_M
logical_K
logical_N

physical_M
physical_K
physical_N

padding_M
padding_K
padding_N

tile_M
tile_K
tile_N

stride0
stride1
stride2

address_alignment

GGUF_type
repacked_type
activation_type

repack_time
repack_bytes

DMA_events
DMA_bytes

VTCM_bytes
VTCM_peak

HVX_cycles
HMX_cycles

kernel_time_us

graph_id
graph_split_id
backend

This dataset can eventually support a predictive cost model.

================================================================================
52. TARGET COST MODEL

Long-term objective:

predict:

  TG(NGL, placement, quantization, geometry, thermal)

from:

  physical tensor properties
  scheduler state
  backend state
  thermal state

A simplified model could become:

T_token =
alpha * bytes_DMA
+ beta * repack_bytes
+ gamma * HVX_cycles
+ delta * HMX_cycles
+ epsilon * graph_splits
+ zeta * synchronization
+ eta * CPU_fallback
+ theta * thermal_penalty

The coefficients must be fitted from controlled measurements.

Do NOT fit this model from mixed-temperature or mixed-build results.

================================================================================
53. ARTIFACTS TO PRESERVE

For every experiment preserve:

  • exact command
  • full stdout
  • full stderr
  • git commit
  • binary SHA256/MD5
  • skel SHA256/MD5
  • GGUF SHA256/MD5
  • model size
  • quantization
  • context
  • batch
  • ubatch
  • threads
  • NGL
  • backend order
  • tensor split
  • OPQUEUE
  • OPBATCH
  • MM_SELECT
  • MBUF
  • VMEM
  • NHVX
  • NHMX
  • temperature
  • thermal zones
  • nsphvx
  • nsphmx
  • graph splits
  • memory breakdown
  • profiling output
  • tombstone/logcat for crashes

Do not rely on a manually copied TPS number.

The raw experiment is the primary artifact.

================================================================================
54. INTERNAL RESEARCH SOURCES

Internal:

RAPPORT_INVESTIGATION_REPACK_Q8_TILED_20260831.md
INVESTIGATION_REPACK_Q8_TILED_20260831.docx

RAG provenance:

code:20260831_repack_q8_tiled_m1_m2

Other internal material:

E1-E9 Qualcomm campaign
MTP 9B validation
thermal 2x5
thermal cooldown
thermal scheduler
instrumented rebuild
CPU/GPU/HTP placement matrix
per-op profiling
AMD XDNA2 reports

Previous governor checkpoint:

71/71 tests OK

The above value is historical and must not be presented as a result
of the current NGL sweep.

================================================================================
55. PUBLIC TECHNICAL REFERENCES

llama.cpp Snapdragon developer documentation:

https://github.com/ggml-org/llama.cpp/blob/master/docs/backend/snapdragon/developer.md

llama.cpp Snapdragon backend:

https://github.com/eullm/llama.cpp/blob/master/docs/backend/snapdragon/README.md

llama.cpp Hexagon discussion:

#23314

Hexagon issues:

#25102
#24201

HeteroLLM:

https://arxiv.org/abs/2501.14794

PowerBench:

https://arxiv.org/abs/2607.05475

Qualcomm QcNode QNN:

https://github.com/qualcomm/QcNode/blob/main/docs/QNN.md

Qualcomm Qwen3-8B:

https://huggingface.co/qualcomm/Qwen3-8B

Qualcomm Qwen3-8B commit:

https://huggingface.co/qualcomm/Qwen3-8B/commit/052c4ad9d7841b644089c123bc88f79a4045678e

Hexagon MUL_MAT / MUL_MAT_ID fusion PR:

#28202

Device discovery PR:

#27785

================================================================================
56. FINAL SCIENTIFIC VERDICT

The Qualcomm SM8850 campaign does NOT support a single-bottleneck
explanation.

The strongest experimentally supported conclusions are:

  1. HTP is highly capable in compute-heavy prefill.

  2. The large HTP prefill advantage does not translate proportionally
    into decode throughput.

  3. Decode performance is strongly dependent on graph placement and
    scheduler behavior.

  4. HTP0-only is not necessarily optimal.

  5. HTP0 -> CPU with the last 33 layers reached approximately
    9.01 tok/s versus approximately 6.74 tok/s for HTP0-only.

  6. This corresponds to approximately +33.7 %.

  7. Attention Q8 -> Q4 reduced model size by approximately 30 %,
    but did not produce a comparable wall-clock decode improvement.

  8. The backend physically repacks quantized weights into tiled
    representations.

  9. Quantized activations remain Q8_0_TILED on the tested Q4_0/Q8_0
    paths.

  10. MUL_MAT dominates DSP time in the profiled workload, but this
    does not prove that MUL_MAT alone dominates wall-clock latency.

  11. Thermal degradation is real and reproducible.

  12. The controlled 2x5 experiment indicates approximately 10-13 %
    thermal degradation depending on token count.

  13. A longer sustained run reached approximately -18.4 % under
    extreme thermal conditions.

  14. AUTO scheduling can outperform forced backend placement.

  15. Forced GPU+HTP is not universally beneficial on the tested 9B
    workload.

  16. Historical smaller-model results prevent the conclusion that
    GPU+HTP is inherently ineffective.

  17. The most likely architecture is a workload-dependent crossover
    between compute, memory, scheduler and synchronization costs.

  18. Alignment/padding/tile geometry is a plausible mechanism, but
    hidden_size % 512 remains an unproven hypothesis.

  19. Gallocr plan/tensor identity mismatches are a serious diagnostic
    signal, but they do not prove memory corruption.

  20. The 32K lm_head restriction is a concrete backend limitation that
    can cause CPU fallback and is directly relevant to Qwen3.5-9B.

  21. PR hexagon: MUL_MAT and MUL_MAT_ID fusion and fixes #28202 is therefore an important experimental intervention
    because it changes the 32K restriction, fusion, VTCM solver,
    OPBATCH/OPQUEUE sizing and buffer/VA management.

The central scientific conclusion is:

THE SM8850 DECODE CEILING IS A COMPOSITE SOFTWARE/HARDWARE PIPELINE
PROBLEM, NOT A SIMPLE "NPU COMPUTE" OR "MODEL SIZE" PROBLEM.

The next decisive step is to measure the physical cost of individual
MUL_MAT operations and correlate:

geometry

  • padding
  • tiled representation
  • repack
  • DMA
  • VTCM
  • HVX/HMX cycles
  • graph splits
  • CPU fallback
  • synchronization
  • thermal state

with:

wall-clock token latency.

================================================================================
57. FINAL EXPERIMENTAL PRIORITY

FIRST:

NGL sweep

0 / 33 / 40 / 50 / 60 / 66 / 75 / 90

SECOND:

local NGL refinement

THIRD:

baseline vs attnQ4 at the same NGL

FOURTH:

OPQUEUE

FIFTH:

OPBATCH

SIXTH:

#28202 before/after

SEVENTH:

per-MUL_MAT physical geometry

EIGHTH:

Q4/Q8/MXFP4 physical traffic

NINTH:

controlled alignment/padding tensors

TENTH:

QAIRT burst/sustained after SIGSEGV resolution

================================================================================
END OF CONSOLIDATED EXPERIMENTAL DOSSIER

@GaTmaNnes

Copy link
Copy Markdown

Date: 2026-09-02
Platform: Snapdragon SM8850-class device / Android
Backend: llama.cpp fork / GGML Hexagon
Device: HTP0
Profiling: GGML_HEXAGON_PROFILE=2 with PMU
Validation: 71/71 checks OK
Raw profiling logs: preserved


1. Executive Summary

This campaign introduces a sparse-MoE control workload to the Qualcomm Hexagon HTP investigation. The purpose is to separate the cost of active matrix computation from the additional costs of MoE routing, expert dispatch, data movement, synchronization, and host/DSP orchestration during batch-1 decode.

The tested workload was Marco-Nano-Instruct, converted from Q8_0 to the HTP-compatible Q4_0 format and executed successfully on HTP0.

The clean result was:

Marco-Nano-Instruct Q4_0
HTP0
26.72 tok/s

The dense Qwen reference from the same campaign was:

Qwen dense MTP1
HTP0
11.26 tok/s

The comparison is:

Metric | Dense Qwen MTP1 | Marco-Nano sparse MoE -- | -- | -- End-to-end decode | 11.26 tok/s | 26.72 tok/s Time/token | 88.8 ms | 37.4 ms DSP MUL_MAT / token | ~65 ms | ~8.7 ms

The lower confidence values intentionally reflect the need for direct event-level wall-clock attribution.


28. Preserved Artifacts

Host model directory:

D:\models_marco\

Primary files:

Marco-Nano-Instruct.Q8_0.gguf
Marco-Nano-Instruct.Q4_0.gguf

Q4_0 size:

4,356 MiB

Report:

bench_results/RAPPORT_CONTROLE_MOE_MARCO_HTP_20260902.md

Validation:

71/71 OK

Raw PMU/profile logs are preserved for re-analysis.

fewtarius pushed a commit to fewtarius/CachyLLama that referenced this pull request Sep 5, 2026
…gml-org#27785)

* hex-devices: add support for lazy session allocation and cleanup dev interfaces

Co-authored-by: Marco Colombo <mcolombo@qti.qualcomm.com>

* hex-devices: support for runtime discovery of available NPU cores

Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com>
Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>

* hex-devices: reject non-existing devices early during init

---------

Co-authored-by: Marco Colombo <mcolombo@qti.qualcomm.com>
Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com>
Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>
thecodacus pushed a commit to thecodacus/llama.cpp that referenced this pull request Sep 7, 2026
…gml-org#27785)

* hex-devices: add support for lazy session allocation and cleanup dev interfaces

Co-authored-by: Marco Colombo <mcolombo@qti.qualcomm.com>

* hex-devices: support for runtime discovery of available NPU cores

Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com>
Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>

* hex-devices: reject non-existing devices early during init

---------

Co-authored-by: Marco Colombo <mcolombo@qti.qualcomm.com>
Co-authored-by: Alexander Lu <alexlu@qti.qualcomm.com>
Co-authored-by: Ehsan Bateni <ebateni@qti.qualcomm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ggml changes relating to the ggml tensor library for machine learning Hexagon merge ready A maintainer can use this label to indicate that they consider the changes final and ready to merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants