"""Adapt the lv-hemingway arms for voice_distance.py, and refuse if its reference is empty. voice_distance.py expects: - files matching voice..jsonl in the eval dir - a `continuation` field per record (gen_beats_chat writes `raw`) - a `seed` field (present) - the control arm's NAME to contain the substring "unadapted" -- it picks the control by that substring, so `base` alone would leave the control unidentified and the whole vs-control table would silently be empty. - a reference built from corpus records whose split == "val" """ import json, sys from collections import Counter from pathlib import Path CORP = Path("/home/infra-ops/lv-hemingway/corpus-renamed/copies") EVAL = Path("/home/infra-ops/r49-runs/hemingway-eval") c = Counter() n = 0 for p in sorted(CORP.glob("*.jsonl")): for line in p.read_text(encoding="utf-8").splitlines(): if not line.strip(): continue r = json.loads(line) n += 1 c[r.get("split")] += 1 print(f"corpus records: {n} split values: {dict(c)}") if c.get("val", 0) == 0: print("== REFUSING: no split=val records; voice_distance would build an EMPTY reference") print(" and every delta_cb would be meaningless rather than absent.") sys.exit(1) NAMES = {"base": "base-unadapted", "ckpt1750": "ckpt1750", "ckpt850": "ckpt850"} for src_arm, out_arm in NAMES.items(): src = EVAL / f"beats5.{src_arm}.jsonl" if not src.exists(): print(f"== missing {src}") sys.exit(1) rows = [json.loads(l) for l in src.read_text(encoding="utf-8").splitlines() if l.strip()] out = EVAL / f"voice.{out_arm}.jsonl" with out.open("w", encoding="utf-8") as fh: for r in rows: fh.write(json.dumps({"id": r["id"], "seed": r["seed"], "continuation": r["raw"]}, ensure_ascii=False) + "\n") print(f" {src.name} -> {out.name} ({len(rows)} records)") print("ready")