|
5 | 5 | <meta charset="utf-8"/> |
6 | 6 | <meta name="viewport" content="width=device-width, initial-scale=1"/> |
7 | 7 | <title>Agg-vs-Disagg Calculator — work backwards from the model architecture</title> |
| 8 | +<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27%3E%3Crect width=%2716%27 height=%2716%27 rx=%273%27 fill=%27%230d1117%27/%3E%3Crect x=%273%27 y=%279%27 width=%273%27 height=%274%27 fill=%27%2358a6ff%27/%3E%3Crect x=%277%27 y=%276%27 width=%273%27 height=%277%27 fill=%27%23d29922%27/%3E%3Crect x=%2711%27 y=%273%27 width=%273%27 height=%2710%27 fill=%27%233fb950%27/%3E%3C/svg%3E"> |
8 | 9 | <!-- Self-contained. NO API keys. Physics is a faithful JS port of analyze/calc.py + cost.py + optimizer.py |
9 | 10 | (calibrated to MEASURED Nemotron-3 Ultra 550B / p5en anchors). Chart.js (CDN) for the two charts only. --> |
10 | 11 | <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script> |
11 | 12 | <style> |
12 | 13 | :root{--bg:#0d1117;--card:#161b22;--card2:#1c2230;--fg:#e6edf3;--mut:#8b949e;--acc:#58a6ff;--ok:#3fb950;--warn:#d29922;--bad:#f85149;--line:#30363d} |
13 | 14 | *{box-sizing:border-box} body{margin:0;background:var(--bg);color:var(--fg);font:14px/1.5 system-ui,Segoe UI,Roboto,sans-serif} |
| 15 | + .disclaimer{margin:10px 24px 0;padding:9px 13px;border:1px solid #c89b3c;border-left:4px solid #c89b3c;background:#2a2410;color:#e8d9a0;border-radius:6px;font-size:12px;line-height:1.5} |
| 16 | + .disclaimer b{color:#f0c552} |
| 17 | + .glossary{margin:8px 24px 0;font-size:12px;color:var(--mut)} .glossary summary{cursor:pointer;color:var(--acc)} |
| 18 | + .gloss-grid{display:grid;grid-template-columns:1fr 1fr;gap:3px 24px;margin-top:6px} .gloss-grid b{color:var(--fg)} |
| 19 | + @media(max-width:760px){.gloss-grid{grid-template-columns:1fr}} |
| 20 | + @media print{ |
| 21 | + :root{--bg:#fff;--card:#fff;--card2:#fff;--fg:#111;--mut:#444} |
| 22 | + body{background:#fff;color:#111} |
| 23 | + details{display:block!important} details>summary{font-weight:600} |
| 24 | + .disclaimer{border:1px solid #b8860b;background:#fff8e6;color:#5a4500;-webkit-print-color-adjust:exact;print-color-adjust:exact} |
| 25 | + button{display:none} .card,.step{border:1px solid #ccc;break-inside:avoid} |
| 26 | + } |
| 27 | + @media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;transition-duration:.001ms!important}} /* WCAG 2.3.3 */ |
14 | 28 | header{padding:16px 24px;border-bottom:1px solid var(--line)} h1{margin:0;font-size:19px} .sub{color:var(--mut);font-size:13px;margin-top:4px} |
15 | 29 | .sub .honest{color:var(--fg)} /* the agg-vs-disagg honesty line reads as a feature, not a footnote (mirrors index.html) */ |
16 | 30 | .wrap{display:grid;grid-template-columns:340px 1fr;gap:18px;padding:18px 24px;align-items:start} |
|
27 | 41 | .ad{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px} |
28 | 42 | .ad>div{background:var(--card2);border-radius:6px;padding:8px 10px} .ad .h{font-size:11px;text-transform:uppercase;letter-spacing:.04em;color:var(--mut)} |
29 | 43 | .agg .h{color:var(--acc)} .dis .h{color:var(--ok)} |
30 | | - .verdict{font-size:24px;font-weight:800;margin:2px 0} .disaggregate{color:var(--ok)} .hybrid{color:var(--warn)} .aggregate{color:var(--acc)} |
| 44 | + .verdict{font-size:28px;font-weight:800;margin:2px 0;letter-spacing:-.3px} .disaggregate{color:var(--ok)} .hybrid{color:var(--warn)} .aggregate{color:var(--acc)} |
31 | 45 | /* verdict carries a SHAPE prefix too (CSS ::before keyed on the verdict class the JS sets) — meaning is |
32 | 46 | never color-only, so it passes a11y / colorblind. Pure presentation; no JS change. */ |
33 | 47 | .verdict::before{font-family:ui-monospace,Menlo,monospace;margin-right:9px;font-size:19px;vertical-align:1px} |
@@ -116,13 +130,17 @@ <h1>Aggregation vs Disaggregation Calculator</h1> |
116 | 130 | transfer-toll vs interference → <b>verdict</b> → $/Mtok → optimal operating point. |
117 | 131 | <b class="honest">Disaggregation is not free — it helps for some workloads and regresses for others. This tool tells you which: when it helps, when it’s a no-op, and when it costs you (at the 1P:1D floor it’s a latency play, not a cost play).</b> |
118 | 132 | Physics mirrors <code>analyze/calc.py</code> + <code>cost.py</code> + <code>optimizer.py</code>, calibrated to measured 550B/p5en.</div> |
119 | | - <div style="margin:10px 0;padding:8px 12px;border:1px solid #c89b3c;background:#2a2410;color:#e8d9a0;border-radius:6px;font-size:12px;line-height:1.45"> |
120 | | - <b>Disclaimer.</b> Provided free of charge, as a utility, for quick <b>estimation and planning only</b>. AWS and the |
121 | | - authors make <b>no representation, warranty, or guarantee</b> of model performance, throughput, latency, or cost, and |
122 | | - <b>accept no liability</b> for any outcome arising from its use. Actual measured results will differ from the |
123 | | - calculated numbers — always validate on your own hardware with your own workload before deployment or purchasing |
124 | | - decisions. Provided <b>“AS IS”</b>. |
125 | | - </div> |
| 133 | + <div class="disclaimer" role="note" aria-label="Disclaimer"><b>⚠ Disclaimer:</b> Provided free, as a utility, for quick <b>estimation and planning only</b>. AWS and the authors make <b>no representation, warranty, or guarantee</b> of model performance, throughput, latency, or cost, and <b>accept no liability</b> for any outcome of its use. Actual measured results will differ — always validate on your own hardware before deployment or purchasing decisions. Provided <b>“AS IS”</b>.</div> |
| 134 | + <details class="glossary"><summary>Glossary — terms used below</summary> |
| 135 | + <div class="gloss-grid"> |
| 136 | + <span><b>ISL</b> input seq length (prompt tokens)</span><span><b>OSL</b> output seq length (generated tokens)</span> |
| 137 | + <span><b>KV</b> key/value attention cache</span><span><b>HBM</b> GPU high-bandwidth memory</span> |
| 138 | + <span><b>TTFT</b> time to first token</span><span><b>ITL/TPOT</b> inter-token latency / time per output token</span> |
| 139 | + <span><b>SLO/SLA</b> latency target / service-level agreement</span><span><b>TP/PP</b> tensor / pipeline parallelism</span> |
| 140 | + <span><b>1P:1D</b> 1 prefill : 1 decode worker</span><span><b>MFU/MBU</b> model-FLOP / memory-bandwidth utilization</span> |
| 141 | + <span><b>RDMA</b> remote direct memory access (EFA)</span><span><b>$/Mtok</b> cost per 1M output tokens</span> |
| 142 | + </div> |
| 143 | + </details> |
126 | 144 | </header> |
127 | 145 | <div class="wrap"> |
128 | 146 | <!-- ============ INPUTS (the architecture) ============ --> |
@@ -356,6 +374,8 @@ <h4><span aria-hidden="true">▲</span> Disaggregate</h4> |
356 | 374 | </div> |
357 | 375 |
|
358 | 376 | <script> |
| 377 | +// a11y (WCAG 2.3.3): respect prefers-reduced-motion — disable Chart.js animation for motion-sensitive users. |
| 378 | +try{ if(window.Chart && window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches){ Chart.defaults.animation=false; } }catch(e){} |
359 | 379 | // ============================ physics constants (mirror analyze/) ============================ |
360 | 380 | const INSTANCES = { |
361 | 381 | "p5.48xlarge": {gpu:"H100", gpus:8, hbm_GBs:3350, hbm_cap_GB:80, fp16_TFLOPs:989, efa_nics:32, efa_Gbps:100, nvlink_GBs:900}, |
|
0 commit comments