#!/usr/bin/env python3 """Verification du playbook gagnant AfriVoices, point 2 : DECODAGE EN UNE PASSE. Sur AfriVoices, l'equipe 1re place a gagne en decodant les clips >38 s d'un seul tenant au lieu de les chunker : les encodages de position RELATIFS du Conformer extrapolent bien au-dela de la fenetre d'entrainement, et chunker coupe des mots et reinitialise le contexte du LM. Pricile chunquait a 60 s et avait laisse du score sur la table. Ici on verifie : (a) la distribution des durees du test, (b) qu'aucun clip n'est tronque ni chunke par notre chaine, (c) que les clips LONGS ne produisent pas une sortie degeneree (effondrement du debit en fin de clip). """ import csv, json, os import numpy as np import soundfile as sf AUD = "/scratch/p2_16k" SUB = "/root/sub_CALIBU2.csv" lang = json.load(open("/root/test_lang.json")) sub = {r["ID"]: r["Target"] for r in csv.DictReader(open(SUB, encoding="utf-8"))} rows = [] for k, t in sub.items(): p = os.path.join(AUD, k + ".wav") if not os.path.exists(p): continue i = sf.info(p) rows.append((k, lang.get(k), i.frames / float(i.samplerate), t)) print("=== DUREES DU TEST (892 clips) ===") for lg in ("lin", "sna"): d = np.array([r[2] for r in rows if r[1] == lg]) print(" %s : n=%d | p50 %.1f s | p90 %.1f s | p99 %.1f s | MAX %.1f s | >38 s : %d | >60 s : %d" % (lg, len(d), np.percentile(d, 50), np.percentile(d, 90), np.percentile(d, 99), d.max(), (d > 38).sum(), (d > 60).sum())) print("\n=== DEBIT MOTS/SECONDE PAR TRANCHE DE DUREE ===") print(" (si les clips longs s'effondrent, leur debit chute nettement)") for lg in ("lin", "sna"): sel = [r for r in rows if r[1] == lg] print(" --- %s ---" % lg) for lo, hi in ((0, 15), (15, 25), (25, 38), (38, 60), (60, 999)): g = [r for r in sel if lo <= r[2] < hi] if not g: continue wps = np.array([len(r[3].split()) / r[2] for r in g]) print(" %3d-%3ds : n=%3d | mots/s median %.2f | min %.2f | clips a moins de 0.5 mot/s : %d" % (lo, hi, len(g), np.median(wps), wps.min(), (wps < 0.5).sum())) print("\n=== CLIPS LES PLUS LONGS : sortie plausible ? ===") for k, lg, d, t in sorted(rows, key=lambda r: -r[2])[:6]: print(" %s [%s] %.1f s | %d mots (%.2f mots/s)" % (k, lg, d, len(t.split()), len(t.split()) / d)) print(" %s" % (t[:150] + ("..." if len(t) > 150 else ""))) print("\n=== LA CHAINE DE DECODAGE CHUNKE-T-ELLE ? ===") import re src = open("/root/multi_avg.py", encoding="utf-8").read() chunk = re.search(r"truncation|max_length|chunk|window|\[:\s*\d{5,}\]", src) print(" motif de troncature/chunking dans multi_avg.py :", chunk.group(0) if chunk else "AUCUN") print(" batches(files, 90) regroupe des CLIPS ENTIERS par budget de duree,") print(" il ne decoupe aucun clip : chaque clip est vu d'un seul tenant.") print("WHOLECLIP_CHECK_DONE")