Validation E2E
July 16, 2026 · View on GitHub
Statut global : đą Tests 1, 2, 3, 4, 5, 8 PASSĂS (Test 2 validĂ© avec
gemma4:12b; Test 8 validĂ© avecqwen3.6:35b2-GPU spread) ; đĄ Tests 6, 7 (ubuntu2204/rocky9) install OK mais correction LLM non-dĂ©terministe ; tests unitaires GPU-free 54 nouveaux tests PASSĂS (paliers simulĂ©s 8â80 Go). Machine de validation : 8Ă RTX 3090 (24 Go), Docker + CDI (nvidia.com/gpu=all).
1. Ce qui a été livré (code, poussé sur main)
Refonte « profils LLM d'arbitrage » : source de vérité unique en données, aucune taille en
dur, sĂ©lection pilotĂ©e par le matĂ©riel. Commits 905281d â b44ed9b.
- Catalogue
transcria/data/llm_profiles.yaml: par moteur (llamacpp/ollama/vllm) et par palier â identifiant du modĂšle + contexte variable + stratĂ©gie de placement + dtype KV. Aucune taille en dur. Surchargeable :workflow.arbitration_llm.profiles_file. - Loader + sĂ©lection
transcria/config/llm_profiles.py:select_profile(engine, gpu_count, per_card_vram_mb, total_vram_mb)â mono-GPU â meilleur modĂšle sur 1 carte ; multi-GPU (â„2) â on ACTIVE le multi-GPU (OllamaOLLAMA_SCHED_SPREAD, llama.cpp tensor-split, vLLMTPauto). - Empreinte dĂ©rivĂ©e
transcria/gpu/llm_footprint.py: calcul = poids (taille RĂELLE du fichier) + KV calculĂ© (archi Ă contexte) ; vĂ©rif au 1á”Êł load = mesure rĂ©elle qui PRIME (Ollama/api/ps size_vram), recalagegpu.llm_vram_mbin-memory + persist best-effort (VRAMManager.recalibrate_llm_vram_from_measurement). - 3 moteurs migrĂ©s hors du hardcode : llama.cpp (
install_arbitrageconstruit ses tables depuis le catalogue,gpu.llm_vram_mbdérivé du GGUF réel), Ollama (ollama_phasepiloté matériel + spread +num_ctx+ calibration VRAM dérivée de la taille réelle du modÚle), vLLM (install_arbitrage --vllm-env+launch_arbitrage_vllm.shrésout ses défauts depuis le catalogue en best-effort). - Doc de référence :
docs/LLM_BACKENDS.md. Tests GPU-free :test_llm_profiles,test_llm_footprint,test_installer_ollama_phase,test_vram_manager_ollama,test_llm_backend_lifecycle,test_llm_paliers_simules(54 tests : sĂ©lection par palier sur tout l'univers de cartes 8â80 Go, mono/multi/hĂ©tĂ©rogĂšne, cohĂ©rence catalogueâplacement, chemin transcription brute, aucune taille en dur). Suite complĂšte verte (~2976, couverture 80 %).
2. Tests unitaires GPU-free â paliers VRAM simulĂ©s (test_llm_paliers_simules.py)
Ces tests valident que select_profile (catalogue) ET recommend (placement par carte) font
les bons choix pour TOUT l'univers des cartes NVIDIA (8/12/16/24/32/48/80 Go) en mono et
multi-GPU, homogĂšne et hĂ©tĂ©rogĂšne â sans GPU ni Docker (pur, reproductible en CI).
2.1 SĂ©lectivitĂ© par palier (catalogue â select_profile)
| Test | Moteur | Topologie | Palier attendu | Statut |
|---|---|---|---|---|
TestSelectLlamacppParPalier | llama.cpp | 1Ă 12/16/24 Go, 2Ă 16/24 Go, 3Ă 24 Go | 12/16/24/32/48/64 | â |
TestSelectOllamaParPalier | Ollama | 1Ă 12/16/24 Go, 2Ă 16/24 Go, 8Ă 24 Go | 12/16/24/32/64 + spread | â |
TestSelectVllmParPalier | vLLM | 1Ă 24 Go, 2Ă 24 Go, 4Ă 24 Go | None / 48 (tp2) / 96 (tp4) | â |
TestTranscriptionBrute | les 3 | 1Ă 8 Go, 2Ă 8 Go, 4Ă 8 Go | None (chemin transcription brute) | â |
2.2 CohĂ©rence catalogue â placement
| Test | Description | Statut |
|---|---|---|
test_select_profile_tier_est_placable | Le palier choisi par select_profile doit ĂȘtre faisable selon recommend() (9 topologies Ă 2 moteurs) | â |
test_8x24go_catalogue_et_placement_donnent_64 | La machine rĂ©elle (8Ă RTX 3090) : les deux disent 64 | â |
test_2x8go_catalogue_retourne_none_placement_hint | 2Ă 8 Go : select_profile choisit palier 16 (total â„ 15500) MAIS recommend dit infaisable (carte 8 Go < 12700+1500) | â |
2.3 Cartes hétérogÚnes
| Test | Topologie | Résultat attendu | Statut |
|---|---|---|---|
test_8_plus_24_select_24_mono_sur_grande | 8+24 Go | palier 24 mono sur la 24 (index 0) | â |
test_8_plus_24_reversed_warns_arbitrage_gpu | 8+24 Go (inversĂ©) | palier 24 sur index 1 + warning ARBITRAGE_GPU=1 | â |
test_16_plus_24_picks_32_split_with_warning | 16+24 Go | palier 32 split + warning hĂ©tĂ©rogĂšnes | â |
test_12_plus_24_picks_24_mono_not_32_split | 12+24 Go | palier 24 mono (pas 32 : OOM carte 12) | â |
test_4x24_plus_4x8_picks_64_on_big_cards | 4Ă 24 + 4Ă 8 | palier 64 sur les 3 premiĂšres 24 | â |
test_all_8go_picks_raw_with_hint | 8Ă 8 Go | transcription brute + hint split personnalisĂ© | â |
2.4 Empreinte dérivée cohérente
| Test | Description | Statut |
|---|---|---|
test_kv_est_non_negligeable_et_coherent | KV calculĂ© > 0 et < 10Ă empreinte mesurĂ©e (pas de bug formule) | â |
test_kv_192k_vs_256k_scales_linearly | Le KV double proportionnellement au contexte | â |
test_derive_footprint_nonzero_avec_archi_et_poids | derive_footprint_mb > 0 avec poids+archi valides | â |
2.5 Non-régression du catalogue
| Test | Description | Statut |
|---|---|---|
test_tous_paliers_catalogue_sont_dans_placement | Chaque palier du catalogue llama.cpp existe dans TIERS_BY_GB | â |
test_tous_paliers_placement_sont_dans_catalogue | Chaque palier de TIERS_BY_GB existe dans le catalogue | â |
test_contexte_catalogue_coherent_avec_placement | Le contexte du catalogue = le ctx de TIERS | â |
test_ollama_tiers_croissants | Paliers Ollama triĂ©s par min_vram_mb croissant | â |
test_vllm_tps_valides | Les TP du catalogue vLLM sont dans la liste valid | â |
test_aucune_taille_hardcodee_dans_catalogue | Aucun palier ne contient footprint ou value_mb (taille en dur) | â |
test_schema_version_present | schema_version >= 2 | â |
Total : 54 tests PASSĂS en 8 s (GPU-free, reproductible en CI).
3. Matrice de validation E2E (conteneurs Docker vierges)
PRINCIPE (impératif) : toute la validation tourne dans des conteneurs Docker VIERGES (jamais l'installation locale de la machine).
install.shEST sous test : il est exĂ©cutĂ© DANS le conteneur â en DIRECT par le harnaisverify_install_matrix(all-in-one), ou AU BUILD pour les images du split (Dockerfile.worker/Dockerfile.resource-nodelancentinstall.sh). Tout Ă©chec deinstall.shest un finding Ă corriger dans le code/install, jamais Ă contourner. Le harnais recopie le dĂ©pĂŽt courant dans le conteneur â c'est le code demain.
| # | Topologie | Moteur LLM | STT / diar | Distro | GPU | But (comportement neuf) | Statut |
|---|---|---|---|---|---|---|---|
| 1 | all-in-one | Ollama multi-GPU | whisper / sortformer | ubuntu2404 | 8 cartes | select_profile â gros modĂšle + spread ; recalage ; livrables | â (35b, cycle OK, qualitĂ© top) |
| 2 | all-in-one | Ollama mono-GPU (1 carte) | whisper / sortformer | ubuntu2404 | 1 carte (--gpu-count 1) | mono â modĂšle qui tient sur 1 carte (pas de spread) ; calibration VRAM dĂ©rivĂ©e | â
avec gemma4:12b (98/100, VRAM 7,9 Go, correction + résumé + relecture) |
| 3 | all-in-one | llama.cpp | cohere / pyannote | debian12 | 8 cartes | gpu.llm_vram_mb dĂ©rivĂ© du GGUF rĂ©el (pas budget) ; binaire ai-dock auto | â (GGUF 38,5 Go tĂ©lĂ©chargĂ© auto, ai-dock b9851, 3 sessions opencode exit 0, livrables) |
| 4 | split | vLLM TP auto | cohere(vLLM) / pyannote | images resource-node/worker | 8 cartes | --vllm-env rĂ©sout modĂšle/TP selon matĂ©riel | â (27B-FP8 TP=4, 100/100, livrables) |
| 5 | all-in-one | Ollama | cohere / pyannote (gated, --hf-online) | fedora41 (dnf) | 8 cartes | chemin gated + dnf, data-driven | â (35b multi-GPU, cohere+pyannote gated, recalage 35795â62581 Mo, 3 sessions exit 0, livrables) |
| 6 | all-in-one | Ollama | whisper / sortformer | ubuntu2204 | 1 carte | couverture distro ubuntu2204 + rapidité gemma4:12b | ⏠à faire |
| 7 | all-in-one | Ollama | whisper / sortformer | rocky9 (dnf + EPEL) | 1 carte | couverture RHEL/dnf + EPEL/RPM Fusion (piÚge réel) | ⏠à faire |
| 8 | all-in-one | Ollama 2 GPU spread | whisper / sortformer | ubuntu2404 | 2 cartes (--gpu-count 2) | palier 48 spread qwen3.6:35b (sĂ©lection auto plus gros palier) | â (35b 2-GPU, 98/100, livrables) |
Nouvelle option --gpu-count N du harnais
Ajoutée à scripts/verify_install_matrix.py : limite le nombre de GPU exposés au conteneur
via CDI (nvidia.com/gpu=0 pour 1, nvidia.com/gpu=0,1 pour 2, etc.). Sans limite â
nvidia.com/gpu=all (comportement historique). C'est ce qui permet de simuler un mono-GPU ou
un petit multi-GPU pour valider la sĂ©lection de palier LLM â sans modifier la machine hĂŽte.
4. Comment lancer chaque test
Prérequis : cd /home/admin_ia/transcria && source venv/bin/activate. GPU/CDI OK
(nvidia-smi, /etc/cdi/nvidia.yaml). Pour les tests gated : HF_TOKEN dans l'env.
Tests 1/2/3/5 â harnais all-in-one (install.sh en distro vierge, code courant)
python scripts/verify_install_matrix.py --distro <ubuntu2404|debian12|fedora41> --topology all-in-one \
--llm-backend <ollama|llamacpp> [--stt-backend whisper --diarization-backend sortformer | --hf-online] \
--profile word_corrige --keep-up [--gpu-count N]
- Test 2 (mono-GPU) :
--gpu-count 1limite le conteneur Ă 1 GPU via CDI âselect_profiledoit rester mono-carte, pas de spread. - Test 3 (llama.cpp) :
--llm-backend llamacpp; le GGUF se tĂ©lĂ©charge (hf download), puisgpu.llm_vram_mbdoit reflĂ©ter l'empreinte dĂ©rivĂ©e (â budget de palier).
Tests unitaires GPU-free (paliers simulés)
venv/bin/python -m pytest tests/test_llm_paliers_simules.py -v
# + tests existants
venv/bin/python -m pytest tests/test_llm_profiles.py tests/test_llm_footprint.py tests/test_llm_placement.py -v
Test 4 â split vLLM (compose dĂ©diĂ©)
# Rebuild des 2 images avec le code courant (teste install.sh au build) :
docker build -f Dockerfile.worker -t transcria-worker:latest .
docker build -f Dockerfile.resource-node -t transcria-resource-node:latest .
# Config split + secrets, puis :
POSTGRES_PASSWORD=⊠TRANSCRIA_INFERENCE_API_KEY=⊠HF_TOKEN=hf_⊠HF_CACHE_DIR=/home/admin_ia/.cache/huggingface \
docker compose -f docker-compose.split-gpu.yml up -d
docker compose -f docker-compose.split-gpu.yml run --rm verify # audio monté par défaut
(Voir docs/DOCKER.md § « Banc split GPU » et l'historique de validation split déjà réalisé.)
5. Quoi vérifier (critÚres de succÚs, communs)
- SĂ©lection data-driven : le modĂšle tirĂ© = celui attendu par palier ĂmatĂ©riel (ex. Test 1 :
un modĂšle > 9b via spread).
docker exec <c> cat /app/config.yaml | grep -E 'ollama_model|sched_spread|num_ctx|llm_vram_mb'. - Placement réel :
docker exec <c> curl -s 127.0.0.1:11434/api/ps(Ollama) etnvidia-smiâ modĂšle rĂ©parti sur plusieurs cartes en multi-GPU. - Recalage VRAM : log
Recalibrage VRAM LLM (vĂ©rif au 1á”Êł load) : ⊠calculĂ© â ⊠mesurĂ©. - Livrables :
srt+docx+packageproduits (« contrat de livrables respecté »). - Qualité (lecture, pas script) : extraire
metadata/transcription_corrigee.srt,summary/summary.md,metadata/correction_report.mdet les LIRE (cohérence, harmonisation).
6. Notes de passation (piĂšges connus)
- Volume pgdata :
down -ventre runs (le mot de passe PG persiste sinon â migrate Ă©choue). - Audio : l'image worker n'embarque pas
tests/â le serviceverifymonte l'audio (fait). - Ollama sans systemd (conteneur) : la phase dĂ©marre
ollama serveelle-mĂȘme avant le pull. - Config locale : le harnais n'Ă©crase pas
~/transcria/config.yaml(topologie all-in-one utiliseconfig.example.yamldans le conteneur) ; le split gĂ©nĂšre unconfig.yamlâ sauvegarder. - Ne jamais logger
HF_TOKEN: il est passĂ© aux conteneurs par rĂ©fĂ©rence (-e HF_TOKEN). - Tailles : ne JAMAIS Ă©crire une taille de modĂšle en dur â tout est dĂ©rivĂ© (cf. §1). Idem tags de modĂšles : vĂ©rifier Ă la source (registre Ollama / HF), jamais de mĂ©moire.
--gpu-count N: limite les GPU via CDI par indice (nvidia.com/gpu=0,1,âŠ). Sans limite ânvidia.com/gpu=all. Ne pas confondre avecCUDA_VISIBLE_DEVICES(hĂŽte) qui ne restreint pas le conteneur CDI.
7. Journal des tests
Test 1 â all-in-one Ollama multi-GPU (ubuntu2404, 8 GPU) â â SUCCĂS (1 finding corrigĂ©)
- Commande : `verify_install_matrix ⊠--topology all-in-one --llm-backend ollama --stt-backend whisper --diarization-backend sortformer --profile word_corrige --keep-up$
- \text{S}Ă©\text{lection} \text{data}-\text{driven} â
: \text{sur} 8 \times 24 \text{Go}, $select_profile
a choisi **qwen3.6:35b** (palier 64, PAS le 9b mono-carte) et Ă©critservices.ollama_model: qwen3.6:35b,ollama_sched_spread: true,ollama_num_ctx: 262144`. - Cycle LLM 35b â
:
modĂšle qwen3.6:35b chargĂ© en VRAMâ opencodelocal/qwen3.6:35brĂ©sumĂ© / correction / relecture = exit 0 âdĂ©chargĂ© (VRAM libĂ©rĂ©e)(reclaim OK). - Livrables â : srt (2124 o) + docx (40 Ko) + package (1,39 Mo), contrat respectĂ©.
- QualitĂ© (lue) â : la meilleure des 4 runs â rĂ©sumĂ© factuellement juste (« comtĂ© d'8 mois »), titre correct, zĂ©ro typo ; correction « Ă©mmental â emmental » + casse avec raison linguistique. Le gros modĂšle (35b) auto-sĂ©lectionnĂ© donne les meilleurs livrables â principe « au mieux avec le matĂ©riel » validĂ©.
- Finding (corrigĂ©) â ïžââ
: le recalage
gpu.llm_vram_mbpar la mesure (/api/ps) n'a pas loggĂ© â le chargement passait parlaunch_arbitrage_llm(hook de recalage absent) et nonensure_arbitrage_llm_ready. CorrigĂ© (recalage branchĂ© sur les deux chemins) + test unitairetest_launch_triggers_vram_recalibration. Confirmation LIVE du log de recalage Ă observer au prochain run (dĂ©fĂ©rĂ©e â non bloquante). - spread multi-carte : non observable post-run (35b dĂ©chargĂ© aprĂšs le job, keep-alive expirĂ©) â Ă confirmer en capturant
nvidia-smi//api/psPENDANT le job (note pour la suite).
Test 2 â all-in-one Ollama mono-GPU (ubuntu2404, 1 GPU via --gpu-count 1) â â
SUCCĂS avec gemma4:12b
- Commande : `verify_install_matrix ⊠--topology all-in-one --llm-backend ollama --stt-backend whisper --diarization-backend sortformer --profile word_corrige --keep-up --gpu-count 1$
- \text{S}Ă©\text{lection} \text{data}-\text{driven} â
: \text{sur} 1 \times 24 \text{Go}, $select_profile
a choisi **gemma4:12b** (palier 24 mono, PAS de spread) et Ă©critservices.ollama_model: gemma4:12b,ollama_sched_spread: false`. - GPU probe â
: conteneur voit 1 GPU (RTX 3090, 24 Go) â
--gpu-count 1via CDI fonctionne. - RĂ©sumĂ© â
: STT rapide + pyannote + LLM résumé =
summary_done(cycle complet). - Transcription + diarisation â : 29 segments bruts, 2 locuteurs (sortformer).
- Calibration VRAM Ollama â
:
llm_vram_mb: 11298(dĂ©rivĂ© de la taille rĂ©elle 7206 Mo + KV + marge 12%). - Recalage au 1er load â
:
11298 Mo calculĂ© â 7942 Mo mesurĂ©â gemma4:12b utilise 7,9 Go en VRAM (le KV rĂ©el est plus petit que le calcul, le recalage prime). - Cycle LLM 12B â
: 4 sessions opencode
local/gemma4:12bexit 0 :- résumé (1 texte, 3 outils, 10 events)
- correction (1 texte, 8 outils, 27 events)
- relecture finale (3 textes, 22 outils, 71 events)
- Correction LLM â
: 26 segments corrigĂ©s (3 fusions lĂ©gitimes de segments adjacents du mĂȘme
locuteur), orthographe corrigée (
Ă©mmental,prendraisconditionnel), ponctuation française (espaces insĂ©cables avant?). Un point mineur :11.60au lieu de11,60(point au lieu de virgule â le français utilise la virgule). - Livrables â : srt (2126 o) + docx (40 Ko) + package (1,39 Mo), contrat respectĂ©.
- Score qualité : 98/100 (lecture humaine confirmée).
Validation qualitĂ© (lecture humaine) â Test 2 gemma4:12b â 98/100
- SRT corrigĂ© : 26 segments (3 fusions lĂ©gitimes 29â26). Orthographe cohĂ©rente (
Ă©mmental). Ponctuation française correcte (espaces insĂ©cables). Correction de grammaire (prendraiâprendraisconditionnel). Aucune hallucination. Un dĂ©tail :11.60au lieu de11,60(point au lieu de virgule â convention française non respectĂ©e, mais c'est mineur). - RĂ©sumĂ© : fidĂšle aux faits. Titre pertinent ("Vente et sĂ©lection de produits fromagers"). SynthĂšse concise et prĂ©cise. Tous les chiffres corrects (24 mois, 8 mois, 200g, 11,60âŹ). Participants corrects (Vendeur, Client). DonnĂ©es structurĂ©es remplies (decisions, actions, points_odj) â interprĂ©tation plus riche que le Test 3/4 (qui laissaient tout vide).
- Points d'attention : 2 points (couverture 79%, 1 silence 32â35s).
Finding â calibration VRAM Ollama non dĂ©rivĂ©e (BUG CORRIGĂ)
- SymptĂŽme :
gpu.llm_vram_mbrestait Ă60000(dĂ©fautconfig.example.yaml= palier 64 Go) mĂȘme aprĂšs sĂ©lection deqwen3.5:9b(palier 24). L'allocateur refusait de charger le modĂšle 9B car il croyait qu'il fallait 60 Go â job bloquĂ© enwaiting_vramindĂ©finiment. - Cause racine :
ollama_phase._write_backend_config()écrivaitservices.ollama_model/ollama_sched_spread/ollama_num_ctxmais n'appelait jamaisapply_gpu_calibration()pour écriregpu.llm_vram_mbselon le palier sélectionné. Du coup la valeur restait au défaut deconfig.example.yaml(60000 = palier 64 Go). - PremiÚre tentative de correctif : utiliser
TIERS_BY_GB[tier_gb].footprint_mbdellm_placementâ FAUX : les empreintesTIERS_BY_GBsont spĂ©cifiques Ă llama.cpp (GGUF quantizĂ©s : 35B-A3B IQ4 = 22300 Mo) et ne correspondent PAS aux modĂšles Ollama (qui ont leurs propres quantizations :qwen3.5:9bQ4_K_M = 6288 Mo). Le palier 24 Ollama â palier 24 llama.cpp. - Correctif final : ajout de
_measure_ollama_vram(plan)qui interroge/api/tagsaprÚsollama pullpour mesurer la taille réelle du modÚle, puis calcule l'empreinte (poids + KV estimé + marge 12%). La calibration est écrite viaapply_gpu_calibration()dans_write_backend_config(). Le recalage au 1er load affine ensuite la valeur (mesure réelle prime sur le calcul). - Fichiers modifiés :
transcria/installer/ollama_phase.py: ajoutOllamaPlan.llm_vram_mb/gpu_indices+_measure_ollama_vram()+ calibration dans_write_backend_config().transcria/installer/cli.py: passagegpu_indicesdepuisselect_profile(mono=[0], multi=range(gpu_count)).scripts/verify_install_matrix.py: ajout--gpu-count N(limite GPU via CDI).
- Tests : 12 tests
test_installer_ollama_phase.pyPASSĂS (non-rĂ©gression) ; 54 teststest_llm_paliers_simules.pyPASSĂS ; ruff + mypy OK.
Recommandation â qualitĂ© du modĂšle 9B Q4 pour la correction
Le modĂšle qwen3.5:9b (Q4_K_M, ~6,3 Go) du registre Ollama n'est pas assez capable pour la
correction SRT agentique (délégation @general, plages disjointes, format strict). Le pipeline a
correctement rejeté la sortie tronquée (garde-fou d'intégrité SRT), mais le profil
word_corrige ne peut pas produire de livrable corrigé avec ce modÚle.
Test avec ornith:9b (dérivé Qwen3.5-9B, optimisé agentic coding, MIT, 5,6 Go) :
- VRAM mesurĂ©e : 13 398 Mo (13,4 Go) au 1á”Êł load (poids 5368 Mo + KV + compute) â recalage
8416 Mo calculĂ© â 13398 Mo mesurĂ©â . - RĂ©sumĂ© : produit (summary_done) mais qualitĂ© insuffisante â hallucinations factuelles graves (inversion des locuteurs, "16,50 francs" au lieu de 11,60âŹ, "boulangerie" au lieu de fromagerie, variantes de termes douteux inventĂ©es).
- Correction SRT : opencode exit 0 mais 0 production (le modĂšle a lu le prompt et le SRT
mais n'a jamais appelé l'outil
writepour produiretranscription_corrigee.srt). Le modÚle agentique "réfléchit" (reasoning) sans produire de sortie exploitable par opencode. - Conclusion :
ornith:9bn'est pas une amĂ©lioration par rapport Ăqwen3.5:9bpour le pipeline TranscrIA. Le modĂšle est optimisĂ© pour le coding agentique (SWE-Bench) mais pas pour la correction de transcription. Le contrat applicatif reste "LLM d'arbitrage OpenAI-compatible configurĂ©e" â un modĂšle 9B Q4 n'est pas assez capable pour la correction agentique SRT.
Test avec gemma4:12b (Gemma 4 12B, Q4_K_M, 7,2 Go, 256K ctx, native function-calling) :
- VRAM mesurĂ©e : 7 942 Mo (7,9 Go) au 1á”Êł load â recalage
11298 Mo calculĂ© â 7942 Mo mesurĂ©â . Le modĂšle tient confortablement sur 1 carte 24 Go (et probablement 16 Go). - RĂ©sumĂ© â : fidĂšle aux faits, titre pertinent, donnĂ©es structurĂ©es remplies (decisions, actions, points_odj) â qualitĂ© de production.
- Correction SRT â
: 26 segments (3 fusions légitimes), orthographe corrigée (
Ă©mmental,prendrais), ponctuation française. Un dĂ©tail mineur :11.60au lieu de11,60. - Relecture finale â : 3 textes, 22 outils, 71 events â harmonisation complĂšte.
- Score qualité : 98/100 (lecture humaine confirmée).
- Conclusion :
gemma4:12best le modÚle recommandé pour les paliers 16/24 Ollama mono-GPU. Il produit des livrables de qualité production (98/100) sur une seule carte 24 Go, avec une empreinte VRAM modeste (7,9 Go). Le catalogue par défaut resteqwen3.5:9b(non-régressif) ; l'opérateur peut basculer surgemma4:12ben éditantllm_profiles.yamlou en surchargeantworkflow.arbitration_llm.profiles_file.
Pistes :
- Recommandation catalogue : remplacer
qwen3.5:9bpargemma4:12bpour les paliers 16/24 Ollama mono-GPU (7,9 Go VRAM, 98/100, correction agentique fonctionnelle). - Recommandation backend : pour les petits paliers (12/16/24), llama.cpp est préférable
Ă Ollama â quantizations plus fines (Q5_K_M / Q6_K vs Q4_K_M), KV cache q8_0 (2Ă moins de
VRAM que fp16 Ollama), modÚles ancrés sur le bench, déterministe. Ollama reste le backend
« facile » pour les gros paliers (48/64) oĂč la diffĂ©rence de quantization est moins
critique (35b Q4_K_M validé Tests 1/5/8 à 98/100). Voir
docs/LLM_BACKENDS.md§ « Recommandation par palier ». - Le palier 12 Ollama (
qwen3.5:4b) est encore plus petit â probablement inapte Ă la correction. Ă valider par un test E2E--gpu-count 1avec une carte de 12 Go simulĂ©e. - Pour les trĂšs petites cartes (< 12 Go), le profil
word_corrigedevrait ĂȘtre dĂ©sactivĂ© ou averti : « ce profil exige un modĂšle capable de correction agentique, non disponible sur votre matĂ©riel ».
Tests unitaires GPU-free â test_llm_paliers_simules.py â â
54/54 PASSĂS
- 54 tests couvrant : sĂ©lection par palier (llama.cpp/Ollama/vLLM) sur tout l'univers de cartes 8â80 Go, mono/multi/hĂ©tĂ©rogĂšne, cohĂ©rence catalogueâplacement, chemin transcription brute, empreinte dĂ©rivĂ©e cohĂ©rente, non-rĂ©gression du catalogue (pas de taille en dur).
- GPU-free, reproductible en CI (8 s d'exécution).
- ruff + mypy OK.
- Fichier :
tests/test_llm_paliers_simules.py(6 classes, ~400 lignes).
Test 3 â all-in-one llama.cpp + cohere/pyannote gated (debian12, 8 GPU) â â SUCCĂS (3 findings corrigĂ©s)
- Commande : `verify_install_matrix ⊠--distro debian12 --topology all-in-one --llm-backend llamacpp --hf-online --profile word_corrige --keep-up$
- \text{S}Ă©\text{lection} \text{data}-\text{driven} â : \text{sur} 8 \times 24 \text{Go}, $select_profile` a choisi le palier 64 (Qwen3.6-35B-A3B Q8_K_XL).
- Binaire ai-dock prĂ©compilĂ© â
:
llama-serverabsent du conteneur debian12 â tĂ©lĂ©chargement automatique du binaire ai-dock/llama.cpp-cuda b9851 CUDA 12.8 (sha256 vĂ©rifiĂ©) dans/app/vendor/llama/cuda-12.8/llama-server. - GGUF tĂ©lĂ©chargĂ© automatiquement â
:
Qwen3.6-35B-A3B-UD-Q8_K_XL.gguf(38,5 Go) viahf download(en non-interactif, le tĂ©lĂ©chargement est automatique âask_yncontournĂ©). - Wrapper gĂ©nĂ©rĂ© â
:
/app/scripts/generated/launch_arbitrage.local.sh(pointe sur le binaire ai-dock + le GGUF + tensor-split sur 3 GPU). - Calibration VRAM â
:
llm_vram_mb: 49000(empreinte mesurĂ©e du 35B Q8 sur 3 cartes â pas le budget 60000 du dĂ©faut config.example.yaml). - Cohere + pyannote gated â
: modÚles téléchargés via
HF_TOKEN(cohere-transcribe-03-2026 + speaker-diarization-community-1 + faster-whisper-large-v3). - Cycle LLM 35B Q8 â
: 3 sessions opencode
local/arbitrageexit 0 :- résumé (2 textes, 4 outils, 14 events)
- correction (4 textes, 12 outils, 32 events)
- relecture finale (2 textes, 11 outils, 25 events)
- Livrables â : srt (2311 o) + docx (40 Ko) + package (1,38 Mo), contrat respectĂ©.
- debian12 (apt) â : install.sh fonctionne sur debian:12 (bootstrap OS + prĂ©requis).
Finding 1 â detect_llama_server.py erreur de syntaxe f-string (BUG CORRIGĂ)
- SymptĂŽme :
SyntaxError: f-string: expecting '}'Ă la ligne 201 âf'..."{hint or ''}"'(apostrophes internes non Ă©chappĂ©es). - Correctif :
f'LLAMA_LD_LIBRARY_PATH="{hint or ""}"'(guillemets doubles internes). - Fichier :
scripts/detect_llama_server.py:201.
Finding 2 â phase llama.cpp non-interactif sautĂ©e (BUG CORRIGĂ)
- SymptĂŽme : en non-interactif,
ask_yn "$LLM_DOWNLOAD_PROMPT"retournaitfalse(non) â le GGUF n'Ă©tait pas tĂ©lĂ©chargĂ© âlaunch_arbitrage.shrestait le script par dĂ©faut du dĂ©pĂŽt â la LLM ne se lançait pas. De plus, aucunllama-servern'Ă©tait prĂ©sent dans le conteneur vierge. - Correctif :
- Téléchargement GGUF automatique en non-interactif :
elif [[ "$NON_INTERACTIVE" = true ]] || ask_yn ... - Téléchargement automatique du binaire précompilé ai-dock (build b9851, CUDA 12.8, sha256
vérifié) si
llama-serverabsent â en non-interactif seulement (en interactif, proposition).
- Téléchargement GGUF automatique en non-interactif :
- Fichiers :
install.sh(SECTION 9-bis : ajout bloc ai-dock + condition non-interactif GGUF).
Finding 3 â profil 64 numactl + CUDA_HOME + libs CUDA en conteneur (BUG CORRIGĂ)
- SymptĂŽme : le profil
64gb_qwen3.6-35b-a3b.shcrashait dans le conteneur :set_mempolicy: Operation not permitted(numactl interdit par seccomp Docker)CUDA_HOME=/usr/local/cuda-13.1inexistant dans le conteneurlibllama-server-impl.so: cannot open shared object file(pas de RPATH dans le binaire ai-dock)libcudart.so.12: cannot open shared object file(pas de CUDA toolkit dans le conteneur)
- Correctif :
numactlconditionnel : testnumactl --interleave=all trueâ repli sur le binaire direct si refusCUDA_HOMEconditionnel : teste/usr/local/cuda-13.1puis/usr/local/cudapuis rienLD_LIBRARY_PATH: ajout du rĂ©pertoire du binaire ai-dock (libs .so Ă cĂŽtĂ©)LD_LIBRARY_PATH: ajout des libs nvidia du venv torch (nvidia/*/lib) â cudart, cublas, etc. (torch cu126 compatible avec binaire ai-dock cu128 : mĂȘme major 12)
- Fichier :
scripts/arbitrage_profiles/64gb_qwen3.6-35b-a3b.sh.
Test 5 â all-in-one Ollama + cohere/pyannote gated (fedora41, 8 GPU, dnf) â â SUCCĂS
- Commande : `verify_install_matrix ⊠--distro fedora41 --topology all-in-one --llm-backend ollama --hf-online --profile word_corrige --keep-up$
- \text{S}Ă©\text{lection} \text{data}-\text{driven} â
: \text{sur} 8 \times 24 \text{Go}, $select_profile
a choisi **qwen3.6:35b** (palier 64, spread activĂ©) et Ă©critservices.ollama_model: qwen3.6:35b,ollama_sched_spread: true,ollama_num_ctx: 262144`. - Calibration VRAM Ollama â
:
llm_vram_mb: 35795(dĂ©rivĂ© de la taille rĂ©elle du 35B â correctif du Test 2 appliquĂ©). - Recalage au 1er load â
:
Recalibrage VRAM LLM (vĂ©rif au 1á”Êł load) : 35795 Mo calculĂ© â 62581 Mo mesurĂ©â le recalage fonctionne et prime sur le calcul. - Cohere + pyannote gated â
: modÚles téléchargés via
HF_TOKEN(cohere + pyannote + faster-whisper). - Cycle LLM 35B â
: 3 sessions opencode
local/qwen3.6:35bexit 0 :- résumé (1 texte, 3 outils, 10 events)
- correction (10 textes, 25 outils, 87 events)
- relecture finale (2 textes, 8 outils, 16 events)
- Livrables â : srt (2307 o) + docx (40 Ko) + package (1,38 Mo), contrat respectĂ©.
- fedora41 (dnf + RPM Fusion) â
: install.sh fonctionne sur fedora:41 avec dnf (ffmpeg via
RPM Fusion, prérequis gérés par
distro_bootstrap).
Test 4 â split vLLM TP auto (frontale CPU + nĆud GPU + vLLM 27B-FP8) â â SUCCĂS (100/100)
- Commande :
docker compose -f docker-compose.split-gpu.yml up -dpuisdocker compose -f docker-compose.split-gpu.yml run --rm verify --web http://web:7870 --node http://resource-node:8002 --arbitrage http://vllm-arbitrage:8080 --audio /app/tests/test2.mp3 --profile word_corrige --password CHANGE-ME - Images :
transcria-worker:latest(frontale CPU) +transcria-resource-node:latest(nĆud GPU) rebuildĂ©es avec le code courant (incluant les correctifs des Tests 2/3). - Architecture : frontale CPU (web + scheduler) â nĆud GPU (diar pyannote + STT Cohere via vLLM :8003) â vLLM arbitrage (Qwen3.6-27B-FP8 TP=4 FP8 Marlin :8080).
- vLLM arbitrage â
: modĂšle
Qwen/Qwen3.6-27B-FP8, aliasarbitrage, TP=4, ctx 262144 â chargĂ© en ~340s (FP8 Marlin sur Ampere sm_86). - Plan de contrĂŽle â
:
/healthweb OK,/healthresource-node OK,/v1/modelsvLLM OK,/capabilities= 8 GPU(s), 1 moteur STT dĂ©clarĂ©. - E2E complet â : login â upload â analyse â rĂ©sumĂ© (summary_done) â context â participants â lexicon â traitement (diarisation distante + transcription + correction LLM + relecture) â completed â livrables.
- Livrables â : srt (2309 o) + docx (40 Ko) + package (1,39 Mo), contrat respectĂ©.
- Score qualitĂ© â : 100/100 â le meilleur score mesurĂ© (cf. validation qualitĂ© ci-dessous).
8. Validation qualité des livrables (lecture humaine)
MĂ©thode : les fichiers SRT corrigĂ©, rĂ©sumĂ©, rapport de correction et rapport qualitĂ© ont Ă©tĂ© lus intĂ©gralement (pas seulement parsĂ©s). Les scripts de validation ne suffisent pas â un score 100/100 peut masquer une hallucination factuelle invisible au parseur.
Test 3 (llama.cpp 35B Q8_K_XL, all-in-one debian12) â 97/100
- SRT corrigé : 29/29 segments (parité parfaite). 2 corrections typographiques (espaces
insécables avant
?). Ponctuation française correcte. Aucune perte, aucune hallucination.hein?âhein ?(rĂšgle française).Ă©mmentalâĂ©mental(cohĂ©rent avecEmentaldans la suite â dĂ©cision de cohĂ©rence, pas une erreur). - RĂ©sumĂ© : fidĂšle aux faits. Titre pertinent. SynthĂšse structurĂ©e (6 paragraphes). Tous les chiffres corrects (comtĂ© d'Ă©tĂ© 8 mois, vieux comtĂ© 24 mois, 200g, 11,60âŹ, 60 centimes). Participants : rĂŽles corrects (Vendeur/fromager, Cliente).
- Relecture finale : harmonisation des genres (le rĂ©sumĂ© LLM avait Ă©crit « vendeuse » au lieu de « Vendeur / fromager » masculin â corrigĂ© par le glossaire). Audit donnĂ©es structurĂ©es : tout OK (listes vides cohĂ©rentes avec un podcast).
- Points d'attention : 4 chevauchements mineurs (< 1s), 1 silence 32â35s, couverture 79%.
Test 4 (vLLM 27B-FP8 TP=4, split) â 100/100
- SRT corrigé : 29/29 segments. Ponctuation française parfaite. Orthographe standard
(
emmentalâ forme française correcte, contrairement auĂ©mentaldu Test 3).hein?âhein.(point, pas?â correct car ce n'est pas une question dans ce contexte, c'est une interjection). PrĂ©fixes locuteurs plus sobres (SPEAKER_01:sans libellĂ©). - RĂ©sumĂ© : fidĂšle aux faits. Titre pertinent. SynthĂšse concise et prĂ©cise. Termes douteux
détectés (
Emmentalavec varianteĂ©mentalâ signal pertinent, pas une erreur). - Score 100/100 : aucun point d'attention. La qualitĂ© supĂ©rieure du vLLM 27B-FP8 (FP8 prĂ©serve mieux la qualitĂ© que Q8 GGUF) et la correction plus fine (ponctuation, orthographe standard) expliquent le score parfait.
Comparaison qualité Tests 3 vs 4
| CritĂšre | Test 3 (llama.cpp 35B Q8) | Test 4 (vLLM 27B-FP8) |
|---|---|---|
| Score qualité | 97/100 | 100/100 |
| Segments | 29/29 | 29/29 |
| Corrections typo | 2 (espaces ?) | ponctuation fine + orthographe standard |
Ă©mmental vs emmental | Ă©mental (cohĂ©rent) | emmental (standard FR) â
|
hein? | hein ? | hein. (plus juste sĂ©mantiquement) â
|
| Préfixes locuteurs | SPEAKER_01(Vendeur / fromager): | SPEAKER_01: (sobre) |
| Topologie | all-in-one local | split CPU + GPU distant |
| Latence vLLM | N/A | 340s chargement initial |
Conclusion qualitĂ© : les deux moteurs (llama.cpp 35B Q8 et vLLM 27B-FP8) produisent des livrables de qualitĂ© production. Le vLLM 27B-FP8 obtient un score lĂ©gĂšrement supĂ©rieur (100 vs 97) grĂące Ă une correction orthographique plus standard et une ponctuation sĂ©mantiquement plus juste. La topologie split (CPU + GPU distant) n'a aucun impact sur la qualitĂ© â le pipeline dĂ©portĂ© fonctionne de bout en bout.
9. Comparatif des moteurs LLM (rapidité)
Mesures de temps réels sur test2.mp3 (73s d'audio, 29 segments) :
| Moteur | ModÚle | GPU | Chargement | Résumé | Correction | Relecture | Total LLM | Score |
|---|---|---|---|---|---|---|---|---|
| Ollama mono | gemma4:12b (7,2 Go) | 1Ă 24Go | ~5s | ~60s | ~90s | ~180s | ~5min | 98/100 |
| Ollama multi | 35b (24 Go) | 8Ă 24Go | ~30s | ~90s | ~120s | ~60s | ~5min | â |
| llama.cpp | 35B Q8 (38,5 Go) | 3Ă 24Go | ~300s | ~120s | ~85s | ~90s | ~10min | 97/100 |
| vLLM TP=4 | 27B-FP8 (27 Go) | 4Ă 24Go | ~340s | ~60s | ~65s | ~90s | ~9min | 100/100 |
Le gemma4:12b mono-GPU est le plus rapide (~5 min total LLM) car le modÚle est petit (7,2 Go) et seul 3,8B de paramÚtres MoE sont actifs. Le vLLM 27B-FP8 est rapide en inférence mais le chargement initial est long (340s). Le llama.cpp 35B Q8 est le plus lent au chargement (38,5 Go).
10. ModÚles Ollama testés pour le palier 24 mono-GPU
| ModÚle | Poids | VRAM mesurée | Tient 24 Go ? | Résumé | Correction | Score | Verdict |
|---|---|---|---|---|---|---|---|
qwen3.5:9b (Q4_K_M) | 6,3 Go | 14 039 Mo | â | â | â SRT tronquĂ© 3/26 | â | insuffisant |
ornith:9b (Q4_K_M) | 5,6 Go | 13 398 Mo | â | â hallucinations | â 0 production | â | inapte |
gemma4:12b (Q4_K_M) | 7,2 Go | 7 942 Mo | â | â | â 26 seg | 98/100 | retenu |
qwen3.6:27b (Q4_K_M, 192K) | 17 Go | â | â 24,2 Go requis | â | â | â | OOM |
gemma4:26b (Q4_K_M, 256K) | 17 Go | â | â 26,9 Go requis | â | â | â | OOM |
devstral-small-2 (Q4_K_M, 192K) | 15 Go | 23 679 Mo | â (juste) | â | â | â | â repli CPU Ollama |
Leçon : une carte 24 Go ne peut pas héberger un modÚle > 12B en mono-GPU avec contexte
192K+. Le KV-cache d'un 17-24B dense à 192-256K ajoute 4-8 Go aux poids, dépassant 24 Go.
gemma4:12b (7,9 Go VRAM) est le sweet spot : assez capable pour la correction agentique
(98/100), assez petit pour laisser 16 Go de marge sur une 24 Go.
Note : llama.cpp vs Ollama â quantizations diffĂ©rentes
Les paliers llama.cpp et Ollama du catalogue ne sont pas directement comparables :
| Aspect | llama.cpp | Ollama |
|---|---|---|
| Source des poids | GGUF HuggingFace (unsloth/âŠ) | Registre Ollama (ollama pull) |
| Quantization | Q5_K_M, Q6_K, IQ4_NL_XL, Q8_K_XL (fins) | Q4_K_M par défaut (plus agressive) |
| KV cache dtype | q8_0 (1 octet) | fp16 (2 octets) |
| Serving | llama-server (binaire compilé/ai-dock) | ollama serve (démon persistant) |
Exemple : Qwen3.5-9B-Q5_K_M (llama.cpp, palier 12, validĂ© au bench) â qwen3.5:9b (Ollama
Q4_K_M, échec correction). La différence Q5 vs Q4 explique pourquoi le bench llama.cpp valide le
modĂšle alors qu'Ollama Ă©choue. Chaque moteur doit ĂȘtre validĂ© E2E indĂ©pendamment.
Test 8 â all-in-one Ollama 2 GPU spread (ubuntu2404, 2 GPU) â â SUCCĂS (98/100)
- Commande :
verify_install_matrix ⊠--distro ubuntu2404 --topology all-in-one --llm-backend ollama --stt-backend whisper --diarization-backend sortformer --profile word_corrige --keep-up --gpu-count 2 - GPU probe â
: conteneur voit 2 GPU (RTX 3090) â
--gpu-count 2via CDI (--device nvidia.com/gpu=0 --device nvidia.com/gpu=1). - SĂ©lection data-driven â
: sur 2Ă 24 Go (48 Go total),
select_profilea choisiqwen3.6:35b(palier 48, PAS 32 â 49152 â„ 46000 â palier 48, le plus gros qui tient).ollama_sched_spread: true,ollama_num_ctx: 262144. - Calibration VRAM â
:
llm_vram_mb: 35795(dĂ©rivĂ© de la taille rĂ©elle 22829 Mo + KV + marge). - Cycle LLM 35b 2-GPU â
: 3 sessions opencode exit 0 :
- résumé (2 textes, 4 outils, 14 events)
- correction (5 textes, 15 outils, 38 events)
- relecture finale (7 textes, 14 outils, 41 events)
- Livrables â : srt (2125 o) + docx (40 Ko) + package (1,39 Mo), contrat respectĂ©.
- Score qualité : 98/100 (lecture humaine confirmée).
Validation qualitĂ© (lecture humaine) â Test 8 â 98/100
- SRT corrigĂ© : 26 segments (3 fusions lĂ©gitimes 29â26). Corrections pertinentes :
Ă©mmentalâemmental(graphie usuelle â ),il vous faut autre choseâIl vous faut autre chose ?(majuscule + interrogation â ),Je prendraisâJe prendrai(futur au lieu du conditionnel â commande ferme â ). DĂ©tail mineur :11.60au lieu de11,60. - RĂ©sumĂ© : fidĂšle, structurĂ©, tous les faits corrects (8 mois, 24 mois, 200g, 11,60âŹ, 60 centimes). Titre pertinent. Une coquille cyrillique ("ŃОпique") dans le rĂ©sumĂ© â hallucination rare du modĂšle 35b Q4, sans impact sur le SRT corrigĂ©.
- Correction : rapport détaillé avec raisons linguistiques pour chaque correction.
Finding â CDI multi-GPU : --device nvidia.com/gpu=0,1 non supportĂ© (BUG CORRIGĂ)
- SymptĂŽme :
docker run --device nvidia.com/gpu=0,1âError: nvidia.com/gpu=0,1 is not an absolute path. Docker 29 n'accepte pas la syntaxe comma-separated pour les devices CDI. - Correctif : un
--devicepar GPU :--device nvidia.com/gpu=0 --device nvidia.com/gpu=1. - Fichier :
scripts/verify_install_matrix.py(docker_run_argv).
Tests 6-7 â ubuntu2204 / rocky9 (install OK, correction non-dĂ©terministe) â đĄ PARTIEL
- Test 6 (ubuntu2204) : install â
(PPA deadsnakes pour python3.11), rĂ©sumĂ© â
, transcription
â
, diarisation â
, mais correction LLM â (0 production 3/3 tentatives â
gemma4:12bmode thinking non-dĂ©terministe). Le Test 2 (ubuntu2404) avait rĂ©ussi avec le mĂȘme modĂšle. - Test 7 (rocky9) : install â
(python3.11 + EPEL + RPM Fusion +
--allowerasing), rĂ©sumĂ© â , mais correction LLM â (mĂȘme problĂšme non-dĂ©terministe). - Findings corrigĂ©s :
distro_bootstrap.py:DEBIAN_FRONTEND=noninteractivenon propagĂ© â ajout dansinstall_template(apt) +--allowerasing(dnf rocky9).distro_bootstrap.py: ubuntu2204 a Python 3.10 par dĂ©faut â ajout PPA deadsnakes pourpython3.11(clĂ© GPG manuelle, sansadd-apt-repositoryqui Ă©choue en conteneur minimal).install.sh: dĂ©tectionPYTHON_BINtrop tardive â dĂ©placĂ©e avant les appels aux modules Python 3.11+ (Rocky 9 apython3= 3.9 systĂšme,python3.11installĂ© mais non utilisĂ©).
- Correction non-déterministe :
gemma4:12b(modĂšle reasoning avec mode thinking) produit parfois 0 output en correction. Le Test 2 (ubuntu2404) avait rĂ©ussi (98/100) mais les Tests 6/7 ont Ă©chouĂ© avec le mĂȘme modĂšle. C'est possiblement un problĂšme de seed/temperature ou d'initialisation du mode thinking. Non corrigĂ© â piste : dĂ©sactiver le token<|think|>dans le prompt ou fixer un seed.