PRISM-project-Evaluation-functional-request / benchmark_quality_OpenAI_performance.html
flaviojoshua's picture
Upload 6 files
985cf9c verified
Raw History Blame Contribute Delete
34 kB
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Benchmark AI — Qualità OpenAI vs prestazioni V3</title>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-HMZQ3QVL91"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-HMZQ3QVL91');
</script>
<style>
/* Stili incorporati: la dashboard resta utilizzabile offline e senza build. */
:root { color-scheme:dark; --bg:#070a12; --panel:#101521; --panel2:#151c2b; --line:#2b3447; --muted:#9aa6bd; --text:#f5f7fb; --accent:#fb7185; --cyan:#67e8f9; }
* { box-sizing:border-box; }
body { margin:0; background:radial-gradient(circle at 8% 0%,rgba(251,113,133,.12),transparent 30rem),radial-gradient(circle at 95% 20%,rgba(59,130,246,.10),transparent 34rem),var(--bg); color:var(--text); font:15px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
.page { width:min(1440px,calc(100% - 32px)); margin:auto; padding:42px 0 64px; }
nav { display:flex; flex-wrap:wrap; gap:14px; margin-bottom:22px; }
nav a { color:var(--muted); }
nav a[aria-current="page"] { color:var(--accent); }
header { display:grid; grid-template-columns:1fr auto; gap:24px; align-items:end; margin-bottom:28px; }
.eyebrow { margin:0 0 8px; color:var(--accent); font-size:12px; font-weight:800; letter-spacing:.16em; text-transform:uppercase; }
h1 { max-width:900px; margin:0; font-size:clamp(32px,5vw,64px); line-height:1.02; letter-spacing:-.045em; }
.subtitle { max-width:800px; margin:18px 0 0; color:var(--muted); font-size:17px; }
.snapshot { padding:10px 14px; border:1px solid var(--line); border-radius:999px; background:rgba(16,21,33,.78); color:var(--muted); white-space:nowrap; }
.metrics { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:12px; }
.metric,.card { border:1px solid var(--line); background:rgba(16,21,33,.9); box-shadow:0 20px 60px rgba(0,0,0,.18); }
.metric { padding:17px 20px; border-radius:14px; }
.metric span { display:block; color:var(--muted); font-size:12px; letter-spacing:.08em; text-transform:uppercase; }
.metric strong { display:block; margin-top:4px; font-size:24px; }
.card { border-radius:18px; overflow:hidden; }
.toolbar { display:flex; flex-wrap:wrap; gap:10px; padding:16px 18px; border-bottom:1px solid var(--line); background:rgba(21,28,43,.72); }
label { display:grid; gap:5px; color:var(--muted); font-size:11px; font-weight:700; letter-spacing:.08em; text-transform:uppercase; }
select,button { min-height:38px; border:1px solid #38435a; border-radius:9px; background:#0d121d; color:var(--text); font:inherit; }
select { min-width:160px; padding:0 34px 0 11px; }
button { align-self:end; padding:0 14px; cursor:pointer; }
button:hover,select:focus { border-color:var(--cyan); outline:none; }
.layout { display:grid; grid-template-columns:minmax(0,1fr) 245px; min-height:650px; }
.chart-wrap { min-width:0; padding:16px; }
svg { display:block; width:100%; height:610px; overflow:visible; }
.grid-line { stroke:#222b3b; stroke-width:1; }
.axis-line { stroke:#71809a; stroke-width:1.2; }
.tick-label { fill:#95a2b8; font-size:12px; }
.axis-title { fill:#e7ebf3; font-size:13px; font-weight:700; }
.point { cursor:pointer; stroke:rgba(255,255,255,.88); stroke-width:1.8; transition:filter .18s; }
.point:hover,.point:focus { filter:brightness(1.25) drop-shadow(0 0 8px currentColor); outline:none; }
.point-label { fill:#dce3ef; font-size:11px; font-weight:650; pointer-events:none; paint-order:stroke; stroke:#070a12; stroke-width:3px; stroke-linejoin:round; }
.legend { padding:22px 18px; border-left:1px solid var(--line); background:rgba(10,14,23,.52); }
.legend h2 { margin:0 0 16px; font-size:15px; }
.legend-section { margin-bottom:24px; }
.legend-title { margin:0 0 9px; color:var(--muted); font-size:11px; font-weight:800; letter-spacing:.09em; text-transform:uppercase; }
.legend-row { display:flex; gap:9px; align-items:center; margin:8px 0; color:#d9e0ec; font-size:13px; }
.swatch { width:11px; height:11px; border-radius:50%; flex:none; }
.bubble { display:inline-block; border:1.5px solid #d8e0ed; border-radius:50%; background:rgba(148,163,184,.18); }
.bubble.small { width:10px; height:10px; } .bubble.medium { width:17px; height:17px; } .bubble.large { width:24px; height:24px; }
.quality-stripes { width:18px; height:12px; border-radius:3px; background:repeating-linear-gradient(135deg,transparent 0 4px,#ef4444 4px 6px,transparent 6px 10px); flex:0 0 auto; }
.tooltip { position:fixed; z-index:10; width:min(360px,calc(100vw - 24px)); padding:14px; border:1px solid #47536b; border-radius:12px; background:rgba(7,10,18,.97); box-shadow:0 16px 50px rgba(0,0,0,.45); pointer-events:none; opacity:0; transform:translateY(4px); transition:opacity .12s,transform .12s; }
.tooltip.visible { opacity:1; transform:translateY(0); }
.tooltip strong { display:block; margin-bottom:8px; overflow-wrap:anywhere; }
.tooltip-grid { display:grid; grid-template-columns:auto 1fr; gap:4px 10px; color:var(--muted); font-size:12px; }
.tooltip-grid b { color:#eef2f8; font-weight:650; }
.note { margin-top:14px; padding:18px 20px; color:var(--muted); font-size:13px; }
.note strong { color:var(--text); }
.empty { fill:var(--muted); font-size:15px; text-anchor:middle; }
@media (max-width:900px) { header { grid-template-columns:1fr; } .snapshot { justify-self:start; } .metrics { grid-template-columns:repeat(2,1fr); } .layout { grid-template-columns:1fr; } .legend { border-top:1px solid var(--line); border-left:0; display:grid; grid-template-columns:repeat(2,1fr); gap:0 20px; } }
@media (max-width:560px) { .page { width:calc(100% - 18px); padding-top:24px; } .metrics { grid-template-columns:1fr; } .chart-wrap { overflow-x:auto; } svg { min-width:700px; } .legend { grid-template-columns:1fr; } }
/* Titolo PRISM con spaziatura ampia, come nella presentazione prism_motti_total_time.html */
.prism-mark { display:flex; gap:clamp(14px,3vw,36px); margin:0 0 14px; font-family:Georgia,"Times New Roman",serif; font-size:clamp(2.2rem,5vw,3.6rem); font-weight:400; line-height:1; letter-spacing:.2rem; color:#fff; }
</style>
</head>
<body>
<main class="page">
<nav aria-label="Pagine benchmark">
<a href="benchmark_quality_performance.html">Qualità Self‑Judge</a>
<a href="benchmark_quality_OpenAI_performance.html" aria-current="page">Qualità OpenAI</a>
<a href="benchmark_speed_performance.html">Tempi di conclusione</a>
<a href="benchmark_judges_comparison.html">Self‑Judge vs OpenAI</a>
<a href="prism_motti_total_time.html">Presentazione PRISM</a>
</nav>
<header>
<div>
<div class="prism-mark" aria-label="PRISM"><span>P</span><span>R</span><span>I</span><span>S</span><span>M</span></div>
<p class="eyebrow">Benchmark locale · Giudice terzo OpenAI</p>
<h1>Qualità OpenAI vs prestazioni V3</h1>
<p class="subtitle">Ogni cerchio rappresenta una configurazione. L’asse X mostra il throughput V3; l’asse Y usa esclusivamente l’Asse C ricalcolato dal giudice OpenAI.</p>
</div>
<div class="snapshot">gpt-5.6-sol · snapshot 2026-08-14 14:15 UTC</div>
</header>
<section class="metrics" aria-label="Riepilogo dei dati visibili">
<div class="metric"><span>Configurazioni visibili</span><strong id="model-count">20</strong></div>
<div class="metric"><span>Qualità OpenAI massima</span><strong id="best-quality">99,3%</strong></div>
<div class="metric"><span>Velocità massima</span><strong id="best-speed">57,07 tok/s</strong></div>
<div class="metric"><span>Dataset confrontato</span><strong>V3</strong></div>
</section>
<section class="card" aria-label="Grafico interattivo qualità OpenAI e prestazioni">
<div class="toolbar">
<label>Famiglia<select id="family-filter"><option value="all">Tutte</option></select></label>
<label>Hardware<select id="hardware-filter"><option value="all">Tutti</option></select></label>
<label>Formato<select id="format-filter"><option value="all">Tutti</option></select></label>
<label>Raccolta<select id="collection-filter"><option value="all">Tutte</option></select></label>
<button id="reset-button" type="button">Azzera filtri</button>
</div>
<div class="layout">
<div class="chart-wrap">
<svg id="chart" viewBox="0 0 1050 610" role="img" aria-labelledby="chart-title chart-desc">
<title id="chart-title">Scatter plot qualità OpenAI e prestazioni dei modelli V3</title>
<desc id="chart-desc">Asse X asimmetrico: i valori da 0 a 30 token al secondo occupano quattro quinti dello spazio, mentre quelli da 30 a 130 occupano il quinto restante. Asse Y Asse C OpenAI, dimensione del cerchio parametri e colore famiglia del modello. Le barre diagonali rosse indicano Asse C sotto 60%.</desc>
</svg>
</div>
<aside class="legend" aria-label="Legende del grafico">
<h2>Come leggere il grafico</h2>
<div class="legend-section"><p class="legend-title">Asse X · Prestazioni</p><div class="legend-row">Token generati al secondo</div><div class="legend-row">Scala asimmetrica: 0–30 = 4/5; 30–130 = 1/5</div><div class="legend-row">← più lento · più veloce →</div></div>
<div class="legend-section"><p class="legend-title">Asse Y · Qualità</p><div class="legend-row">Asse C V3, merito (%)</div><div class="legend-row">Sorgente: OpenAI</div><div class="legend-row">Giudice: gpt-5.6-sol</div></div>
<div class="legend-section"><p class="legend-title">Dimensione · Parametri</p><div class="legend-row"><span class="bubble small"></span>3B</div><div class="legend-row"><span class="bubble medium"></span>8–9B</div><div class="legend-row"><span class="bubble large"></span>12–20B</div></div>
<div class="legend-section"><p class="legend-title">Forma · Esecuzione</p><div class="legend-row">● locale</div><div class="legend-row">▲ A100</div><div class="legend-row">+ Inference Provider</div></div>
<div class="legend-section" id="family-legend"><p class="legend-title">Colore · Famiglia</p></div>
<div class="legend-section"><p class="legend-title">Segnalazione qualità</p><div class="legend-row"><span class="quality-stripes"></span> Barre rosse: Asse C &lt; 60%</div></div>
</aside>
</div>
</section>
<section class="card note"><strong>Perimetro del test.</strong> La qualità usa <code>third_party_axis_c_pct</code> dei run V3 valutati da OpenAI nello snapshot del 2026-08-14 14:15 UTC, compresi GPT‑OSS standard su 2GPU, A100 e Together. Come nella dashboard Self‑Judge, le configurazioni con qualità nulla non sono disegnate e non entrano nelle metriche visibili. Il record V2 con <code>MODEL_ID=NA</code> è escluso. Per <code>gpt-5.6-sol</code> candidato e giudice coincidono: il 99,26% è quindi un auto-giudizio, non una valutazione indipendente.</section>
<section class="card note" aria-label="Inference Provider valutati dal giudice OpenAI">
<strong>Inference Provider: valutazione OpenAI completata.</strong> Together <code>openai/gpt-oss-20b</code>: 113,05 tok/s, Asse C Auto-Judge 43,0%, giudice OpenAI <strong>43,33%</strong>. Together <code>openai/gpt-oss-120b</code>: 120,49 tok/s, Asse C Auto-Judge 95,9%, giudice OpenAI <strong>94,26%</strong>.
</section>
</main>
<div class="tooltip" id="tooltip" role="status" aria-live="polite"></div>
<script>
"use strict";
// Snapshot OpenAI associato per run_id alle configurazioni V3 e al relativo throughput.
const BENCHMARKS = [
{model:"meta-llama/Llama-3.2-3B-Instruct",short:"Llama 3.2 3B",family:"Llama",collection:"models_hf_2",mode:"instruct",format:"BF16",hardware:"2GPU:0",sizeB:3,speed:38.96,quality:32.78,run:"77da692740027aac8dc3"},
{model:"Qwen/Qwen3-14B-AWQ",short:"Qwen3 14B AWQ",family:"Qwen",collection:"models_hf_2",mode:"instruct",format:"AWQ Int4",hardware:"2GPU:0",sizeB:14,speed:26.82,quality:73.15,run:"7a1a02410b3d63071292"},
{model:"Qwen/Qwen2.5-14B-Instruct-AWQ",short:"Qwen2.5 AWQ",family:"Qwen",collection:"models_hf_2",mode:"instruct",format:"AWQ Int4",hardware:"2GPU:0",sizeB:14,speed:25.46,quality:36.30,run:"546922b18201607e6991"},
{model:"nvidia/NVIDIA-Nemotron-Nano-9B-v2",short:"Nemotron 9B",family:"Nemotron",collection:"models_hf",mode:"standard",format:"BF16",hardware:"2GPU:0,1",sizeB:9,speed:19.11,quality:66.11,run:"c25fc1db90ecc6da54d1"},
{model:"meta-llama/Llama-3.1-8B-Instruct",short:"Llama 3.1 8B",family:"Llama",collection:"models_hf_2",mode:"instruct",format:"BF16",hardware:"2GPU:0,1",sizeB:8,speed:17.13,quality:24.26,run:"68edee1086277f7cc5aa"},
{model:"cyankiwi/gemma-4-12B-it-AWQ-INT4",short:"Gemma 4 AWQ",family:"Gemma",collection:"models_hf_2",mode:"instruct",format:"AWQ Int4",hardware:"2GPU:0,1",sizeB:12,speed:10.44,quality:63.52,run:"077b752b96eaf5201c87"},
{model:"google/gemma-4-12B-it-qat-w4a16-ct",short:"Gemma 4 QAT",family:"Gemma",collection:"models_hf_2",mode:"instruct",format:"QAT W4A16",hardware:"2GPU:0,1",sizeB:12,speed:10.37,quality:50.74,run:"41726d7f5731ceaca514"},
{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 GPTQ",family:"Qwen",collection:"Qwen",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0",sizeB:14,speed:25.87,quality:48.89,run:"11ffadb7036cc7d0c88f"},
{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 Int8",family:"Qwen",collection:"Qwen",mode:"instruct",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:14,speed:9.35,quality:40.93,run:"3fc9a83cf3562b08069c"},
{model:"mistralai/Ministral-3-8B-Instruct-2512-BF16",short:"Ministral 8B",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BF16",hardware:"2GPU:0,1",sizeB:8,speed:17.88,quality:60.00,run:"270aa0b472398e9b625a"},
{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B GPTQ",family:"Ministral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0",sizeB:14,speed:27.36,quality:75.74,run:"42938dc5461e556b43db"},
{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B Int8",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:14,speed:9.68,quality:80.00,run:"f94715ad2746dbce0111"},
{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek BF16 std",family:"DeepSeek",collection:"models_hf",mode:"standard",format:"BF16",hardware:"2GPU:0,1",sizeB:7,speed:11.25,quality:0.00,run:"3c839679c4e8aadf0cc7"},
{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek BF16 inst",family:"DeepSeek",collection:"models_hf",mode:"instruct",format:"BF16",hardware:"2GPU:0,1",sizeB:7,speed:9.77,quality:48.70,run:"9baed2fcd3838025d78c"},
{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek Int8 std",family:"DeepSeek",collection:"models_hf",mode:"standard",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:7,speed:9.69,quality:0.00,run:"ab90429701d17ae8a056"},
{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek Int8 inst",family:"DeepSeek",collection:"models_hf",mode:"instruct",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:7,speed:9.70,quality:0.00,run:"7b7db66a1452d088e27e"},
{model:"openai/gpt-oss-20b",short:"GPT-OSS 20B inst",family:"GPT-OSS",reasoning:"medium",collection:"models_hf",mode:"instruct",format:"MXFP4",hardware:"2GPU:0,1",sizeB:20,speed:27.47,quality:85.74,run:"e2432081b3e89610e190"}
,{model:"openai/gpt-oss-20b",short:"GPT-OSS 20B std 2GPU",family:"GPT-OSS",reasoning:"medium",collection:"models_hf",mode:"standard",format:"MXFP4",hardware:"2GPU:0,1",sizeB:20,speed:27.24,quality:85.93,run:"c112b7f8f1c2ab68d02e"}
,{model:"openai/gpt-oss-20b",short:"GPT-OSS 20B std A100",family:"GPT-OSS",reasoning:"medium",collection:"models_hf",mode:"standard",format:"MXFP4",hardware:"A100:0",sizeB:20,speed:10.58,quality:64.07,run:"8ce1175e2cc57cf7c27d"}
,{model:"mistralai/Ministral-3-8B-Instruct-2512-BF16",short:"Ministral 8B BF16 A100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:8,speed:19.06,quality:68.7,run:"ff2b334016b402df51d4"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B BF16 A100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:14,speed:16.15,quality:50.19,run:"e2136d050547e9ebf498"}
,{model:"mistralai/Mistral-Small-3.2-24B-Instruct-2506",short:"Mistral 24B BF16 A100",family:"Mistral",collection:"Mistral",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:24,speed:18,quality:79.81,run:"b6eba98759dcd0904838"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B GPTQ A100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"A100:0",sizeB:14,speed:7.75,quality:62.04,run:"2e8c4e8d70f57c645716"}
,{model:"mistralai/Mistral-Small-3.2-24B-Instruct-2506",short:"Mistral 24B GPTQ A100",family:"Mistral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"A100:0",sizeB:24,speed:8.09,quality:57.41,run:"60f62742bb1b9b936ee8"}
,{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 14B BF16 A100",family:"Qwen",collection:"Qwen",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:14,speed:14.62,quality:62.59,run:"27ef3859e684ca074a46"}
,{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 14B GPTQ A100",family:"Qwen",collection:"Qwen",mode:"instruct",format:"GPTQ Int4",hardware:"A100:0",sizeB:14,speed:6.81,quality:42.78,run:"6fe7d24e4e5089e45ee8"}
,{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 14B Int8 A100",family:"Qwen",collection:"Qwen",mode:"instruct",format:"BitsAndBytes Int8",hardware:"A100:0",sizeB:14,speed:3.09,quality:45.93,run:"c4433f21159917892ee4"}
,{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek 7B BF16 A100",family:"DeepSeek",collection:"models_hf",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:7,speed:20.85,quality:41.48,run:"8ba80082c0ad4fa71403"}
,{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek 7B Int8 A100",family:"DeepSeek",collection:"models_hf",mode:"instruct",format:"BitsAndBytes Int8",hardware:"A100:0",sizeB:7,speed:5.93,quality:40.74,run:"0206051fb277ad4cdb89"}
,{model:"nvidia/NVIDIA-Nemotron-Nano-9B-v2",short:"Nemotron 9B BF16 A100",family:"Nemotron",collection:"models_hf",mode:"instruct",format:"BF16",hardware:"A100:0",sizeB:9,speed:18.72,quality:69.63,run:"ee8a6a0b4db4499290d8"}
,{model:"mistralai/Ministral-3-8B-Instruct-2512-BF16",short:"Ministral 8B BF16 2GPU",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BF16",hardware:"2GPU:0,1",sizeB:8,speed:18.06,quality:60,run:"878e9fb36f32e1077d50"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B GPTQ 2GPU",family:"Ministral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0",sizeB:14,speed:28.79,quality:75.74,run:"eeb1a40117fe0e5cde84"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B Int8 2GPU",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:14,speed:9.71,quality:79.26,run:"1ce437d15d8e6131a94b"}
,{model:"mistralai/Mistral-Small-3.2-24B-Instruct-2506",short:"Mistral 24B GPTQ 2GPU",family:"Mistral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0,1",sizeB:24,speed:17.7,quality:45.74,run:"f801bc653cca40e37144"}
,{model:"mistralai/Ministral-3-8B-Instruct-2512-BF16",short:"Ministral 8B GPTQ 2GPU",family:"Ministral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0",sizeB:8,speed:41.79,quality:51.48,run:"af6fdbe8728a394611d9"}
,{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 14B GPTQ 2GPU",family:"Qwen",collection:"Qwen",mode:"instruct",format:"GPTQ Int4",hardware:"2GPU:0",sizeB:14,speed:26.34,quality:50.37,run:"0108f1a07e6d3482384b"}
,{model:"Qwen/Qwen2.5-14B-Instruct",short:"Qwen2.5 14B Int8 2GPU",family:"Qwen",collection:"Qwen",mode:"instruct",format:"BitsAndBytes Int8",hardware:"2GPU:0,1",sizeB:14,speed:9.24,quality:40.93,run:"426acf61aa73abd3ca0d"}
,{model:"openai/gpt-oss-20b",short:"+ GPT-OSS 20B Together",family:"GPT-OSS",reasoning:"low",collection:"Inference Provider",mode:"instruct",format:"Inference Provider",hardware:"Together",sizeB:20,speed:113.05,quality:43.33,execution:"inference_provider",run:"799e04c2fbfc4eb6c363"}
,{model:"openai/gpt-oss-120b",short:"+ GPT-OSS 120B Together",family:"GPT-OSS",reasoning:"low",collection:"Inference Provider",mode:"instruct",format:"Inference Provider",hardware:"Together",sizeB:120,speed:120.49,quality:94.26,execution:"inference_provider",run:"44ef5cb03b37c4592e2a"}
,{model:"gpt-5.6-sol",short:"GPT-5.6 Sol API",family:"OpenAI",collection:"OpenAI",mode:"instruct",format:"API",hardware:"OpenAI API",sizeB:null,speed:57.07,quality:99.26,run:"70ad80d55b99ac8b5d48"}
,{model:"mistralai/Mistral-Small-3.2-24B-Instruct-2506",short:"Mistral 24B NF4 V100",family:"Mistral",collection:"Mistral",mode:"instruct",format:"BitsAndBytes NF4",hardware:"V100",sizeB:24,speed:16.78,quality:79.07,run:"58ef777c86aa62128d06"}
,{model:"mistralai/Mistral-Small-3.2-24B-Instruct-2506",short:"Mistral 24B GPTQ ExLlamaV2 V100 (run 3/3)",family:"Mistral",collection:"Mistral",mode:"instruct",format:"GPTQ Int4",hardware:"V100",sizeB:24,speed:12.62,quality:45.74,run:"4337f6820977d37d0ca6"}
,{model:"mistralai/Ministral-3-8B-Instruct-2512-BF16",short:"Ministral 8B FP16 V100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"FP16",hardware:"V100",sizeB:8,speed:19.09,quality:65.56,run:"3f5c33c7ea9cc82d6402"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B FP16 V100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"FP16",hardware:"V100",sizeB:14,speed:13.53,quality:64.81,run:"70b13f68e8e3e3696be9"}
,{model:"mistralai/Ministral-3-14B-Instruct-2512-BF16",short:"Ministral 14B Int8 V100",family:"Ministral",collection:"Mistral",mode:"instruct",format:"BitsAndBytes Int8",hardware:"V100",sizeB:14,speed:6.50,quality:54.44,run:"2ea1abaa6fca51fc75df"}
,{model:"deepseek-ai/DeepSeek-Prover-V2-7B",short:"DeepSeek FP16 V100",family:"DeepSeek",collection:"models_hf",mode:"instruct",format:"FP16",hardware:"V100",sizeB:7,speed:8.58,quality:0.0,run:"a272de4536603fa9f23f"}
];
// [Aggiornato: 2026-08-19] "Mistral" (24B) non aveva voce: stesso bug e
// stessa scelta (#22d3ee, ciano) di benchmark_quality_performance.html,
// verificata con lo stesso script dataviz validate_palette.py.
const COLORS={Llama:"#60a5fa",Qwen:"#34d399",Nemotron:"#f59e0b",Gemma:"#f472b6",Ministral:"#c084fc",Mistral:"#22d3ee",DeepSeek:"#fb7185","GPT-OSS":"#facc15",OpenAI:"#ef4444"};
const chart=document.getElementById("chart"),tooltip=document.getElementById("tooltip"),NS="http://www.w3.org/2000/svg";
const controls={family:document.getElementById("family-filter"),hardware:document.getElementById("hardware-filter"),format:document.getElementById("format-filter"),collection:document.getElementById("collection-filter")};
const plot={left:76,right:1018,top:28,bottom:538};
/** Crea un nodo SVG. @param {string} name Nome elemento. @param {Record<string,string|number>} attrs Attributi. @returns {SVGElement} Nodo allocato. @throws {DOMException} Per dati DOM non validi; nessun fallback sicuro. @sideEffects Alloca un nodo senza inserirlo. */
function svgElement(name,attrs={}) { const node=document.createElementNS(NS,name);Object.entries(attrs).forEach(([key,value])=>node.setAttribute(key,String(value)));return node; }
/** Formatta un numero in italiano. @param {number} value Numero finito. @param {number} decimals Decimali. @returns {string} Numero localizzato. @throws {RangeError} Per decimali non validi; i chiamanti usano costanti. @sideEffects Nessuno. */
function itNumber(value,decimals=1) { return value.toLocaleString("it-IT",{minimumFractionDigits:decimals,maximumFractionDigits:decimals}); }
/** Popola un filtro. @param {HTMLSelectElement} select Controllo. @param {string[]} values Valori. @returns {void} @throws {DOMException} Per errori DOM; resta l'opzione Tutti. @sideEffects Aggiunge option. */
function populateFilter(select,values) { [...new Set(values)].sort().forEach((value)=>{const option=document.createElement("option");option.value=value;option.textContent=value;select.append(option);}); }
/** Seleziona i benchmark positivi conformi ai filtri. @returns {typeof BENCHMARKS} Nuovo array filtrato. @throws {Error} Non atteso con controlli locali completi. @sideEffects Nessuno. */
function visibleBenchmarks() { return BENCHMARKS.filter((item)=>item.quality>0&&Object.entries(controls).every(([key,select])=>select.value==="all"||item[key]===select.value)); }
/** Mostra il dettaglio del punto. @param {PointerEvent|FocusEvent} event Evento. @param {(typeof BENCHMARKS)[number]} item Benchmark. @returns {void} @throws {Error} Non atteso con dati incorporati completi. @sideEffects Aggiorna e posiziona il tooltip. */
function showTooltip(event,item) { const parameterLabel=item.sizeB===null?"NA (non pubblicati)":`${itNumber(item.sizeB)}B`;tooltip.innerHTML=`<strong>${item.model} [${item.format}]</strong><div class="tooltip-grid"><span>Parametri</span><b>${parameterLabel}</b><span>Raccolta</span><b>${item.collection}</b><span>Numero dataset V3</span><b>3</b><span>Prestazioni</span><b>${itNumber(item.speed,2)} tok/s</b><span>Asse C OpenAI</span><b>${itNumber(item.quality,2)}%</b><span>Hardware</span><b>${item.hardware}</b><span>Reasoning candidato</span><b>${item.reasoning||"NA"}</b><span>run_id</span><b>${item.run}</b></div>`;const e=/** @type {PointerEvent} */(event),x=Number.isFinite(e.clientX)?e.clientX:innerWidth/2,y=Number.isFinite(e.clientY)?e.clientY:innerHeight/2;tooltip.style.left=`${Math.min(x+16,innerWidth-tooltip.offsetWidth-12)}px`;tooltip.style.top=`${Math.min(y+16,innerHeight-tooltip.offsetHeight-12)}px`;tooltip.classList.add("visible"); }
/** Nasconde il tooltip. @returns {void} @throws {Error} Non atteso. @sideEffects Rimuove la classe visibile. */
function hideTooltip() { tooltip.classList.remove("visible"); }
/** Ridisegna assi, forme, etichette e metriche. @returns {void} @throws {DOMException} Per errori SVG; testo e metodologia restano il fallback. @sideEffects Sostituisce il grafico generato. */
function renderChart() {
chart.querySelectorAll(".generated").forEach((node)=>node.remove());const data=visibleBenchmarks();
// La scala spezzata riserva quattro quinti della larghezza ai valori 0–30
// e comprime 30–130 nel quinto finale: include quindi i provider oltre
// 60 tok/s senza alterare la leggibilità dei benchmark locali più lenti.
const xScale=(value)=>{const width=plot.right-plot.left,firstSegmentWidth=width*0.8;if(value<=30)return plot.left+(value/30)*firstSegmentWidth;return plot.left+firstSegmentWidth+((value-30)/100)*(width-firstSegmentWidth);},yScale=(value)=>plot.bottom-((value+5)/105)*(plot.bottom-plot.top),radius=(value)=>value===null?14:7+Math.sqrt(value/14)*19;
for(let value=0;value<=130;value+=10){const x=xScale(value);chart.append(svgElement("line",{x1:x,x2:x,y1:plot.top,y2:plot.bottom,class:"generated grid-line"}));const label=svgElement("text",{x,y:plot.bottom+23,"text-anchor":"middle",class:"generated tick-label"});label.textContent=String(value);chart.append(label);}
for(let value=0;value<=100;value+=10){const y=yScale(value);chart.append(svgElement("line",{x1:plot.left,x2:plot.right,y1:y,y2:y,class:"generated grid-line"}));const label=svgElement("text",{x:plot.left-13,y:y+4,"text-anchor":"end",class:"generated tick-label"});label.textContent=`${value}%`;chart.append(label);}
// Le soglie distinguono la raccomandazione con revisione umana da quella automatica.
[{value:60,label:"Consigliata con revisione · 60%",color:"#f59e0b"},{value:80,label:"Consigliata automatica · 80%",color:"#22c55e"}].forEach((threshold)=>{const y=yScale(threshold.value);chart.append(svgElement("line",{x1:plot.left,x2:plot.right,y1:y,y2:y,stroke:threshold.color,"stroke-width":"1.5","stroke-dasharray":"6 4",class:"generated"}));const label=svgElement("text",{x:plot.right-4,y:y-5,"text-anchor":"end",fill:threshold.color,"font-size":"11","font-weight":"700",class:"generated"});label.textContent=threshold.label;chart.append(label);});
chart.append(svgElement("line",{x1:plot.left,x2:plot.right,y1:plot.bottom,y2:plot.bottom,class:"generated axis-line"}));chart.append(svgElement("line",{x1:plot.left,x2:plot.left,y1:plot.top,y2:plot.bottom,class:"generated axis-line"}));
// Due tacche oblique presso 30 tok/s segnalano che la densità della scala cambia.
const xBreak=xScale(30);chart.append(svgElement("path",{d:`M ${xBreak-8} ${plot.bottom+5} l 7 -10 M ${xBreak+1} ${plot.bottom+5} l 7 -10`,class:"generated axis-line",fill:"none"}));
const xTitle=svgElement("text",{x:(plot.left+plot.right)/2,y:593,"text-anchor":"middle",class:"generated axis-title"});xTitle.textContent="PRESTAZIONI — token generati al secondo (tok/s) →";chart.append(xTitle);
const yTitle=svgElement("text",{x:20,y:(plot.top+plot.bottom)/2,transform:`rotate(-90 20 ${(plot.top+plot.bottom)/2})`,"text-anchor":"middle",class:"generated axis-title"});yTitle.textContent="QUALITÀ — Asse C V3, giudice OpenAI (%) →";chart.append(yTitle);
/** Disegna due barre rosse sopra un punto sotto soglia senza coprire gli eventi del punto. @param {number} x Coordinata orizzontale del simbolo. @param {number} y Coordinata verticale del simbolo. @param {number} radius Raggio o semilato del simbolo. @returns {void} Non restituisce valori. @sideEffects Aggiunge due linee SVG non interattive al grafico. @throws {DOMException} Se il DOM SVG non accetta l'inserimento; nessun fallback sicuro. */
function drawBelowThresholdStripes(x,y,radius){const stripeLength=radius*.72;[-radius*.34,radius*.34].forEach((offset)=>{chart.append(svgElement("line",{x1:x-stripeLength+offset,y1:y+stripeLength,x2:x+stripeLength+offset,y2:y-stripeLength,stroke:"#ef4444","stroke-width":"2.2","stroke-linecap":"round","pointer-events":"none",class:"generated"}));});}
// Il colore identifica sempre la famiglia, come dichiarato dalla legenda; le soglie sono linee separate.
data.forEach((item)=>{const x=xScale(item.speed),y=yScale(item.quality),pointRadius=radius(item.sizeB),pointColor=COLORS[item.family],label=`${item.model}, ${item.speed} token al secondo, qualità OpenAI ${item.quality}%`,point=item.execution==="inference_provider"?svgElement("text",{x,y:y+pointRadius*.35,"text-anchor":"middle",fill:pointColor,"font-size":pointRadius*1.7,"font-weight":"800",class:"generated point",tabindex:"0",role:"button","aria-label":label}):item.hardware.startsWith("A100")?svgElement("polygon",{points:`${x},${y-pointRadius} ${x+pointRadius},${y+pointRadius*.8} ${x-pointRadius},${y+pointRadius*.8}`,fill:pointColor,class:"generated point",tabindex:"0",role:"button","aria-label":label}):svgElement("circle",{cx:x,cy:y,r:pointRadius,fill:pointColor,class:"generated point",tabindex:"0",role:"button","aria-label":label});if(item.execution==="inference_provider")point.textContent="+";point.style.color=pointColor;point.addEventListener("pointerenter",(event)=>showTooltip(event,item));point.addEventListener("pointermove",(event)=>showTooltip(event,item));point.addEventListener("pointerleave",hideTooltip);point.addEventListener("focus",(event)=>showTooltip(event,item));point.addEventListener("blur",hideTooltip);chart.append(point);if(item.quality<60)drawBelowThresholdStripes(x,y,pointRadius);});
data.forEach((item)=>{const label=svgElement("text",{x:xScale(item.speed),y:yScale(item.quality)-radius(item.sizeB)-7,"text-anchor":"middle",class:"generated point-label"});label.textContent=item.short.includes(`${item.sizeB}B`)?item.short:`${item.short} · ${item.sizeB}B`;chart.append(label);});
if(!data.length){const empty=svgElement("text",{x:550,y:285,class:"generated empty"});empty.textContent="Nessun modello corrisponde ai filtri selezionati.";chart.append(empty);}
document.getElementById("model-count").textContent=String(data.length);document.getElementById("best-quality").textContent=data.length?`${itNumber(Math.max(...data.map((item)=>item.quality)),1)}%`:"—";document.getElementById("best-speed").textContent=data.length?`${itNumber(Math.max(...data.map((item)=>item.speed)),2)} tok/s`:"—";
}
/** Inizializza filtri, legenda e grafico. @returns {void} @throws {DOMException} Per struttura HTML incompleta; nessun fallback silenzioso. @sideEffects Registra listener e crea contenuti. */
function initializeDashboard() { Object.entries(controls).forEach(([key,select])=>{populateFilter(select,BENCHMARKS.map((item)=>item[key]));select.addEventListener("change",renderChart);});const legend=document.getElementById("family-legend");Object.entries(COLORS).forEach(([family,color])=>{const row=document.createElement("div");row.className="legend-row";row.innerHTML=`<span class="swatch" style="background:${color}"></span>${family}`;legend.append(row);});document.getElementById("reset-button").addEventListener("click",()=>{Object.values(controls).forEach((select)=>{select.value="all";});renderChart();});renderChart(); }
initializeDashboard();
</script>
</body>
</html>