Nanthasit commited on
Commit
c5b2405
Β·
verified Β·
1 Parent(s): 80484d8

Upload eval/workbench-7b-endpoint-test.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. eval/workbench-7b-endpoint-test.py +218 -0
eval/workbench-7b-endpoint-test.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Workbench test: 7B merged model via Inference Endpoint."""
3
+ import json, time, os, sys
4
+ import requests
5
+
6
+ MODEL = "Nanthasit/sakthai-context-7b-merged"
7
+ ENDPOINT_URL = None # Set dynamically after deployment
8
+
9
+ # Read endpoint URL from args or env
10
+ if len(sys.argv) > 1:
11
+ ENDPOINT_URL = sys.argv[1]
12
+ elif "ENDPOINT_URL" in os.environ:
13
+ ENDPOINT_URL = os.environ["ENDPOINT_URL"]
14
+ else:
15
+ print("Usage: python3 sakthai-7b-workbench-test.py <endpoint_url>")
16
+ print("Or set ENDPOINT_URL env var")
17
+ sys.exit(1)
18
+
19
+ TOKEN_PATH = "/opt/data/profiles/sakthai/home/.cache/huggingface/token"
20
+ with open(TOKEN_PATH) as f:
21
+ HF_TOKEN = f.read().strip()
22
+
23
+ HEADERS = {
24
+ "Authorization": f"Bearer {HF_TOKEN}",
25
+ "Content-Type": "application/json"
26
+ }
27
+
28
+ tests = [
29
+ {
30
+ "name": "basic_greeting",
31
+ "desc": "Say hello in one sentence",
32
+ "messages": [
33
+ {"role": "system", "content": "You are SakThai, a helpful assistant. Be concise."},
34
+ {"role": "user", "content": "Say hello in one sentence."}
35
+ ],
36
+ "checks": ["non_empty", "substantial"]
37
+ },
38
+ {
39
+ "name": "tool_call_intent",
40
+ "desc": "Tool-use intent",
41
+ "messages": [
42
+ {"role": "system", "content": "You are SakThai with tools: search(query), read_file(path), run_command(command)."},
43
+ {"role": "user", "content": "Search for the latest AI news"}
44
+ ],
45
+ "checks": ["non_empty", "substantial"]
46
+ },
47
+ {
48
+ "name": "name_recall",
49
+ "desc": "Remember name across 3 turns",
50
+ "messages": [
51
+ {"role": "system", "content": "You are SakThai."},
52
+ {"role": "user", "content": "My name is Beer."},
53
+ {"role": "assistant", "content": "Nice to meet you, Beer!"},
54
+ {"role": "user", "content": "What's my name?"}
55
+ ],
56
+ "checks": ["non_empty", "name_recall"]
57
+ },
58
+ {
59
+ "name": "factual_qa",
60
+ "desc": "Simple factual question",
61
+ "messages": [
62
+ {"role": "system", "content": "You are SakThai. Be concise."},
63
+ {"role": "user", "content": "What is the capital of Japan?"}
64
+ ],
65
+ "checks": ["non_empty", "correct"]
66
+ },
67
+ {
68
+ "name": "json_output",
69
+ "desc": "Structured JSON",
70
+ "messages": [
71
+ {"role": "system", "content": "You are SakThai. Only respond with valid JSON."},
72
+ {"role": "user", "content": 'List 3 ML frameworks: {"frameworks": ["a","b","c"]}'}
73
+ ],
74
+ "checks": ["non_empty", "valid_json"]
75
+ },
76
+ {
77
+ "name": "instruction_following",
78
+ "desc": "Follow formatting instruction",
79
+ "messages": [
80
+ {"role": "system", "content": "You are SakThai. Exactly one sentence."},
81
+ {"role": "user", "content": "Explain what a transformer is."}
82
+ ],
83
+ "checks": ["non_empty", "substantial"]
84
+ },
85
+ {
86
+ "name": "multi_step_reasoning",
87
+ "desc": "Multi-step reasoning",
88
+ "messages": [
89
+ {"role": "system", "content": "You are SakThai, a helpful assistant."},
90
+ {"role": "user", "content": "If you have 3 apples and give away 1, then buy 5 more, how many do you have? Show your work."}
91
+ ],
92
+ "checks": ["non_empty", "substantial"]
93
+ },
94
+ {
95
+ "name": "context_window",
96
+ "desc": "Longer context understanding",
97
+ "messages": [
98
+ {"role": "system", "content": "You are SakThai. Be concise."},
99
+ {"role": "user", "content": "The transformer architecture introduced in 'Attention Is All You Need' revolutionized NLP by replacing recurrent layers with multi-head self-attention. It uses positional encodings, layer normalization, and feed-forward networks in an encoder-decoder structure. BERT, GPT, and T5 all build on this foundation. What year was the original transformer paper published?"}
100
+ ],
101
+ "checks": ["non_empty", "correct_answer"]
102
+ }
103
+ ]
104
+
105
+ print(f"πŸ§ͺ WORKBENCH TEST β€” SakThai Context 7B")
106
+ print(f" Endpoint: {ENDPOINT_URL}")
107
+ print(f" Model: {MODEL}")
108
+ print(f" Time: {time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}")
109
+ print()
110
+
111
+ results = []
112
+ for i, test in enumerate(tests):
113
+ print(f"{'─'*60}")
114
+ print(f"TEST {i+1}: {test['name']} β€” {test['desc']}")
115
+ print(f" Turns: {len(test['messages'])}", flush=True)
116
+
117
+ try:
118
+ t0 = time.time()
119
+ resp = requests.post(
120
+ f"{ENDPOINT_URL}/v1/chat/completions",
121
+ headers=HEADERS,
122
+ json={
123
+ "model": "tgi",
124
+ "messages": test["messages"],
125
+ "max_tokens": 256,
126
+ "temperature": 0.1,
127
+ },
128
+ timeout=120
129
+ )
130
+ elapsed = time.time() - t0
131
+
132
+ if resp.status_code != 200:
133
+ raise Exception(f"HTTP {resp.status_code}: {resp.text[:200]}")
134
+
135
+ data = resp.json()
136
+ choice = data["choices"][0]
137
+ content = choice["message"]["content"].strip()
138
+ finish = choice.get("finish_reason", "")
139
+ usage = data.get("usage", {})
140
+
141
+ # Run quality checks
142
+ checks = []
143
+ if len(content) > 0:
144
+ checks.append("non_empty")
145
+ if len(content) > 10:
146
+ checks.append("substantial")
147
+
148
+ if "beer" in content.lower() and test["name"] == "name_recall":
149
+ checks.append("name_recall")
150
+ if "tokyo" in content.lower() and test["name"] == "factual_qa":
151
+ checks.append("correct")
152
+ if "2017" in content and test["name"] == "context_window":
153
+ checks.append("correct_answer")
154
+ if test["name"] == "json_output":
155
+ try:
156
+ json.loads(content)
157
+ checks.append("valid_json")
158
+ except:
159
+ pass
160
+
161
+ result = {
162
+ "name": test["name"],
163
+ "passed": len(checks) > 0,
164
+ "response_preview": content[:200],
165
+ "response_length": len(content),
166
+ "latency_seconds": round(elapsed, 2),
167
+ "prompt_tokens": usage.get("prompt_tokens"),
168
+ "completion_tokens": usage.get("completion_tokens"),
169
+ "finish_reason": finish,
170
+ "checks": checks
171
+ }
172
+
173
+ print(f" {'βœ…' if result['passed'] else '❌'} Response: {content[:150]}")
174
+ print(f" ⏱ {elapsed:.2f}s | βœ… {checks} | πŸ”š {finish}")
175
+ if result.get("prompt_tokens"):
176
+ print(f" πŸ“ {result['prompt_tokens']}β†’{result['completion_tokens']}")
177
+
178
+ except Exception as e:
179
+ result = {
180
+ "name": test["name"],
181
+ "passed": False,
182
+ "error": str(e)[:300]
183
+ }
184
+ print(f" ❌ FAIL: {e}")
185
+
186
+ results.append(result)
187
+ sys.stdout.flush()
188
+
189
+ # Summary
190
+ print(f"\n{'='*60}")
191
+ passed = sum(1 for r in results if r.get("passed"))
192
+ total = len(results)
193
+ print(f"πŸ“Š WORKBENCH SUMMARY β€” 7B ({MODEL})")
194
+ print(f"\nResults: {passed}/{total} passed")
195
+ print()
196
+
197
+ for r in results:
198
+ status = "βœ…" if r.get("passed") else "❌"
199
+ name = r["name"].ljust(22)
200
+ lat = f"{r.get('latency_seconds', 0):.1f}s" if r.get("passed") else " - "
201
+ detail = str(r.get("checks", r.get("error", "?")[:60]))
202
+ print(f" {status} {name} ⏱ {lat} {detail}")
203
+
204
+ # Save record
205
+ record = {
206
+ "test_run": f"workbench-{time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}",
207
+ "model": MODEL,
208
+ "endpoint_url": ENDPOINT_URL,
209
+ "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
210
+ "results": results,
211
+ "summary": f"{passed}/{total} passed"
212
+ }
213
+
214
+ output_path = "/opt/data/sakthai-7b-workbench-test-record.json"
215
+ with open(output_path, "w") as f:
216
+ json.dump(record, f, indent=2)
217
+ print(f"\nπŸ’Ύ Saved: {output_path}")
218
+ print("🏁 Done.")