elephant-1-onnx / diff_bidi.py
electroglyph's picture
Upload folder using huggingface_hub
fb62ba4 verified
Raw History Blame Contribute Delete
3.36 kB
"""Diff ONNX-bidi slot logits / answers vs the torch noncausal reference.
Usage:
python diff_bidi.py --model ./model --cuda # fp16 bidi
python diff_bidi.py --model ./model-cuda-int4 --cuda # int4 bidi
Compares per-branch slot LOGITS (torch-ref.json diag) and final answer
probabilities. Needs torch-ref.json (patched qev engine, debug=True).
"""
import argparse
import json
import sys
from pathlib import Path
import numpy as np
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
from onnx_raw import OnnxLM # noqa: E402
from score_elephant import OnnxScorer, decide, plan, verify_slots # noqa: E402
def main():
p = argparse.ArgumentParser()
p.add_argument("--model", default=str(HERE / "model"))
p.add_argument("--onnx", default="model.onnx")
p.add_argument("--cuda", action="store_true")
p.add_argument("--ref", default=str(HERE / "torch-ref.json"))
a = p.parse_args()
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained(str(HERE / "orig_tokenizer"), local_files_only=True)
slot_ids = verify_slots(tok)
providers = ["CUDAExecutionProvider", "CPUExecutionProvider"] if a.cuda else ["CPUExecutionProvider"]
lm = OnnxLM(str(Path(a.model) / a.onnx), providers=providers)
ref = json.load(open(a.ref))
worst_logit, worst_prob, agree = 0.0, 0.0, True
for name in ["support", "moderation"]:
body = json.load(open(HERE / "examples" / f"{name}.json"))
full, rendered, owners, total, plen = plan(body["state"], body["questions"], tok, 1)
scorer = OnnxScorer(lm, slot_ids, plen)
print(f"--- {name} ---")
for (br_ids, br) in zip(full, rendered):
ologits, _ = scorer.score(br_ids, br.n_slots)
tlogits = ref[name]["diag"][br.qid]["slot_logits"][0]
d = max(abs(x - y) for x, y in zip(ologits, tlogits))
worst_logit = max(worst_logit, d)
print(f" {br.qid}: max|Δlogit|={d:.4f} (k={br.n_slots})")
ans_ox, _ = decide(body["state"], body["questions"], tok,
lambda pl: OnnxScorer(lm, slot_ids, pl), 1.0, 1, 4)
for qid, ta in ref[name]["answers"].items():
oa = ans_ox[qid]
tp = ta["noul"] if ta["type"] == "noul" else None
if ta["type"] == "noul":
d = abs(ta["noul"] - oa["noul"])
worst_prob = max(worst_prob, d)
if (ta["noul"] > 0.5) != (oa["noul"] > 0.5):
agree = False
print(f" {qid}: torch={ta['noul']:.4f} onnx={oa['noul']:.4f} |Δ|={d:.4f}")
else:
tk = {k: v for k, v in ta["probabilities"].items()}
ok = oa["probabilities"]
top_t, top_o = max(tk, key=tk.__getitem__), max(ok, key=ok.__getitem__)
if top_t != top_o:
agree = False
for opt in tk:
d = abs(tk[opt] - ok[opt])
worst_prob = max(worst_prob, d)
print(f" {qid}: top torch={top_t} onnx={top_o}; "
+ " ".join(f"{o}:Δ={abs(tk[o]-ok[o]):.4f}" for o in tk))
print(f"WORST |Δlogit|={worst_logit:.4f} WORST |Δprob|={worst_prob:.4f} "
f"top-1: {'PASS' if agree else 'FAIL'}")
if __name__ == "__main__":
main()