| import argparse, json, collections |
| import soundfile as sf, torch, jiwer |
| from transformers import AutoModelForCTC, AutoProcessor |
| SR=16000 |
| def norm(s): return " ".join(str(s).replace("|"," ").split()) |
| ap=argparse.ArgumentParser() |
| ap.add_argument("--model",required=True) |
| ap.add_argument("--manifest",default="/root/devhard/devhard_all.jsonl") |
| a=ap.parse_args() |
| proc=AutoProcessor.from_pretrained(a.model) |
| model=AutoModelForCTC.from_pretrained(a.model,torch_dtype=torch.bfloat16).cuda().eval() |
| rows=[json.loads(l) for l in open(a.manifest,encoding="utf-8")] |
| by=collections.defaultdict(lambda:{"r":[],"h":[]}) |
| with torch.inference_mode(): |
| for i,r in enumerate(rows): |
| au=sf.read(r["audio"],dtype="float32")[0] |
| x=proc(au,sampling_rate=SR,return_tensors="pt") |
| x={k:(v.to("cuda",dtype=torch.bfloat16) if v.dtype==torch.float32 else v.to("cuda")) for k,v in x.items()} |
| ids=model(**x).logits.argmax(-1).cpu().numpy() |
| hyp=norm(proc.batch_decode(ids)[0]); ref=norm(r["text"]) |
| L=r.get("lang","?"); by[L]["r"].append(ref); by[L]["h"].append(hyp) |
| if (i+1)%300==0: print(f"{i+1}/{len(rows)}",flush=True) |
| scores=[] |
| for L in sorted(by): |
| R=[x for x in by[L]["r"] if x.strip()]; H=[by[L]["h"][j] for j,x in enumerate(by[L]["r"]) if x.strip()] |
| wer=jiwer.wer(R,H); cer=jiwer.cer(R,H); comb=0.5*wer+0.5*cer; sc=1-comb |
| scores.append(sc) |
| print(f"{L}: n={len(R)} WER={wer:.4f} CER={cer:.4f} combine={comb:.4f} score={sc:.4f}") |
| print(f"MACRO score={sum(scores)/len(scores):.4f}") |
|
|