OliverPerrin commited on
Commit
4a825c2
·
1 Parent(s): 4423aaf

Fix Gradio schema bug: replace Dataframe with Markdown tables

Browse files

The gr.Dataframe component generates JSON schemas with additionalProperties: true
which causes TypeError in gradio_client when parsing API info. Replaced with
Markdown tables which don't have this issue.

Files changed (1) hide show
  1. scripts/demo_gradio.py +38 -54
scripts/demo_gradio.py CHANGED
@@ -441,56 +441,50 @@ def generate_fallback_summary(text: str, max_chars: int = 320) -> str:
441
  return " ".join(fragments)
442
 
443
 
444
- def load_metrics_report():
 
445
  if not EVAL_REPORT_PATH.exists():
446
- return (
447
- pd.DataFrame(),
448
- pd.DataFrame(),
449
- None,
450
- {
451
- "error": f"Evaluation report not found at {EVAL_REPORT_PATH}. Run scripts/evaluate.py first."
452
- },
453
- )
454
 
455
  try:
456
  with EVAL_REPORT_PATH.open("r", encoding="utf-8") as handle:
457
  report = json.load(handle)
458
  except Exception as exc:
459
  logger.error("Failed to read evaluation report: %s", exc, exc_info=True)
460
- return pd.DataFrame(), pd.DataFrame(), None, {"error": str(exc)}
461
-
462
- # Summarization & Emotion Metrics
463
- summary_metrics = [
464
- {
465
- "Task": "Summarization",
466
- "Metric": "ROUGE-Like",
467
- "Value": report["summarization"]["rouge_like"],
468
- },
469
- {"Task": "Summarization", "Metric": "BLEU", "Value": report["summarization"]["bleu"]},
470
- {"Task": "Emotion", "Metric": "F1 (Macro)", "Value": report["emotion"]["f1_macro"]},
471
- {"Task": "Topic", "Metric": "Accuracy", "Value": report["topic"]["accuracy"]},
472
- ]
473
- summary_df = pd.DataFrame(summary_metrics)
474
-
475
- # Topic Classification Report
 
476
  topic_report = report["topic"]["classification_report"]
477
- topic_rows = []
478
  for label, metrics in topic_report.items():
479
- if isinstance(metrics, dict):
480
- row = {"Label": label}
481
- row.update(metrics)
482
- topic_rows.append(row)
483
- topic_df = pd.DataFrame(topic_rows)
484
 
485
  # Confusion Matrix
486
  cm_image = str(CONFUSION_MATRIX_PATH) if CONFUSION_MATRIX_PATH.exists() else None
487
 
488
- metadata = {
489
- "split": report.get("split", "unknown"),
490
- "last_updated": datetime.fromtimestamp(EVAL_REPORT_PATH.stat().st_mtime).isoformat(),
491
- }
492
 
493
- return summary_df, topic_df, cm_image, metadata
494
 
495
 
496
  SAMPLE_TEXT = (
@@ -516,7 +510,7 @@ def create_interface() -> gr.Blocks:
516
  )
517
 
518
  initial_visuals, initial_visual_status = load_visualization_gallery()
519
- summary_df, topic_df, cm_image, metrics_meta = load_metrics_report()
520
 
521
  with gr.Row():
522
  with gr.Column(scale=1):
@@ -542,23 +536,17 @@ def create_interface() -> gr.Blocks:
542
  gr.Markdown("*Shows decoder attention if a summary is available.*")
543
  with gr.TabItem("Model Performance"):
544
  gr.Markdown("### Overall Metrics")
545
- metrics_table = gr.Dataframe(
546
- value=summary_df, headers=["Task", "Metric", "Value"], interactive=False
547
- )
548
  gr.Markdown("### Topic Classification Report")
549
- topic_table = gr.Dataframe(
550
- value=topic_df,
551
- headers=["Label", "precision", "recall", "f1-score", "support"],
552
- interactive=False,
553
- )
554
  gr.Markdown("### Topic Confusion Matrix")
555
  cm_output = gr.Image(value=cm_image, label="Confusion Matrix")
556
-
557
  metrics_meta_text = gr.Textbox(
558
- value=json.dumps(metrics_meta, indent=2),
559
- label="Metadata",
560
  interactive=False,
561
- lines=4,
562
  )
563
  refresh_metrics = gr.Button("Refresh Metrics")
564
 
@@ -591,12 +579,8 @@ def create_interface() -> gr.Blocks:
591
  inputs=None,
592
  outputs=[visuals, visuals_notice],
593
  )
