realArceus commited on
Commit
b6c8fe4
·
verified ·
1 Parent(s): 2de953c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -55
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
  import time
3
  import torch
 
4
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoModelForCausalLM, pipeline
5
 
6
  # ── Device ────────────────────────────────────────────────────────────────────
@@ -48,9 +49,23 @@ Final Answer: <answer>
48
  Be deliberate. Show your full working. Each step should be one clear thought."""
49
 
50
  # ── Step Probe inference ──────────────────────────────────────────────────────
51
- def probe_step(problem: str, steps_so_far: list) -> tuple:
52
- context = " ".join(steps_so_far[:-1]) if len(steps_so_far) > 1 else ""
 
 
 
 
 
 
 
 
53
  current = steps_so_far[-1] if steps_so_far else ""
 
 
 
 
 
 
54
  input_text = (
55
  f"[PROBLEM] {problem.strip()} "
56
  f"[STEPS SO FAR] {context} "
@@ -70,6 +85,7 @@ def probe_step(problem: str, steps_so_far: list) -> tuple:
70
  return label, conf
71
 
72
  # ── Core pipeline ─────────────────────────────────────────────────────────────
 
73
  def run_twt(problem: str):
74
  if not problem.strip():
75
  yield ("", "<div class='msg warn'>⚠️ Enter a problem to analyze.</div>", "<div class='msg empty'>Waiting...</div>")
@@ -77,7 +93,6 @@ def run_twt(problem: str):
77
 
78
  cot_html = ""
79
 
80
- # Build prompt
81
  messages = [
82
  {"role": "system", "content": SYSTEM_PROMPT},
83
  {"role": "user", "content": problem.strip()}
@@ -95,15 +110,17 @@ def run_twt(problem: str):
95
 
96
  lines = full_response.strip().split("\n")
97
  parsed_steps = [l.strip() for l in lines if l.strip()]
98
- displayed_steps = []
99
- first_fail_seen = False
 
100
 
101
  for i, step in enumerate(parsed_steps):
102
  displayed_steps.append(step)
103
  is_final = step.lower().startswith("final answer")
104
 
105
  if not is_final:
106
- label, conf = probe_step(problem, displayed_steps)
 
107
  else:
108
  label, conf = "FINAL", 1.0
109
 
@@ -124,18 +141,20 @@ def run_twt(problem: str):
124
  </div>"""
125
  cot_html += step_card
126
 
127
- yield (full_response, cot_html, build_trace(problem, displayed_steps, first_fail_seen))
128
  time.sleep(0.1)
129
 
130
- yield (full_response, cot_html, build_trace(problem, displayed_steps, first_fail_seen, done=True))
131
 
132
 
133
- def build_trace(problem, displayed, first_fail, done=False):
134
  faults, rows = 0, ""
 
135
  for i, s in enumerate(displayed):
136
  is_final = s.lower().startswith("final answer")
137
  if not is_final:
138
- lbl, conf = probe_step(problem, displayed[:i+1])
 
139
  if lbl == "FAIL": faults += 1
140
  dot = f"<span class='dot dot-{'ok' if lbl == 'OK' else 'fail'}'></span>"
141
  rows += f"<div class='trace-row'>{dot} Step {i+1} <span class='trace-conf'>&mdash; {int(conf*100)}%</span></div>"
