omnijev-work / code /build_text4.py
fnruha0921's picture
code for H200 job
8c867d9 verified
Raw History Blame Contribute Delete
9.96 kB
"""Large public typed-decision corpora -> MM-Jev train records. Each builder returns a list of records; pipeline.py caches
every part to disk, so a crash / disconnect only redoes the part in flight.
Benchmark sources are removed by name (tasksource): AG News, emotion (DAIR), Banking77, MASSIVE, XNLI.
"""
import ast, json, random, re
from datasets import load_dataset
from mmjev import Seg, options_of
BANNED = re.compile(r"(^|/)(ag_news|emotion|banking77|massive|xnli)(/|$)|multilingual/massive|multilingual/xnli", re.I)
MAX_OPTS, MAX_STATE = 100, 3500
def _rec(task, state, qs, targets):
ys = [int(max(range(len(t)), key=lambda i: t[i])) for t in targets]
return dict(task=task, modality="text", split="train", state=[Seg("text", str(state)[:MAX_STATE])], qs=qs, ys=ys,
targets=targets, raw=None)
def _norm(t):
t = [max(0.0, float(x)) for x in t]
s = sum(t)
return [x / s for x in t] if s > 0 else None
def _parse(x):
if isinstance(x, (list, dict)):
return x
try:
return json.loads(x)
except Exception:
return ast.literal_eval(x)
def row_question(kind, question, options, target):
"""Row-schema (Open-Jev / SargeDev / tasksource): options list + target distribution -> (question, target)."""
options = [str(o) for o in options]
if kind == "noul" and len(target) == 1:
target = [1 - float(target[0]), float(target[0])]
options = ["false", "true"]
target = _norm(target)
if target is None or len(options) != len(target) or not (2 <= len(options) <= MAX_OPTS):
return None
if kind == "noul":
p = target[-1] if len(target) == 2 else target[0]
return {"type": "noul", "instructions": question}, [1 - p, p]
if kind == "score":
return {"type": "score", "instructions": question, "criteria": [o[:160] for o in options]}, target
crit = {}
for i, o in enumerate(options):
if ": " in o and len(o.split(": ", 1)[0]) <= 40:
k, v = o.split(": ", 1)
elif len(o) > 60:
k, v = f"option {i + 1}", o
else:
k, v = o, ""
crit[k.strip()] = v[:300]
if len(crit) != len(options):
return None
return {"type": "choice", "instructions": question, "criteria": crit}, target
def grouped_rows(rows, task, n_groups, rng, state_key="state_json"):
groups = {}
for r in rows:
groups.setdefault(r["group_id"], []).append(r)
keys = list(groups); rng.shuffle(keys)
out = []
for g in keys[:n_groups]:
qs, ts, st = [], [], None
for r in groups[g][:6]:
st = st if st is not None else _parse(r[state_key]) if r[state_key] else ""
got = row_question(r["kind"], r["question"], _parse(r["options"]), _parse(r["target"]))
if got:
qs.append(got[0]); ts.append(got[1])
if qs:
st = st if isinstance(st, str) else json.dumps(st, ensure_ascii=False)
out.append(_rec(task, st, qs, ts))
return out
def openjev_v11(n_ctrl=5000, n_wanli=1500, seed=11):
rng = random.Random(seed)
ds = load_dataset("ZefanCai/Open-Jev-v1.1", "community-hard-mix-v2-redistributable", split="train")
rows = ds.to_list()
wanli = [r for r in rows if "wanli" in (r["source"] or "").lower()]
ctrl = [r for r in rows if "wanli" not in (r["source"] or "").lower()]
return grouped_rows(ctrl, "openjev_v11", n_ctrl, rng) + grouped_rows(wanli, "openjev_v11_wanli", n_wanli, rng)
def openjev_v2(n=3000, seed=12):
ds = load_dataset("ZefanCai/Open-Jev", "release-v2-redistributable", split="train")
return grouped_rows(ds.to_list(), "openjev_v2", n, random.Random(seed))
def bev(cfgs=(("default", 4000), ("hard_50k", 3000), ("numeric_temporal", 1500), ("skills", 2000)), seed=13):
out = []
for cfg, n in cfgs:
ds = load_dataset("avbiswas/bev-decision", cfg, split="train").shuffle(seed=seed).select(range(n))
for ex in ds:
qs_raw = _parse(ex["questions_json"])
qs, ts = [], []
for qid, q in list(qs_raw.items())[:6]:
t, crit, lab = q["type"], q.get("criteria"), q.get("label")
if t == "noul":
p = float(lab) if isinstance(lab, (int, float)) and not isinstance(lab, bool) else float(bool(lab))
qs.append({"type": "noul", "instructions": q["instructions"]}); ts.append([1 - p, p])
elif t == "score":
crit = list(crit)
lv = int(lab) if lab is not None else 0
if not (0 <= lv < len(crit)):
continue
qs.append({"type": "score", "instructions": q["instructions"], "criteria": [str(c) for c in crit]})
ts.append([1.0 if i == lv else 0.0 for i in range(len(crit))])
else:
crit = crit if isinstance(crit, dict) else {str(c): "" for c in crit}
keys = list(crit)
if str(lab) not in keys or not (2 <= len(keys) <= MAX_OPTS):
continue
qs.append({"type": "choice", "instructions": q["instructions"], "criteria": {k: str(v or "") for k, v in crit.items()}})
ts.append([1.0 if k == str(lab) else 0.0 for k in keys])
if qs:
out.append(_rec(f"bev:{cfg}", ex["state"], qs, ts))
return out
def tasksource(n=7000, shards=(0, 4, 8), many_frac=0.45, seed=14):
"""Non-streaming shards (the streaming shuffle walks whole shards); benchmark sources dropped by name;
rows with >= 10 options over-sampled so the K distribution covers intent-style label spaces."""
rng = random.Random(seed)
files = [f"hf://datasets/tasksource/tasksource-jev-typed-decisions/data/train-{i:05d}-of-00012.parquet" for i in shards]
ds = load_dataset("parquet", data_files=files, split="train")
ds = ds.filter(lambda b: [not BANNED.search(s or "") for s in b["source"]], batched=True)
many, few = [], []
for ex in ds.shuffle(seed=seed).select(range(min(len(ds), 60000))):
try:
opts = _parse(ex["options"]) if ex["options"] else ["false", "true"]
tgt = _parse(ex["target"])
except Exception:
continue
got = row_question(ex["kind"], ex["question"], opts, tgt if isinstance(tgt, list) else [1 - tgt, tgt])
if not got:
continue
r = _rec(f"tasksource:{(ex['source'] or '?').split('/')[0]}", ex["state"] or "", [got[0]], [got[1]])
(many if len(got[1]) >= 10 else few).append(r)
k_many = min(len(many), int(n * many_frac))
return rng.sample(many, k_many) + rng.sample(few, min(len(few), n - k_many))
def jev_decisions(n=2000, seed=15):
"""Agent tool / action choice: candidates -> options, target candidate -> gold."""
rng = random.Random(seed)
ds = load_dataset("samatv256/jev-decisions-v1", split="validation", streaming=True)
out, seen = [], 0
for ex in ds:
seen += 1
if seen > 60000 or len(out) >= n:
break
if ex["status"] != "trainable" or rng.random() > 0.25:
continue
try:
cands = _parse(ex["candidates"]); tgt = _parse(ex["target"])
except Exception:
continue
if not (2 <= len(cands) <= 40) or not isinstance(tgt, dict) or not tgt.get("candidate_id"):
continue
keys = [c.get("name") or c.get("id") for c in cands]
ids = [c.get("id") for c in cands]
if tgt["candidate_id"] not in ids or len(set(keys)) != len(keys):
continue
crit = {k: str(c.get("description") or "")[:200] for k, c in zip(keys, cands)}
st = ex["state"] if isinstance(ex["state"], str) else json.dumps(ex["state"], ensure_ascii=False)
st = st[-MAX_STATE:] # keep the most recent part of long agent traces
g = ids.index(tgt["candidate_id"])
out.append(_rec(f"jev_decisions:{ex['decision_type']}", st,
[{"type": "choice", "instructions": "Which action or tool should the agent use next?", "criteria": crit}],
[[1.0 if i == g else 0.0 for i in range(len(keys))]]))
return out
def sargedev(n_v3=15000, n_v1=4000, seed=16):
ds = load_dataset("json", data_files="hf://datasets/SargeDev/jev-distill-corpus-v3/train.jsonl", split="train")
rng = random.Random(seed)
by = {"yuri_v3": [], "yuri_v1": []}
for i, s in enumerate(ds["source"]):
if s in by:
by[s].append(i)
idx = rng.sample(by["yuri_v3"], min(n_v3, len(by["yuri_v3"]))) + rng.sample(by["yuri_v1"], min(n_v1, len(by["yuri_v1"])))
out = []
for ex in ds.select(idx):
got = row_question(ex["kind"], ex["question"], ex["options"], ex["target"])
if got:
out.append(_rec(f"sargedev:{ex['source']}", ex["state"], [got[0]], [got[1]]))
return out
def clinc_full(n=1200, seed=17):
"""CLINC150 with the FULL 150-intent label space (K matched to many-label intent routing)."""
ds = load_dataset("clinc/clinc_oos", "plus", split="train").shuffle(seed=seed)
names = ds.features["intent"].names
labels = [x for x in names if x != "oos"]
ds = ds.filter(lambda e: names[e["intent"]] != "oos").select(range(n))
crit = {x.replace("_", " "): "" for x in labels}
keys = list(crit)
return [_rec("clinc150_full", ex["text"], [{"type": "choice", "instructions": "Which single label best describes the input text?",
"criteria": crit}],
[[1.0 if k == names[ex["intent"]].replace("_", " ") else 0.0 for k in keys]]) for ex in ds]
BUILDERS = {"openjev_v11": openjev_v11, "openjev_v2": openjev_v2, "bev": bev, "tasksource": tasksource,
"jev_decisions": jev_decisions, "sargedev": sargedev, "clinc_full": clinc_full}