Spaces:
Running
Running
Download app.py from hmb/decision-models-comparison: direct link, hf CLI and curl.
- Browser
- Download file 3.44 kB
-
https://huggingface.co/spaces/hmb/decision-models-comparison/resolve/main/app.py
- Command line
-
hf download hf://spaces/hmb/decision-models-comparison/app.py
-
curl -L -o app.py https://huggingface.co/spaces/hmb/decision-models-comparison/resolve/main/app.py
3.44 kB
| """Decision Models Comparison: a minimal gr.Workflow. | |
| Prompt + "question + options" -> one format step -> 4 decision-model Space nodes in parallel | |
| (vllm-sr/d3, Cloudflare/clef, autotrust/JEV-27B-VL, Mapika/decider-2b) -> one compare step | |
| -> one comparison output (table + probability bars). Graph: workflow.json (see build_graph.py).""" | |
| import json | |
| import re | |
| import gradio as gr | |
| MODELS = [("d3", "vllm-sr/d3"), ("clef", "Cloudflare/clef"), | |
| ("jev", "autotrust/JEV-27B-VL"), ("decider", "Mapika/decider-2b")] | |
| def _key(o: str) -> str: | |
| return re.sub(r"[^a-z0-9_]+", "_", o.lower()).strip("_") or "opt" | |
| def format_question(question_block: str): | |
| """First line = question, following lines (or commas) = options. | |
| Returns the question in each model family's input format.""" | |
| lines = [x.strip() for x in (question_block or "").splitlines() if x.strip()] | |
| question = lines[0] if lines else "Which option fits best?" | |
| opts = [_key(o) for line in lines[1:] for o in line.split(",") if o.strip()] or ["yes", "no"] | |
| questions_json = json.dumps({"decision": {"type": "choice", "instructions": question, | |
| "criteria": {o: o for o in opts}}}) | |
| decider = f"choice decision: {question}\n" + "\n".join(f"- {o}" for o in opts) | |
| return questions_json, question, "\n".join(opts), decider | |
| def _probs(raw) -> dict: | |
| if isinstance(raw, str): | |
| try: | |
| raw = json.loads(raw) | |
| except Exception: | |
| return {} | |
| if not isinstance(raw, dict): | |
| return {} | |
| if "answers" in raw: | |
| raw = raw["answers"].get("decision", {}) | |
| return {_key(k): float(v) for k, v in (raw.get("probabilities") or {}).items()} | |
| def _bar(p: float, width: int = 20) -> str: | |
| n = round(p * width) | |
| return "█" * n + "░" * (width - n) | |
| def compare_decisions(d3: dict, clef: dict, jev: str, decider: str) -> str: | |
| """Merge the four models' outputs into one markdown view: table + probability bars.""" | |
| res = {name: _probs(r) for (_, name), r in zip(MODELS, (d3, clef, jev, decider))} | |
| opts = sorted({o for p in res.values() for o in p}) | |
| table = ["| Model | Decision | Confidence | Margin vs 2nd | " + " | ".join(opts) + " |", | |
| "|---" * (4 + len(opts)) + "|"] | |
| bars, votes = [], {} | |
| for name, p in res.items(): | |
| if not p: | |
| table.append(f"| {name} | ⚠️ no result |" + " |" * (2 + len(opts))) | |
| continue | |
| ranked = sorted(p.items(), key=lambda kv: -kv[1]) | |
| top, conf = ranked[0] | |
| margin = conf - (ranked[1][1] if len(ranked) > 1 else 0) | |
| votes[top] = votes.get(top, 0) + 1 | |
| cells = " | ".join(f"**{p.get(o, 0):.1%}**" if o == top else f"{p.get(o, 0):.1%}" for o in opts) | |
| table.append(f"| {name} | **{top}** | {conf:.1%} | {margin:.1%} | {cells} |") | |
| bars.append(f"{name:<22} " + " ".join(f"{o}:{_bar(p.get(o, 0), 10)}" for o in opts)) | |
| verdict = ", ".join(f"{k}: {v}/{len(res)}" for k, v in sorted(votes.items(), key=lambda kv: -kv[1])) | |
| agree = "✅ all models agree" if len(votes) == 1 else "⚠️ models disagree" | |
| return ("### Decision comparison\n\n" + "\n".join(table) + f"\n\n**Votes:** {verdict} ({agree})" | |
| + "\n\n#### Probabilities\n```\n" + "\n".join(bars) + "\n```") | |
| demo = gr.Workflow(graph="workflow.json", bind=[format_question, compare_decisions]) | |
| if __name__ == "__main__": | |
| demo.launch() | |