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 &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>