openjev / code /order_test.py
AlexWortega's picture
code: order_test.py
8e01204 verified
Raw
History Blame Contribute Delete
2.31 kB
#!/usr/bin/env python
"""Option-order invariance and run-to-run determinism of the jev decision wrapper, on the public JevBench items.
OPENJEV_DEVICE=cuda python order_test.py --model ckpt/qwen3.5-0.8b-nli-v2s --tasks easy.jsonl original.jsonl hard.jsonl
For every item: the same question with options in the given order, reversed, and shuffled, plus the given order a
second time. Reports label flips and the largest change in any option's probability.
"""
import argparse
import json
import random
from openjev_decide import OpenJev, RUBRIC_MARK
from think_probe import options
def ask(jev, task, order):
opts = options(task)
q = {"type": "choice", "options": order,
"instructions": task["question"]["instructions"] + RUBRIC_MARK + json.dumps({k: opts[k] for k in order})}
state = task["state"] if isinstance(task["state"], str) else json.dumps(task["state"], ensure_ascii=False)
return jev.decide(state, [q])[0]["probabilities"]
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--model", required=True)
ap.add_argument("--tasks", nargs="+", required=True)
ap.add_argument("--out", default=None)
args = ap.parse_args()
jev = OpenJev.from_pretrained(args.model)
rng = random.Random(0)
stats = {k: {"flips": 0, "max_dp": 0.0, "sum_dp": 0.0} for k in ("rerun", "reversed", "shuffled")}
n = 0
for path in args.tasks:
for line in open(path):
t = json.loads(line)
base = list(options(t))
if len(base) < 2:
continue
ref = ask(jev, t, base)
shuf = base[:]
rng.shuffle(shuf)
for name, order in (("rerun", base), ("reversed", base[::-1]), ("shuffled", shuf)):
p = ask(jev, t, order)
dp = max(abs(p[k] - ref[k]) for k in base)
s = stats[name]
s["flips"] += max(p, key=p.get) != max(ref, key=ref.get)
s["max_dp"] = max(s["max_dp"], dp); s["sum_dp"] += dp
n += 1
for s in stats.values():
s["mean_dp"] = s.pop("sum_dp") / n
res = {"model": args.model, "n_items": n, **stats}
print(json.dumps(res, indent=1))
if args.out:
json.dump(res, open(args.out, "w"), indent=1)
if __name__ == "__main__":
main()