594
- def load_metrics_report_for_ui():
595
- summary_df, topic_df, cm_image, metadata = load_metrics_report()
596
- return summary_df, topic_df, cm_image, json.dumps(metadata, indent=2)
597
-
598
  refresh_metrics.click(
599
- fn=load_metrics_report_for_ui,
600
  inputs=None,
601
  outputs=[metrics_table, topic_table, cm_output, metrics_meta_text],
602
  )
 
441
  return " ".join(fragments)
442
 
443
 
444
+ def load_metrics_report_as_markdown() -> tuple[str, str, str | None, str]:
445
+ """Load metrics and return as Markdown strings to avoid Gradio schema issues."""
446
  if not EVAL_REPORT_PATH.exists():
447
+ error_msg = f"Evaluation report not found at {EVAL_REPORT_PATH}. Run scripts/evaluate.py first."
448
+ return error_msg, "", None, error_msg
 
 
 
 
 
 
449
 
450
  try:
451
  with EVAL_REPORT_PATH.open("r", encoding="utf-8") as handle:
452
  report = json.load(handle)
453
  except Exception as exc:
454
  logger.error("Failed to read evaluation report: %s", exc, exc_info=True)
455
+ error_msg = f"Error loading report: {exc}"
456
+ return error_msg, "", None, error_msg
457
+
458
+ # Build overall metrics markdown table
459
+ summary_md = """| Task | Metric | Value |
460
+ |------|--------|-------|
461
+ | Summarization | ROUGE-Like | {:.4f} |
462
+ | Summarization | BLEU | {:.4f} |
463
+ | Emotion | F1 (Macro) | {:.4f} |
464
+ | Topic | Accuracy | {:.4f} |""".format(
465
+ report["summarization"]["rouge_like"],
466
+ report["summarization"]["bleu"],
467
+ report["emotion"]["f1_macro"],
468
+ report["topic"]["accuracy"],
469
+ )
470
+
471
+ # Build topic classification report markdown table
472
  topic_report = report["topic"]["classification_report"]
473
+ topic_lines = ["| Label | Precision | Recall | F1-Score | Support |", "|-------|-----------|--------|----------|---------|"]
474
  for label, metrics in topic_report.items():
475
+ if isinstance(metrics, dict) and "precision" in metrics:
476
+ topic_lines.append(
477
+ f"| {label} | {metrics['precision']:.4f} | {metrics['recall']:.4f} | {metrics['f1-score']:.4f} | {int(metrics.get('support', 0))} |"
478
+ )
479
+ topic_md = "\n".join(topic_lines)
480
 
481
  # Confusion Matrix
482
  cm_image = str(CONFUSION_MATRIX_PATH) if CONFUSION_MATRIX_PATH.exists() else None
483
 
484
+ # Metadata
485
+ meta_str = f"Split: {report.get('split', 'unknown')}\nLast updated: {datetime.fromtimestamp(EVAL_REPORT_PATH.stat().st_mtime).isoformat()}"
 
 
486
 
487
+ return summary_md, topic_md, cm_image, meta_str
488
 
489
 
490
  SAMPLE_TEXT = (
 
510
  )
511
 
512
  initial_visuals, initial_visual_status = load_visualization_gallery()
513
+ summary_md, topic_md, cm_image, metrics_meta = load_metrics_report_as_markdown()
514
 
515
  with gr.Row():
516
  with gr.Column(scale=1):
 
536
  gr.Markdown("*Shows decoder attention if a summary is available.*")
537
  with gr.TabItem("Model Performance"):
538
  gr.Markdown("### Overall Metrics")
539
+ metrics_table = gr.Markdown(value=summary_md)
 
 
540
  gr.Markdown("### Topic Classification Report")
541
+ topic_table = gr.Markdown(value=topic_md)
 
 
 
 
542
  gr.Markdown("### Topic Confusion Matrix")
543
  cm_output = gr.Image(value=cm_image, label="Confusion Matrix")
544
+ gr.Markdown("### Metadata")
545
  metrics_meta_text = gr.Textbox(
546
+ value=metrics_meta,
547
+ label="Info",
548
  interactive=False,
549
+ lines=2,
550
  )
551
  refresh_metrics = gr.Button("Refresh Metrics")
552
 
 
579
  inputs=None,
580
  outputs=[visuals, visuals_notice],
581
  )
 
 
 
 
582
  refresh_metrics.click(
583
+ fn=load_metrics_report_as_markdown,
584
  inputs=None,
585
  outputs=[metrics_table, topic_table, cm_output, metrics_meta_text],
586
  )