A chaque moteur son modele, et un forcage manuel

app.py passait CONFIG["model"] — un depot MLX — quel que soit le moteur detecte.
Sur une machine sans Apple Silicon, faster-whisper aurait recu un depot qu'il ne
sait pas charger. Le defaut etait invisible ici, la detection rendant toujours
"mlx" sur ce Mac : aucun test ne pouvait le voir.

MODELES_PAR_MOTEUR associe chaque moteur a son depot. Les valeurs viennent de la
mesure du jour (trois echantillons, amorce active, CPU Apple Silicon) :

  faster-whisper base   0,52 s  10/13 termes techniques   142 Mo
  faster-whisper small  1,42 s  11/13                     464 Mo
  faster-whisper medium 4,40 s  13/13                    1460 Mo
  MLX medium (GPU)      0,75 s  11/13                     489 Mo

Le GPU vise donc la precision (medium, 13/13, il absorbe le cout) ; le CPU vise
la latence (small, 11/13 — AUTANT que le MLX utilise aujourd'hui — pour 1,4 s).
`medium` sur CPU serait plus juste, mais ces 4,4 s sont celles d'un CPU Apple
Silicon : sur un CPU Intel ou Windows, le meme modele peut demander trois a quatre
fois plus. La commande de diagnostic mesurera la machine reelle et pourra
promouvoir `medium`.

CONFIG["model"] passe a None et devient un FORCAGE manuel qui prime sur la table,
au lieu d'un reglage mort qu'on modifie sans effet.

115 tests. Comportement inchange sur ce Mac : moteur mlx, modele identique.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-23 18:45:14 +02:00
co-authored by Claude Opus 5
parent 6974a3406c
commit 2ccb614649
3 changed files with 96 additions and 4 deletions
+40 -1
View File
@@ -6,7 +6,9 @@ Tout ce qui est ici est testable sans micro, sans clavier, sans modèle.
import re
CONFIG = {
"model": "mlx-community/whisper-medium",
# Forcage manuel du modele. None = on suit MODELES_PAR_MOTEUR, qui choisit
# d'apres le moteur detecte. Renseigner cette cle prime sur la table.
"model": None,
"language": "fr",
"hotkey": "<cmd>+<ctrl>+d", # Cmd+Ctrl+D (libre : ni macOS ni VS Code ne l'utilisent)
"sounds": True,
@@ -163,6 +165,43 @@ def duree_vie_overlay_coherente(config):
return config["duree_max_overlay_s"] >= config["max_duration_s"] + MARGE_TRANSCRIPTION_S
# --- modele par moteur ----------------------------------------------------
# Chaque moteur a son propre format de depot : MLX lit `mlx-community/*`,
# faster-whisper lit `Systran/faster-whisper-*`. Passer l'un a l'autre echoue.
#
# Mesure du 2026-08-23, trois echantillons, amorce de vocabulaire active,
# sur le CPU d'un Apple Silicon :
# faster-whisper base 0,52 s 10/13 termes techniques 142 Mo
# faster-whisper small 1,42 s 11/13 464 Mo
# faster-whisper medium 4,40 s 13/13 1460 Mo
# MLX medium (GPU) 0,75 s 11/13 489 Mo
#
# D'ou les choix : le GPU vise la precision (medium, 13/13, le GPU absorbe le
# cout) ; le CPU vise la latence (small, 11/13 — soit AUTANT que le MLX utilise
# aujourd'hui — pour 1,4 s ici). `medium` sur CPU serait plus juste, mais 4,4 s
# ont ete mesures sur un CPU Apple Silicon, rapide : sur un CPU Intel ou Windows,
# le meme modele peut demander trois a quatre fois plus. La commande de
# diagnostic (etape 4) mesurera la machine reelle et pourra promouvoir `medium`.
MODELES_PAR_MOTEUR = {
"mlx": "mlx-community/whisper-medium",
"faster-gpu": "Systran/faster-whisper-medium",
"faster-cpu": "Systran/faster-whisper-small",
}
def modele_retenu(nom_moteur, forcage=None):
"""Modele finalement utilise : le forcage manuel s'il est renseigne, sinon la
table. Une chaine vide est traitee comme une absence de forcage."""
return forcage or modele_pour_moteur(nom_moteur)
def modele_pour_moteur(nom):
"""Rend le depot de modele adapte a ce moteur. Leve KeyError si inconnu."""
if nom not in MODELES_PAR_MOTEUR:
raise KeyError(f"Aucun modele connu pour le moteur : {nom}")
return MODELES_PAR_MOTEUR[nom]
def validate_config(config):
"""Valide la config ; lève ValueError si une valeur est aberrante."""
if config["min_duration_s"] < 0: