girish00 commited on
Commit
ed2b121
·
verified ·
1 Parent(s): eb09e6b

update endpoint helper files

Browse files
Files changed (1) hide show
  1. evaluate_model.py +154 -0
evaluate_model.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import json
3
+ import subprocess
4
+ import sys
5
+
6
+
7
+ DEFAULT_TEST_PROMPTS = [
8
+ "Fix this Python code: def add(a,b) return a+b",
9
+ "Explain what this code does: for i in range(3): print(i)",
10
+ "Write Python code for linear regression and explain it.",
11
+ "Debug this snippet: if x = 5: print(x)",
12
+ ]
13
+
14
+
15
+ def run_inference(python_exec, model_path, base_model, prompt, max_new_tokens, allow_downloads):
16
+ cmd = [
17
+ python_exec,
18
+ "infer_local.py",
19
+ "--model-path",
20
+ model_path,
21
+ "--base-model",
22
+ base_model,
23
+ "--prompt",
24
+ prompt,
25
+ "--max-new-tokens",
26
+ str(max_new_tokens),
27
+ ]
28
+ if allow_downloads:
29
+ cmd.append("--allow-downloads")
30
+ result = subprocess.run(cmd, check=False, capture_output=True, text=True)
31
+ if result.returncode != 0:
32
+ return None, f"inference failed: {result.stderr.strip()}"
33
+
34
+ stdout = result.stdout.strip()
35
+ try:
36
+ payload = json.loads(stdout)
37
+ return payload, None
38
+ except json.JSONDecodeError as exc:
39
+ # Some libraries may emit informational logs before/after JSON.
40
+ merged = f"{result.stdout}\n{result.stderr}"
41
+ start = merged.find("{")
42
+ end = merged.rfind("}")
43
+ if start != -1 and end != -1 and end > start:
44
+ candidate = merged[start : end + 1]
45
+ try:
46
+ payload = json.loads(candidate)
47
+ return payload, None
48
+ except json.JSONDecodeError:
49
+ pass
50
+ return None, f"invalid json output: {exc}: {stdout[:300]}"
51
+
52
+
53
+ def safe_float(value):
54
+ try:
55
+ return float(value)
56
+ except (TypeError, ValueError):
57
+ return 0.0
58
+
59
+
60
+ def score_payload(payload):
61
+ required_keys = {
62
+ "code",
63
+ "explanation",
64
+ "confidence",
65
+ "important_tokens",
66
+ "relevancy_score",
67
+ "hallucination",
68
+ "hallucination_check_reason",
69
+ "latency_ms",
70
+ }
71
+ has_all_keys = required_keys.issubset(payload.keys())
72
+ code_ok = bool(str(payload.get("code", "")).strip())
73
+ explanation_ok = bool(str(payload.get("explanation", "")).strip())
74
+ confidence = safe_float(payload.get("confidence", 0.0))
75
+ relevancy = safe_float(payload.get("relevancy_score", 0.0))
76
+ hallucination = bool(payload.get("hallucination", False))
77
+
78
+ return {
79
+ "schema_ok": has_all_keys,
80
+ "content_ok": code_ok and explanation_ok,
81
+ "confidence": confidence,
82
+ "relevancy": relevancy,
83
+ "hallucination": hallucination,
84
+ }
85
+
86
+
87
+ def main():
88
+ parser = argparse.ArgumentParser()
89
+ parser.add_argument("--model-path", type=str, default="model")
90
+ parser.add_argument("--base-model", type=str, default="Qwen/Qwen2.5-Coder-0.5B-Instruct")
91
+ parser.add_argument("--max-new-tokens", type=int, default=320)
92
+ parser.add_argument("--strict-min-confidence", type=float, default=0.6)
93
+ parser.add_argument("--strict-min-relevancy", type=float, default=0.25)
94
+ parser.add_argument("--prompt", action="append", default=[])
95
+ parser.add_argument(
96
+ "--allow-downloads",
97
+ action="store_true",
98
+ help="Allow infer_local.py to download missing model files from Hugging Face.",
99
+ )
100
+ args = parser.parse_args()
101
+
102
+ prompts = args.prompt if args.prompt else DEFAULT_TEST_PROMPTS
103
+ results = []
104
+ passed = 0
105
+
106
+ for prompt in prompts:
107
+ payload, error = run_inference(
108
+ python_exec=sys.executable,
109
+ model_path=args.model_path,
110
+ base_model=args.base_model,
111
+ prompt=prompt,
112
+ max_new_tokens=args.max_new_tokens,
113
+ allow_downloads=args.allow_downloads,
114
+ )
115
+ if error:
116
+ results.append({"prompt": prompt, "error": error, "pass": False})
117
+ continue
118
+
119
+ metrics = score_payload(payload)
120
+ is_pass = (
121
+ metrics["schema_ok"]
122
+ and metrics["content_ok"]
123
+ and metrics["confidence"] >= args.strict_min_confidence
124
+ and metrics["relevancy"] >= args.strict_min_relevancy
125
+ and not metrics["hallucination"]
126
+ )
127
+ if is_pass:
128
+ passed += 1
129
+
130
+ results.append(
131
+ {
132
+ "prompt": prompt,
133
+ "pass": is_pass,
134
+ "metrics": metrics,
135
+ }
136
+ )
137
+
138
+ accuracy = passed / len(prompts) if prompts else 0.0
139
+ summary = {
140
+ "total_tests": len(prompts),
141
+ "passed_tests": passed,
142
+ "accuracy": round(accuracy, 4),
143
+ "thresholds": {
144
+ "min_confidence": args.strict_min_confidence,
145
+ "min_relevancy": args.strict_min_relevancy,
146
+ "hallucination_must_be_false": True,
147
+ },
148
+ "results": results,
149
+ }
150
+ print(json.dumps(summary, indent=2, ensure_ascii=False))
151
+
152
+
153
+ if __name__ == "__main__":
154
+ main()