dynamic-accent-duplex / code /eval /build_asr_eval.py
UncleanCode's picture
Dynamic Accent Duplex 0.2.0: Dynamic ASR real as default ASR (omniASR fallback)
ac573f1 verified
Raw History Blame
2.9 kB
"""Build held-out ASR/LID eval set -> /scratch/duplex/asr_eval/{wav/*.wav, list.jsonl}
Mono: WAXAL test (ibo/yor/hau/pcm, 40 each, spread over speakers), FLEURS val eng (30).
CS: 40 synthetic code-switched clips = two held-out clips of different languages concatenated (0.25 s gap), ref = joined text + per-word lang labels.
All splits are test/val/dev splits never used in TTS training; whether the ASR models saw them is unknown (noted in report)."""
import json, os, random, numpy as np, soundfile as sf, librosa
H = os.path.expanduser("~"); OUT = "/scratch/duplex/asr_eval"; os.makedirs(OUT + "/wav", exist_ok=True)
random.seed(7)
def rows(d, pred):
R = [json.loads(l) for l in open(f"{d}/meta.jsonl")]
return [r for r in R if pred(r)]
def audio(d, r):
a = np.memmap(f"{d}/pcm24k.i16", dtype=np.int16, mode="r")
y = a[r["off24"]: r["off24"] + r["n24"]].astype(np.float32) / 32768
return librosa.resample(y, orig_sr=24000, target_sr=16000)
def pick(R, n):
by = {}
for r in R: by.setdefault(r.get("spk"), []).append(r)
for v in by.values(): random.shuffle(v)
out = []
while len(out) < n and any(by.values()):
for k in list(by):
if by[k] and len(out) < n: out.append(by[k].pop())
return out
items = []
W = f"{H}/data3/waxal"
for L in ["ibo", "yor", "hau", "pcm"]:
for r in pick(rows(W, lambda r: r["lang"] == L and r["split"] == "test" and 1.5 < r["dur"] < 14), 40):
items.append(("waxal_test", W, r, L))
F = f"{H}/data3/fleurs"
for r in pick(rows(F, lambda r: r["lang"] == "eng" and r["split"] == "val" and r["dur"] < 16), 30): items.append(("fleurs_val", F, r, "eng"))
recs = []; pool = {}
for src, d, r, L in items:
y = audio(d, r); i = f"{L}_{len(recs):03d}"
sf.write(f"{OUT}/wav/{i}.wav", y, 16000)
rec = dict(id=i, wav=f"{OUT}/wav/{i}.wav", lang=L, text=r["text"], src=f"{src}:{r['id']}", dur=round(len(y) / 16000, 2),
wlang=[L] * len(r["text"].split()))
recs.append(rec); pool.setdefault(L, []).append((rec, y))
pairs = [("eng", "ibo"), ("ibo", "eng"), ("eng", "yor"), ("yor", "eng"), ("eng", "hau"), ("hau", "eng"), ("pcm", "eng"), ("eng", "pcm"), ("pcm", "ibo"), ("pcm", "yor")]
for k in range(40):
a, b = pairs[k % len(pairs)]
(ra, ya), (rb, yb) = random.choice(pool[a]), random.choice(pool[b])
y = np.concatenate([ya, np.zeros(4000, np.float32), yb]); i = f"cs_{k:03d}"
sf.write(f"{OUT}/wav/{i}.wav", y, 16000)
recs.append(dict(id=i, wav=f"{OUT}/wav/{i}.wav", lang="cs", langs=[a, b], text=ra["text"] + " " + rb["text"], src=f"concat:{ra['id']}+{rb['id']}",
dur=round(len(y) / 16000, 2), wlang=ra["wlang"] + rb["wlang"]))
with open(f"{OUT}/list.jsonl", "w") as f:
for r in recs: f.write(json.dumps(r, ensure_ascii=False) + "\n")
from collections import Counter; print(Counter(r["lang"] for r in recs)); print("BUILD_DONE", len(recs))