File size: 34,042 Bytes
985cf9c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | <!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 < 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>
|