import asyncio import json from collections import defaultdict from pathlib import Path # Gradio 5.19's safe_get_lock() returns None on Python 3.12+/3.14 when no # event loop exists yet, which breaks /queue/join (pending_message_lock). try: asyncio.get_running_loop() except RuntimeError: asyncio.set_event_loop(asyncio.new_event_loop()) import gradio as gr import pandas as pd from ui import ( render_footer, render_header, render_image_workspace, ) # Visual tokens from https://www.pruna.ai/ and https://playground.pruna.ai/ custom_css = """ :root, :host, .dark, :host(.dark) { --pruna-bg-primary: #120b1b; --pruna-bg-card: #171021; --pruna-bg-elevated: #1d1429; --pruna-bg-header: #17101f; --pruna-border: rgba(74, 57, 98, 0.75); --pruna-hairline: rgba(255, 255, 255, 0.08); --pruna-text-primary: #fafafa; --pruna-text-body: #d4d4d4; --pruna-text-muted: #a3a3a3; --pruna-accent: #9334e9; --pruna-accent-bright: #8f35ff; --pruna-lavender: #d8b4fe; --pruna-link: #bf8bff; --pruna-font: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif; --pruna-glow: radial-gradient(ellipse 60% 35% at 50% -5%, rgba(147, 52, 233, 0.18), transparent 55%); --pruna-card-bg: color-mix(in oklab, #1d1429 92%, black 8%); --pruna-card-shadow: 0 24px 55px rgba(0, 0, 0, 0.42), inset 0 1px rgba(255, 255, 255, 0.04); --pruna-callout-bg: color-mix(in oklab, #171021 82%, black 18%); --pruna-menu-border: rgba(255, 255, 255, 0.08); --pruna-menu-bg: rgba(255, 255, 255, 0.03); --pruna-menu-hover-bg: rgba(255, 255, 255, 0.05); --pruna-menu-hover-color: #e4e4e7; --pruna-menu-selected-bg: rgba(143, 53, 255, 0.22); --pruna-menu-selected-color: #ffffff; --pruna-tab-hover: #e4e4e7; --pruna-tab-selected: #ffffff; --pruna-input-bg: rgba(255, 255, 255, 0.03); --pruna-input-border: rgba(255, 255, 255, 0.08); --pruna-focus-border: rgba(143, 53, 255, 0.45); --pruna-focus-ring: 0 0 0 3px rgba(143, 53, 255, 0.16); --pruna-table-hover: rgba(143, 53, 255, 0.16); --pruna-table-hover-text: #ffffff; --pruna-table-sticky: #17101f; --pruna-table-sticky-hover: #2a1844; --pruna-rank-bg: rgba(143, 53, 255, 0.22); --pruna-rank-ring: 0 0 0 1px rgba(143, 53, 255, 0.45); --pruna-score: #ddd6fe; --pruna-accordion-bg: rgba(255, 255, 255, 0.02); --pruna-accordion-border: rgba(216, 180, 254, 0.15); --pruna-dropdown-hover: #2a1844; color-scheme: dark; } .light, :host(.light) { --pruna-bg-primary: #f6f3fa; --pruna-bg-card: #ffffff; --pruna-bg-elevated: #ffffff; --pruna-bg-header: #f3eef8; --pruna-border: rgba(126, 34, 206, 0.16); --pruna-hairline: rgba(24, 24, 27, 0.08); --pruna-text-primary: #18181b; --pruna-text-body: #3f3f46; --pruna-text-muted: #71717a; --pruna-accent: #9334e9; --pruna-accent-bright: #7c22ce; --pruna-lavender: #7e22ce; --pruna-link: #6d28d9; --pruna-glow: radial-gradient(ellipse 60% 35% at 50% -5%, rgba(147, 52, 233, 0.10), transparent 55%); --pruna-card-bg: #ffffff; --pruna-card-shadow: 0 10px 28px rgba(88, 28, 135, 0.08); --pruna-callout-bg: #ffffff; --pruna-menu-border: var(--pruna-border); --pruna-menu-bg: var(--pruna-bg-card); --pruna-menu-hover-bg: rgba(147, 52, 233, 0.06); --pruna-menu-hover-color: var(--pruna-text-primary); --pruna-menu-selected-bg: rgba(147, 52, 233, 0.12); --pruna-menu-selected-color: var(--pruna-accent-bright); --pruna-tab-hover: var(--pruna-text-primary); --pruna-tab-selected: var(--pruna-text-primary); --pruna-input-bg: var(--pruna-bg-card); --pruna-input-border: var(--pruna-border); --pruna-focus-border: rgba(124, 34, 206, 0.45); --pruna-focus-ring: 0 0 0 3px rgba(143, 53, 255, 0.16); --pruna-table-hover: rgba(147, 52, 233, 0.08); --pruna-table-hover-text: var(--pruna-text-primary); --pruna-table-sticky: var(--pruna-bg-card); --pruna-table-sticky-hover: #f3e8ff; --pruna-rank-bg: rgba(147, 52, 233, 0.12); --pruna-rank-ring: 0 0 0 1px rgba(147, 52, 233, 0.28); --pruna-score: var(--pruna-accent-bright); --pruna-accordion-bg: var(--pruna-bg-card); --pruna-accordion-border: var(--pruna-border); --pruna-dropdown-hover: #f3e8ff; color-scheme: light; } html, body { width: 100% !important; max-width: 100% !important; overflow-x: clip; -webkit-tap-highlight-color: transparent; } html, body, .gradio-container, .main { background: var(--pruna-bg-primary) !important; color: var(--pruna-text-primary) !important; font-family: var(--pruna-font) !important; } button, a, label, input, select, textarea, [role="button"], [role="tab"], [role="radio"], .gradio-container * { -webkit-tap-highlight-color: transparent !important; } .gradio-container { --input-radius: 10px; --container-radius: 10px; --block-radius: 10px; } /* Subtle depth — not a marketing-site hero glow */ body, .gradio-container { background-image: var(--pruna-glow) !important; background-attachment: fixed !important; } .gradio-container { width: 100% !important; max-width: 1200px !important; margin: 0 auto !important; padding-top: 0 !important; padding-left: 20px !important; padding-right: 20px !important; box-sizing: border-box !important; overflow-x: clip; } .gradio-container .main, .gradio-container .wrap, .gradio-container .contain, .gradio-container .block, .gradio-container .form, .gradio-container .row, .gradio-container .column, .gradio-container .gap, .gradio-container .html-container, .gradio-container .prose, .gradio-container .padded, .main-tabs, .main-tabs .tab-wrapper, .main-tabs .tabitem, .leaderboard-controls, .workspace-shell, .workspace-filters, .view-filters { max-width: 100% !important; } /* —— App header (P-Bench only) —— */ .app-header-host, .app-header-host .html-container, .app-header-host .prose, .app-header-host.block, .app-header-host .padded { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 auto !important; width: 100% !important; max-width: none !important; display: block !important; text-align: center !important; overflow: visible !important; } .app-header { position: relative; display: flex; flex-direction: column; align-items: stretch; width: 100%; margin: 8px 0 0; padding: 4px 0 10px; text-align: center; } .app-header-bar { display: grid; grid-template-columns: minmax(36px, 1fr) auto minmax(36px, 1fr); align-items: center; width: 100%; column-gap: 8px; } .app-header .theme-toggle, button.theme-toggle { position: static !important; top: auto; right: auto; grid-column: 3; justify-self: end; display: inline-flex !important; align-items: center !important; justify-content: center !important; width: 36px !important; height: 36px !important; min-width: 36px !important; min-height: 36px !important; margin: 0 !important; padding: 0 !important; border: 1px solid var(--pruna-menu-border) !important; border-radius: 10px !important; background: var(--pruna-menu-bg) !important; color: var(--pruna-text-muted) !important; box-shadow: none !important; appearance: none !important; -webkit-appearance: none !important; box-sizing: border-box !important; font: inherit !important; line-height: 0 !important; cursor: pointer; z-index: 6; } .app-header .theme-toggle:hover, .app-header .theme-toggle:active, button.theme-toggle:hover, button.theme-toggle:active { color: var(--pruna-menu-hover-color) !important; background: var(--pruna-menu-hover-bg) !important; border-color: var(--pruna-menu-border) !important; box-shadow: none !important; } .app-header .theme-toggle:focus, button.theme-toggle:focus { outline: none !important; } .app-header .theme-toggle:focus-visible, button.theme-toggle:focus-visible { color: var(--pruna-menu-hover-color) !important; background: var(--pruna-menu-hover-bg) !important; border-color: var(--pruna-focus-border) !important; box-shadow: var(--pruna-focus-ring) !important; } .app-header .theme-toggle svg, button.theme-toggle svg { width: 18px; height: 18px; flex-shrink: 0; } .app-header .theme-toggle .theme-icon-sun, button.theme-toggle .theme-icon-sun { display: block !important; } .app-header .theme-toggle .theme-icon-moon, button.theme-toggle .theme-icon-moon { display: none !important; } .app-header .theme-toggle[data-mode="light"] .theme-icon-sun, button.theme-toggle[data-mode="light"] .theme-icon-sun { display: none !important; } .app-header .theme-toggle[data-mode="light"] .theme-icon-moon, button.theme-toggle[data-mode="light"] .theme-icon-moon { display: block !important; } .app-header-brand { display: inline-flex !important; flex-direction: row; align-items: center; justify-content: center; gap: 12px; grid-column: 2; justify-self: center; width: auto !important; max-width: 100%; margin: 0; } .app-header-logo { display: block !important; width: 44px !important; height: 52px !important; margin: 0 !important; object-fit: contain; flex: 0 0 auto; } /* —— Page tabs: centered underline nav —— */ .workspace-shell, .workspace-shell.block, .workspace-shell.column, .workspace-shell.gap { display: flex !important; flex-direction: column !important; gap: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; } .workspace-shell > .tabs, .workspace-shell > .main-tabs, .workspace-shell > .block:not(.workspace-filters), .workspace-shell .tabs.main-tabs { display: contents !important; } .workspace-filters { order: 2 !important; } .main-tabs .tabitem { order: 3 !important; } .tabs { gap: 0 !important; } .main-tabs > .tab-wrapper { order: 1 !important; height: auto !important; min-height: 0 !important; padding: 0 !important; margin: 0 0 16px !important; justify-content: center !important; width: 100% !important; } .main-tabs .tab-container { height: auto !important; justify-content: center !important; flex-wrap: wrap !important; overflow: hidden !important; max-width: 100% !important; gap: 2px; } .main-tabs .tab-container::after { background: var(--pruna-hairline) !important; } .main-tabs .tab-container > button { font-family: var(--pruna-font) !important; font-size: 0.95rem !important; font-weight: 600 !important; letter-spacing: -0.015em !important; color: var(--pruna-text-muted) !important; background: transparent !important; border: none !important; border-radius: 0 !important; box-shadow: none !important; padding: 12px 20px !important; min-height: 44px !important; height: auto !important; } .main-tabs .tab-container > button:hover:not(.selected), .main-tabs .tab-container > button:active:not(.selected) { color: var(--pruna-tab-hover) !important; background: transparent !important; } .main-tabs .tab-container > button.selected, .main-tabs .tab-container > button[aria-selected="true"] { color: var(--pruna-tab-selected) !important; background: transparent !important; } .main-tabs .tab-container > button:disabled, .main-tabs .tab-container > button[disabled] { opacity: 0.4 !important; color: var(--pruna-text-muted) !important; cursor: not-allowed !important; } .main-tabs .tab-container > button.selected::after, .main-tabs .tab-container > button[aria-selected="true"]::after { background: var(--pruna-accent-bright) !important; height: 2px !important; } .main-tabs .tabitem { padding: 8px 0 0 !important; border-radius: 0 !important; overflow: visible !important; } /* —— About: two columns on desktop, stacked on phone —— */ .about-layout, .about-layout.row, .about-layout .form { display: flex !important; flex-wrap: wrap !important; align-items: flex-start !important; gap: 8px 40px !important; width: 100% !important; } .about-layout > .about-col, .about-layout .form > .about-col { flex: 1 1 340px !important; min-width: 280px !important; max-width: 100% !important; } .about-copy, .about-copy.block, .about-copy .prose, .about-copy.prose, .about-copy.padded { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: 100% !important; overflow-wrap: break-word !important; word-break: break-word !important; } .about-copy ol, .about-copy ul, .about-copy .prose ol, .about-copy .prose ul { padding-left: 1.25rem !important; margin: 0 0 0.8rem !important; } .about-copy li, .about-copy .prose li { overflow-wrap: break-word; } @media (max-width: 700px) { .gradio-container { padding-left: 12px !important; padding-right: 12px !important; } .gradio-container .block, .gradio-container .form, .gradio-container .row, .gradio-container .column, .gradio-container .wrap, .leaderboard-controls, .view-filters { min-width: 0 !important; max-width: 100% !important; } .app-header { padding: 4px 0 8px; margin: 4px 0 0; } .app-header-logo { width: 36px !important; height: 42px !important; } .app-header-brand h1, .gradio-container .app-header-brand h1 { font-size: 1.55rem !important; } .app-header-tagline { font-size: 0.88rem !important; padding: 0 8px !important; } .main-tabs > .tab-wrapper { margin: 4px 0 14px !important; } .main-tabs .tab-container { flex-wrap: wrap !important; justify-content: center !important; gap: 0 !important; } .main-tabs .tab-container > button { padding: 10px 12px !important; font-size: 0.88rem !important; min-height: 40px !important; } .about-layout, .about-layout.row, .about-layout .form { flex-direction: column !important; flex-wrap: nowrap !important; gap: 8px !important; } .about-layout > .about-col, .about-layout > div { flex: 1 1 auto !important; width: 100% !important; } .about-copy h1, .about-copy .prose h1 { font-size: 1.3rem !important; } .about-copy h2, .about-copy .prose h2 { margin-top: 1.25rem !important; font-size: 1.12rem !important; } .community-footer-links { gap: 10px 14px; } .leaderboard-controls, .leaderboard-controls.row, .leaderboard-controls .form, .view-filters, .view-filters.row, .view-filters .form { flex-direction: column !important; align-items: stretch !important; } .leaderboard-controls > div, .leaderboard-controls .form > div, .view-filters > div, .view-filters .form > div { flex: 1 1 auto !important; width: 100% !important; max-width: 100% !important; } .ranking-table-scroll { max-height: min(75vh, 640px); width: 100%; } .ranking-table th, .ranking-table td, .prose .ranking-table th, .prose .ranking-table td { padding: 8px 10px !important; } .ranking-table .rank, .prose .ranking-table .rank, .ranking-table th.rank { position: sticky !important; left: 0 !important; width: 2.4rem; min-width: 2.4rem; } .ranking-table .model-cell, .prose .ranking-table .model-cell, .ranking-table th.model-cell { position: sticky !important; left: 2.4rem !important; min-width: 108px; max-width: 36vw; } .ranking-table .model-cell strong { white-space: nowrap; } .compare-controls, .compare-controls.row, .compare-controls .form { flex-direction: column !important; flex-wrap: nowrap !important; flex: 0 0 auto !important; align-items: stretch !important; align-content: flex-start !important; height: auto !important; min-height: 0 !important; gap: 10px !important; margin-bottom: 12px !important; } .compare-controls .compare-models, .compare-controls .compare-prompt-count, .compare-controls .compare-shuffle, .compare-controls .form > div { flex: 0 0 auto !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; height: auto !important; min-height: 0 !important; align-self: stretch !important; } .compare-controls .compare-prompt-count { max-width: 100% !important; } .compare-controls .compare-models .wrap, .compare-controls .compare-models .wrap-inner { height: auto !important; min-height: 40px !important; } .compare-controls .compare-shuffle, .compare-controls .compare-shuffle button { width: 100% !important; align-self: stretch !important; margin-top: 0 !important; } .compare-row { grid-template-columns: 1fr !important; } .compare-prompt-meta { flex-wrap: wrap; } .pareto-layout, .pareto-layout.row, .pareto-layout .form { flex-direction: column !important; } .pareto-layout > .pareto-col, .pareto-layout > div, .pareto-layout .form > div { flex: 1 1 auto !important; width: 100% !important; } } /* —— Workspace filters (dataset / metric / models) —— */ .workspace-filters, .workspace-filters.block, .workspace-filters.column, .workspace-filters.gap { margin: 0 0 12px; padding: 0 !important; gap: 12px !important; overflow: visible !important; } .view-filters { display: flex !important; flex-wrap: wrap !important; align-items: end !important; gap: 12px !important; margin: 0; overflow: visible !important; } .view-filters > div, .view-filters > .block, .view-filters > .form { flex: 1 1 0 !important; min-width: 0 !important; } .view-filters > .block, .view-filters .form, .view-filters .block { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; overflow: visible !important; --block-border-width: 0 !important; } .view-filters label { display: block !important; margin: 0 !important; padding: 0 0 8px !important; color: var(--pruna-text-muted) !important; font-size: 0.8rem !important; font-weight: 500 !important; line-height: 1.2 !important; } .view-filters .wrap { min-width: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; overflow: visible !important; } .view-filters .wrap-inner { display: flex !important; flex-wrap: nowrap !important; align-items: center !important; gap: 6px !important; min-height: 40px !important; height: 40px !important; padding: 0 10px !important; border: 1px solid var(--pruna-input-border) !important; border-radius: 10px !important; background: var(--pruna-input-bg) !important; box-shadow: none !important; overflow: hidden !important; } .view-filters .secondary-wrap { display: flex !important; flex-wrap: nowrap !important; align-items: center !important; flex: 1 1 auto !important; min-width: 0 !important; height: 40px !important; margin: 0 !important; padding: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; overflow: visible !important; } .view-filters .filter-chips .wrap-inner { overflow-x: auto !important; overflow-y: hidden !important; overscroll-behavior-x: contain; scrollbar-width: thin; scrollbar-color: var(--pruna-border) transparent; } .view-filters .filter-chips .secondary-wrap { min-width: 2.5rem !important; } .view-filters .filter-chips .wrap-inner::-webkit-scrollbar { height: 6px; } .view-filters .filter-chips .wrap-inner::-webkit-scrollbar-thumb { background: var(--pruna-border); border-radius: 99px; } .view-filters .filter-chips .token { flex: 0 0 auto !important; white-space: nowrap !important; word-break: keep-all !important; } .view-filters .filter-chips .token span { white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; max-width: 14rem; } .view-filters .token:empty { display: none !important; } .view-filters input { border: none !important; background: transparent !important; box-shadow: none !important; min-height: 28px !important; height: 28px !important; width: 100% !important; min-width: 0 !important; padding: 0 4px !important; line-height: 28px !important; } .view-filters .dropdown-arrow, .view-filters .icon-wrap { flex: 0 0 auto !important; align-self: center !important; margin-left: auto !important; } .view-title, .view-title.block, .view-title .padded { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 0 8px !important; } .view-title h1, .view-title .prose h1, .gradio-container .view-title h1 { margin: 0.35rem 0 0.4rem !important; font-size: 1.45rem !important; } .filter-help-host, .filter-help-host.block, .filter-help-host .padded, .filter-help-host .html-container, .filter-help-host .prose { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; } .view-help-host, .view-help-host.block, .view-help-host .padded, .view-help-host .html-container, .view-help-host .prose { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 0 10px !important; } .filter-help, .prose .filter-help, .view-help, .prose .view-help { margin: 0 !important; color: var(--pruna-text-muted) !important; font-size: 0.95rem !important; line-height: 1.45 !important; font-weight: 400 !important; } .view-filters span[data-testid="block-info"], .view-filters .info, .view-filters .block-info { color: var(--pruna-text-muted) !important; font-size: 0.75rem !important; line-height: 1.35 !important; margin-top: 4px !important; } .compare-prompt-block { border: 1px solid var(--pruna-border) !important; border-radius: 16px !important; background: var(--pruna-card-bg) !important; box-shadow: var(--pruna-card-shadow) !important; } /* Page footer — flat community strip + quiet citation accordion */ .page-footer-host, .page-footer-host .html-container, .page-footer-host .prose, .page-footer-host.block, .page-footer-host .padded { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: none !important; overflow: visible !important; } .page-footer { margin: 32px 0 16px; padding: 20px 0 0; border-top: 1px solid var(--pruna-hairline); } .page-footer h3 { margin: 0 0 10px !important; font-size: 1.05rem !important; font-weight: 600 !important; letter-spacing: -0.015em !important; text-transform: none !important; color: var(--pruna-text-primary) !important; } .community-footer-links { display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: center; } .community-footer-links a { color: var(--pruna-text-muted) !important; text-decoration: none !important; font-size: 0.9rem !important; font-weight: 500 !important; } .community-footer-links a:hover { color: var(--pruna-link) !important; } /* Citation accordion — full-width control, not a section heading */ .citation-accordion { margin: 0 0 28px !important; } .citation-accordion, .citation-accordion.block { border: 1px solid var(--pruna-accordion-border) !important; border-radius: 10px !important; background: var(--pruna-accordion-bg) !important; box-shadow: none !important; overflow: hidden !important; } .citation-accordion > .label-wrap, .citation-accordion .label-wrap { border: none !important; background: transparent !important; box-shadow: none !important; padding: 11px 14px !important; font-size: 0.92rem !important; font-weight: 500 !important; color: var(--pruna-text-primary) !important; letter-spacing: -0.01em !important; } .citation-accordion > .label-wrap:hover, .citation-accordion .label-wrap:hover { background: var(--pruna-menu-hover-bg) !important; } .citation-accordion > .label-wrap span, .citation-accordion .label-wrap span { color: var(--pruna-text-primary) !important; font-size: 0.92rem !important; font-weight: 500 !important; } .citation-accordion .icon, .citation-accordion .label-wrap .icon { color: var(--pruna-text-muted) !important; opacity: 0.9; } .citation-accordion .prose, .citation-accordion .markdown, .citation-accordion pre, .citation-accordion code { color: var(--pruna-text-muted) !important; background: transparent !important; border: none !important; box-shadow: none !important; } .citation-accordion .wrap, .citation-accordion > .wrap { border-top: 1px solid var(--pruna-hairline) !important; padding: 4px 14px 12px !important; background: transparent !important; } .citation-accordion pre { margin: 0 !important; padding: 0 !important; font-size: 0.8rem !important; line-height: 1.55 !important; overflow-x: auto; } .pareto-plot, .pareto-plot.block, .pareto-plot .plotly, .pareto-plot .js-plotly-plot, .pareto-plot .plot-container, .pareto-plot .svg-container, .pareto-plot .main-svg { width: 100% !important; max-width: 100% !important; background: transparent !important; border-color: var(--pruna-border) !important; } .pareto-plot .modebar { display: none !important; } .leaderboard-controls { display: flex !important; flex-wrap: wrap !important; align-items: end !important; gap: 10px !important; margin-bottom: 12px; overflow: visible !important; } .leaderboard-controls > div { min-width: 0 !important; } .leaderboard-controls > .block, .leaderboard-controls .form, .leaderboard-controls .block { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; --block-border-width: 0 !important; } .leaderboard-controls label { color: var(--pruna-text-muted) !important; font-size: 0.8rem !important; font-weight: 500 !important; } .leaderboard-controls textarea { min-height: 40px !important; height: 40px !important; padding: 0 12px !important; border: 1px solid var(--pruna-input-border) !important; border-radius: 10px !important; background: var(--pruna-input-bg) !important; box-shadow: none !important; color: var(--pruna-text-primary) !important; font-family: var(--pruna-font) !important; font-size: 0.9rem !important; line-height: 40px !important; resize: none !important; } .leaderboard-controls textarea:focus { border-color: var(--pruna-focus-border) !important; outline: none !important; box-shadow: var(--pruna-focus-ring) !important; } .leaderboard-controls .wrap { min-height: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; overflow: visible !important; } .leaderboard-controls .wrap-inner { display: flex !important; flex-wrap: wrap !important; align-items: center !important; gap: 6px !important; min-height: 40px !important; height: auto !important; padding: 4px 10px !important; border: 1px solid var(--pruna-input-border) !important; border-radius: 10px !important; background: var(--pruna-input-bg) !important; box-shadow: none !important; overflow: visible !important; } .leaderboard-controls .secondary-wrap { display: flex !important; flex-wrap: wrap !important; align-items: center !important; gap: 6px !important; flex: 1 1 auto !important; min-width: 0 !important; min-height: 0 !important; height: auto !important; margin: 0 !important; padding: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; } .leaderboard-controls .token { display: inline-flex !important; align-items: center !important; max-width: 100% !important; margin: 0 !important; } .leaderboard-controls .token:empty { display: none !important; } .leaderboard-controls .dropdown-arrow, .leaderboard-controls .icon-wrap { flex: 0 0 auto !important; align-self: center !important; margin-left: auto !important; } .ranking-table-host, .ranking-table-host .html-container, .ranking-table-host .prose, .ranking-table-host.block, .ranking-table-host .padded, .ranking-table-host.prose { display: grid !important; grid-template-columns: minmax(0, 1fr) !important; border: none !important; outline: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important; overflow: hidden !important; --block-border-width: 0 !important; } .ranking-table-scroll { border: 1px solid var(--pruna-menu-border); border-radius: 12px; background: var(--pruna-menu-bg); box-shadow: none; width: 100%; max-width: 100%; min-width: 0; max-height: min(70vh, 720px); overflow-x: auto; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain; } .ranking-table, .prose .ranking-table { width: 100%; margin: 0 !important; overflow: visible; } .ranking-table table, .prose .ranking-table table { display: table !important; width: max-content !important; min-width: 100% !important; max-width: none !important; margin: 0 !important; border-collapse: separate !important; border-spacing: 0 !important; color: var(--pruna-text-body) !important; font-size: 13px !important; line-height: 1.35 !important; background: transparent !important; border: none !important; outline: none !important; } .ranking-table thead { display: table-header-group !important; } .ranking-table tbody { display: table-row-group !important; } .ranking-table tr { display: table-row !important; } .ranking-table th, .ranking-table td, .prose .ranking-table th, .prose .ranking-table td { display: table-cell !important; vertical-align: middle !important; padding: 11px 14px !important; border: 0 !important; border-bottom: 1px solid var(--pruna-hairline) !important; background: transparent !important; box-shadow: none !important; outline: none !important; } .ranking-table th, .prose .ranking-table th { position: sticky; top: 0; z-index: 3; background: var(--pruna-bg-header) !important; color: var(--pruna-text-muted) !important; font-size: 11px !important; font-weight: 600 !important; letter-spacing: 0.04em; text-align: left; text-transform: uppercase; white-space: nowrap; box-shadow: 0 1px 0 var(--pruna-hairline) !important; } .ranking-table th.sortable-col { cursor: pointer; user-select: none; } .ranking-table th.sortable-col:hover { color: var(--pruna-lavender) !important; } .ranking-table th.sortable-col.sorted-asc::after, .ranking-table th.sortable-col.sorted-desc::after { margin-left: 0.35em; font-size: 0.85em; opacity: 0.85; } .ranking-table th.sortable-col.sorted-asc::after { content: "▲"; } .ranking-table th.sortable-col.sorted-desc::after { content: "▼"; } .ranking-table tbody tr:last-child td { border-bottom: 0 !important; } .ranking-table tbody tr:hover td { background: var(--pruna-table-hover) !important; } .ranking-table tbody tr:hover td, .ranking-table tbody tr:hover .rank, .ranking-table tbody tr:hover .metric-score, .ranking-table tbody tr:hover .text-cell, .ranking-table tbody tr:hover .model-cell strong, .ranking-table tbody tr:hover .model-cell span { color: var(--pruna-table-hover-text) !important; } .ranking-table .rank, .prose .ranking-table .rank { position: sticky; left: 0; z-index: 1; box-sizing: border-box; width: 3.25rem; min-width: 3.25rem; color: var(--pruna-lavender) !important; font-weight: 700 !important; text-align: center; background: var(--pruna-table-sticky) !important; } .ranking-table th.rank, .prose .ranking-table th.rank { top: 0; left: 0; z-index: 5; text-align: center; background: var(--pruna-bg-header) !important; } .ranking-table .model-cell, .prose .ranking-table .model-cell { position: sticky; left: 3.25rem; z-index: 1; min-width: 180px; max-width: 260px; background: var(--pruna-table-sticky) !important; } .ranking-table th.model-cell, .prose .ranking-table th.model-cell { top: 0; left: 3.25rem; z-index: 5; background: var(--pruna-bg-header) !important; } .ranking-table tbody tr:hover .rank, .ranking-table tbody tr:hover .model-cell { background: var(--pruna-table-sticky-hover) !important; } .ranking-table .model-cell strong, .ranking-table .model-cell span { display: block; } .ranking-table .model-cell strong { color: var(--pruna-text-primary) !important; font-weight: 600 !important; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .ranking-table .model-cell span { margin-top: 3px; color: var(--pruna-text-muted) !important; font-size: 12px; } .ranking-table .text-cell, .prose .ranking-table .text-cell { color: var(--pruna-text-muted) !important; font-weight: 500 !important; white-space: nowrap; } .ranking-table .metric-score, .prose .ranking-table .metric-score { color: var(--pruna-text-primary) !important; font-variant-numeric: tabular-nums; font-weight: 600 !important; text-align: right; white-space: nowrap; } .ranking-table th.metric-score { text-align: right; } .ranking-table .empty-state { color: var(--pruna-text-muted); padding: 32px; text-align: center; } .compare-samples-help { color: var(--pruna-text-body); margin-bottom: 8px; } .compare-controls, .compare-controls.row, .compare-controls.column, .compare-controls .form { display: flex !important; flex-direction: column !important; flex-wrap: nowrap !important; align-items: stretch !important; align-content: flex-start !important; justify-content: flex-start !important; gap: 12px !important; width: 100% !important; max-width: 100% !important; flex-grow: 0 !important; height: auto !important; min-height: 0 !important; margin-bottom: 16px; } .compare-controls > .block, .compare-controls .form, .compare-controls .block, .compare-controls .compare-models, .compare-controls .compare-prompt-count { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; --block-border-width: 0 !important; height: auto !important; min-height: 0 !important; } .compare-controls label, .compare-controls span[data-testid="block-info"] { display: block !important; margin: 0 0 6px !important; padding: 0 !important; color: var(--pruna-text-muted) !important; font-size: 0.8rem !important; font-weight: 500 !important; line-height: 1.2 !important; } .compare-controls .compare-models span[data-testid="block-info"] { min-height: 1.15rem; } .compare-controls .compare-models { flex: 0 0 auto !important; width: 100% !important; min-width: 0 !important; max-width: 100% !important; align-self: stretch !important; } .compare-controls .compare-prompt-count { flex: 0 0 auto !important; width: 100% !important; min-width: 0 !important; max-width: 100% !important; align-self: stretch !important; } .compare-controls .compare-shuffle { flex: 0 0 auto !important; width: 100% !important; max-width: 100% !important; align-self: stretch !important; } .compare-controls .compare-models .wrap, .compare-controls .compare-models .wrap-inner { min-height: 40px !important; height: auto !important; overflow: hidden !important; border: 1px solid var(--pruna-input-border) !important; border-radius: 10px !important; background: var(--pruna-input-bg) !important; box-shadow: none !important; } .compare-controls .compare-models .wrap-inner { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; gap: 6px !important; width: 100% !important; padding: 4px 8px !important; } .compare-controls .compare-models .secondary-wrap { display: flex !important; flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; gap: 6px !important; flex: 1 1 auto !important; width: auto !important; min-width: 0 !important; height: auto !important; margin: 0 !important; padding: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; } .compare-controls .compare-models .token { display: inline-flex !important; align-items: center !important; justify-content: center !important; width: auto !important; max-width: 100% !important; margin: 0 !important; white-space: nowrap !important; } .compare-controls .compare-models .token:empty { display: none !important; } .compare-controls .compare-models input { width: auto !important; min-width: 2.5rem !important; flex: 1 1 5rem !important; height: 28px !important; min-height: 28px !important; } .compare-controls .compare-models .dropdown-arrow, .compare-controls .compare-models .icon-wrap { flex: 0 0 auto !important; align-self: center !important; margin-left: auto !important; } .compare-controls .compare-prompt-count .wrap { display: grid !important; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 40px; gap: 6px 10px; align-items: center; width: 100%; min-height: 0 !important; height: auto !important; margin: 0 !important; padding: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; } .compare-controls .compare-prompt-count .head { display: contents; margin: 0 !important; } .compare-controls .compare-prompt-count .head label { grid-column: 1 / -1; grid-row: 1; } .compare-controls .compare-prompt-count .tab-like-container { grid-column: 2; grid-row: 2; height: 40px !important; min-height: 40px !important; align-self: stretch; border: 1px solid var(--pruna-input-border) !important; border-radius: 10px !important; background: var(--pruna-input-bg) !important; overflow: hidden; } .compare-controls .compare-prompt-count .slider_input_container { grid-column: 1; grid-row: 2; height: 40px !important; min-height: 40px !important; margin: 0 !important; gap: 0 !important; } .compare-controls .compare-prompt-count .min_value, .compare-controls .compare-prompt-count .max_value { display: none !important; } .compare-controls .compare-prompt-count input[type="range"] { height: 40px !important; min-width: 0 !important; margin: 0 !important; padding: 0 !important; background: transparent !important; border: none !important; box-shadow: none !important; } .compare-controls .compare-prompt-count input[type="number"] { height: 40px !important; min-height: 40px !important; min-width: 2.5rem !important; margin: 0 !important; padding: 0 8px !important; line-height: 40px !important; border: none !important; background: transparent !important; box-shadow: none !important; } .compare-controls .compare-shuffle.block:not(button) { width: 100% !important; max-width: 100% !important; align-self: stretch !important; background: transparent !important; border: none !important; box-shadow: none !important; padding: 0 !important; } .compare-controls button.compare-shuffle, .compare-controls .compare-shuffle button, .compare-controls .compare-shuffle button.primary, .compare-controls .compare-shuffle button.secondary { display: inline-flex !important; justify-content: center !important; align-items: center !important; width: 100% !important; min-width: 0 !important; height: 44px !important; min-height: 44px !important; margin: 0 !important; padding: 0 16px !important; border-radius: 10px !important; align-self: stretch !important; appearance: none !important; -webkit-appearance: none !important; -webkit-tap-highlight-color: transparent !important; background: var(--pruna-accent) !important; border: 1px solid color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important; color: #fff !important; font-family: var(--pruna-font) !important; font-size: 0.95rem !important; font-weight: 600 !important; letter-spacing: -0.01em !important; box-shadow: inset 0 1px #fff3 !important; outline: none !important; } .compare-controls button.compare-shuffle:hover, .compare-controls button.compare-shuffle:active, .compare-controls button.compare-shuffle:focus, .compare-controls button.compare-shuffle:focus-visible, .compare-controls .compare-shuffle button:hover, .compare-controls .compare-shuffle button:active, .compare-controls .compare-shuffle button:focus, .compare-controls .compare-shuffle button:focus-visible { background: var(--pruna-accent) !important; border-color: color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important; color: #fff !important; outline: none !important; box-shadow: inset 0 1px #fff3 !important; -webkit-tap-highlight-color: transparent !important; } @media (min-width: 701px) { .compare-controls, .compare-controls.row, .compare-controls.column, .compare-controls .form { flex-direction: row !important; flex-wrap: nowrap !important; align-items: flex-end !important; } .compare-controls .compare-models { flex: 4 1 0 !important; width: auto !important; max-width: none !important; align-self: flex-end !important; } .compare-controls .compare-prompt-count { flex: 1 1 200px !important; width: auto !important; min-width: 180px !important; max-width: 280px !important; align-self: flex-end !important; } .compare-controls .compare-shuffle, .compare-controls .compare-shuffle.block:not(button) { flex: 0 0 auto !important; width: auto !important; max-width: none !important; align-self: flex-end !important; } .compare-controls button.compare-shuffle, .compare-controls .compare-shuffle button { width: auto !important; min-width: 10.5rem !important; } } .compare-prompt-block { margin: 0 0 22px; padding: 14px 16px; background: var(--pruna-callout-bg) !important; } .compare-prompt-meta { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 8px; color: var(--pruna-text-muted); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; } .compare-prompt-text { margin: 0 0 14px; color: var(--pruna-text-body); font-size: 15px; line-height: 1.45; } .compare-gallery, .compare-gallery.block, .compare-gallery .html-container, .compare-gallery .prose { width: 100% !important; max-width: 100% !important; min-width: 0 !important; overflow-x: hidden !important; border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 !important; } .compare-row { display: grid; gap: 12px; min-width: 0; width: 100%; } .compare-prompt-text { overflow-wrap: anywhere; } .pareto-layout, .pareto-layout.row, .pareto-layout .form { display: flex !important; flex-wrap: wrap !important; align-items: stretch !important; gap: 16px !important; width: 100% !important; max-width: 100% !important; } .pareto-layout > .pareto-col, .pareto-layout .form > .pareto-col { flex: 1 1 360px !important; min-width: 0 !important; max-width: 100% !important; } .compare-cell { min-width: 0; } .compare-model-label { margin-bottom: 6px; color: var(--pruna-lavender); font-size: 13px; font-weight: 700; word-break: break-word; } .compare-cell img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 12px; border: 1px solid var(--pruna-border); background: var(--pruna-bg-elevated); } .compare-empty, .pareto-note-copy { margin: 0; padding: 14px 16px; background: var(--pruna-callout-bg, var(--pruna-bg-card)); border: 1px dashed color-mix(in oklab, var(--pruna-border) 70%, transparent); border-radius: 10px; color: var(--pruna-text-muted); font-size: 0.95rem; line-height: 1.5; text-align: left; } /* Type scale (playground-like): product title > page h1 > section h2/h3 > meta labels > body Uppercase lavender is reserved for meta labels only — not section titles. */ .app-header-brand h1, .prose .app-header-brand h1, .gradio-container .app-header-brand h1, .app-header .app-header-brand h1 { display: block !important; width: max-content !important; max-width: none !important; flex: 0 0 auto !important; margin: 0 !important; padding: 0 !important; text-align: center !important; font-size: clamp(1.9rem, 3vw, 2.4rem) !important; font-weight: 700 !important; letter-spacing: -0.035em; line-height: 1 !important; color: var(--pruna-text-primary) !important; } .app-header-tagline, .prose .app-header-tagline, .gradio-container .app-header-tagline, .prose p.app-header-tagline { display: block !important; width: 100% !important; margin: 8px 0 0 !important; padding: 0 !important; text-align: center !important; color: var(--pruna-text-muted) !important; font-size: 0.95rem !important; line-height: 1.45 !important; font-weight: 400 !important; } .gradio-container h1, .markdown h1, .md h1, .prose h1 { margin: 0 0 0.65rem !important; padding: 0 !important; color: var(--pruna-text-primary) !important; font-family: var(--pruna-font) !important; font-size: 1.5rem !important; font-weight: 700 !important; letter-spacing: -0.03em !important; line-height: 1.2 !important; text-transform: none !important; } .gradio-container h2, .markdown h2, .md h2, .prose h2 { margin: 1.75rem 0 0.75rem !important; padding: 0 !important; color: var(--pruna-text-primary) !important; font-family: var(--pruna-font) !important; font-size: 1.25rem !important; font-weight: 600 !important; letter-spacing: -0.02em !important; line-height: 1.3 !important; text-transform: none !important; } .gradio-container h3, .markdown h3, .md h3, .prose h3 { margin: 1.35rem 0 0.5rem !important; padding: 0 !important; color: var(--pruna-text-primary) !important; font-family: var(--pruna-font) !important; font-size: 1.05rem !important; font-weight: 600 !important; letter-spacing: -0.015em !important; line-height: 1.35 !important; text-transform: none !important; } .gradio-container h4, .markdown h4, .md h4, .prose h4 { margin: 1rem 0 0.4rem !important; padding: 0 !important; color: var(--pruna-text-body) !important; font-family: var(--pruna-font) !important; font-size: 0.95rem !important; font-weight: 600 !important; letter-spacing: -0.01em !important; line-height: 1.35 !important; text-transform: none !important; } .markdown, .md, .prose, .gradio-container .markdown, .gradio-container .prose { overflow-wrap: break-word; max-width: 100%; } .markdown p, .md p, .prose p, .gradio-container .markdown p { margin: 0 0 0.8rem !important; color: var(--pruna-text-body) !important; font-size: 0.95rem !important; font-weight: 400 !important; line-height: 1.55 !important; } .markdown li, .md li, .prose li { color: var(--pruna-text-body) !important; font-size: 0.95rem; line-height: 1.5; } .markdown strong, .md strong, .prose strong { color: var(--pruna-text-primary) !important; font-weight: 600 !important; } label, .block-label span { color: var(--pruna-text-muted) !important; font-size: 0.8rem !important; font-weight: 500 !important; } a { color: var(--pruna-link); } /* Gradio form chrome → playground */ button.primary, .gr-button-primary, .primary-button, button.primary:hover, button.primary:active, button.primary:focus, .gr-button-primary:hover, .gr-button-primary:active { background: var(--pruna-accent) !important; border: 1px solid color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important; color: #fff !important; border-radius: 8px !important; box-shadow: inset 0 1px #fff3 !important; font-weight: 600 !important; outline: none !important; -webkit-tap-highlight-color: transparent !important; } button.secondary:active, button.secondary:focus, .gr-button-secondary:active { outline: none !important; -webkit-tap-highlight-color: transparent !important; } .block, .gr-group, .form, .panel { border-color: var(--pruna-border) !important; background: transparent !important; } input, textarea, select { background: var(--pruna-bg-card) !important; border-color: var(--pruna-border) !important; color: var(--pruna-text-primary) !important; border-radius: 10px !important; } .view-filters input, .leaderboard-controls .wrap-inner input { background: transparent !important; border: none !important; box-shadow: none !important; min-height: 28px !important; height: 28px !important; padding: 0 4px !important; line-height: 28px !important; } .view-filters .wrap-inner:focus-within, .leaderboard-controls .wrap-inner:focus-within { border-color: var(--pruna-focus-border) !important; box-shadow: var(--pruna-focus-ring) !important; } footer, .footer { display: none !important; } .pareto-note, .pareto-note.block, .pareto-note .html-container, .pareto-note .prose { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 0 12px !important; } .pareto-metric-block { padding-bottom: 0.5rem; border-bottom: 1px solid var(--pruna-hairline); } .pareto-metric-block:last-child { border-bottom: none; } .pareto-metric-title { margin: 0 0 0.75rem; color: var(--pruna-text-primary); font-size: 1.05rem; font-weight: 600; } .pareto-subhead, .pareto-subhead.block, .pareto-subhead .prose, .pareto-subhead .html-container { border: none !important; background: transparent !important; box-shadow: none !important; padding: 0 !important; margin: 0 0 0.4rem !important; color: var(--pruna-text-muted); } .pareto-subhead h4, .pareto-subhead .prose h4 { margin: 0 !important; color: var(--pruna-text-muted) !important; font-size: 0.95rem !important; font-weight: 600 !important; } .options, ul.options { position: absolute !important; top: calc(100% + 4px) !important; bottom: auto !important; left: 0 !important; right: auto !important; width: 100% !important; max-height: min(280px, 60vh) !important; background: var(--pruna-bg-card) !important; color: var(--pruna-text-primary) !important; border: 1px solid var(--pruna-border) !important; border-radius: 10px !important; overflow: auto !important; z-index: 50 !important; } .options .item:first-child, .options li:first-child { border-top-left-radius: 10px !important; border-top-right-radius: 10px !important; } .options .item:last-child, .options li:last-child { border-bottom-left-radius: 10px !important; border-bottom-right-radius: 10px !important; } .dropdown-arrow-inner { background: var(--pruna-bg-card) !important; color: var(--pruna-text-primary) !important; border-color: var(--pruna-border) !important; } .options .item, .options li { color: var(--pruna-text-primary) !important; } .options .item:hover, .options li:hover, .options .item.selected { background: var(--pruna-dropdown-hover) !important; color: var(--pruna-text-primary) !important; } input[type="range"] { accent-color: var(--pruna-accent); } """ theme = gr.themes.Base( primary_hue=gr.themes.Color( c50="#faf5ff", c100="#f3e8ff", c200="#e9d5ff", c300="#d8b4fe", c400="#c084fc", c500="#9334e9", c600="#9334e9", c700="#7e22ce", c800="#6b21a8", c900="#3b0764", c950="#120b1b", ), secondary_hue="zinc", neutral_hue="zinc", font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"], font_mono=[gr.themes.GoogleFont("IBM Plex Mono"), "ui-monospace", "monospace"], ).set( body_background_fill="#f6f3fa", body_background_fill_dark="#120b1b", body_text_color="#18181b", body_text_color_dark="#fafafa", body_text_color_subdued="#71717a", body_text_color_subdued_dark="#a3a3a3", background_fill_primary="#f6f3fa", background_fill_primary_dark="#120b1b", background_fill_secondary="#ffffff", background_fill_secondary_dark="#171021", block_background_fill="#ffffff", block_background_fill_dark="#1d1429", block_border_color="#e4d7f2", block_border_color_dark="#4a3962bf", block_label_text_color="#71717a", block_label_text_color_dark="#a3a3a3", block_title_text_color="#18181b", block_title_text_color_dark="#fafafa", border_color_primary="#e4d7f2", border_color_primary_dark="#4a3962bf", button_primary_background_fill="#9334e9", button_primary_background_fill_dark="#9334e9", button_primary_background_fill_hover="#7c22ce", button_primary_background_fill_hover_dark="#8f35ff", button_primary_text_color="#ffffff", button_primary_text_color_dark="#ffffff", button_secondary_background_fill="#ffffff", button_secondary_background_fill_dark="#ffffff05", button_secondary_background_fill_hover="#f3e8ff", button_secondary_background_fill_hover_dark="rgba(147, 52, 233, 0.10)", button_secondary_text_color="#18181b", button_secondary_text_color_dark="#fafafa", button_secondary_border_color="#e4d7f2", button_secondary_border_color_dark="#d8b4fe26", input_background_fill="#ffffff", input_background_fill_dark="#171021", input_border_color="#e4d7f2", input_border_color_dark="#4a3962bf", input_placeholder_color="#71717a", input_placeholder_color_dark="#a3a3a3", link_text_color="#6d28d9", link_text_color_dark="#bf8bff", link_text_color_hover="#7c22ce", link_text_color_hover_dark="#d2a8ff", shadow_drop="none", shadow_drop_lg="none", ) space_root = Path(__file__).resolve().parent data_dir = space_root / "data" def _resolve_data_path(*candidates): """Prefer Space-local data/, fall back to monorepo parent for local edits.""" for path in candidates: if path.exists(): return path return candidates[0] oneig_path = _resolve_data_path( data_dir / "oneig_model_price_and_median_generation_time.csv", space_root.parent / "oneig_model_price_and_median_generation_time.csv", ) def load_sample_comparison_data(folder): """Load prompts + generations for the Compare samples tab.""" folder = Path(folder) prompts_path = folder / "prompts.jsonl" generations_path = folder / "generations.jsonl" if not prompts_path.exists() or not generations_path.exists(): return None prompts = {} with prompts_path.open() as handle: for line in handle: if not line.strip(): continue row = json.loads(line) prompts[row["prompt_id"]] = row.get("text", "") images = defaultdict(dict) with generations_path.open() as handle: for line in handle: if not line.strip(): continue row = json.loads(line) model_id = row["model_id"] prompt_id = row["prompt_id"] image_url = row.get("image") if model_id and prompt_id and image_url: images[model_id][prompt_id] = image_url models = sorted(images) if not models or not prompts: return None return { "prompts": prompts, "images": {model: dict(prompt_map) for model, prompt_map in images.items()}, "models": models, "prompt_ids": sorted(prompts), } def _as_numeric(df, columns): for column in columns: if column in df.columns: df[column] = pd.to_numeric(df[column], errors="coerce") return df def load_oneig_dataframe(path): df = pd.read_csv(path, na_values=["N/A", "n/a", ""]) df = df.rename( columns={ "Owner": "Endpoint Owner", "Anime Alignment Score": "OneIG (Anime Alignment)", "Human Alignment Score": "OneIG (Human Alignment)", "Object Alignment Score": "OneIG (Object Alignment)", "OneIG (Anime and Stylization) (Alignment Score)": "OneIG (Anime Alignment)", "OneIG (Portrait) (Alignment Score)": "OneIG (Human Alignment)", "OneIG (General Object) (Alignment Score)": "OneIG (Object Alignment)", } ) df = df.drop( columns=[ column for column in ("URL", "Device", "Optimization", "Optimization Details") if column in df.columns ] ) if "Optimized" in df.columns: df["Optimized"] = df["Optimized"].map( {True: "Yes", False: "No", "TRUE": "Yes", "FALSE": "No"} ).fillna(df["Optimized"]) return _as_numeric( df, [ "Price / Image (USD)", "Median Generation Time (s)", "Min Generation Time (s)", "OneIG (Anime Alignment)", "OneIG (Human Alignment)", "OneIG (Object Alignment)", "OneIG Anime Elo", "OneIG Human Elo", "OneIG Object Elo", "P-Judge Overall", "Rapidata Elo", ], ) def load_artificial_analysis_dataframe(path): """Load the Artificial Analysis text-to-image leaderboard.""" df = pd.read_csv(path, na_values=["N/A", "n/a", ""]) df = df.rename( columns={ "model": "Model", "elo": "Artificial Analysis Elo", "price_per_image_usd": "Price / Image (USD)", } ) df["Model"] = df["Model"].astype(str).str.strip() return _as_numeric( df, ["Artificial Analysis Elo", "Price / Image (USD)"] ).reset_index(drop=True) ARENA_CATEGORY_COLUMNS = { "product_branding_commercial_design_elo": "Arena Branding / Commercial Elo", "3d_imaging_and_modeling_elo": "Arena 3D Imaging Elo", "cartoon_anime_and_fantasy_elo": "Arena Cartoon / Anime Elo", "photorealistic_and_cinematic_imagery_elo": "Arena Photorealistic Elo", "art_elo": "Arena Art Elo", "portraits_elo": "Arena Portraits Elo", "text_rendering_elo": "Arena Text Rendering Elo", } def load_arena_ai_dataframe(path): """Load the Arena AI text-to-image leaderboard (overall + category Elos).""" df = pd.read_csv(path, na_values=["N/A", "n/a", ""]) rename_map = {"model": "Model", "elo": "Arena Elo"} rename_map.update( { source: label for source, label in ARENA_CATEGORY_COLUMNS.items() if source in df.columns } ) df = df.rename(columns=rename_map) df["Model"] = df["Model"].astype(str).str.strip() score_columns = [ column for column in ["Arena Elo", *ARENA_CATEGORY_COLUMNS.values()] if column in df.columns ] df = _as_numeric(df, score_columns) ordered = ["Model", *score_columns] return df[[column for column in ordered if column in df.columns]].reset_index( drop=True ) def load_qwen_combined_dataframe(path): """Load the combined Qwen Image Bench metrics table.""" df = pd.read_csv(path, na_values=["N/A", "n/a", ""]) model_column = "Rapidata Model" if "Rapidata Model" in df.columns else "Model" df = df.rename(columns={model_column: "Model"}) # Rows prefixed with '#' are commented-out variants in the source exports. df = df[~df["Model"].astype(str).str.startswith("#")].copy() df["Model"] = df["Model"].astype(str).str.strip() return _as_numeric( df, [ "Price / Image (USD)", "Median Generation Time (s)", "Min Generation Time (s)", "P-Judge Overall", "Rapidata Elo", "Datapoint Elo", ], ).reset_index(drop=True) df = load_oneig_dataframe(oneig_path) oneig_metric_columns = [ col for col in [ "OneIG (Anime Alignment)", "OneIG (Human Alignment)", "OneIG (Object Alignment)", ] if col in df.columns ] oneig_df = df.copy() if oneig_metric_columns: oneig_df["OneIG Overall Score"] = oneig_df[oneig_metric_columns].mean( axis=1, skipna=True ) oneig_display_columns = [ col for col in [ "Platform", "Endpoint Owner", "Model", "Optimized", "OneIG Overall Score", *oneig_metric_columns, "OneIG Anime Elo", "OneIG Human Elo", "OneIG Object Elo", "P-Judge Overall", "Rapidata Elo", "Evaluation Date (UTC)", "Median Generation Time (s)", "Min Generation Time (s)", "Price / Image (USD)", ] if col in oneig_df.columns ] oneig_combined_dir = _resolve_data_path( data_dir / "oneig_combined", space_root.parent / "oneig_combined", ) qwen_combined_dir = _resolve_data_path( data_dir / "qwen_image_bench_combined", space_root.parent / "qwen_image_bench_combined", ) qwen_path = _resolve_data_path( data_dir / "qwen_image_bench_model_price_and_median_generation_time.csv", space_root.parent / "qwen_image_bench_model_price_and_median_generation_time.csv", ) aa_path = _resolve_data_path( data_dir / "artificial_analysis_text_to_image_leaderboard.csv", space_root.parent / "artificial_analysis_text_to_image_leaderboard.csv", ) arena_path = _resolve_data_path( data_dir / "arena_ai_text_to_image_leaderboard.csv", space_root.parent / "arena_ai_text_to_image_leaderboard.csv", ) qwen_df = load_qwen_combined_dataframe(qwen_path) aa_df = load_artificial_analysis_dataframe(aa_path) arena_df = load_arena_ai_dataframe(arena_path) qwen_display_columns = [ col for col in [ "Model", "Datapoint Elo", "Rapidata Elo", "P-Judge Overall", "Raw Win Rate", "Median Generation Time (s)", "Min Generation Time (s)", "Price / Image (USD)", ] if col in qwen_df.columns ] aa_display_columns = [ col for col in [ "Model", "Artificial Analysis Elo", "Price / Image (USD)", ] if col in aa_df.columns ] arena_display_columns = [ col for col in [ "Model", "Arena Elo", *ARENA_CATEGORY_COLUMNS.values(), ] if col in arena_df.columns ] oneig_samples = load_sample_comparison_data(oneig_combined_dir) qwen_samples = load_sample_comparison_data(qwen_combined_dir) metrics = [ {"id": "datapoint_elo", "column": "Datapoint Elo"}, {"id": "rapidata_elo", "column": "Rapidata Elo"}, {"id": "pjudger", "column": "P-Judge Overall"}, {"id": "alignment_overall", "column": "OneIG Overall Score"}, {"id": "datapoint_elo_anime", "column": "OneIG Anime Elo"}, {"id": "datapoint_elo_human", "column": "OneIG Human Elo"}, {"id": "datapoint_elo_object", "column": "OneIG Object Elo"}, {"id": "aa_elo", "column": "Artificial Analysis Elo"}, {"id": "arena_elo", "column": "Arena Elo"}, {"id": "arena_branding", "column": "Arena Branding / Commercial Elo"}, {"id": "arena_3d", "column": "Arena 3D Imaging Elo"}, {"id": "arena_cartoon", "column": "Arena Cartoon / Anime Elo"}, {"id": "arena_photo", "column": "Arena Photorealistic Elo"}, {"id": "arena_art", "column": "Arena Art Elo"}, {"id": "arena_portraits", "column": "Arena Portraits Elo"}, {"id": "arena_text", "column": "Arena Text Rendering Elo"}, ] def _metric_ids_for(data, metric_ids): columns = getattr(data, "columns", []) return [ metric_id for metric_id in metric_ids if any(metric["id"] == metric_id and metric["column"] in columns for metric in metrics) ] qwen_metric_ids = _metric_ids_for( qwen_df, ["datapoint_elo", "rapidata_elo", "pjudger"] ) oneig_metric_ids = _metric_ids_for( oneig_df, [ "alignment_overall", "rapidata_elo", "pjudger", "datapoint_elo_anime", "datapoint_elo_human", "datapoint_elo_object", ], ) aa_metric_ids = _metric_ids_for(aa_df, ["aa_elo"]) arena_metric_ids = _metric_ids_for( arena_df, [ "arena_elo", "arena_branding", "arena_3d", "arena_cartoon", "arena_photo", "arena_art", "arena_portraits", "arena_text", ], ) datasets = [ { "id": "qwen", "name": "Qwen Image Dataset", "data": qwen_df, "columns": qwen_display_columns, "metric_ids": qwen_metric_ids, "note": "Rapidata Elo is a metric on this dataset, not a dataset of its own.", "samples": qwen_samples, }, { "id": "oneig", "name": "OneIG Alignment Dataset", "data": oneig_df, "columns": oneig_display_columns, "metric_ids": oneig_metric_ids, "note": ( "Alignment Overall is the mean of the available category scores. " "Missing categories are skipped for that model." ), "samples": oneig_samples, }, { "id": "artificial_analysis", "name": "Artificial Analysis Dataset", "data": aa_df, "columns": aa_display_columns, "metric_ids": aa_metric_ids, "note": "", "samples": None, }, { "id": "arena_ai", "name": "Arena AI Dataset", "data": arena_df, "columns": arena_display_columns, "metric_ids": arena_metric_ids, "note": "", "samples": None, }, ] datasets = [dataset for dataset in datasets if dataset["metric_ids"]] DEFAULT_DATASET_ID = next( (dataset["id"] for dataset in datasets if dataset["id"] == "qwen"), datasets[0]["id"] if datasets else None, ) DEFAULT_METRIC_ID = None custom_head = """ """ with gr.Blocks( title="P-Bench", theme=theme, fill_width=True, css=custom_css, head=custom_head, ) as demo: render_header() render_image_workspace( datasets, metrics, DEFAULT_DATASET_ID, DEFAULT_METRIC_ID, ) render_footer() if __name__ == "__main__": demo.launch( ssr_mode=False, allowed_paths=[str(space_root)], )