Spaces:
Running
Running
| # Refactor Proposal: Cleaner GRM Leaderboard Space | |
| ## Goal | |
| Build a cleaner version of the Game Ready Leaderboard that keeps the same information, copy direction, dark NVIDIA-inspired theme, and green accent system, but removes the layout constraints currently caused by the Gradio page structure. | |
| The main product change is to consolidate stacked sections into a smaller number of interactive surfaces. In particular, the current Leaderboard plus three collapsed Per-Benchmark Score Breakdown tables should become one score explorer with filters, toggles, and expandable benchmark detail views. | |
| The updated benchmark and score plan should be treated as coming from `ref/GRM Eval - Benchmarks PRD.pdf`. | |
| ## Recommended Stack | |
| Use Streamlit as the next implementation target. | |
| Reasons: | |
| - Hugging Face Spaces supports Streamlit directly through README metadata with `sdk: streamlit`. | |
| - Streamlit gives enough native interactivity for filters, segmented controls, tabs, tables, expanders, and sidebar controls without building a custom frontend stack. | |
| - The existing Python data files can be reused with minimal migration. | |
| - The app can stay frontend-only and file-backed, matching the current Hugging Face Space model. | |
| - Custom CSS can preserve the current dark surface, muted text, and NVIDIA green accent style. | |
| Alternative: a static React/Vite Space would give better table UX and visual polish, especially with TanStack Table, but it would require a larger rewrite and a separate build step. For this repo, Streamlit is the best next step unless the target is a fully custom product UI. | |
| ## Space Metadata Changes | |
| If moving to Streamlit, update the README frontmatter: | |
| ```yaml | |
| --- | |
| title: GRM Leaderboard | |
| colorFrom: gray | |
| colorTo: blue | |
| sdk: streamlit | |
| app_file: streamlit_app.py | |
| pinned: false | |
| --- | |
| ``` | |
| Recommended files: | |
| - `streamlit_app.py`: page composition, controls, CSS injection, table rendering. | |
| - `benchmarks.py`: benchmark registry and PRD-derived metadata. | |
| - `scores.py`: score data. | |
| - `scoring.py`: weighted scoring and ranking logic. | |
| - `theme.py` or `ui_theme.py`: reusable color tokens and CSS strings. | |
| - `data_views.py`: table-shaping helpers for leaderboard, benchmark matrix, and benchmark detail views. | |
| Keep `app.py` during migration until the Streamlit version is accepted, then remove or archive the Gradio entry point. | |
| ## Product Shape | |
| ### Current Pain | |
| The current Gradio app stacks the experience as: | |
| 1. Overview | |
| 2. Leaderboard | |
| 3. Proprietary model toggle | |
| 4. Per-Benchmark Score Breakdown, split into three collapsed category tables | |
| 5. Evaluation Suite | |
| 6. Benchmark Details | |
| 7. Separate GRM-Bench tab | |
| This works, but it makes users scroll and mentally reconcile several tables that all describe the same score system. | |
| ### Proposed Shape | |
| Use two top-level pages or tabs: | |
| 1. `Leaderboard` | |
| 2. `Benchmark Library` | |
| The first page is the primary product surface. The second page is the methodology/reference surface. | |
| ## Page 1: Leaderboard | |
| ### Header | |
| Keep the existing hero identity and tone: | |
| - Eyebrow: `NVIDIA Game Ready Evaluation` | |
| - H1: `Game Ready Leaderboard` | |
| - Supporting copy: `An open game model evaluation surface for comparing LLMs across roleplay, gameplay actions, and practical in-game reasoning.` | |
| Keep the overview copy nearby, but make it less dominant. Use a short default summary with an expandable `About GRM Score` section containing the full paragraphs and formulas. | |
| ### Score Explorer | |
| Replace the separate Leaderboard and Per-Benchmark Score Breakdown sections with one consolidated score explorer. | |
| Controls: | |
| - Model visibility: `All models` / `Open-source only` | |
| - Score view: `Summary` / `Category` / `Benchmark matrix` | |
| - Category filter: `All`, `Roleplay`, `Actions`, `General` | |
| - Benchmark priority filter: `P0`, `P1`, `P2`, `All` | |
| - Benchmark source filter: `All`, `External`, `GRM-Bench` | |
| - Domain filter for PRD domains such as conversational breadth/coherence, multi-turn tool calling, input resilience, input grounding, restriction adherence, and common sense. | |
| - Search box for model or benchmark name. | |
| - Optional checkbox: `Show missing scores`. | |
| Default columns in `Summary` view: | |
| | Rank | Model | GRM Score | Roleplay | Actions | General | | |
| | --- | --- | --- | --- | --- | --- | | |
| Default columns in `Category` view: | |
| | Rank | Model | GRM Score | Selected Category Score | Core Avg | Supplementary Avg | Missing | | |
| | --- | --- | --- | --- | --- | --- | --- | | |
| Default columns in `Benchmark matrix` view: | |
| | Rank | Model | GRM Score | Roleplay | Actions | General | Selected benchmark columns... | | |
| | --- | --- | --- | --- | --- | --- | --- | | |
| Behavior: | |
| - The same table changes shape based on the selected view. | |
| - Category filters control which benchmark score columns appear. | |
| - Benchmark priority/source/domain filters reduce the matrix without changing the overall GRM calculation unless a separate `Recalculate using visible benchmarks` toggle is enabled. | |
| - Clicking or selecting a model reveals a detail panel below the table with category breakdowns and strongest/weakest benchmark scores. | |
| - Clicking or selecting a benchmark reveals the benchmark description, priority, weight, source, paper link, and PRD summary. | |
| This makes the per-benchmark breakdown part of the main leaderboard instead of a second section users have to open one category at a time. | |
| ### Score Cards | |
| Above the table, show small dense stats rather than big decorative cards: | |
| - Top model | |
| - Best open-source model | |
| - Number of models | |
| - Number of benchmarks with active score data | |
| - Latest data source: `ref/GRM Eval - Benchmarks PRD.pdf` or generated data snapshot date | |
| These should be compact and utilitarian, not marketing-style hero cards. | |
| ### Notes | |
| Keep the current warning that scores are placeholder/static until replaced, but attach it to the table caption or data status line instead of a separate section note. | |
| Suggested copy: | |
| `Current score values are static placeholders unless replaced with benchmark outputs from the PRD-backed data pipeline.` | |
| ## Page 2: Benchmark Library | |
| This page consolidates Evaluation Suite, Benchmark Details, and GRM-Bench authored benchmark descriptions. | |
| ### Benchmark Registry Table | |
| One searchable/filterable table: | |
| | Category | Domain | Benchmark | Source | Priority | Weight | Included in GRM | Description | | |
| | --- | --- | --- | --- | --- | --- | --- | --- | | |
| This replaces the current Evaluation Suite table and gives it the extra PRD fields. | |
| ### Benchmark Detail Drawer or Expander | |
| Selecting a benchmark opens details below the table: | |
| - Summary | |
| - Methodology | |
| - Detection scope, where applicable | |
| - Paper/source link | |
| - Test sample availability | |
| - Whether it is included in GRM score | |
| For Streamlit, this can be a `st.expander` or a selected-row-driven detail panel. If row selection is awkward in Streamlit, use a selectbox above the detail panel. | |
| ### GRM-Bench Authored Families | |
| Fold the authored GRM-Bench tab into the Benchmark Library page. Use a segmented control or filter rather than a separate top-level tab. | |
| PRD-backed authored dimensions: | |
| | Dimension | Phase | Included in GRM | Notes | | |
| | --- | --- | --- | --- | | |
| | Coherence | Phase 1 | Yes | Logical soundness, contradictions, role confusion, knowledge boundaries, false premises. | | |
| | Response Diversity | Phase 1 | Yes | Avoids repetitive language, sentence frames, and stale delivery. | | |
| | Prompt Robustness | Phase 1 | Yes | Handles the same intent across terse, verbose, structured, and noisy prompts. | | |
| | Persona-Aligned Actions | Phase 1 | Yes | Ensures personality instructions are followed in tool use and planning. | | |
| | Tool Recovery | Phase 1 | Yes | Recovers from missed calls, malformed arguments, explicit failures, and fabricated outputs. | | |
| | State Adaption / State Tracking | Phase 1 | Yes | Tracks changing world state without stale values or entity drift. | | |
| | Emotional Intelligence | Sanity / non-scored | No | Important for immersion but marked as not included in GRM score in the PRD. | | |
| | Role Diversity | Phase 2 / non-scored | No | Diverse characters, accents, speech patterns, and scenarios. | | |
| | Spatial & Temporal Awareness | Phase 2 | TBD | Correctly tracks entities, locations, navigation, and state over time. | | |
| | Group Conversations | Phase 2 | TBD | Maintains roleplay quality when multiple parties participate. | | |
| | Self Triggering | Phase 2 | TBD | Judges when to trigger events from situational awareness without a user prompt. | | |
| Note: normalize the spelling in the UI to `State Adaptation`, but preserve any original PRD labels in source metadata if needed. | |
| ## Updated Data Model | |
| The current benchmark registry has `name`, `category`, `calc_weight`, `description`, `summary`, and `paper`. | |
| The PRD implies a richer registry: | |
| ```python | |
| BENCHMARKS = [ | |
| { | |
| "id": "grm_coherence", | |
| "name": "GRM - Coherence", | |
| "category": "ROLEPLAY", | |
| "domain": "Conversational breadth/coherence", | |
| "source": "GRM-Bench", | |
| "phase": "Phase 1", | |
| "priority": "P0", | |
| "calc_weight": 1.0, | |
| "included_in_grm": True, | |
| "description": "Logically sound and coherent across turns without contradictions.", | |
| "summary": "...", | |
| "methodology": "...", | |
| "detection_scope": [...], | |
| "paper": None, | |
| }, | |
| ] | |
| ``` | |
| Recommended score shape: | |
| ```python | |
| MODEL_SCORES = { | |
| "Qwen3.5-4B": { | |
| "grm_coherence": 41.4, | |
| "multichallenge": 49.0, | |
| } | |
| } | |
| ``` | |
| Use 0-100 values directly if the PRD data is already in that scale. The current app stores 0.0-1.0 values and formats them as percentages; the refactor should pick one canonical scale and document it. I recommend storing 0-100 because the PRD table is already expressed that way. | |
| Recommended model metadata: | |
| ```python | |
| MODEL_METADATA = { | |
| "Qwen3.5-4B": { | |
| "family": "Qwen", | |
| "size": "4B", | |
| "open_weights": True, | |
| "precision": None, | |
| } | |
| } | |
| ``` | |
| ## PRD Benchmark Suite Mapping | |
| The Streamlit version should update the visible suite to match the PRD table, not the older placeholder-only registry. | |
| ### Roleplay, 33 percent | |
| Domain: conversational breadth/coherence. | |
| | Benchmark | Priority | Weight | Source | | |
| | --- | --- | --- | --- | | |
| | MultiChallenge | P0 | 1.0 | External | | |
| | RoleBench | P0 | 1.0 | External | | |
| | RoleMRC | P1 | 0.5 | External | | |
| | EQ-Bench v3 | P1 | 0.5 | External | | |
| | GRM - Coherence | P0 | 1.0 | GRM-Bench | | |
| | GRM - Resp. Div | P0 | 1.0 | GRM-Bench | | |
| ### Actions, 33 percent | |
| Domain: multi-turn tool calling. | |
| | Benchmark | Priority | Weight | Source | | |
| | --- | --- | --- | --- | | |
| | BFCL v3 | P0 | 1.0 | External | | |
| | When2Call-MT | P0 | 1.0 | External | | |
| | ToolSandbox | P0 | 1.0 | External | | |
| | Tau2-Bench | P0 | 1.0 | External | | |
| | BFCL v4 | P1 | 0.5 | External | | |
| | GRM - Tool Rec | P0 | 1.0 | GRM-Bench | | |
| ### General, 33 percent | |
| Domains: input resilience, input grounding, restriction adherence, and common sense. | |
| | Domain | Benchmark | Priority | Weight | Source | | |
| | --- | --- | --- | --- | --- | | |
| | Input resilience | IHEval | P0 | 1.0 | External | | |
| | Input resilience | RULER | P0 | 1.0 | External | | |
| | Input resilience | LongMemEval | P1 | 0.5 | External | | |
| | Input resilience | AgentIF | P1 | 0.5 | External | | |
| | Input resilience | GRM - Prompt Rob | P0 | 1.0 | GRM-Bench | | |
| | Input resilience | GRM - State Adapt | P0 | 1.0 | GRM-Bench | | |
| | Input grounding | GaRAGe | P0 | 1.0 | External | | |
| | Input grounding | RAGTruth | P1 | 0.5 | External | | |
| | Restriction adherence | StructEval-T | P1 | 0.5 | External | | |
| | Restriction adherence | IFBench | P1 | 0.5 | External | | |
| | Restriction adherence | GRM - Persona Act | P0 | 1.0 | GRM-Bench | | |
| | Common sense | GSM8K | P2 | 0.25 | External | | |
| | Common sense | HumanEval | P2 | 0.25 | External | | |
| | Common sense | MBPP | P2 | 0.25 | External | | |
| ## Scoring Rules | |
| Keep the current top-level scoring model: | |
| ```text | |
| GRM Score = (Roleplay + Actions + General) / 3 | |
| Category Score = sum(score x weight) / sum(weight) | |
| ``` | |
| Refinements: | |
| - Only benchmarks with `included_in_grm = True` count toward category scores. | |
| - Missing scores are skipped in the weighted average, but the UI should display missing counts. | |
| - Non-scored dimensions like Emotional Intelligence and Role Diversity appear in the Benchmark Library, not in the GRM calculation. | |
| - If a user turns on `Recalculate using visible benchmarks`, label the result as an exploratory filtered score, not the official GRM Score. | |
| ## Visual System | |
| Preserve the current theme direction: | |
| ```css | |
| :root { | |
| --bg-top: #202327; | |
| --bg-bottom: #0f1012; | |
| --surface: #15181b; | |
| --surface-strong: #24282d; | |
| --surface-alt: #1d2126; | |
| --text-main: #f5f7f8; | |
| --text-muted: #c1c6cb; | |
| --text-soft: #a2a8ae; | |
| --accent: #76b900; | |
| --rule: rgba(255, 255, 255, 0.08); | |
| } | |
| ``` | |
| Streamlit CSS targets should style: | |
| - App background gradient. | |
| - Main content width around 1260px. | |
| - Compact table headers with uppercase muted text. | |
| - Alternating table rows using `#1c2024` and `#24282d`. | |
| - Top ranked row highlight using a dark green-tinted row like `#252d1d`. | |
| - Accent links and selected controls with `#76b900`. | |
| - Dense control rows rather than stacked controls. | |
| Avoid a marketing-style redesign. This should feel like a sharp evaluation tool: compact, scannable, and built for repeated comparison. | |
| ## Streamlit Layout Sketch | |
| ```python | |
| st.set_page_config( | |
| page_title="GRM Score - Game Ready Leaderboard", | |
| layout="wide", | |
| ) | |
| inject_theme_css() | |
| render_header() | |
| render_about_grm_expander() | |
| tab_leaderboard, tab_library = st.tabs(["Leaderboard", "Benchmark Library"]) | |
| with tab_leaderboard: | |
| controls = render_score_controls() | |
| leaderboard_frame = build_score_explorer_frame(controls) | |
| st.dataframe( | |
| leaderboard_frame, | |
| use_container_width=True, | |
| hide_index=True, | |
| ) | |
| render_selected_model_or_benchmark_details(controls) | |
| with tab_library: | |
| filters = render_benchmark_filters() | |
| benchmark_frame = build_benchmark_registry_frame(filters) | |
| st.dataframe(benchmark_frame, use_container_width=True, hide_index=True) | |
| render_benchmark_detail_panel(filters) | |
| ``` | |
| ## Migration Plan | |
| 1. Add PRD fields to `benchmarks.py`: `id`, `domain`, `source`, `phase`, `priority`, and `included_in_grm`. | |
| 2. Convert `scores.py` to canonical 0-100 values and PRD model names. | |
| 3. Update `scoring.py` to use benchmark IDs and `included_in_grm`. | |
| 4. Add table view helpers in `data_views.py`. | |
| 5. Build `streamlit_app.py` with the two-page/tab structure. | |
| 6. Port the existing CSS tokens into Streamlit CSS injection. | |
| 7. Update README metadata to `sdk: streamlit` and `app_file: streamlit_app.py`. | |
| 8. Keep `app.py` until parity is verified, then remove the Gradio dependency from `requirements.txt`. | |
| 9. Verify locally with `streamlit run streamlit_app.py`. | |
| 10. Deploy to Hugging Face Space and confirm the Space launches with the new SDK metadata. | |
| ## Acceptance Criteria | |
| - The first screen shows the header, concise overview, score controls, and leaderboard without requiring deep scrolling. | |
| - The Leaderboard and Per-Benchmark Score Breakdown are one consolidated interactive table surface. | |
| - Users can filter by category, domain, priority, source, model visibility, and benchmark name. | |
| - Users can switch between summary, category, and benchmark matrix views without leaving the leaderboard. | |
| - The Benchmark Library includes Evaluation Suite, Benchmark Details, and GRM-Bench authored descriptions in one place. | |
| - The visual theme matches the current dark NVIDIA-accented design. | |
| - The scoring logic matches the existing formula and the PRD weights. | |
| - Non-scored dimensions are visible but clearly excluded from official GRM Score. | |
| - The Hugging Face Space runs without an external database or backend. | |
| ## Open Decisions | |
| - Whether to keep official score storage as 0-100 values, matching the PRD, or preserve the current 0.0-1.0 internal scale. | |
| - Whether Streamlit's built-in dataframe is sufficient, or whether the app needs `streamlit-aggrid` for stronger filtering, pinned columns, and row selection. | |
| - Whether non-scored PRD dimensions should live in the main Benchmark Library by default or behind a `Show future/non-scored dimensions` toggle. | |
| - Whether the old Gradio app should remain as `app_gradio.py` for a short transition period. |