@@ -160,34 +179,32 @@ CSS = """
160
  *, *::before, *::after { box-sizing: border-box; }
161
  body, .gradio-container, .gradio-container * {
162
  font-family: 'Inter', -apple-system, sans-serif !important;
163
- color: #1e293b !important; /* Forces dark slate text universally */
164
  }
165
  .gradio-container {
166
- background-color: #f4f6f8 !important; /* Cool corporate gray backdrop */
167
- max-width: 1280px !important; /* Widened slightly to fit dense data */
168
- padding-top: 1rem !important; /* Reduced top padding */
169
  }
170
 
171
  /* Header */
172
  .twt-header {
173
  text-align: center;
174
- padding: 0 1rem 1rem; /* Compact padding */
175
- margin-bottom: 1.5rem; /* Reduced margin */
176
  border-bottom: 1px solid #cbd5e1;
177
  }
178
  .twt-title {
179
- font-size: 2rem; /* Scaled down for density */
180
  font-weight: 800;
181
  letter-spacing: -0.03em;
182
  font-family: 'JetBrains Mono', monospace !important;
183
  margin-bottom: 0.25rem;
184
  color: #0f172a !important;
185
  }
186
- .twt-title span {
187
- color: #0033a0 !important; /* Morgan Stanley signature blue */
188
- }
189
  .twt-sub {
190
- font-size: 0.85rem; /* Scaled down */
191
  color: #475569 !important;
192
  font-weight: 500;
193
  letter-spacing: 0.02em;
@@ -195,12 +212,12 @@ body, .gradio-container, .gradio-container * {
195
 
196
  /* Labels */
197
  .input-label, .panel-label {
198
- font-size: 0.7rem; /* Compact label */
199
  font-weight: 700;
200
  color: #334155 !important;
201
  text-transform: uppercase;
202
  letter-spacing: 0.08em;
203
- margin-bottom: 0.5rem; /* Reduced margin */
204
  display: block;
205
  }
206
  .panel-label {
@@ -212,11 +229,11 @@ body, .gradio-container, .gradio-container * {
212
  textarea {
213
  background: #ffffff !important;
214
  border: 1px solid #94a3b8 !important;
215
- border-radius: 6px !important; /* Sharper corners */
216
  color: #0f172a !important;
217
- font-size: 0.85rem !important; /* Scaled down text */
218
  line-height: 1.5 !important;
219
- padding: 0.75rem !important; /* Compact padding */
220
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.05) !important;
221
  transition: all 0.2s ease !important;
222
  }
@@ -229,13 +246,13 @@ textarea::placeholder { color: #94a3b8 !important; }
229
 
230
  /* Primary Button */
231
  button.primary {
232
- background: #0033a0 !important; /* Morgan Stanley Deep Navy */
233
  color: #ffffff !important;
234
  font-weight: 600 !important;
235
  border: none !important;
236
- border-radius: 6px !important; /* Sharper corners */
237
- padding: 0.6rem 1.25rem !important; /* Compact padding */
238
- font-size: 0.85rem !important; /* Scaled down */
239
  box-shadow: 0 2px 4px -1px rgba(0, 51, 160, 0.2) !important;
240
  transition: all 0.15s ease-in-out !important;
241
  cursor: pointer !important;
@@ -255,14 +272,14 @@ button.primary:active {
255
  .step-card {
256
  display: flex;
257
  align-items: flex-start;
258
- gap: 0.75rem; /* Reduced gap */
259
- padding: 0.75rem 1rem; /* Compact padding */
260
- margin-bottom: 0.5rem; /* Reduced margin to pack them closer */
261
  background: #ffffff;
262
  border: 1px solid #cbd5e1;
263
- border-radius: 6px; /* Sharper corners */
264
  line-height: 1.5;
265
- animation: fadeUp 0.2s ease-out both; /* Faster animation */
266
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
267
  transition: all 0.15s ease;
268
  }
@@ -274,24 +291,22 @@ button.primary:active {
274
  border-color: #fca5a5;
275
  background: #fff1f2;
276
  }
277
- .step-card.step-fault:hover {
278
- border-color: #f87171;
279
- }
280
  @keyframes fadeUp {
281
  from { opacity: 0; transform: translateY(6px); }
282
  to { opacity: 1; transform: translateY(0); }
283
  }
284
- .step-icon { font-size: 1rem; margin-top: 1px; } /* Slightly smaller icon */
285
  .step-text { flex: 1; color: #1e293b !important; font-size: 0.85rem; }
286
 
287
  /* Status Badges */
288
  .badge {
289
  flex-shrink: 0;
290
- font-size: 0.6rem; /* Scaled down */
291
  font-weight: 700;
292
  font-family: 'JetBrains Mono', monospace !important;
293
  letter-spacing: 0.02em;
294
- padding: 0.15rem 0.4rem; /* Compact padding */
295
  border-radius: 4px;
296
  margin-top: 2px;
297
  text-transform: uppercase;
@@ -304,37 +319,37 @@ button.primary:active {
304
  .trace-row {
305
  display: flex;
306
  align-items: center;
307
- gap: 0.5rem; /* Tighter gap */
308
- font-size: 0.75rem; /* Compact font */
309
  color: #334155 !important;
310
  font-family: 'JetBrains Mono', monospace !important;
311
- padding: 0.35rem 0; /* Reduced padding */
312
  border-bottom: 1px solid #e2e8f0;
313
  }
314
  .trace-conf { color: #64748b !important; }
315
- .dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; } /* Smaller dots */
316
  .dot-ok { background: #10b981; box-shadow: 0 0 0 2px #d1fae5; }
317
  .dot-fail { background: #e11d48; box-shadow: 0 0 0 2px #ffe4e6; }
318
  .dot-final { background: #0033a0; box-shadow: 0 0 0 2px #dbeafe; }
319
 
320
  /* Progress Bar */
321
  .trace-summary {
322
- margin-top: 1rem; /* Compact top margin */
323
  padding-top: 0.75rem;
324
  border-top: 1px solid #cbd5e1;
325
  }
326
  .trace-label {
327
- font-size: 0.65rem; /* Scaled down */
328
  font-weight: 700;
329
  color: #475569 !important;
330
  text-transform: uppercase;
331
  letter-spacing: 0.05em;
332
- margin-bottom: 0.4rem; /* Tighter margin */
333
  }
334
  .trace-bar-bg {
335
  background: #cbd5e1;
336
  border-radius: 999px;
337
- height: 4px; /* Thinner progress bar */
338
  overflow: hidden;
339
  }
340
  .trace-bar {
@@ -358,7 +373,7 @@ button.primary:active {
358
  color: #64748b !important;
359
  font-size: 0.8rem;
360
  font-family: 'JetBrains Mono', monospace !important;
361
- padding: 1.5rem 1rem; /* Compact empty state */
362
  text-align: center;
363
  background: #ffffff;
364
  border: 1px dashed #94a3b8;
@@ -375,10 +390,11 @@ HEADER = """
375
  """
376
 
377
  EXAMPLES = [
378
- "If a bat and a ball cost $1.10 in total, and the bat costs $1 more than the ball, how much does the ball cost?",
379
- "A farmer has 17 sheep. All but 9 die. How many sheep are left?",
380
- "What is 15% of 80? Then add that to 25% of 60.",
381
- "If you have a 3-gallon jug and a 5-gallon jug, how do you measure exactly 4 gallons?",
 
382
  ]
383
 
384
  with gr.Blocks(css=CSS, title="ThinkWhileThinking") as demo:
@@ -401,4 +417,4 @@ with gr.Blocks(css=CSS, title="ThinkWhileThinking") as demo:
401
  run_btn.click(fn=run_twt, inputs=[problem_input], outputs=[raw_output, cot_output, trace_output])
402
  problem_input.submit(fn=run_twt, inputs=[problem_input], outputs=[raw_output, cot_output, trace_output])
403
 
404
- demo.launch()
 
1
  import gradio as gr
2
  import time
3
  import torch
4
+ import spaces
5
  from transformers import AutoTokenizer, AutoModelForSequenceClassification, AutoModelForCausalLM, pipeline
6
 
7
  # ── Device ────────────────────────────────────────────────────────────────────
 
49
  Be deliberate. Show your full working. Each step should be one clear thought."""
