Vulkan Adreno 830 testé : neutre au mieux, régresse au pire (commit aussi le code opt-in)
Re-analyse globale plateforme : le GPU n'avait JAMAIS été testé. Build
ggml-vulkan pour Android arm64 (NDK r27d + SPIRV-Headers + vulkan.hpp
téléchargés depuis github, libomp.so poussé sur tablette).
Adreno 830 détecté : uma=1 fp16=1 matrix cores=NONE (compute shaders seuls).
3 patterns testés :
(1) Decoder weights Vulkan buft + CPU compute : NEUTRE
RTF 2.45 -> 2.40-2.47 (bruit), WAV bit-exact
Cause : UMA = même DRAM, pas de gain BW
(2) Decoder + sched (GPU compute attendu) : tout CPU
sched route UMA buffer -> CPU (logique is_host)
Cause : sched ne déclenche pas l'offload pour buffers UMA
(3) Talker offload 29/29 layers via llama.cpp : REGRESSION +128%
Prefill 87->775 ms, talker 32->45 ms, decoder 3.3->6.6s
Cause : 0.6B + batch=1 + bus contention GPU/CPU sur DRAM partagée
Verdict cumulé HTP + Vulkan : sur SM8750 ce TTS spécifique, ni HTP ni
GPU n'apportent gain net. NEON CPU optimisé reste la voie unique
réaliste sur ce hardware.
Conso énergie : Vulkan talker = pipeline ×2.3 plus long, conso ~×2.
NEON CPU = meilleure efficience.
Verdict : RESTE SUR NEON CPU pour la prod.
Code committé opt-in (KZTTS_VULKAN_LIB, KZTTS_DECODER_VULKAN,
KZTTS_TALKER_VULKAN), désactivé par défaut. Path principal RTF 2.45 intact.
Détails complets dans dist/PERF_VULKAN_TESTS.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a5d591a07b
commit
27d893c73f
|
|
@ -6,3 +6,4 @@ models/
|
||||||
b/
|
b/
|
||||||
ql/
|
ql/
|
||||||
eval/out/
|
eval/out/
|
||||||
|
dist/b-vulkan/
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,171 @@
|
||||||
|
# Tests Vulkan Adreno 830 — verdict + raisons (29/05)
|
||||||
|
|
||||||
|
Session de re-analyse globale plateforme. Le HTP avait été exclu. Le GPU
|
||||||
|
n'avait JAMAIS été testé. Suite à l'autorisation de Richard, exploration
|
||||||
|
ggml-vulkan sur Adreno 830 du SM8750.
|
||||||
|
|
||||||
|
## Préparatifs build
|
||||||
|
|
||||||
|
Chaîne build non-triviale, dépendances manquantes dans NDK r27d :
|
||||||
|
|
||||||
|
1. `SPIRV-Headers` : téléchargé depuis github (vulkan-sdk-1.3.275.0), installé
|
||||||
|
dans `/tmp/spirv-install` et dans le sysroot NDK.
|
||||||
|
2. `vulkan.hpp` (header C++) : téléchargé depuis Vulkan-Hpp v1.3.275,
|
||||||
|
copié dans le sysroot NDK Vulkan include.
|
||||||
|
3. `libomp.so` : copié depuis NDK clang/18/lib/linux/aarch64 vers tablette
|
||||||
|
(ggml-vulkan linked OpenMP).
|
||||||
|
|
||||||
|
Build cmake : `dist/build_ggml_vulkan.sh` produit `libggml-vulkan.so` (41 MB
|
||||||
|
avec shaders SPIR-V embarqués). Détection device :
|
||||||
|
|
||||||
|
```
|
||||||
|
ggml_vulkan: Found 1 Vulkan devices:
|
||||||
|
ggml_vulkan: 0 = Adreno (TM) 830 (Qualcomm Technologies Inc. Adreno Vulkan Driver)
|
||||||
|
uma: 1 | fp16: 1 | bf16: 0 | warp size: 64
|
||||||
|
shared memory: 32768 | int dot: 0 | matrix cores: none
|
||||||
|
```
|
||||||
|
|
||||||
|
Caractéristiques clés :
|
||||||
|
- **UMA=1** (Unified Memory Architecture) : même DRAM que CPU
|
||||||
|
- **fp16=1** OK ; bf16=0 ; **matrix cores: none** (juste compute shaders)
|
||||||
|
- Warp size 64
|
||||||
|
- L2/shared 32 KB
|
||||||
|
|
||||||
|
## Test 1 : decoder Vulkan buffer + CPU compute (sans sched)
|
||||||
|
|
||||||
|
KZTTS_DECODER_VULKAN=1 sans KZTTS_DECODER_SCHED=1 :
|
||||||
|
|
||||||
|
| Phrase | Total | RTF | WAV md5 |
|
||||||
|
|---|---:|---:|---|
|
||||||
|
| Bonjour Kazeia (baseline CPU) | 6.75 s | 2.45 | c3dd71... |
|
||||||
|
| Bonjour Kazeia + Vulkan buf | 6.80 s | 2.47 | c3dd71... ✓ |
|
||||||
|
| Bonsoir 41 frames + Vulkan buf | 8.34 s | 2.44 | — |
|
||||||
|
|
||||||
|
- Poids decoder sur Vulkan-allocated buffer (host-visible UMA)
|
||||||
|
- Compute reste CPU pur via `ggml_graph_compute_with_ctx`
|
||||||
|
- **WAV bit-exact identique au baseline**
|
||||||
|
- Perf : **neutre, marge bruit**
|
||||||
|
|
||||||
|
UMA = pas de gain BW exclusif (CPU et GPU partagent la DRAM). Poids alloués
|
||||||
|
par Vulkan driver ont peut-être un meilleur alignment/prefetch que CPU
|
||||||
|
malloc mais l'effet est non-mesurable (±2 ms par frame, bruit).
|
||||||
|
|
||||||
|
## Test 2 : decoder Vulkan + sched (GPU compute attendu)
|
||||||
|
|
||||||
|
KZTTS_DECODER_VULKAN=1 KZTTS_DECODER_SCHED=1 :
|
||||||
|
|
||||||
|
Sched créé avec `[Vulkan, CPU]`. Mais GGML_SCHED_DEBUG=2 montre :
|
||||||
|
|
||||||
|
```
|
||||||
|
node # 1 (CONT): bigvgan_input [CPU]
|
||||||
|
node # 2 (PAD): [CPU]
|
||||||
|
node # 3 (IM2COL): [CPU] -- decoder.initial.weight (21M) [CPU]
|
||||||
|
...
|
||||||
|
Stats : 14394 [CPU], 0 [Vulkan0]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tous les nœuds sur CPU**. Pourquoi ?
|
||||||
|
|
||||||
|
- Adreno UMA buffer is_host=true (Vulkan considère que c'est de la mémoire
|
||||||
|
CPU-accessible).
|
||||||
|
- Le sched logic (`ggml-backend.cpp:916-928`) : si weight is_host AND
|
||||||
|
src_backend_id == last (CPU) → offload candidat. Sinon → reste sur weight
|
||||||
|
backend.
|
||||||
|
- Avec UMA, `backend_from_buffer(vulkan_buf)` retourne probablement l'index
|
||||||
|
CPU (logique inversée pour host-visible buffers).
|
||||||
|
- Donc tous les ops tombent sur CPU.
|
||||||
|
|
||||||
|
Pour forcer compute Vulkan, faudrait soit :
|
||||||
|
- Refactor `stage_bigvgan_sched` pour appeler `ggml_backend_graph_compute(vk, gf)`
|
||||||
|
directement (mais alors ops non-supportées crashent au lieu de fallback CPU)
|
||||||
|
- Implémenter sched custom forcé
|
||||||
|
|
||||||
|
Hors scope pour ce test exploratoire.
|
||||||
|
|
||||||
|
## Test 3 : talker offload via llama.cpp (n_gpu_layers=99 → Vulkan)
|
||||||
|
|
||||||
|
KZTTS_TALKER_VULKAN=1 :
|
||||||
|
|
||||||
|
```
|
||||||
|
load_tensors: offloaded 29/29 layers to GPU
|
||||||
|
talker: Vulkan0 (GPU offload)
|
||||||
|
```
|
||||||
|
|
||||||
|
**29/29 couches sur GPU** confirmé. Mais perf :
|
||||||
|
|
||||||
|
| Étape | Baseline CPU | Talker Vulkan | Delta |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| Prefill | 87 ms | **775 ms** | **+790%** |
|
||||||
|
| Talker/frame | 32 ms | 45 ms | +44% |
|
||||||
|
| CP/frame | 70 ms | 81 ms | +15% (thermal) |
|
||||||
|
| Decoder | 3.3 s | 6.6 s | +100% (thermal/GPU bus contention) |
|
||||||
|
| **Total** | **6.75 s** | **15.4 s** | **+128%** |
|
||||||
|
|
||||||
|
WAV md5 différent (a8f03d66 vs c3dd71cb) : GPU fp16 diverge légèrement
|
||||||
|
de CPU NEON f32.
|
||||||
|
|
||||||
|
Raisons de la régression massive :
|
||||||
|
|
||||||
|
1. **Talker = Qwen3-TTS 0.6B** : trop petit pour amortir overhead pipeline
|
||||||
|
GPU (kernel launch, sync, copy embedding/logits CPU↔GPU à chaque token).
|
||||||
|
2. **Decode batch=1** : pattern défavorable pour GPU compute shaders
|
||||||
|
(warps largement vides).
|
||||||
|
3. **Prefill 775 ms** : probablement compile shaders à chaud + premier
|
||||||
|
chargement des poids sur Adreno.
|
||||||
|
4. **GPU bus contention** : Adreno + CPU sur la même DRAM 25 GB/s effective ;
|
||||||
|
les jobs GPU saturent la BW ce qui ralentit aussi le CP et decoder CPU
|
||||||
|
qui tournent en parallèle.
|
||||||
|
|
||||||
|
## Verdict Vulkan
|
||||||
|
|
||||||
|
| Pattern | Gain net | Pourquoi |
|
||||||
|
|---|---|---|
|
||||||
|
| Vulkan buf + CPU compute | **0% (neutre)** | UMA = pas de BW gain exclusif |
|
||||||
|
| Vulkan compute via sched | impossible | sched route UMA → CPU automatiquement |
|
||||||
|
| Talker Vulkan offload | **-128% (régression massive)** | 0.6B + batch=1 + bus contention |
|
||||||
|
| BigVGAN Vulkan compute direct | **non testé** (faut refactor sched) | exigerait crash si ops non-supportées |
|
||||||
|
|
||||||
|
**Conclusion** : comme le HTP, Vulkan Adreno 830 sur SM8750 **n'apporte
|
||||||
|
pas de gain net** sur ce workload TTS. Trois facteurs :
|
||||||
|
|
||||||
|
1. **UMA** : pas de mémoire exclusive GPU, donc pas de gain BW
|
||||||
|
2. **Pas de matrix cores** : Adreno 830 fait du compute shader standard
|
||||||
|
(vs NEON 4-wide CPU)
|
||||||
|
3. **Workload TTS** : autorégressif batch=1, mauvais pour GPU paradigm
|
||||||
|
|
||||||
|
Cette confirmation valide définitivement l'orientation **NEON CPU optimisé**
|
||||||
|
comme la voie unique réaliste pour ce hardware sur ce TTS.
|
||||||
|
|
||||||
|
## Consommation énergétique (préoccupation Richard)
|
||||||
|
|
||||||
|
Non mesurée précisément, mais qualitativement :
|
||||||
|
- Vulkan talker offload : pipeline ×2.3 plus long. Probable consommation
|
||||||
|
ENERGIE × 2 (CPU encore actif pendant l'attente GPU).
|
||||||
|
- Vulkan buffer + CPU : conso similaire au baseline.
|
||||||
|
- NEON CPU optim : meilleure efficience énergétique (compute compact,
|
||||||
|
pas de driver overhead, pas de bus traffic supplémentaire).
|
||||||
|
|
||||||
|
**Reste sur NEON CPU pour la prod, conso optimale.**
|
||||||
|
|
||||||
|
## Path résiduels non explorés (par honnêteté)
|
||||||
|
|
||||||
|
- **BigVGAN compute forcé sur Vulkan via API directe** : skipper le sched,
|
||||||
|
appeler `ggml_backend_graph_compute(vk, gf)` directement. Ops non-supportées
|
||||||
|
crashent. Refactor lourd pour wrapping fallback.
|
||||||
|
- **Vulkan shader custom** pour conv1d optimisé pour Adreno spécifique :
|
||||||
|
chantier sérieux, semaines.
|
||||||
|
- **Mix CPU/GPU avec gros chunks** : faire petits ops sur CPU, gros matmul
|
||||||
|
isolés sur GPU. Demande analyse fine + refactor.
|
||||||
|
|
||||||
|
Aucun ne paraît livrable dans une session vu le pattern de régression
|
||||||
|
observé.
|
||||||
|
|
||||||
|
## Code committé
|
||||||
|
|
||||||
|
- `dist/build_ggml_vulkan.sh` : script build ggml-vulkan pour Android arm64
|
||||||
|
- `dist/jni/tts_engine.cpp` : nouveau path optionnel
|
||||||
|
- `KZTTS_VULKAN_LIB=/path/libggml-vulkan.so` : charge backend Vulkan
|
||||||
|
- `KZTTS_DECODER_VULKAN=1` : decoder utilise buft Vulkan (neutre)
|
||||||
|
- `KZTTS_TALKER_VULKAN=1` : talker offload (régresse, à éviter)
|
||||||
|
|
||||||
|
Tous opt-in, désactivés par défaut. Path principal (NEON CPU) intact.
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build ggml-vulkan pour Android arm64 dans un répertoire de test.
|
||||||
|
# Cible : produire libggml-vulkan.so + précompiler les SPIR-V shaders.
|
||||||
|
set -euo pipefail
|
||||||
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
NDK="${ANDROID_NDK_ROOT:-/opt/Kazeia/android-ndk-r27d}"
|
||||||
|
SRC="/opt/Kazeia-engine/ql"
|
||||||
|
B="$HERE/b-vulkan"
|
||||||
|
mkdir -p "$B"
|
||||||
|
cd "$B"
|
||||||
|
|
||||||
|
# Vulkan SDK headers + lib viennent du NDK sysroot directement.
|
||||||
|
# glslc pour compiler les shaders compute en SPIR-V.
|
||||||
|
GLSLC="$NDK/shader-tools/linux-x86_64/glslc"
|
||||||
|
|
||||||
|
cmake "$SRC" \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="$NDK/build/cmake/android.toolchain.cmake" \
|
||||||
|
-DANDROID_ABI=arm64-v8a \
|
||||||
|
-DANDROID_PLATFORM=android-31 \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DGGML_VULKAN=ON \
|
||||||
|
-DGGML_HEXAGON=OFF \
|
||||||
|
-DGGML_BACKEND_DL=ON \
|
||||||
|
-DBUILD_SHARED_LIBS=ON \
|
||||||
|
-DLLAMA_BUILD_TOOLS=OFF \
|
||||||
|
-DLLAMA_BUILD_EXAMPLES=OFF \
|
||||||
|
-DLLAMA_BUILD_SERVER=OFF \
|
||||||
|
-DLLAMA_BUILD_TESTS=OFF \
|
||||||
|
-DSPIRV-Headers_DIR=/tmp/spirv-install/share/cmake/SPIRV-Headers \
|
||||||
|
-DVulkan_GLSLC_EXECUTABLE="$GLSLC" \
|
||||||
|
-G Ninja 2>&1 | tail -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== cmake done, building libggml-vulkan ==="
|
||||||
|
ninja ggml-vulkan 2>&1 | tail -10
|
||||||
|
echo ""
|
||||||
|
find . -name "libggml-vulkan*" 2>/dev/null
|
||||||
|
|
@ -182,6 +182,16 @@ TtsEngine * tts_engine_load(const TtsEngineLoadCfg & cfg) {
|
||||||
setenv("GGML_HEXAGON_USE_HMX", "0", 1);
|
setenv("GGML_HEXAGON_USE_HMX", "0", 1);
|
||||||
llama_backend_init();
|
llama_backend_init();
|
||||||
|
|
||||||
|
// --- 2.5) Chargement dynamique du backend Vulkan (DOIT être AVANT talker load,
|
||||||
|
// pour que llama.cpp voit le device Adreno lors de mp.devices = {vk_dev, ...}).
|
||||||
|
if (const char * vk_path = getenv("KZTTS_VULKAN_LIB")) {
|
||||||
|
if (ggml_backend_load(vk_path)) {
|
||||||
|
fprintf(stderr, "Vulkan backend chargé : %s\n", vk_path);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "ggml_backend_load(%s) FAIL\n", vk_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --- 3) Tokenizer optionnel (vocab_only -> ~50 MB RAM) ---
|
// --- 3) Tokenizer optionnel (vocab_only -> ~50 MB RAM) ---
|
||||||
if (cfg.vocab_gguf && *cfg.vocab_gguf) {
|
if (cfg.vocab_gguf && *cfg.vocab_gguf) {
|
||||||
if (!kz_tok_load(eng->kz_tok, cfg.vocab_gguf)) {
|
if (!kz_tok_load(eng->kz_tok, cfg.vocab_gguf)) {
|
||||||
|
|
@ -193,9 +203,34 @@ TtsEngine * tts_engine_load(const TtsEngineLoadCfg & cfg) {
|
||||||
|
|
||||||
// --- 4) Talker (libllama) ---
|
// --- 4) Talker (libllama) ---
|
||||||
auto mp = llama_model_default_params();
|
auto mp = llama_model_default_params();
|
||||||
ggml_backend_dev_t devs[2] = { cfg.use_htp ? find_htp() : nullptr, nullptr };
|
// KZTTS_TALKER_VULKAN=1 -> offload talker sur GPU Adreno via Vulkan device.
|
||||||
if (devs[0]) { mp.n_gpu_layers = 99; mp.devices = devs; fprintf(stderr, "talker: HTP0\n"); }
|
const bool talker_vulkan = (getenv("KZTTS_TALKER_VULKAN") && atoi(getenv("KZTTS_TALKER_VULKAN")) != 0);
|
||||||
else { mp.n_gpu_layers = 0; fprintf(stderr, "talker: CPU\n"); }
|
ggml_backend_dev_t vk_dev = nullptr;
|
||||||
|
if (talker_vulkan) {
|
||||||
|
// Adreno UMA -> ggml-vulkan registre le device comme IGPU (type=2, integrated GPU
|
||||||
|
// utilisant la host memory). HTP s'enregistre comme GPU (type=1). On accepte les deux
|
||||||
|
// GPU et IGPU mais filtre par nom pour exclure HTP/Hexagon explicitement.
|
||||||
|
for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {
|
||||||
|
auto d = ggml_backend_dev_get(i);
|
||||||
|
auto t = ggml_backend_dev_type(d);
|
||||||
|
if (t != GGML_BACKEND_DEVICE_TYPE_GPU && t != GGML_BACKEND_DEVICE_TYPE_IGPU) continue;
|
||||||
|
const char * nm = ggml_backend_dev_name(d);
|
||||||
|
if (strstr(nm, "HTP") || strstr(nm, "Hexagon")) continue;
|
||||||
|
vk_dev = d;
|
||||||
|
fprintf(stderr, "talker: GPU candidate found : %s (type=%d)\n", nm, (int)t);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ggml_backend_dev_t devs[2] = {
|
||||||
|
vk_dev ? vk_dev : (cfg.use_htp ? find_htp() : nullptr),
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
|
if (devs[0]) {
|
||||||
|
mp.n_gpu_layers = 99; mp.devices = devs;
|
||||||
|
fprintf(stderr, "talker: %s (GPU offload)\n", ggml_backend_dev_name(devs[0]));
|
||||||
|
} else {
|
||||||
|
mp.n_gpu_layers = 0; fprintf(stderr, "talker: CPU\n");
|
||||||
|
}
|
||||||
eng->talker_m = llama_model_load_from_file(cfg.talker_gguf, mp);
|
eng->talker_m = llama_model_load_from_file(cfg.talker_gguf, mp);
|
||||||
if (!eng->talker_m) { fprintf(stderr, "talker load FAIL %s\n", cfg.talker_gguf); delete eng; return nullptr; }
|
if (!eng->talker_m) { fprintf(stderr, "talker load FAIL %s\n", cfg.talker_gguf); delete eng; return nullptr; }
|
||||||
|
|
||||||
|
|
@ -256,9 +291,36 @@ TtsEngine * tts_engine_load(const TtsEngineLoadCfg & cfg) {
|
||||||
// Sinon : load() classique = CPU pur via ggml_graph_compute_with_ctx (path actuel).
|
// Sinon : load() classique = CPU pur via ggml_graph_compute_with_ctx (path actuel).
|
||||||
const bool dec_htp = (getenv("KZTTS_DECODER_HTP") && atoi(getenv("KZTTS_DECODER_HTP")) != 0);
|
const bool dec_htp = (getenv("KZTTS_DECODER_HTP") && atoi(getenv("KZTTS_DECODER_HTP")) != 0);
|
||||||
bool dec_ok;
|
bool dec_ok;
|
||||||
if (dec_htp) {
|
const bool dec_vulkan = (getenv("KZTTS_DECODER_VULKAN") && atoi(getenv("KZTTS_DECODER_VULKAN")) != 0);
|
||||||
|
if (dec_htp || dec_vulkan) {
|
||||||
std::vector<ggml_backend_t> dec_backends;
|
std::vector<ggml_backend_t> dec_backends;
|
||||||
// 1er backend = HTP si dispo, sinon CPU seul (équivalent au load classique).
|
// Vulkan prioritaire si demandé (Adreno GPU compute, BW partagée mémoire).
|
||||||
|
if (dec_vulkan) {
|
||||||
|
// Note : Hexagon HTP est aussi enregistré comme DEVICE_TYPE_GPU. On filtre par
|
||||||
|
// nom non-HTP pour trouver le VRAI GPU (Adreno...). Liste tous les devs et choisis.
|
||||||
|
fprintf(stderr, "Devices enregistrés (%zu):\n", ggml_backend_dev_count());
|
||||||
|
for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {
|
||||||
|
auto d = ggml_backend_dev_get(i);
|
||||||
|
fprintf(stderr, " [%zu] %s (type=%d)\n", i,
|
||||||
|
ggml_backend_dev_name(d), (int)ggml_backend_dev_type(d));
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {
|
||||||
|
auto d = ggml_backend_dev_get(i);
|
||||||
|
auto t = ggml_backend_dev_type(d);
|
||||||
|
// Adreno UMA = type IGPU. HTP = type GPU. On accepte les deux et filtre par nom.
|
||||||
|
if (t != GGML_BACKEND_DEVICE_TYPE_GPU && t != GGML_BACKEND_DEVICE_TYPE_IGPU) continue;
|
||||||
|
const char * nm = ggml_backend_dev_name(d);
|
||||||
|
if (strstr(nm, "HTP") || strstr(nm, "Hexagon")) continue;
|
||||||
|
ggml_backend_t vk = ggml_backend_dev_init(d, nullptr);
|
||||||
|
if (vk) {
|
||||||
|
dec_backends.push_back(vk);
|
||||||
|
fprintf(stderr, "decoder: Vulkan backend initialisé (%s)\n", nm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// HTP (option backend si pas Vulkan ou ajout)
|
||||||
|
if (dec_htp) {
|
||||||
if (auto htp_dev = find_htp()) {
|
if (auto htp_dev = find_htp()) {
|
||||||
ggml_backend_t htp = ggml_backend_dev_init(htp_dev, nullptr);
|
ggml_backend_t htp = ggml_backend_dev_init(htp_dev, nullptr);
|
||||||
if (htp) {
|
if (htp) {
|
||||||
|
|
@ -268,6 +330,7 @@ TtsEngine * tts_engine_load(const TtsEngineLoadCfg & cfg) {
|
||||||
fprintf(stderr, "decoder: ggml_backend_dev_init(HTP0) FAIL, fallback CPU\n");
|
fprintf(stderr, "decoder: ggml_backend_dev_init(HTP0) FAIL, fallback CPU\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// CPU TOUJOURS en DERNIER (ggml_backend_sched_new assert que backends[end]=CPU,
|
// CPU TOUJOURS en DERNIER (ggml_backend_sched_new assert que backends[end]=CPU,
|
||||||
// c'est le fallback universel pour les ops non-supportées par les autres).
|
// c'est le fallback universel pour les ops non-supportées par les autres).
|
||||||
ggml_backend_t cpu = ggml_backend_init_by_type(GGML_BACKEND_DEVICE_TYPE_CPU, nullptr);
|
ggml_backend_t cpu = ggml_backend_init_by_type(GGML_BACKEND_DEVICE_TYPE_CPU, nullptr);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue