morseformer - anomalies et dettes techniques

Point de développement après la mise à jour du MODEL_CARD.md, la correction du sampling prose, l'alignement Python 3.10-3.13, la correction du preset Gradio prose et l'ajout du garde-fou runtime Python.

Date : 2026-05-18 Mise à jour : 2026-05-19 (commits bd1045c + 92a6596) Branche : main Dernier commit inspecté : 92a6596 Checks : ruff OK, pytest 24 passed (validation + release_gate)
0 risque haut niveau ouvert (les 2 P0 sont résolus)
4 dettes techniques principales encore actionnables
0 test rouge à l'heure actuelle
6 quick wins traités depuis le premier rapport

État Actuel

Sain

Qualité immédiate du code

La suite locale passe dans le venv Python 3.12 : ruff check . et pytest -q sont verts.

Dernier résultat : 359 passed, 7 skipped.

À surveiller

Surface projet très expérimentale

Le dépôt contient à la fois produit public, historique de recherche, modèles candidats, modèles démotés, scripts de bench et GUI. C'est utile, mais la frontière public / laboratoire reste floue.

Amélioré

Documentation modèle

MODEL_CARD.md décrit maintenant v0.6.3, le checkpoint recommandé rnnt_phase5_5.pt, et le bench LCWO + websdr.

Corrigé

Sampling prose

sample_prose() respecte désormais max_chars après snapping aux frontières de mots, ce qui protège la fenêtre audio de 6 secondes.

Corrigé

Packaging et démo

requires-python est borné à >=3.10,<3.14, la CI couvre Python 3.13, la démo Gradio charge le LM pour le preset prose, et le premier décodage prose prévient du téléchargement LM.

Corrigé

Guidage utilisateur

Un import avec Python hors plage supportée déclenche maintenant un message constructif avec les commandes uv et python3.12 -m venv. Le dossier reports/ a aussi son README.

Anomalies Prioritaires

Priorité Anomalie / dette Impact Action recommandée
Résolu Validation d'entraînement trop faible
ValidationConfig.matching() ne semble pas propager toute l'enveloppe synthétique pertinente.
Le signal de validation peut saturer artificiellement. Les décisions de checkpoint reposent alors sur last.pt et des benches post-hoc au lieu d'un critère d'entraînement robuste. Faire hériter explicitement les paramètres de canal, jitter, dash/dot ratio, gap inflation, word-gap inflation, QRM/QSB/QRN, drift et empty samples. Ajouter des tests qui prouvent cette propagation.
Fait 2026-05-19 — commit bd1045c. 18 champs propagés (6 operator + 8 channel + 4 empty/post-silence). 8 tests ajoutés dont un différentiel acid (jittered cfg produit ≥ N-1/N samples différents de clean cfg).
Résolu Release gate encore trop manuel
Les benches existent, mais il manque une commande unique de décision release.
Risque de publier un checkpoint jugé meilleur qualitativement mais inférieur sur le corpus de référence, comme l'histoire phase5_8 l'a montré. Créer une commande morseformer eval release-gate ou python -m eval.release_gate qui sort JSON + tableau : LCWO, websdr, callsigns, silence, word gaps, contest, prose FR/EN.
Fait 2026-05-19 — commit 92a6596. python -m eval.release_gate avec manifest versionné eval/release_gate_v1.json (10 catégories : 7 LCWO + silence_fp + word_gap_inflation_6x + latency_rtf). Calibration sur rnnt_phase5_5 + 0.5 pp margin. JSON dans reports/release_gate_<acoustic>_<date>.json, exit 0/1. 4 tests smoke end-to-end.
P2 Registry public mêlé aux expériences
rnnt_phase5_9 et rnnt_phase5_10 sont utiles pour l'historique, mais alourdissent la surface mentale.
Le projet est plus difficile à comprendre pour un nouvel utilisateur ou contributeur. Les modèles ratés / candidats ressemblent à des options utilisables. Séparer registry public et registry expérimental : public = recommandé + legacy utiles ; expérimental = candidates, failed retrains, notes de reproduction.
P2 Fusion LM fragmentée
La fusion LM est documentée comme offline-only ; le streaming live la désactive ou la traite comme expérimentale.
Comportement différent entre decode, live, scripts historiques et démo. Risque de confusion produit et de mesures non comparables. Formaliser trois modes : acoustic greedy stable, offline prose fusion stable, streaming fusion experimental hidden. Ajouter tests CLI / docs sur cette sémantique.