50
 
51
  # ── Step Probe inference ──────────────────────────────────────────────────────
52
+ def is_notation_step(step: str) -> bool:
53
+ """Detect pure LaTeX/notation steps restatements, not new reasoning."""
54
+ s = step.strip()
55
+ return (
56
+ s.startswith("\\[") or s.startswith("$$") or
57
+ s.startswith("\\(") or
58
+ (s.startswith("\\") and len(s.split()) < 8)
59
+ )
60
+
61
+ def probe_step(problem: str, steps_so_far: list, prev_result: tuple = None) -> tuple:
62
  current = steps_so_far[-1] if steps_so_far else ""
63
+
64
+ # Notation-only steps inherit previous score — they restate, not reason
65
+ if is_notation_step(current):
66
+ return prev_result if prev_result is not None else ("OK", 0.9)
67
+
68
+ context = " ".join(steps_so_far[:-1]) if len(steps_so_far) > 1 else ""
69
  input_text = (
70
  f"[PROBLEM] {problem.strip()} "
71
  f"[STEPS SO FAR] {context} "
 
85
  return label, conf
86
 
87
  # ── Core pipeline ─────────────────────────────────────────────────────────────
88
+ @spaces.GPU
89
  def run_twt(problem: str):
90
  if not problem.strip():
91
  yield ("", "<div class='msg warn'>⚠️ Enter a problem to analyze.</div>", "<div class='msg empty'>Waiting...</div>")
 
93
 
94
  cot_html = ""
95
 
 
96
  messages = [
97
  {"role": "system", "content": SYSTEM_PROMPT},
98
  {"role": "user", "content": problem.strip()}
 
110
 
111
  lines = full_response.strip().split("\n")
112
  parsed_steps = [l.strip() for l in lines if l.strip()]
113
+ displayed_steps = []
114
+ first_fail_seen = False
115
+ prev_probe_result = None
116
 
117
  for i, step in enumerate(parsed_steps):
118
  displayed_steps.append(step)
119
  is_final = step.lower().startswith("final answer")
120
 
121
  if not is_final:
122
+ label, conf = probe_step(problem, displayed_steps, prev_probe_result)
123
+ prev_probe_result = (label, conf)
124
  else:
125
  label, conf = "FINAL", 1.0
126
 
 
141
  </div>"""
142
  cot_html += step_card
143
 
144
+ yield (full_response, cot_html, build_trace(problem, displayed_steps, first_fail_seen, prev_probe_result))
145
  time.sleep(0.1)
146
 
147
+ yield (full_response, cot_html, build_trace(problem, displayed_steps, first_fail_seen, prev_probe_result, done=True))
148
 
149
 
150
+ def build_trace(problem, displayed, first_fail, prev_result=None, done=False):
151
  faults, rows = 0, ""
152
+ last_result = None
153
  for i, s in enumerate(displayed):
154
  is_final = s.lower().startswith("final answer")
155
  if not is_final:
156
+ lbl, conf = probe_step(problem, displayed[:i+1], last_result)
157
+ last_result = (lbl, conf)
158
  if lbl == "FAIL": faults += 1
159
  dot = f"<span class='dot dot-{'ok' if lbl == 'OK' else 'fail'}'></span>"
160
  rows += f"<div class='trace-row'>{dot} Step {i+1} <span class='trace-conf'>&mdash; {int(conf*100)}%</span></div>"
 
179
  *, *::before, *::after { box-sizing: border-box; }
180
  body, .gradio-container, .gradio-container * {
181
  font-family: 'Inter', -apple-system, sans-serif !important;
182
+ color: #1e293b !important;
183
  }
184
  .gradio-container {
185
+ background-color: #f4f6f8 !important;
186
+ max-width: 1280px !important;
187
+ padding-top: 1rem !important;
188
  }
189
 
190
  /* Header */
191
  .twt-header {
192
  text-align: center;
193
+ padding: 0 1rem 1rem;
194
+ margin-bottom: 1.5rem;
195
  border-bottom: 1px solid #cbd5e1;
196
  }
197
  .twt-title {
198
+ font-size: 2rem;
199
  font-weight: 800;
200
  letter-spacing: -0.03em;
201
  font-family: 'JetBrains Mono', monospace !important;
202
  margin-bottom: 0.25rem;
203
  color: #0f172a !important;
204
  }
205
+ .twt-title span { color: #0033a0 !important; }
 
 
206
  .twt-sub {
207
+ font-size: 0.85rem;
208
  color: #475569 !important;
209
  font-weight: 500;
210
  letter-spacing: 0.02em;
 
212
 
213
  /* Labels */
214
  .input-label, .panel-label {
215
+ font-size: 0.7rem;
216
  font-weight: 700;
217
  color: #334155 !important;
218
  text-transform: uppercase;
219
  letter-spacing: 0.08em;
220
+ margin-bottom: 0.5rem;
221
  display: block;
222
  }
223
  .panel-label {
 
229
  textarea {
230
  background: #ffffff !important;
231
  border: 1px solid #94a3b8 !important;
232
+ border-radius: 6px !important;
233
  color: #0f172a !important;
234
+ font-size: 0.85rem !important;
235
  line-height: 1.5 !important;
236
+ padding: 0.75rem !important;
237
  box-shadow: inset 0 1px 2px rgba(15, 23, 42, 0.05) !important;
238
  transition: all 0.2s ease !important;
239
  }
 
246
 
247
  /* Primary Button */
248
  button.primary {
249
+ background: #0033a0 !important;
250
  color: #ffffff !important;
251
  font-weight: 600 !important;
252
  border: none !important;
253
+ border-radius: 6px !important;
254
+ padding: 0.6rem 1.25rem !important;
255
+ font-size: 0.85rem !important;
256
  box-shadow: 0 2px 4px -1px rgba(0, 51, 160, 0.2) !important;
257
  transition: all 0.15s ease-in-out !important;
258
  cursor: pointer !important;
 
272
  .step-card {
273
  display: flex;
274
  align-items: flex-start;
275
+ gap: 0.75rem;
276
+ padding: 0.75rem 1rem;
277
+ margin-bottom: 0.5rem;
278
  background: #ffffff;
279
  border: 1px solid #cbd5e1;
280
+ border-radius: 6px;
281
  line-height: 1.5;
282
+ animation: fadeUp 0.2s ease-out both;
283
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
284
  transition: all 0.15s ease;
285
  }
 
291
  border-color: #fca5a5;
292
  background: #fff1f2;
293
  }
294
+ .step-card.step-fault:hover { border-color: #f87171; }
 
 
295
  @keyframes fadeUp {
296
  from { opacity: 0; transform: translateY(6px); }
297
  to { opacity: 1; transform: translateY(0); }
298
  }
299
+ .step-icon { font-size: 1rem; margin-top: 1px; }
300
  .step-text { flex: 1; color: #1e293b !important; font-size: 0.85rem; }
301
 
302
  /* Status Badges */
303
  .badge {
304
  flex-shrink: 0;
305
+ font-size: 0.6rem;
306
  font-weight: 700;
307
  font-family: 'JetBrains Mono', monospace !important;
308
  letter-spacing: 0.02em;
309
+ padding: 0.15rem 0.4rem;
310
  border-radius: 4px;
311
  margin-top: 2px;
312
  text-transform: uppercase;
 
319
  .trace-row {
320
  display: flex;
321
  align-items: center;
322
+ gap: 0.5rem;
323
+ font-size: 0.75rem;
324
  color: #334155 !important;
325
  font-family: 'JetBrains Mono', monospace !important;
326
+ padding: 0.35rem 0;
327
  border-bottom: 1px solid #e2e8f0;
328
  }
329
  .trace-conf { color: #64748b !important; }
330
+ .dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
331
  .dot-ok { background: #10b981; box-shadow: 0 0 0 2px #d1fae5; }
332
  .dot-fail { background: #e11d48; box-shadow: 0 0 0 2px #ffe4e6; }
333
  .dot-final { background: #0033a0; box-shadow: 0 0 0 2px #dbeafe; }
334
 
335
  /* Progress Bar */
336
  .trace-summary {
337
+ margin-top: 1rem;
338
  padding-top: 0.75rem;
339
  border-top: 1px solid #cbd5e1;
340
  }
341
  .trace-label {
342
+ font-size: 0.65rem;
343
  font-weight: 700;
344
  color: #475569 !important;
345
  text-transform: uppercase;
346
  letter-spacing: 0.05em;
347
+ margin-bottom: 0.4rem;
348
  }
349
  .trace-bar-bg {
350
  background: #cbd5e1;
351
  border-radius: 999px;
352
+ height: 4px;
353
  overflow: hidden;
354
  }
355
  .trace-bar {
 
373
  color: #64748b !important;
374
  font-size: 0.8rem;
375
  font-family: 'JetBrains Mono', monospace !important;
376
+ padding: 1.5rem 1rem;
377
  text-align: center;
378
  background: #ffffff;
379
  border: 1px dashed #94a3b8;
 
390
  """
391
 
392
  EXAMPLES = [
393
+ "Janet has 3 times as many apples as John. John has 8 apples. How many apples does Janet have?",
394
+ "A store had 50 chocolates. They sold 18 in the morning and 14 in the afternoon. How many chocolates are left?",
395
+ "Tom reads 12 pages every day. How many pages will he read in 3 weeks?",
396
+ "A train travels 60 miles per hour. How far will it travel in 2 hours and 30 minutes?",
397
+ "Lucy earns $15 per hour. She worked 6 hours on Monday and 4 hours on Tuesday. How much did she earn in total?",
398
  ]
399
 
400
  with gr.Blocks(css=CSS, title="ThinkWhileThinking") as demo:
 
417
  run_btn.click(fn=run_twt, inputs=[problem_input], outputs=[raw_output, cot_output, trace_output])
418
  problem_input.submit(fn=run_twt, inputs=[problem_input], outputs=[raw_output, cot_output, trace_output])
419
 
420
+ demo.launch()