kazeia/kazeia-android/COMPILE_WHISPER_NPU.md

185 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Compiling Whisper for Qualcomm NPU (AI Hub)
Guide pour compiler les modèles Whisper (Base/Small/Medium) via Qualcomm AI Hub
pour déploiement NPU sur Snapdragon 8 Elite (SM8750).
## Prérequis
### Environnement Python
```bash
# Créer un venv dédié (Python 3.10 recommandé)
python3 -m venv /opt/Kazeia/qnn_venv
source /opt/Kazeia/qnn_venv/bin/activate
# Installer qai-hub et les modèles
pip install qai-hub qai-hub-models
```
### Compte Qualcomm AI Hub
1. Créer un compte sur https://aihub.qualcomm.com
2. Générer un API token dans les paramètres du compte
3. Configurer le token :
```bash
qai-hub configure --api_token <VOTRE_TOKEN>
```
La configuration est sauvée dans `~/.qai_hub/client.ini`.
## Compilation
### Commande générale
```bash
source /opt/Kazeia/qnn_venv/bin/activate
python3 -m qai_hub_models.models.<MODEL_NAME>.export \
--device "Snapdragon 8 Elite QRD" \
--target-runtime precompiled_qnn_onnx \
--precision float \
--skip-profiling \
--skip-inferencing \
--output-dir /opt/Kazeia/models_qnn/<OUTPUT_DIR>
```
### Modèles disponibles
| Modèle | Module | Paramètres | Layers | Heads |
|--------|--------|------------|--------|-------|
| Whisper-Base | `whisper_base` | 77M | 6 | 8 |
| Whisper-Small | `whisper_small` | 244M | 12 | 12 |
| Whisper-Medium | `whisper_medium` | 769M | 24 | 16 |
### Exemple : Whisper-Small
```bash
python3 -m qai_hub_models.models.whisper_small.export \
--device "Snapdragon 8 Elite QRD" \
--target-runtime precompiled_qnn_onnx \
--precision float \
--skip-profiling \
--skip-inferencing \
--output-dir /opt/Kazeia/models_qnn/whisper-small-sm8750
```
**Temps de compilation** : ~5-10 minutes (upload modèle + compilation cloud).
### Exemple : Whisper-Base
```bash
python3 -m qai_hub_models.models.whisper_base.export \
--device "Snapdragon 8 Elite QRD" \
--target-runtime precompiled_qnn_onnx \
--precision float \
--skip-profiling \
--skip-inferencing \
--output-dir /opt/Kazeia/models_qnn/whisper-base-sm8750
```
### Options de device
```bash
# Lister les devices disponibles
qai-hub list-devices | grep -i "8 elite\|sm8750"
# Devices SM8750 (Snapdragon 8 Elite) :
# "Snapdragon 8 Elite QRD" → chipset: qualcomm-snapdragon-8-elite, sm8750
# "Samsung Galaxy S25 (Family)" → chipset: qualcomm-snapdragon-8-elite-for-galaxy, sm8750-ac
#
# Note: OnePlus Pad 2/3 utilise sm8750 standard (pas "for-galaxy")
```
## Fichiers générés
La compilation produit un sous-dossier avec :
```
whisper_small-precompiled_qnn_onnx-float-qualcomm_snapdragon_8_elite/
├── HfWhisperEncoder.onnx # Stub ONNX (~3KB)
├── HfWhisperEncoder_qairt_context.bin # Context binaire QNN (encoder)
├── HfWhisperDecoder.onnx # Stub ONNX (~8KB)
├── HfWhisperDecoder_qairt_context.bin # Context binaire QNN (decoder)
├── metadata.yaml # Métadonnées de compilation
└── vocab.bin # Vocabulaire (non utilisé)
```
### Architecture des modèles
**Encoder** (HfWhisperEncoder) :
- Input : `input_features` [1, 80, 3000] fp16
- Output : Cross-attention KV caches (N layers × k,v)
- `k_cache_cross_N` : [num_heads, 1, 64, 1500] fp16
- `v_cache_cross_N` : [num_heads, 1, 1500, 64] fp16
**Decoder** (HfWhisperDecoder) — KV-cache autorégressif :
- Inputs :
- `input_ids` : [1, 1] int32 (un token à la fois)
- `attention_mask` : [1, 1, 1, 200] fp16 (right-aligned, -100 pour masqué)
- `k_cache_self_N_in` / `v_cache_self_N_in` : Self KV caches (199 slots, init zeros)
- `k_cache_cross_N` / `v_cache_cross_N` : Cross KV caches (depuis encoder)
- `position_ids` : [1] int32
- Outputs :
- `logits` : [1, 51865, 1, 1] fp16
- `k_cache_self_N_out` / `v_cache_self_N_out` : Self KV caches mis à jour
## Déploiement sur tablette
### 1. Copier les modèles
```bash
MODEL_DIR="/data/local/tmp/kazeia/models/whisper-small-sm8750"
SRC="<chemin_local>/whisper_small-precompiled_qnn_onnx-float-qualcomm_snapdragon_8_elite"
adb shell "mkdir -p $MODEL_DIR"
adb push $SRC/HfWhisperEncoder.onnx $MODEL_DIR/
adb push $SRC/HfWhisperEncoder_qairt_context.bin $MODEL_DIR/
adb push $SRC/HfWhisperDecoder.onnx $MODEL_DIR/
adb push $SRC/HfWhisperDecoder_qairt_context.bin $MODEL_DIR/
```
### 2. Copier les assets partagés
Les fichiers `mel_filters.json` et `vocab.json` sont communs à toutes les variantes Whisper :
```bash
# Si déjà présents depuis une autre variante :
adb shell "cp /data/local/tmp/kazeia/models/whisper-sm8750/mel_filters.json $MODEL_DIR/"
adb shell "cp /data/local/tmp/kazeia/models/whisper-sm8750/vocab.json $MODEL_DIR/"
```
### 3. Configurer le chemin dans KazeiaService.kt
```kotlin
npuStt.load("$modelsDir/whisper-small-sm8750")
```
## Tailles des modèles compilés
| Modèle | Encoder (bin) | Decoder (bin) | Total |
|--------|--------------|---------------|-------|
| Whisper-Base | 47 MB | 145 MB | ~192 MB |
| Whisper-Small | 201 MB | 345 MB | ~546 MB |
## Performances sur OnePlus Pad (SM8750)
| Étape | Whisper-Base | Whisper-Small |
|-------|-------------|---------------|
| Mel (C++ natif) | ~220ms | ~220ms |
| Encoder NPU | ~140ms | ~270ms* |
| Decoder NPU (par step) | ~13ms | TBD |
| Load encoder | ~150ms | ~270ms |
| Load decoder | ~150ms | ~250ms |
*À confirmer avec des benchmarks réels sur audio.
## Dépannage
### "resource failed to call close"
Warnings bénins de l'ONNX Runtime. Les sessions ORT non fermées proprement génèrent ces messages lors du GC.
### Modèle ne se charge pas
- Vérifier que `HfWhisperEncoder_qairt_context.bin` est dans le MÊME répertoire que `HfWhisperEncoder.onnx`
- Vérifier que `libQnnHtp.so` est accessible via `nativeLibDir`
- Le modèle doit être compilé pour le bon chipset (sm8750, pas sm8750-ac ni sm8850)
### Mauvaise détection de langue
Whisper-Base est peu fiable pour la détection de langue sur segments courts. Whisper-Small est nettement meilleur. Si besoin, on peut forcer le token de langue après SOT.
## Référence
- Qualcomm AI Hub : https://aihub.qualcomm.com
- Code de référence : `qai_hub_models/models/_shared/hf_whisper/app.py`
- HuggingFace Whisper-Base : https://huggingface.co/qualcomm/Whisper-Base
- HuggingFace Whisper-Small : https://huggingface.co/qualcomm/Whisper-Small