File size: 2,303 Bytes
6eed659
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/env python3
"""Finale 2 = modèle MULTILINGUE joint_cont2 sur TOUS les clips Phase 2, SANS routage.
Robuste à la confusion lug/sna du LID (dégrade gracieusement)."""
import csv, glob, os
import soundfile as sf, torch
from transformers import AutoModelForCTC, AutoProcessor

SR = 16000
MODEL = "/root/models/joint_cont2_best"
AUD = "/root/phase2_audio/audio"
OUT = "/root/sub_finale2_multi.csv"
TESTCSV = "/root/Test_phase2.csv"


def norm(s):
    return " ".join(str(s).replace("|", " ").split())


def main():
    test_ids = [r["ID"] for r in csv.DictReader(open(TESTCSV, encoding="utf-8"))]
    files = sorted(glob.glob(os.path.join(AUD, "*.wav")))
    durs = {f: sf.info(f).duration for f in files}
    files.sort(key=lambda f: -durs[f])
    proc = AutoProcessor.from_pretrained(MODEL)
    m = AutoModelForCTC.from_pretrained(MODEL, torch_dtype=torch.bfloat16).cuda().eval()
    # batching par budget de durée
    bs, cur, bud = [], [], 0.0
    for f in files:
        if cur and bud + durs[f] > 140:
            bs.append(cur); cur, bud = [], 0.0
        cur.append(f); bud += durs[f]
    if cur:
        bs.append(cur)
    out = {}
    with torch.inference_mode():
        for j, b in enumerate(bs):
            au = [sf.read(f, dtype="float32")[0] for f in b]
            x = proc(au, sampling_rate=SR, return_tensors="pt", padding=True)
            x = {k: v.to("cuda", dtype=torch.bfloat16 if v.dtype == torch.float32 else v.dtype) for k, v in x.items()}
            ids = m(**x).logits.float().argmax(-1).cpu().numpy()
            for f, s in zip(b, proc.batch_decode(ids)):
                out[os.path.splitext(os.path.basename(f))[0]] = norm(s)
            if (j + 1) % 20 == 0:
                print(f"{j+1}/{len(bs)} batches", flush=True)
    empt = sum(1 for t in test_ids if not out.get(t, "").strip())
    with open(OUT, "w", newline="", encoding="utf-8") as fo:
        w = csv.writer(fo); w.writerow(["ID", "Target"])
        for t in test_ids:
            w.writerow([t, out.get(t) or "a"])
    print(f"MULTI_DONE {OUT} | {len(test_ids)} IDs | couvre={set(test_ids)==set(out)|(set(test_ids)>=set(out))} | vides={empt}", flush=True)
    # apercu
    for t in test_ids[:4]:
        print(f"  {t}: {out.get(t,'')[:80]}", flush=True)


if __name__ == "__main__":
    main()