Dettes Par Domaine

Évaluation — Résolu

Le benchmark réel est désormais l'arbitre obligatoire

Le release gate eval/release_gate.py rend la discipline mécanique. Tout candidate acoustic doit passer un manifest versionné (eval/release_gate_v1.json, 10 catégories) avant de pouvoir ship. Cf NEXT.md §4 anti-recommandations : « ne pas ship un acoustic candidate sans release_gate PASS ».

  • Créer un manifeste de release gate versionné. Fait
  • Fixer les seuils de non-régression par catégorie. Fait (+0.5 pp absolu)
  • Exporter les résultats en JSON pour comparer deux commits / checkpoints. Fait
  • Prochaine étape : étendre le manifest avec de vraies données opérateur multi-bandes (cf domaine Données ci-dessous).
Données

Le corpus réel est le facteur limitant

Le modèle a déjà bénéficié d'un petit mix réel. Le gain marginal vient probablement plus de données réelles diverses que d'une architecture plus grande.

  • Collecter plusieurs opérateurs, vitesses, récepteurs, bandes et conditions.
  • Stocker les transcriptions avec score d'alignement / qualité.
  • Séparer données d'entraînement, validation de décision, et tests live qualitatifs.
Packaging

Environnement local clarifié

Le README prescrit désormais Python 3.12 pour le développement local, le package borne Python à >=3.10,<3.14, la CI couvre 3.10-3.13, et le package affiche un message constructif si l'utilisateur lance une version hors support.

  • Surveiller les futures versions PyTorch / torchaudio avant d'ouvrir Python 3.14.
  • Garder la matrice CI alignée avec requires-python.
  • Documenter l'installation CPU PyTorch recommandée.
  • Garder le message runtime aligné avec requires-python.
Documentation

README recentré

Le README est recentré sur l'usage, le bench courant, l'architecture actuelle, le setup dev et les pointeurs historiques. CHANGELOG.md reste la source historique unique, et reports/README.md explique le rôle des snapshots de dette.

  • Éviter de réintroduire des sections longues de phase history dans le README.
  • Maintenir MODEL_CARD.md et CHANGELOG.md comme sources détaillées.
Produit

Gradio aligné sur le preset prose

La démo Gradio charge maintenant le LM quand le preset sélectionné le demande. Un test smoke verrouille ce chemin sans lancer de serveur ni charger de checkpoint réel, et le menu indique que le premier décodage prose télécharge aussi le LM.

  • Continuer à vérifier que file decode, live decode et Gradio partagent les mêmes defaults là où c'est applicable.
  • Garder explicite le fait que le live reste acoustic-only.
Tests

Les tests sont bons mais certains skips doivent rester intentionnels

Le test É / À a été marqué obsolète parce que les accents ne sont plus une priorité release. C'est acceptable à condition que les skips soient périodiquement revus.

  • Nommer les skips obsolètes avec une raison claire.
  • Ajouter un test de non-régression sur sample_prose(max_chars=22) dans les chemins corpus et fallback.
  • Surveiller le nombre de skips dans la CI.

Plan Court Terme Recommandé

Ordre Travail Résultat attendu
1 Corriger / étendre ValidationConfig.matching(). Fait 2026-05-19 Validation entraînement fidèle aux curricula Phase 5.x — commit bd1045c.
2 Créer un release gate automatisé. Fait 2026-05-19 Décision de checkpoint reproductible — commit 92a6596, python -m eval.release_gate.
3 Nettoyer la frontière registry public / expérimental. Surface utilisateur plus lisible sans perdre la reproductibilité des phases ratées.
4 Élargir les tests de cohérence des presets entre CLI, GUI et Gradio. Moins de divergence entre les surfaces utilisateur.
5 Ajouter un smoke eval minimal audio + silence. Détection rapide des régressions grossières du pipeline decode.

Conclusion

Mise à jour 2026-05-19. Le projet est techniquement sain et la dette de gouvernance expérimentale qui motivait ce rapport est partiellement levée : les deux P0 sont fermés, le signal de validation reflète enfin la distribution d'entraînement, et la décision de ship est mécanique via release_gate. Les P2 (registry public/expérimental, formalisation des trois modes de fusion LM) restent ouverts mais ne bloquent plus un éventuel nouveau cycle de training. Lire NEXT.md §3 pour les options en aval (plateau / data collection / scale-up / switch d'architecture).