HK2184 commited on
Commit
b6fccb1
Β·
verified Β·
1 Parent(s): db0caba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -77
app.py CHANGED
@@ -18,9 +18,9 @@ DTYPE = torch.bfloat16 if torch.cuda.is_available() else torch.float32
18
  base = AutoModelForCausalLM.from_pretrained(
19
  BASE_MODEL,
20
  torch_dtype=DTYPE,
21
- device_map="cpu", # load to CPU first, avoids meta tensor issue
22
  trust_remote_code=True,
23
- low_cpu_mem_usage=False, # disable β€” this is what triggers meta tensors
24
  )
25
  model = PeftModel.from_pretrained(
26
  base,
@@ -79,6 +79,48 @@ SUBJECT_EXAMPLES = {
79
 
80
  history_store = []
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  def generate_answer(question, opa, opb, opc, opd, temperature, max_tokens):
83
  if not question.strip():
84
  return "⚠️ Please enter a question.", "", "0.00s", str(query_count["total"])
@@ -112,15 +154,13 @@ def generate_answer(question, opa, opb, opc, opd, temperature, max_tokens):
112
 
113
  query_count["total"] += 1
114
 
115
- # Store in history
116
  letter = result.strip()[0] if result.strip() else "?"
117
  history_store.append({
118
- "q": question[:60] + "..." if len(question) > 60 else question,
119
- "ans": letter,
120
  "time": f"{elapsed:.2f}s"
121
  })
122
 
123
- # Build confidence display
124
  options_map = {"A": opa, "B": opb, "C": opc, "D": opd}
125
  pred_letter = ""
126
  for ch in result.upper():
@@ -143,7 +183,7 @@ def build_confidence(pred_letter, full_text):
143
  for i, k in enumerate(others):
144
  scores[k] = [remaining * 0.6, remaining * 0.25, remaining * 0.15][i] if i < 3 else 0
145
 
146
- bars = ""
147
  colors = {"A": "#00c8f0", "B": "#00f0a0", "C": "#ff6030", "D": "#ffcc00"}
148
  for letter in ["A", "B", "C", "D"]:
149
  w = scores[letter]
@@ -180,8 +220,7 @@ def load_subject_examples(subject):
180
  return gr.update(value=None)
181
  examples = SUBJECT_EXAMPLES.get(subject, [])
182
  if examples:
183
- ex = examples[0]
184
- return gr.update(value=ex[0])
185
  return gr.update(value=None)
186
 
187
 
@@ -214,8 +253,6 @@ body, .gradio-container {
214
  margin: 0 auto !important;
215
  padding: 0 20px 60px !important;
216
  }
217
-
218
- /* ── Header ── */
219
  #header {
220
  padding: 44px 0 28px;
221
  border-bottom: 1px solid var(--border);
@@ -237,7 +274,6 @@ body, .gradio-container {
237
  .b-rocm { color: var(--accent); border-color: #00c8f030; background: #00c8f008; }
238
  .b-lora { color: var(--green); border-color: #00f0a030; background: #00f0a008; }
239
  .b-live { color: #ffcc00; border-color: #ffcc0030; background: #ffcc0008; }
240
-
241
  h1#title {
242
  font-family: 'Syne', sans-serif !important;
243
  font-size: 42px !important; font-weight: 800 !important;
@@ -246,8 +282,6 @@ h1#title {
246
  }
247
  h1#title em { color: var(--accent); font-style: normal; }
248
  .subtitle { font-size: 14px; color: var(--muted); font-weight: 300; line-height: 1.6; max-width: 600px; }
249
-
250
- /* ── Stats ── */
251
  #stats {
252
  display: flex; border: 1px solid var(--border);
253
  border-radius: 12px; overflow: hidden;
@@ -259,8 +293,6 @@ h1#title em { color: var(--accent); font-style: normal; }
259
  .sl { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
260
  .dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--green); margin-right: 4px; animation: blink 2s infinite; }
261
  @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.3} }
262
-
263
- /* ── Inputs ── */
264
  label span, .label-wrap span {
265
  font-family: 'DM Sans', sans-serif !important;
266
  font-size: 11px !important; font-weight: 500 !important;
@@ -279,8 +311,6 @@ textarea:focus, input[type=text]:focus {
279
  border-color: var(--accent) !important;
280
  box-shadow: 0 0 0 3px #00c8f012 !important; outline: none !important;
281
  }
282
-
283
- /* ── Section labels ── */
284
  .section-label {
285
  font-size: 10px; font-weight: 600; letter-spacing: 0.12em;
286
  text-transform: uppercase; color: var(--muted); margin-bottom: 10px;
@@ -290,11 +320,8 @@ textarea:focus, input[type=text]:focus {
290
  content: ''; width: 5px; height: 5px; border-radius: 50%;
291
  background: var(--accent); display: inline-block;
292
  }
293
-
294
- /* ── Tabs ── */
295
  .tab-nav button {
296
- background: transparent !important;
297
- color: var(--muted) !important;
298
  border: none !important; border-bottom: 2px solid transparent !important;
299
  font-family: 'DM Sans', sans-serif !important;
300
  font-size: 13px !important; font-weight: 500 !important;
@@ -305,8 +332,6 @@ textarea:focus, input[type=text]:focus {
305
  color: var(--accent) !important;
306
  border-bottom-color: var(--accent) !important;
307
  }
308
-
309
- /* ── Buttons ── */
310
  button.lg.primary {
311
  background: linear-gradient(135deg, var(--accent2), var(--accent)) !important;
312
  border: none !important; border-radius: 10px !important;
@@ -317,7 +342,6 @@ button.lg.primary {
317
  transition: opacity 0.2s, transform 0.15s !important;
318
  }
319
  button.lg.primary:hover { opacity: 0.85 !important; transform: translateY(-1px) !important; }
320
-
321
  button.lg.secondary {
322
  background: var(--surface2) !important;
323
  border: 1px solid var(--border) !important;
@@ -328,8 +352,20 @@ button.lg.secondary {
328
  transition: border-color 0.2s !important;
329
  }
330
  button.lg.secondary:hover { border-color: var(--accent) !important; color: var(--accent) !important; }
331
-
332
- /* ── Output ── */
 
 
 
 
 
 
 
 
 
 
 
 
333
  .out-box textarea {
334
  background: var(--surface2) !important;
335
  border: 1px solid var(--border) !important;
@@ -337,15 +373,8 @@ button.lg.secondary:hover { border-color: var(--accent) !important; color: var(-
337
  line-height: 1.8 !important; color: var(--text) !important;
338
  min-height: 220px !important;
339
  }
340
-
341
- /* ── Sliders ── */
342
  input[type=range] { accent-color: var(--accent) !important; }
343
-
344
- /* ── Dropdowns ── */
345
  .wrap-inner { background: var(--surface2) !important; border-color: var(--border) !important; }
346
- .svelte-1gfkn6j { background: var(--surface) !important; color: var(--text) !important; }
347
-
348
- /* ── Examples ── */
349
  .examples-holder table {
350
  background: var(--surface) !important;
351
  border: 1px solid var(--border) !important;
@@ -357,14 +386,6 @@ input[type=range] { accent-color: var(--accent) !important; }
357
  font-family: 'DM Sans', sans-serif !important;
358
  }
359
  .examples-holder tr:hover td { background: var(--surface2) !important; cursor: pointer; }
360
-
361
- /* ── Info cards ── */
362
- .info-card {
363
- background: var(--surface); border: 1px solid var(--border);
364
- border-radius: 12px; padding: 16px;
365
- }
366
-
367
- /* ── Footer ── */
368
  #footer {
369
  margin-top: 44px; padding-top: 22px;
370
  border-top: 1px solid var(--border);
@@ -379,7 +400,6 @@ input[type=range] { accent-color: var(--accent) !important; }
379
 
380
  with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
381
 
382
- # ── Header ────────────────────────────────────────────────────────────────
383
  gr.HTML("""
384
  <div id="header">
385
  <div class="badges">
@@ -404,14 +424,11 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
404
  </div>
405
  """)
406
 
407
- # ── Main Tabs ─────────────────────────────────────────────────────────────
408
  with gr.Tabs():
409
 
410
- # ── TAB 1: Ask a Question ─────────────────────────────────────────────
411
  with gr.Tab("Ask a Question"):
412
  with gr.Row():
413
 
414
- # Left column β€” inputs
415
  with gr.Column(scale=5):
416
  gr.HTML('<div class="section-label">Clinical Question</div>')
417
  question = gr.Textbox(
@@ -419,19 +436,27 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
419
  placeholder="e.g. A 45-year-old presents with sudden onset severe headache and neck stiffness...",
420
  lines=4,
421
  )
422
- gr.HTML('<div class="section-label" style="margin-top:14px">Answer Options</div>')
 
 
 
 
 
 
 
 
 
423
  with gr.Row():
424
- opa = gr.Textbox(label="Option A", placeholder="First option")
425
- opb = gr.Textbox(label="Option B", placeholder="Second option")
426
  with gr.Row():
427
- opc = gr.Textbox(label="Option C", placeholder="Third option")
428
- opd = gr.Textbox(label="Option D", placeholder="Fourth option")
429
 
430
  with gr.Row():
431
  btn = gr.Button("βš• Analyze Question", variant="primary")
432
  clr_btn = gr.Button("βœ• Clear", variant="secondary")
433
 
434
- # Settings accordion
435
  with gr.Accordion("βš™ Generation Settings", open=False):
436
  temperature = gr.Slider(
437
  minimum=0.1, maximum=1.5, value=0.7, step=0.05,
@@ -447,16 +472,15 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
447
  Higher = more creative explanations.
448
  </p>""")
449
 
450
- # Right column β€” outputs
451
  with gr.Column(scale=5):
452
  gr.HTML('<div class="section-label">AI Answer & Reasoning</div>')
453
- # AFTER β€” works on Gradio 6
454
  output = gr.Textbox(
455
  label="",
456
  placeholder="Answer and clinical explanation will appear here...",
457
  lines=10,
458
  elem_classes=["out-box"],
459
- )
 
460
 
461
  gr.HTML('<div class="section-label" style="margin-top:16px">Answer Confidence</div>')
462
  confidence = gr.HTML(
@@ -465,24 +489,22 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
465
 
466
  with gr.Row():
467
  inf_time = gr.Textbox(label="Inference Time", value="β€”", interactive=False, scale=1)
468
- query_disp = gr.Textbox(label="Total Queries", value="0", interactive=False, scale=1)
469
 
470
- # ── Examples ──────────────────────────────────────────────────────
471
  gr.HTML('<div class="section-label" style="margin-top:24px">Browse by Subject</div>')
472
  with gr.Row():
473
  subject_dd = gr.Dropdown(
474
  choices=SUBJECTS, value="All Subjects", label="Filter by subject", scale=2
475
  )
476
- gr.HTML('<div style="flex:5"></div>')
477
 
478
  gr.HTML('<div class="section-label" style="margin-top:12px">Sample Questions β€” click any to load</div>')
479
  gr.Examples(
480
  examples=EXAMPLES,
481
  inputs=[question, opa, opb, opc, opd],
482
  label="",
 
483
  )
484
 
485
- # ── TAB 2: History ────────────────────────────────────────────────────
486
  with gr.Tab("Query History"):
487
  gr.HTML('<div class="section-label">Recent Queries</div>')
488
  history_html = gr.HTML(
@@ -490,11 +512,9 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
490
  )
491
  refresh_btn = gr.Button("↻ Refresh History", variant="secondary")
492
 
493
- # ── TAB 3: About ──────────────────────────────────────────────────────
494
  with gr.Tab("About"):
495
  gr.HTML("""
496
  <div style="max-width:800px;margin:0 auto;padding:24px 0;">
497
-
498
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:16px;padding:28px;margin-bottom:20px;">
499
  <h2 style="font-family:'Syne',sans-serif;color:#deeeff;font-size:22px;margin-bottom:16px;">What is MedQA?</h2>
500
  <p style="color:#4a6080;font-size:14px;line-height:1.8;">
@@ -504,33 +524,26 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
504
  the clinical reasoning.
505
  </p>
506
  </div>
507
-
508
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px;">
509
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
510
  <h3 style="color:#00c8f0;font-size:14px;margin-bottom:12px;">MODEL</h3>
511
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
512
- Base: Qwen3-1.7B<br>
513
- Fine-tuning: LoRA (r=4)<br>
514
- Trainable: 2.2M / 1.7B params<br>
515
- Precision: bfloat16
516
  </p>
517
  </div>
518
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
519
  <h3 style="color:#00f0a0;font-size:14px;margin-bottom:12px;">HARDWARE</h3>
520
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
521
- AMD Instinct MI300X<br>
522
- 192GB HBM3 memory<br>
523
- ROCm 7.2 on Ubuntu 24.04<br>
524
- No CUDA required
525
  </p>
526
  </div>
527
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
528
  <h3 style="color:#ff6030;font-size:14px;margin-bottom:12px;">TRAINING</h3>
529
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
530
- Dataset: MedMCQA (500 samples)<br>
531
- Time: ~5 minutes on MI300X<br>
532
- Optimizer: AdamW<br>
533
- Scheduler: Constant + warmup
534
  </p>
535
  </div>
536
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
@@ -543,7 +556,6 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
543
  </p>
544
  </div>
545
  </div>
546
-
547
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
548
  <h3 style="color:#deeeff;font-size:14px;margin-bottom:12px;">BUILT BY</h3>
549
  <p style="color:#4a6080;font-size:13px;">
@@ -551,11 +563,9 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
551
  AMD Hackathon 2025 on lablab.ai
552
  </p>
553
  </div>
554
-
555
  </div>
556
  """)
557
 
558
- # ── Footer ────────────────────────────────────────────────────────────────
559
  gr.HTML("""
560
  <div id="footer">
561
  <div class="fl">
@@ -572,6 +582,12 @@ with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
572
  """)
573
 
574
  # ── Events ────────────────────────────────────────────────────────────────
 
 
 
 
 
 
575
  btn.click(
576
  fn=generate_answer,
577
  inputs=[question, opa, opb, opc, opd, temperature, max_tokens],
 
18
  base = AutoModelForCausalLM.from_pretrained(
19
  BASE_MODEL,
20
  torch_dtype=DTYPE,
21
+ device_map="cpu",
22
  trust_remote_code=True,
23
+ low_cpu_mem_usage=False,
24
  )
25
  model = PeftModel.from_pretrained(
26
  base,
 
79
 
80
  history_store = []
81
 
82
+
83
+ def autogenerate_options(question):
84
+ if not question.strip():
85
+ return "", "", "", ""
86
+
87
+ prompt = (
88
+ f"Generate exactly 4 multiple choice options for this medical question. "
89
+ f"One must be correct, three must be plausible but wrong.\n"
90
+ f"Question: {question}\n\n"
91
+ f"Reply ONLY in this exact format, nothing else:\n"
92
+ f"A) <option>\n"
93
+ f"B) <option>\n"
94
+ f"C) <option>\n"
95
+ f"D) <option>"
96
+ )
97
+
98
+ inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
99
+ with torch.no_grad():
100
+ out = model.generate(
101
+ **inputs,
102
+ max_new_tokens=120,
103
+ do_sample=True,
104
+ temperature=0.8,
105
+ top_p=0.9,
106
+ repetition_penalty=1.2,
107
+ eos_token_id=tokenizer.eos_token_id,
108
+ pad_token_id=tokenizer.eos_token_id,
109
+ )
110
+ new = out[0][inputs["input_ids"].shape[-1]:]
111
+ result = tokenizer.decode(new, skip_special_tokens=True).strip()
112
+
113
+ lines = result.split("\n")
114
+ opts = {"A": "", "B": "", "C": "", "D": ""}
115
+ for line in lines:
116
+ line = line.strip()
117
+ for letter in ["A", "B", "C", "D"]:
118
+ if line.upper().startswith(f"{letter})"):
119
+ opts[letter] = line[2:].strip()
120
+
121
+ return opts["A"], opts["B"], opts["C"], opts["D"]
122
+
123
+
124
  def generate_answer(question, opa, opb, opc, opd, temperature, max_tokens):
125
  if not question.strip():
126
  return "⚠️ Please enter a question.", "", "0.00s", str(query_count["total"])
 
154
 
155
  query_count["total"] += 1
156
 
 
157
  letter = result.strip()[0] if result.strip() else "?"
158
  history_store.append({
159
+ "q": question[:60] + "..." if len(question) > 60 else question,
160
+ "ans": letter,
161
  "time": f"{elapsed:.2f}s"
162
  })
163
 
 
164
  options_map = {"A": opa, "B": opb, "C": opc, "D": opd}
165
  pred_letter = ""
166
  for ch in result.upper():
 
183
  for i, k in enumerate(others):
184
  scores[k] = [remaining * 0.6, remaining * 0.25, remaining * 0.15][i] if i < 3 else 0
185
 
186
+ bars = ""
187
  colors = {"A": "#00c8f0", "B": "#00f0a0", "C": "#ff6030", "D": "#ffcc00"}
188
  for letter in ["A", "B", "C", "D"]:
189
  w = scores[letter]
 
220
  return gr.update(value=None)
221
  examples = SUBJECT_EXAMPLES.get(subject, [])
222
  if examples:
223
+ return gr.update(value=examples[0][0])
 
224
  return gr.update(value=None)
225
 
226
 
 
253
  margin: 0 auto !important;
254
  padding: 0 20px 60px !important;
255
  }
 
 
256
  #header {
257
  padding: 44px 0 28px;
258
  border-bottom: 1px solid var(--border);
 
274
  .b-rocm { color: var(--accent); border-color: #00c8f030; background: #00c8f008; }
275
  .b-lora { color: var(--green); border-color: #00f0a030; background: #00f0a008; }
276
  .b-live { color: #ffcc00; border-color: #ffcc0030; background: #ffcc0008; }
 
277
  h1#title {
278
  font-family: 'Syne', sans-serif !important;
279
  font-size: 42px !important; font-weight: 800 !important;
 
282
  }
283
  h1#title em { color: var(--accent); font-style: normal; }
284
  .subtitle { font-size: 14px; color: var(--muted); font-weight: 300; line-height: 1.6; max-width: 600px; }
 
 
285
  #stats {
286
  display: flex; border: 1px solid var(--border);
287
  border-radius: 12px; overflow: hidden;
 
293
  .sl { font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
294
  .dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--green); margin-right: 4px; animation: blink 2s infinite; }
295
  @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.3} }
 
 
296
  label span, .label-wrap span {
297
  font-family: 'DM Sans', sans-serif !important;
298
  font-size: 11px !important; font-weight: 500 !important;
 
311
  border-color: var(--accent) !important;
312
  box-shadow: 0 0 0 3px #00c8f012 !important; outline: none !important;
313
  }
 
 
314
  .section-label {
315
  font-size: 10px; font-weight: 600; letter-spacing: 0.12em;
316
  text-transform: uppercase; color: var(--muted); margin-bottom: 10px;
 
320
  content: ''; width: 5px; height: 5px; border-radius: 50%;
321
  background: var(--accent); display: inline-block;
322
  }
 
 
323
  .tab-nav button {
324
+ background: transparent !important; color: var(--muted) !important;
 
325
  border: none !important; border-bottom: 2px solid transparent !important;
326
  font-family: 'DM Sans', sans-serif !important;
327
  font-size: 13px !important; font-weight: 500 !important;
 
332
  color: var(--accent) !important;
333
  border-bottom-color: var(--accent) !important;
334
  }
 
 
335
  button.lg.primary {
336
  background: linear-gradient(135deg, var(--accent2), var(--accent)) !important;
337
  border: none !important; border-radius: 10px !important;
 
342
  transition: opacity 0.2s, transform 0.15s !important;
343
  }
344
  button.lg.primary:hover { opacity: 0.85 !important; transform: translateY(-1px) !important; }
 
345
  button.lg.secondary {
346
  background: var(--surface2) !important;
347
  border: 1px solid var(--border) !important;
 
352
  transition: border-color 0.2s !important;
353
  }
354
  button.lg.secondary:hover { border-color: var(--accent) !important; color: var(--accent) !important; }
355
+ .auto-btn button {
356
+ background: linear-gradient(135deg, #1a0055, #0055ff44) !important;
357
+ border: 1px solid var(--accent2) !important;
358
+ border-radius: 10px !important; color: var(--accent) !important;
359
+ font-family: 'DM Sans', sans-serif !important;
360
+ font-size: 13px !important; font-weight: 600 !important;
361
+ padding: 10px !important; width: 100% !important;
362
+ cursor: pointer !important; letter-spacing: 0.04em !important;
363
+ transition: opacity 0.2s, box-shadow 0.2s !important;
364
+ }
365
+ .auto-btn button:hover {
366
+ box-shadow: 0 0 12px #0055ff44 !important;
367
+ opacity: 0.9 !important;
368
+ }
369
  .out-box textarea {
370
  background: var(--surface2) !important;
371
  border: 1px solid var(--border) !important;
 
373
  line-height: 1.8 !important; color: var(--text) !important;
374
  min-height: 220px !important;
375
  }
 
 
376
  input[type=range] { accent-color: var(--accent) !important; }
 
 
377
  .wrap-inner { background: var(--surface2) !important; border-color: var(--border) !important; }
 
 
 
378
  .examples-holder table {
379
  background: var(--surface) !important;
380
  border: 1px solid var(--border) !important;
 
386
  font-family: 'DM Sans', sans-serif !important;
387
  }
388
  .examples-holder tr:hover td { background: var(--surface2) !important; cursor: pointer; }
 
 
 
 
 
 
 
 
389
  #footer {
390
  margin-top: 44px; padding-top: 22px;
391
  border-top: 1px solid var(--border);
 
400
 
401
  with gr.Blocks(css=CSS, title="MedQA β€” AMD ROCm") as demo:
402
 
 
403
  gr.HTML("""
404
  <div id="header">
405
  <div class="badges">
 
424
  </div>
425
  """)
426
 
 
427
  with gr.Tabs():
428
 
 
429
  with gr.Tab("Ask a Question"):
430
  with gr.Row():
431
 
 
432
  with gr.Column(scale=5):
433
  gr.HTML('<div class="section-label">Clinical Question</div>')
434
  question = gr.Textbox(
 
436
  placeholder="e.g. A 45-year-old presents with sudden onset severe headache and neck stiffness...",
437
  lines=4,
438
  )
439
+
440
+ auto_btn = gr.Button(
441
+ "✨ Auto-generate Options A B C D from Question",
442
+ variant="secondary",
443
+ elem_classes=["auto-btn"],
444
+ )
445
+ gr.HTML("<p style='font-size:11px;color:#4a6080;margin-bottom:10px;'>"
446
+ "Type your question above then click to auto-fill all 4 options using AI.</p>")
447
+
448
+ gr.HTML('<div class="section-label">Answer Options</div>')
449
  with gr.Row():
450
+ opa = gr.Textbox(label="Option A", placeholder="Auto-generated or type manually")
451
+ opb = gr.Textbox(label="Option B", placeholder="Auto-generated or type manually")
452
  with gr.Row():
453
+ opc = gr.Textbox(label="Option C", placeholder="Auto-generated or type manually")
454
+ opd = gr.Textbox(label="Option D", placeholder="Auto-generated or type manually")
455
 
456
  with gr.Row():
457
  btn = gr.Button("βš• Analyze Question", variant="primary")
458
  clr_btn = gr.Button("βœ• Clear", variant="secondary")
459
 
 
460
  with gr.Accordion("βš™ Generation Settings", open=False):
461
  temperature = gr.Slider(
462
  minimum=0.1, maximum=1.5, value=0.7, step=0.05,
 
472
  Higher = more creative explanations.
473
  </p>""")
474
 
 
475
  with gr.Column(scale=5):
476
  gr.HTML('<div class="section-label">AI Answer & Reasoning</div>')
 
477
  output = gr.Textbox(
478
  label="",
479
  placeholder="Answer and clinical explanation will appear here...",
480
  lines=10,
481
  elem_classes=["out-box"],
482
+ show_copy_button=True,
483
+ )
484
 
485
  gr.HTML('<div class="section-label" style="margin-top:16px">Answer Confidence</div>')
486
  confidence = gr.HTML(
 
489
 
490
  with gr.Row():
491
  inf_time = gr.Textbox(label="Inference Time", value="β€”", interactive=False, scale=1)
492
+ query_disp = gr.Textbox(label="Total Queries", value="0", interactive=False, scale=1)
493
 
 
494
  gr.HTML('<div class="section-label" style="margin-top:24px">Browse by Subject</div>')
495
  with gr.Row():
496
  subject_dd = gr.Dropdown(
497
  choices=SUBJECTS, value="All Subjects", label="Filter by subject", scale=2
498
  )
 
499
 
500
  gr.HTML('<div class="section-label" style="margin-top:12px">Sample Questions β€” click any to load</div>')
501
  gr.Examples(
502
  examples=EXAMPLES,
503
  inputs=[question, opa, opb, opc, opd],
504
  label="",
505
+ elem_classes=["examples-holder"],
506
  )
507
 
 
508
  with gr.Tab("Query History"):
509
  gr.HTML('<div class="section-label">Recent Queries</div>')
510
  history_html = gr.HTML(
 
512
  )
513
  refresh_btn = gr.Button("↻ Refresh History", variant="secondary")
514
 
 
515
  with gr.Tab("About"):
516
  gr.HTML("""
517
  <div style="max-width:800px;margin:0 auto;padding:24px 0;">
 
518
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:16px;padding:28px;margin-bottom:20px;">
519
  <h2 style="font-family:'Syne',sans-serif;color:#deeeff;font-size:22px;margin-bottom:16px;">What is MedQA?</h2>
520
  <p style="color:#4a6080;font-size:14px;line-height:1.8;">
 
524
  the clinical reasoning.
525
  </p>
526
  </div>
 
527
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px;">
528
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
529
  <h3 style="color:#00c8f0;font-size:14px;margin-bottom:12px;">MODEL</h3>
530
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
531
+ Base: Qwen3-1.7B<br>Fine-tuning: LoRA (r=4)<br>
532
+ Trainable: 2.2M / 1.7B params<br>Precision: bfloat16
 
 
533
  </p>
534
  </div>
535
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
536
  <h3 style="color:#00f0a0;font-size:14px;margin-bottom:12px;">HARDWARE</h3>
537
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
538
+ AMD Instinct MI300X<br>192GB HBM3 memory<br>
539
+ ROCm 7.2 on Ubuntu 24.04<br>No CUDA required
 
 
540
  </p>
541
  </div>
542
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
543
  <h3 style="color:#ff6030;font-size:14px;margin-bottom:12px;">TRAINING</h3>
544
  <p style="color:#4a6080;font-size:13px;line-height:1.8;">
545
+ Dataset: MedMCQA (500 samples)<br>Time: ~5 minutes on MI300X<br>
546
+ Optimizer: AdamW<br>Scheduler: Constant + warmup
 
 
547
  </p>
548
  </div>
549
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
 
556
  </p>
557
  </div>
558
  </div>
 
559
  <div style="background:#0f1624;border:1px solid #1a3356;border-radius:12px;padding:20px;">
560
  <h3 style="color:#deeeff;font-size:14px;margin-bottom:12px;">BUILT BY</h3>
561
  <p style="color:#4a6080;font-size:13px;">
 
563
  AMD Hackathon 2025 on lablab.ai
564
  </p>
565
  </div>
 
566
  </div>
567
  """)
568
 
 
569
  gr.HTML("""
570
  <div id="footer">
571
  <div class="fl">
 
582
  """)
583
 
584
  # ── Events ────────────────────────────────────────────────────────────────
585
+ auto_btn.click(
586
+ fn=autogenerate_options,
587
+ inputs=[question],
588
+ outputs=[opa, opb, opc, opd],
589
+ )
590
+
591
  btn.click(
592
  fn=generate_answer,
593
  inputs=[question, opa, opb, opc, opd, temperature, max_tokens],