Initial website
Browse files- app.js +604 -0
- config.json +139 -0
- data.csv +134 -0
- embedl_logo_black_bg.svg +21 -0
- embedl_logo_white_bg.svg +21 -0
- index.html +88 -17
- style.css +368 -18
app.js
ADDED
|
@@ -0,0 +1,604 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// βββ Benchmark Viewer β config-driven from config.json + data.csv βββββββββββββ
|
| 2 |
+
|
| 3 |
+
(async function () {
|
| 4 |
+
|
| 5 |
+
// βββ Theme-aware color helper βββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 6 |
+
|
| 7 |
+
function cssVar(name) {
|
| 8 |
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
// βββ Load config + data βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 12 |
+
|
| 13 |
+
const [config, csvText] = await Promise.all([
|
| 14 |
+
fetch("config.json").then(r => r.json()),
|
| 15 |
+
fetch("data.csv").then(r => r.text()),
|
| 16 |
+
]);
|
| 17 |
+
|
| 18 |
+
// βββ Parse CSV ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 19 |
+
|
| 20 |
+
function parseCSV(text) {
|
| 21 |
+
const lines = text.replace(/\r/g, "").trim().split("\n");
|
| 22 |
+
const headers = lines[0].split(",");
|
| 23 |
+
// Determine which columns are numeric (metrics + numeric filters + numeric display columns)
|
| 24 |
+
const numericCols = new Set(
|
| 25 |
+
config.metrics.map(m => m.column).concat(
|
| 26 |
+
config.filters.filter(f => f.type === "number").map(f => f.column),
|
| 27 |
+
(config.display_columns || []).filter(d => d.type === "number").map(d => d.column)
|
| 28 |
+
)
|
| 29 |
+
);
|
| 30 |
+
return lines.slice(1).map(line => {
|
| 31 |
+
const vals = line.split(",");
|
| 32 |
+
const row = {};
|
| 33 |
+
headers.forEach((h, i) => {
|
| 34 |
+
const raw = (vals[i] || "").trim();
|
| 35 |
+
if (raw === "") {
|
| 36 |
+
row[h] = numericCols.has(h) ? null : "";
|
| 37 |
+
} else if (numericCols.has(h)) {
|
| 38 |
+
row[h] = raw.toUpperCase() === "OOM" ? null : parseFloat(raw);
|
| 39 |
+
} else {
|
| 40 |
+
row[h] = raw;
|
| 41 |
+
}
|
| 42 |
+
});
|
| 43 |
+
return row;
|
| 44 |
+
});
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
const DATA = parseCSV(csvText);
|
| 48 |
+
|
| 49 |
+
// βββ Config shortcuts βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 50 |
+
|
| 51 |
+
const MODEL_COL = config.model_column;
|
| 52 |
+
const FAMILY_COL = config.model_family_column || "";
|
| 53 |
+
const LINK_PREFIX = config.model_link_prefix || "";
|
| 54 |
+
const OPT_ORG = config.optimized_org || "embedl";
|
| 55 |
+
const CHART_CFG = config.chart || {};
|
| 56 |
+
const GROUP_BY = CHART_CFG.group_by || config.filters[config.filters.length - 1]?.column || "";
|
| 57 |
+
const SCENARIOS = CHART_CFG.scenarios || [];
|
| 58 |
+
|
| 59 |
+
function isExternalModel(model) {
|
| 60 |
+
return !model.startsWith(OPT_ORG + "/");
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
// βββ Derive unique values βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 64 |
+
|
| 65 |
+
const ALL_MODELS = [...new Set(DATA.map(r => r[MODEL_COL]))];
|
| 66 |
+
|
| 67 |
+
// βββ Model Family Detection βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 68 |
+
|
| 69 |
+
function detectFamilies() {
|
| 70 |
+
const families = {};
|
| 71 |
+
|
| 72 |
+
if (FAMILY_COL) {
|
| 73 |
+
// Use explicit family column from data
|
| 74 |
+
DATA.forEach(row => {
|
| 75 |
+
const fk = row[FAMILY_COL];
|
| 76 |
+
const model = row[MODEL_COL];
|
| 77 |
+
if (!fk) return;
|
| 78 |
+
if (!families[fk]) families[fk] = { base: fk, models: [] };
|
| 79 |
+
if (!families[fk].models.includes(model)) families[fk].models.push(model);
|
| 80 |
+
});
|
| 81 |
+
} else {
|
| 82 |
+
// Fallback: auto-detect from model name prefixes
|
| 83 |
+
const externalNames = ALL_MODELS.filter(isExternalModel).map(m => m.split("/").pop());
|
| 84 |
+
externalNames.sort((a, b) => b.length - a.length);
|
| 85 |
+
|
| 86 |
+
ALL_MODELS.forEach(model => {
|
| 87 |
+
const shortName = model.split("/").pop();
|
| 88 |
+
if (isExternalModel(model)) {
|
| 89 |
+
if (!families[shortName]) families[shortName] = { base: shortName, models: [] };
|
| 90 |
+
families[shortName].models.push(model);
|
| 91 |
+
} else {
|
| 92 |
+
const match = externalNames.find(base => shortName.startsWith(base));
|
| 93 |
+
const key = match || shortName;
|
| 94 |
+
if (!families[key]) families[key] = { base: key, models: [] };
|
| 95 |
+
families[key].models.push(model);
|
| 96 |
+
}
|
| 97 |
+
});
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
return families;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
const MODEL_FAMILIES = detectFamilies();
|
| 104 |
+
const ALL_FAMILY_KEYS = Object.keys(MODEL_FAMILIES);
|
| 105 |
+
|
| 106 |
+
// βββ Model colors & short labels ββββββββββββββββββββββββββββββββββββββββββββββ
|
| 107 |
+
|
| 108 |
+
function hexToRgba(hex, alpha) {
|
| 109 |
+
const r = parseInt(hex.slice(1,3),16), g = parseInt(hex.slice(3,5),16), b = parseInt(hex.slice(5,7),16);
|
| 110 |
+
return `rgba(${r},${g},${b},${alpha})`;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
function buildColorPalette() {
|
| 114 |
+
const barAlpha = 0.75;
|
| 115 |
+
const neutralAlpha = 0.45;
|
| 116 |
+
const teal = cssVar("--teal"), green = cssVar("--green"), pink = cssVar("--pink"),
|
| 117 |
+
purple = cssVar("--purple"), red = cssVar("--red");
|
| 118 |
+
return {
|
| 119 |
+
palette: [
|
| 120 |
+
{ bg: hexToRgba(teal, barAlpha), border: teal },
|
| 121 |
+
{ bg: hexToRgba(green, barAlpha), border: green },
|
| 122 |
+
{ bg: hexToRgba(pink, barAlpha), border: pink },
|
| 123 |
+
{ bg: hexToRgba(purple, barAlpha), border: purple },
|
| 124 |
+
{ bg: "rgba(255,209,102," + barAlpha + ")", border: "#ffd166" },
|
| 125 |
+
],
|
| 126 |
+
neutral: { bg: hexToRgba(cssVar("--neutral"), neutralAlpha), border: cssVar("--neutral") },
|
| 127 |
+
};
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
let COLOR_PALETTE, NEUTRAL_COLOR;
|
| 131 |
+
|
| 132 |
+
const MODEL_COLORS = {};
|
| 133 |
+
const MODEL_SHORT = {};
|
| 134 |
+
|
| 135 |
+
function assignModelColors() {
|
| 136 |
+
let colorIdx = 0;
|
| 137 |
+
const { palette, neutral } = buildColorPalette();
|
| 138 |
+
COLOR_PALETTE = palette; NEUTRAL_COLOR = neutral;
|
| 139 |
+
ALL_FAMILY_KEYS.forEach(fk => {
|
| 140 |
+
const family = MODEL_FAMILIES[fk];
|
| 141 |
+
family.models.forEach(model => {
|
| 142 |
+
if (isExternalModel(model)) {
|
| 143 |
+
MODEL_COLORS[model] = NEUTRAL_COLOR;
|
| 144 |
+
} else {
|
| 145 |
+
MODEL_COLORS[model] = COLOR_PALETTE[colorIdx % COLOR_PALETTE.length];
|
| 146 |
+
colorIdx++;
|
| 147 |
+
}
|
| 148 |
+
const name = model.split("/").pop();
|
| 149 |
+
const suffix = name.slice(family.base.length).replace(/^-/, "");
|
| 150 |
+
MODEL_SHORT[model] = suffix || (isExternalModel(model) ? "Original" : name);
|
| 151 |
+
});
|
| 152 |
+
});
|
| 153 |
+
}
|
| 154 |
+
assignModelColors();
|
| 155 |
+
|
| 156 |
+
// βββ Helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 157 |
+
|
| 158 |
+
function isOOMRow(row) {
|
| 159 |
+
return config.metrics.every(m => row[m.column] === null);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
function familyRows(familyKey) {
|
| 163 |
+
const models = new Set((MODEL_FAMILIES[familyKey] || { models: [] }).models);
|
| 164 |
+
return DATA.filter(r => models.has(r[MODEL_COL]));
|
| 165 |
+
}
|
| 166 |
+
|
| 167 |
+
function availableOptions(familyKey) {
|
| 168 |
+
const rows = familyRows(familyKey);
|
| 169 |
+
const opts = {};
|
| 170 |
+
config.filters.forEach(f => {
|
| 171 |
+
const vals = [...new Set(rows.map(r => r[f.column]).filter(v => v !== "" && v !== null && v !== undefined))];
|
| 172 |
+
if (f.type === "number") vals.sort((a, b) => a - b);
|
| 173 |
+
opts[f.column] = vals;
|
| 174 |
+
});
|
| 175 |
+
return opts;
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
// Resolve display label for a filter value
|
| 179 |
+
function valueLabel(filterCfg, val) {
|
| 180 |
+
if (filterCfg.value_labels && filterCfg.value_labels[val]) return filterCfg.value_labels[val];
|
| 181 |
+
if (typeof val === "string") return val.charAt(0).toUpperCase() + val.slice(1);
|
| 182 |
+
return String(val);
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
// Sort models: external (original) first, then optimized
|
| 186 |
+
function sortModels(models) {
|
| 187 |
+
return [...models].sort((a, b) => {
|
| 188 |
+
const aExt = isExternalModel(a) ? 0 : 1;
|
| 189 |
+
const bExt = isExternalModel(b) ? 0 : 1;
|
| 190 |
+
return aExt - bExt || a.localeCompare(b);
|
| 191 |
+
});
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
// βββ Populate page from config ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 195 |
+
|
| 196 |
+
// Hero
|
| 197 |
+
if (config.title) document.getElementById("hero-title").innerHTML = config.title.replace(/^(.*?)(\s\S+)$/, '$1 <span class="accent">$2</span>');
|
| 198 |
+
if (config.subtitle) document.getElementById("hero-sub").textContent = config.subtitle;
|
| 199 |
+
|
| 200 |
+
// Sidebar: model families
|
| 201 |
+
const familyNav = document.getElementById("family-nav");
|
| 202 |
+
function renderSidebar() {
|
| 203 |
+
familyNav.innerHTML = ALL_FAMILY_KEYS.map(fk =>
|
| 204 |
+
`<div class="sidebar-item${fk === filters.family ? " active" : ""}" data-family="${fk}">${fk}</div>`
|
| 205 |
+
).join("");
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
|
| 209 |
+
|
| 210 |
+
familyNav.addEventListener("click", e => {
|
| 211 |
+
const item = e.target.closest(".sidebar-item");
|
| 212 |
+
if (!item) return;
|
| 213 |
+
filters.family = item.dataset.family;
|
| 214 |
+
renderSidebar();
|
| 215 |
+
updateDependentFilters();
|
| 216 |
+
render();
|
| 217 |
+
});
|
| 218 |
+
|
| 219 |
+
// Build filter groups container dynamically (no family filter here)
|
| 220 |
+
const filtersBar = document.getElementById("filters-bar");
|
| 221 |
+
filtersBar.innerHTML = "";
|
| 222 |
+
|
| 223 |
+
config.filters.forEach(f => {
|
| 224 |
+
filtersBar.appendChild(createFilterGroup(f.label, "filter-" + f.column));
|
| 225 |
+
});
|
| 226 |
+
|
| 227 |
+
// Metric filter (always last)
|
| 228 |
+
filtersBar.appendChild(createFilterGroup("Metric", "filter-metric"));
|
| 229 |
+
|
| 230 |
+
function createFilterGroup(label, id) {
|
| 231 |
+
const div = document.createElement("div");
|
| 232 |
+
div.className = "filter-group";
|
| 233 |
+
div.innerHTML = `<label>${label}</label><div class="btn-group" id="${id}"></div>`;
|
| 234 |
+
return div;
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
// Metric legend
|
| 238 |
+
const legendGrid = document.getElementById("legend-grid");
|
| 239 |
+
legendGrid.innerHTML = config.metrics.map(m =>
|
| 240 |
+
`<div><strong>${m.short || m.column}</strong> ${m.description || m.label}</div>`
|
| 241 |
+
).join("");
|
| 242 |
+
|
| 243 |
+
// βββ State ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 244 |
+
|
| 245 |
+
const filters = { family: ALL_FAMILY_KEYS[0] || "" };
|
| 246 |
+
config.filters.forEach(f => { filters[f.column] = ""; });
|
| 247 |
+
filters.metric = CHART_CFG.default_metric || config.metrics[0]?.column || "";
|
| 248 |
+
|
| 249 |
+
// βββ Render button groups βββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 250 |
+
|
| 251 |
+
function renderBtnGroup(container, items, activeValue) {
|
| 252 |
+
container.innerHTML = items.map(({ value, label }) =>
|
| 253 |
+
`<button class="btn${String(value) === String(activeValue) ? " active" : ""}" data-value="${value}">${label}</button>`
|
| 254 |
+
).join("");
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
function populateFilters() {
|
| 258 |
+
renderSidebar();
|
| 259 |
+
|
| 260 |
+
// Metric buttons
|
| 261 |
+
const metricEl = document.getElementById("filter-metric");
|
| 262 |
+
renderBtnGroup(metricEl,
|
| 263 |
+
config.metrics.map(m => ({ value: m.column, label: m.short || m.column })),
|
| 264 |
+
filters.metric
|
| 265 |
+
);
|
| 266 |
+
metricEl.closest(".filter-group").style.display = config.metrics.length <= 1 ? "none" : "";
|
| 267 |
+
|
| 268 |
+
updateDependentFilters();
|
| 269 |
+
}
|
| 270 |
+
|
| 271 |
+
function updateDependentFilters() {
|
| 272 |
+
const opts = availableOptions(filters.family);
|
| 273 |
+
|
| 274 |
+
config.filters.forEach(f => {
|
| 275 |
+
let vals = opts[f.column] || [];
|
| 276 |
+
// Sort by value_labels key order if defined
|
| 277 |
+
if (f.value_labels) {
|
| 278 |
+
const labelOrder = Object.keys(f.value_labels);
|
| 279 |
+
vals = [...vals].sort((a, b) => {
|
| 280 |
+
const ai = labelOrder.indexOf(String(a));
|
| 281 |
+
const bi = labelOrder.indexOf(String(b));
|
| 282 |
+
return (ai === -1 ? Infinity : ai) - (bi === -1 ? Infinity : bi);
|
| 283 |
+
});
|
| 284 |
+
}
|
| 285 |
+
const strVals = vals.map(String);
|
| 286 |
+
if (!strVals.includes(String(filters[f.column]))) {
|
| 287 |
+
filters[f.column] = vals[0] ?? "";
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
// For the group_by filter, add "All" option
|
| 291 |
+
const items = [];
|
| 292 |
+
if (f.column === GROUP_BY) {
|
| 293 |
+
items.push({ value: "all", label: "All" });
|
| 294 |
+
}
|
| 295 |
+
vals.forEach(v => items.push({ value: String(v), label: valueLabel(f, v) }));
|
| 296 |
+
|
| 297 |
+
const el = document.getElementById("filter-" + f.column);
|
| 298 |
+
if (el) {
|
| 299 |
+
renderBtnGroup(el, items, String(filters[f.column]));
|
| 300 |
+
// Hide the entire filter group if only one effective choice
|
| 301 |
+
const effectiveCount = f.column === GROUP_BY ? items.length - 1 : items.length;
|
| 302 |
+
el.closest(".filter-group").style.display = effectiveCount <= 1 ? "none" : "";
|
| 303 |
+
}
|
| 304 |
+
});
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
// βββ Event binding ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 308 |
+
|
| 309 |
+
filtersBar.addEventListener("click", e => {
|
| 310 |
+
const btn = e.target.closest(".btn");
|
| 311 |
+
if (!btn) return;
|
| 312 |
+
const group = btn.closest(".btn-group");
|
| 313 |
+
group.querySelectorAll(".btn").forEach(b => b.classList.remove("active"));
|
| 314 |
+
btn.classList.add("active");
|
| 315 |
+
const key = group.id.replace("filter-", "");
|
| 316 |
+
filters[key] = btn.dataset.value;
|
| 317 |
+
render();
|
| 318 |
+
});
|
| 319 |
+
|
| 320 |
+
// βββ Chart ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 321 |
+
|
| 322 |
+
let charts = [];
|
| 323 |
+
|
| 324 |
+
function buildChart(filtered) {
|
| 325 |
+
const section = document.getElementById("charts-section");
|
| 326 |
+
section.innerHTML = "";
|
| 327 |
+
charts.forEach(c => c.destroy());
|
| 328 |
+
charts = [];
|
| 329 |
+
|
| 330 |
+
const metricCol = filters.metric;
|
| 331 |
+
const metricCfg = config.metrics.find(m => m.column === metricCol) || {};
|
| 332 |
+
const groupCol = GROUP_BY;
|
| 333 |
+
const groupFilterCfg = config.filters.find(f => f.column === groupCol);
|
| 334 |
+
|
| 335 |
+
const groupVal = filters[groupCol];
|
| 336 |
+
if (groupVal === "all") return;
|
| 337 |
+
|
| 338 |
+
const groupLabel = groupFilterCfg?.value_labels?.[groupVal] || String(groupVal);
|
| 339 |
+
const gRows = filtered.filter(r => String(r[groupCol]) === String(groupVal));
|
| 340 |
+
if (!gRows.length) return;
|
| 341 |
+
|
| 342 |
+
// If no scenarios configured, show one chart with all rows
|
| 343 |
+
const scenarioList = SCENARIOS.length
|
| 344 |
+
? SCENARIOS
|
| 345 |
+
: [{ label: "", match: {} }];
|
| 346 |
+
|
| 347 |
+
scenarioList.forEach(scenario => {
|
| 348 |
+
// Filter rows matching this scenario
|
| 349 |
+
const matchRows = gRows.filter(r =>
|
| 350 |
+
Object.entries(scenario.match || {}).every(([col, val]) =>
|
| 351 |
+
String(r[col]) === String(val)
|
| 352 |
+
)
|
| 353 |
+
);
|
| 354 |
+
// For models with only OOM rows (no scenario match), include one OOM row
|
| 355 |
+
// but only if it matches the active filter values (e.g. type)
|
| 356 |
+
const matchedModels = new Set(matchRows.map(r => r[MODEL_COL]));
|
| 357 |
+
const oomRows = gRows.filter(r => !matchedModels.has(r[MODEL_COL]) && isOOMRow(r)
|
| 358 |
+
&& Object.entries(scenario.match || {}).every(([col, val]) =>
|
| 359 |
+
r[col] === null || r[col] === "" || r[col] === "OOM" || String(r[col]) === String(val)
|
| 360 |
+
)
|
| 361 |
+
);
|
| 362 |
+
const allRows = matchRows.concat(oomRows);
|
| 363 |
+
|
| 364 |
+
const models = sortModels([...new Set(allRows.map(r => r[MODEL_COL]))]);
|
| 365 |
+
const picked = models.map(m => allRows.find(r => r[MODEL_COL] === m)).filter(Boolean);
|
| 366 |
+
if (!picked.length) return;
|
| 367 |
+
|
| 368 |
+
const labels = picked.map(r => MODEL_SHORT[r[MODEL_COL]]);
|
| 369 |
+
const data = picked.map(r => r[metricCol] === null ? 0 : r[metricCol]);
|
| 370 |
+
const bgColors = picked.map(r => MODEL_COLORS[r[MODEL_COL]].bg);
|
| 371 |
+
const borderColors = picked.map(r => MODEL_COLORS[r[MODEL_COL]].border);
|
| 372 |
+
|
| 373 |
+
const metricHint = metricCfg.higher_is_better ? " (higher is better)" : " (lower is better)";
|
| 374 |
+
const yLabel = (metricCfg.label || metricCol) + metricHint;
|
| 375 |
+
|
| 376 |
+
const chartBlock = document.createElement("div");
|
| 377 |
+
chartBlock.className = "chart-block";
|
| 378 |
+
|
| 379 |
+
const heading = document.createElement("h3");
|
| 380 |
+
heading.className = "chart-heading";
|
| 381 |
+
heading.textContent = groupLabel;
|
| 382 |
+
chartBlock.appendChild(heading);
|
| 383 |
+
|
| 384 |
+
if (scenario.label) {
|
| 385 |
+
const sub = document.createElement("p");
|
| 386 |
+
sub.className = "chart-subtitle";
|
| 387 |
+
sub.textContent = scenario.label;
|
| 388 |
+
chartBlock.appendChild(sub);
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
const wrap = document.createElement("div");
|
| 392 |
+
wrap.className = "chart-wrap";
|
| 393 |
+
const canvas = document.createElement("canvas");
|
| 394 |
+
wrap.appendChild(canvas);
|
| 395 |
+
chartBlock.appendChild(wrap);
|
| 396 |
+
section.appendChild(chartBlock);
|
| 397 |
+
|
| 398 |
+
const c = new Chart(canvas, {
|
| 399 |
+
type: "bar",
|
| 400 |
+
data: {
|
| 401 |
+
labels,
|
| 402 |
+
datasets: [{
|
| 403 |
+
data,
|
| 404 |
+
backgroundColor: bgColors,
|
| 405 |
+
borderColor: borderColors,
|
| 406 |
+
borderWidth: 2, borderRadius: 6, minBarLength: 4,
|
| 407 |
+
}],
|
| 408 |
+
},
|
| 409 |
+
options: {
|
| 410 |
+
responsive: true, maintainAspectRatio: false,
|
| 411 |
+
plugins: {
|
| 412 |
+
legend: { display: false },
|
| 413 |
+
title: { display: false },
|
| 414 |
+
tooltip: {
|
| 415 |
+
backgroundColor: cssVar("--tooltip-bg"), titleColor: cssVar("--tooltip-text"), bodyColor: cssVar("--tooltip-body"),
|
| 416 |
+
borderColor: cssVar("--btn-active-border"), borderWidth: 1,
|
| 417 |
+
callbacks: {
|
| 418 |
+
label: ctx => {
|
| 419 |
+
const orig = picked[ctx.dataIndex]?.[metricCol];
|
| 420 |
+
return orig === null ? "OOM" : orig.toLocaleString();
|
| 421 |
+
},
|
| 422 |
+
},
|
| 423 |
+
},
|
| 424 |
+
},
|
| 425 |
+
scales: {
|
| 426 |
+
y: { beginAtZero: true, title: { display: true, text: yLabel, color: cssVar("--text-muted") }, grid: { color: cssVar("--chart-grid") }, ticks: { color: cssVar("--text-dim") } },
|
| 427 |
+
x: { grid: { display: false }, ticks: { color: cssVar("--text-muted"), font: { size: 14 } } },
|
| 428 |
+
},
|
| 429 |
+
},
|
| 430 |
+
});
|
| 431 |
+
charts.push(c);
|
| 432 |
+
});
|
| 433 |
+
}
|
| 434 |
+
|
| 435 |
+
// βββ Tables βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 436 |
+
|
| 437 |
+
function buildTables(filtered, chartsShown) {
|
| 438 |
+
const section = document.getElementById("tables-section");
|
| 439 |
+
section.innerHTML = "";
|
| 440 |
+
const groupCol = GROUP_BY;
|
| 441 |
+
const groupFilterCfg = config.filters.find(f => f.column === groupCol);
|
| 442 |
+
const groupVal = filters[groupCol];
|
| 443 |
+
const opts = availableOptions(filters.family);
|
| 444 |
+
const groupVals = groupVal === "all" ? (opts[groupCol] || []) : [groupVal];
|
| 445 |
+
|
| 446 |
+
// Determine which display columns are visible given current filter state
|
| 447 |
+
const visibleDisplay = (config.display_columns || []).filter(dc => {
|
| 448 |
+
if (!dc.visible_when) return true;
|
| 449 |
+
return Object.entries(dc.visible_when).every(([filterCol, allowedVals]) =>
|
| 450 |
+
allowedVals.includes(filters[filterCol])
|
| 451 |
+
);
|
| 452 |
+
});
|
| 453 |
+
|
| 454 |
+
// Build column list: Model + visible display cols + metrics
|
| 455 |
+
const colDefs = [
|
| 456 |
+
{ key: MODEL_COL, label: "Model", isModel: true },
|
| 457 |
+
...visibleDisplay.map(dc => ({ key: dc.column, label: dc.label, description: dc.description || "" })),
|
| 458 |
+
...config.metrics.map(m => ({ key: m.column, label: m.short || m.column, isMetric: true, description: m.description || "" })),
|
| 459 |
+
];
|
| 460 |
+
|
| 461 |
+
// Resolve table_sort: family-specific overrides global
|
| 462 |
+
const familyCfg = config.model_families?.[filters.family] || {};
|
| 463 |
+
const sortRules = familyCfg.table_sort || config.table_sort || [];
|
| 464 |
+
const tableGroupBy = familyCfg.table_group_by || config.table_group_by || "";
|
| 465 |
+
|
| 466 |
+
groupVals.forEach(gv => {
|
| 467 |
+
const rows = filtered.filter(r => String(r[groupCol]) === String(gv));
|
| 468 |
+
if (!rows.length) return;
|
| 469 |
+
rows.sort((a, b) => {
|
| 470 |
+
for (const rule of sortRules) {
|
| 471 |
+
const col = rule.column;
|
| 472 |
+
const mul = rule.direction === "desc" ? -1 : 1;
|
| 473 |
+
if (rule.external_first && col === MODEL_COL) {
|
| 474 |
+
const aExt = isExternalModel(a[col]) ? 0 : 1;
|
| 475 |
+
const bExt = isExternalModel(b[col]) ? 0 : 1;
|
| 476 |
+
if (aExt !== bExt) return (aExt - bExt) * mul;
|
| 477 |
+
}
|
| 478 |
+
const av = a[col], bv = b[col];
|
| 479 |
+
if (av === bv || (av == null && bv == null)) continue;
|
| 480 |
+
if (av == null) return 1;
|
| 481 |
+
if (bv == null) return -1;
|
| 482 |
+
if (typeof av === "number" && typeof bv === "number") {
|
| 483 |
+
if (av !== bv) return (av - bv) * mul;
|
| 484 |
+
} else {
|
| 485 |
+
const aNum = parseFloat(String(av));
|
| 486 |
+
const bNum = parseFloat(String(bv));
|
| 487 |
+
if (!isNaN(aNum) && !isNaN(bNum)) {
|
| 488 |
+
if (aNum !== bNum) return (aNum - bNum) * mul;
|
| 489 |
+
}
|
| 490 |
+
const cmp = String(av).localeCompare(String(bv));
|
| 491 |
+
if (cmp !== 0) return cmp * mul;
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
return 0;
|
| 495 |
+
});
|
| 496 |
+
|
| 497 |
+
// Track row group index for alternating backgrounds
|
| 498 |
+
let prevGroupVal = undefined;
|
| 499 |
+
|
| 500 |
+
const card = document.createElement("div");
|
| 501 |
+
card.className = "table-card";
|
| 502 |
+
|
| 503 |
+
const heading = groupFilterCfg?.value_labels?.[gv] || String(gv);
|
| 504 |
+
|
| 505 |
+
let html = chartsShown ? '' : `<h3>${heading}</h3>`;
|
| 506 |
+
html += `<div class="table-scroll"><table><thead><tr>`;
|
| 507 |
+
html += colDefs.map(c => {
|
| 508 |
+
const tip = c.description ? ` data-tip="${c.description.replace(/"/g, '"')}"` : '';
|
| 509 |
+
return `<th${tip}>${c.label}</th>`;
|
| 510 |
+
}).join("");
|
| 511 |
+
html += `</tr></thead><tbody>`;
|
| 512 |
+
|
| 513 |
+
rows.forEach(r => {
|
| 514 |
+
const oom = isOOMRow(r);
|
| 515 |
+
let rowClass = "";
|
| 516 |
+
if (tableGroupBy) {
|
| 517 |
+
const curVal = String(r[tableGroupBy] ?? "");
|
| 518 |
+
if (prevGroupVal !== undefined && curVal !== prevGroupVal) {
|
| 519 |
+
rowClass = "row-group-break";
|
| 520 |
+
}
|
| 521 |
+
prevGroupVal = curVal;
|
| 522 |
+
}
|
| 523 |
+
html += `<tr class="${rowClass}">`;
|
| 524 |
+
colDefs.forEach(c => {
|
| 525 |
+
const val = r[c.key];
|
| 526 |
+
if (c.isModel) {
|
| 527 |
+
const hfUrl = LINK_PREFIX + val;
|
| 528 |
+
const modelColor = MODEL_COLORS[val]?.border || '#888';
|
| 529 |
+
html += `<td class="model-cell"><span class="model-dot" style="background:${modelColor}"></span><a href="${hfUrl}" target="_blank" rel="noopener" style="color:${modelColor}">${val}</a></td>`;
|
| 530 |
+
} else if (oom) {
|
| 531 |
+
html += `<td><span class="oom">OOM</span></td>`;
|
| 532 |
+
} else if (c.isMetric) {
|
| 533 |
+
html += `<td>${val === null ? '<span class="oom">OOM</span>' : (val ?? "β")}</td>`;
|
| 534 |
+
} else {
|
| 535 |
+
html += `<td>${val || "β"}</td>`;
|
| 536 |
+
}
|
| 537 |
+
});
|
| 538 |
+
html += "</tr>";
|
| 539 |
+
});
|
| 540 |
+
|
| 541 |
+
html += "</tbody></table></div>";
|
| 542 |
+
card.innerHTML = html;
|
| 543 |
+
section.appendChild(card);
|
| 544 |
+
});
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
// βββ Experiment Setup βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 548 |
+
|
| 549 |
+
function buildExperimentSetup() {
|
| 550 |
+
const section = document.getElementById("experiment-setup");
|
| 551 |
+
section.innerHTML = "";
|
| 552 |
+
const familyCfg = config.model_families?.[filters.family] || {};
|
| 553 |
+
const setupMap = familyCfg.experiment_setup || {};
|
| 554 |
+
const groupCol = GROUP_BY;
|
| 555 |
+
const groupVal = filters[groupCol];
|
| 556 |
+
|
| 557 |
+
const deviceVals = groupVal === "all"
|
| 558 |
+
? []
|
| 559 |
+
: (setupMap[groupVal] ? [groupVal] : []);
|
| 560 |
+
|
| 561 |
+
if (!deviceVals.length) {
|
| 562 |
+
section.style.display = "none";
|
| 563 |
+
return;
|
| 564 |
+
}
|
| 565 |
+
section.style.display = "";
|
| 566 |
+
|
| 567 |
+
deviceVals.forEach(dv => {
|
| 568 |
+
const text = setupMap[dv];
|
| 569 |
+
if (!text) return;
|
| 570 |
+
const p = document.createElement("p");
|
| 571 |
+
p.textContent = text;
|
| 572 |
+
section.appendChild(p);
|
| 573 |
+
});
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
// βββ Render βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 577 |
+
|
| 578 |
+
function render() {
|
| 579 |
+
const familyModels = MODEL_FAMILIES[filters.family]
|
| 580 |
+
? new Set(MODEL_FAMILIES[filters.family].models)
|
| 581 |
+
: new Set(ALL_MODELS);
|
| 582 |
+
|
| 583 |
+
const filtered = DATA.filter(r => {
|
| 584 |
+
if (!familyModels.has(r[MODEL_COL])) return false;
|
| 585 |
+
for (const f of config.filters) {
|
| 586 |
+
const fv = filters[f.column];
|
| 587 |
+
if (fv === "all") continue;
|
| 588 |
+
if (String(r[f.column]) !== String(fv)) return false;
|
| 589 |
+
}
|
| 590 |
+
return true;
|
| 591 |
+
});
|
| 592 |
+
|
| 593 |
+
buildChart(filtered);
|
| 594 |
+
const chartsShown = filters[GROUP_BY] !== "all";
|
| 595 |
+
buildTables(filtered, chartsShown);
|
| 596 |
+
buildExperimentSetup();
|
| 597 |
+
}
|
| 598 |
+
|
| 599 |
+
// βββ Init βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 600 |
+
|
| 601 |
+
populateFilters();
|
| 602 |
+
render();
|
| 603 |
+
|
| 604 |
+
})();
|
config.json
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"title": "Edge Inference Benchmarks",
|
| 3 |
+
"subtitle": "Compare throughput and latency across devices and model variants. Use filters to focus on what matters.",
|
| 4 |
+
"model_column": "model",
|
| 5 |
+
"model_family_column": "model_family",
|
| 6 |
+
"model_link_prefix": "https://huggingface.co/",
|
| 7 |
+
"optimized_org": "embedl",
|
| 8 |
+
"filters": [
|
| 9 |
+
{
|
| 10 |
+
"column": "type",
|
| 11 |
+
"label": "Inference Type"
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"column": "batch",
|
| 15 |
+
"label": "Batch Size",
|
| 16 |
+
"type": "number"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"column": "device",
|
| 20 |
+
"label": "Device",
|
| 21 |
+
"value_labels": {
|
| 22 |
+
"orin_nano": "Jetson Orin Nano Super",
|
| 23 |
+
"orin_nano_super": "Jetson Orin Nano Super",
|
| 24 |
+
"agx_orin": "Jetson AGX Orin",
|
| 25 |
+
"agx_thor": "Jetson AGX Thor"
|
| 26 |
+
}
|
| 27 |
+
}
|
| 28 |
+
],
|
| 29 |
+
"metrics": [
|
| 30 |
+
{
|
| 31 |
+
"column": "tps",
|
| 32 |
+
"label": "Tokens / sec",
|
| 33 |
+
"short": "TPS β",
|
| 34 |
+
"higher_is_better": true,
|
| 35 |
+
"description": "Tokens per second (higher is better). Number of output tokens generated per second during the decoding phase. "
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"column": "tpot",
|
| 39 |
+
"label": "Time per Output Token (ms)",
|
| 40 |
+
"short": "TPOT β",
|
| 41 |
+
"higher_is_better": false,
|
| 42 |
+
"description": "Time per output token in ms (lower is better). Average time (in milliseconds) required to generate one output token during decoding. Computed as TPOT = (last_token_ts - first_token_ts) / total_output_tokens."
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"column": "ttft",
|
| 46 |
+
"label": "Time to First Token (ms)",
|
| 47 |
+
"short": "TTFT β",
|
| 48 |
+
"higher_is_better": false,
|
| 49 |
+
"description": "Time to first token in ms (lower is better). Time from request submission to generation of the first output token. This includes vision encoding, prompt prefill, KV cache initialization."
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"column": "e2e",
|
| 53 |
+
"label": "End-to-End Latency (s)",
|
| 54 |
+
"short": "E2E β",
|
| 55 |
+
"higher_is_better": false,
|
| 56 |
+
"description": "End-to-end latency in seconds (lower is better). Total time from request submission to completion of the full generated response. This reflects real user-perceived latency."
|
| 57 |
+
}
|
| 58 |
+
],
|
| 59 |
+
"display_columns": [
|
| 60 |
+
{
|
| 61 |
+
"column": "res",
|
| 62 |
+
"label": "Resolution",
|
| 63 |
+
"visible_when": {
|
| 64 |
+
"type": [
|
| 65 |
+
"video",
|
| 66 |
+
"image"
|
| 67 |
+
]
|
| 68 |
+
}
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"column": "fps",
|
| 72 |
+
"label": "FPS",
|
| 73 |
+
"type": "number",
|
| 74 |
+
"visible_when": {
|
| 75 |
+
"type": [
|
| 76 |
+
"video"
|
| 77 |
+
]
|
| 78 |
+
}
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"column": "frames",
|
| 82 |
+
"label": "Frames",
|
| 83 |
+
"type": "number",
|
| 84 |
+
"visible_when": {
|
| 85 |
+
"type": [
|
| 86 |
+
"video"
|
| 87 |
+
]
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
],
|
| 91 |
+
"chart": {
|
| 92 |
+
"default_metric": "tps",
|
| 93 |
+
"group_by": "device",
|
| 94 |
+
"scenarios": [
|
| 95 |
+
{
|
| 96 |
+
"label": "Text",
|
| 97 |
+
"match": {
|
| 98 |
+
"type": "text"
|
| 99 |
+
}
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"label": "Image Β· 1280Γ720",
|
| 103 |
+
"match": {
|
| 104 |
+
"type": "image",
|
| 105 |
+
"res": "1280x720"
|
| 106 |
+
}
|
| 107 |
+
},
|
| 108 |
+
{
|
| 109 |
+
"label": "Video Β· 1280Γ720 Β· 4 FPS",
|
| 110 |
+
"match": {
|
| 111 |
+
"type": "video",
|
| 112 |
+
"res": "1280x720",
|
| 113 |
+
"fps": 4
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
]
|
| 117 |
+
},
|
| 118 |
+
"table_sort": [
|
| 119 |
+
{
|
| 120 |
+
"column": "res",
|
| 121 |
+
"direction": "asc"
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"column": "fps",
|
| 125 |
+
"direction": "desc"
|
| 126 |
+
}
|
| 127 |
+
],
|
| 128 |
+
"table_group_by": "model",
|
| 129 |
+
"model_families": {
|
| 130 |
+
"Cosmos-Reason2-2B": {
|
| 131 |
+
"table_group_by": "res",
|
| 132 |
+
"experiment_setup": {
|
| 133 |
+
"agx_thor": "Measurement setup: NVIDIA vLLM 26.01, 256 tokens generated, 10 warm-up runs, averaged over 25 runs.",
|
| 134 |
+
"agx_orin": "Measurement setup: NVIDIA vLLM 0.14.0 for Jetson, 256 tokens generated, 10 warm-up runs, averaged over 25 runs.",
|
| 135 |
+
"orin_nano": "Measurement setup: NVIDIA vLLM 0.14.0 for Jetson, 256 tokens generated, 10 warm-up runs, averaged over 25 runs."
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
}
|
data.csv
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
model_family,model,type,batch,device,res,fps,frames,e2e,tps,tpot,ttft
|
| 2 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,1,agx_thor,1920x1080,N/A,N/A,2.8774,88.97,9.78,28.01
|
| 3 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,8,agx_thor,1920x1080,N/A,N/A,7.7989,262.60,13.22,29.21
|
| 4 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,1,agx_thor,854x480,N/A,N/A,3.2376,79.07,10.24,28.37
|
| 5 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,8,agx_thor,854x480,N/A,N/A,7.0134,292.01,13.61,63.15
|
| 6 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,1,agx_thor,1280x720,N/A,N/A,3.0668,83.48,9.68,27.34
|
| 7 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,image,8,agx_thor,1280x720,N/A,N/A,8.0958,252.97,13.77,60.15
|
| 8 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,text,1,agx_thor,N/A,N/A,N/A,2.2147,115.59,8.61,10.17
|
| 9 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,text,8,agx_thor,N/A,N/A,N/A,2.5627,799.15,9.88,26.92
|
| 10 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,1,agx_thor,1280x720,4,12,2.8978,88.34,10.27,186.62
|
| 11 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,1280x720,2,6,5.1466,397.93,12.00,776.65
|
| 12 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,1280x720,4,12,5.1346,398.87,11.96,779.69
|
| 13 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,1,agx_thor,1920x1080,2,6,3.7115,68.98,11.99,411.17
|
| 14 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,1,agx_thor,1920x1080,4,12,3.7154,68.90,12.00,412.31
|
| 15 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,1920x1080,2,6,8.4629,242.00,16.00,1744.43
|
| 16 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,1920x1080,4,12,8.3780,244.45,15.64,1741.12
|
| 17 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,1,agx_thor,854x480,2,6,2.6527,96.50,9.63,115.92
|
| 18 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,1,agx_thor,854x480,4,12,2.6462,96.74,9.60,115.65
|
| 19 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,854x480,2,6,3.8647,529.93,11.02,349.41
|
| 20 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-NVFP4A16,video,8,agx_thor,854x480,4,12,4.0195,509.52,11.55,349.17
|
| 21 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_orin,1280x720,N/A,N/A,3.2759,70.82,11.80,54.90
|
| 22 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_orin,1920x1080,N/A,N/A,3.1621,73.37,11.75,53.14
|
| 23 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_orin,854x480,N/A,N/A,3.2648,71.06,11.76,55.98
|
| 24 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,text,1,agx_orin,N/A,N/A,N/A,2.5601,100.00,9.85,35.56
|
| 25 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,1280x720,4,12,3.4416,74.38,11.71,243.54
|
| 26 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,1280x720,2,6,3.4448,74.31,11.75,248.53
|
| 27 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,1920x1080,2,6,4.4439,57.61,14.06,507.71
|
| 28 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,1920x1080,4,12,4.4386,57.68,14.00,508.39
|
| 29 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,854x480,2,6,3.0156,84.89,10.77,143.20
|
| 30 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_orin,854x480,4,12,3.0035,85.23,10.76,144.12
|
| 31 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_thor,1280x720,N/A,N/A,3.0483,83.98,9.81,15.44
|
| 32 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,8,agx_thor,1280x720,N/A,N/A,9.1849,222.97,12.98,28.81
|
| 33 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_thor,1920x1080,N/A,N/A,2.8439,90.02,9.71,15.53
|
| 34 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,8,agx_thor,1920x1080,N/A,N/A,6.2494,327.71,12.81,28.80
|
| 35 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,agx_thor,854x480,N/A,N/A,3.1369,81.61,10.18,15.95
|
| 36 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,8,agx_thor,854x480,N/A,N/A,6.9387,295.15,12.96,28.91
|
| 37 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,text,1,agx_thor,N/A,N/A,N/A,2.2340,114.59,8.67,11.13
|
| 38 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,text,8,agx_thor,N/A,N/A,N/A,2.2974,891.44,8.86,24.25
|
| 39 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_thor,1280x720,4,12,2.5977,98.55,9.10,185.63
|
| 40 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,1280x720,2,6,5.0695,403.98,11.64,779.90
|
| 41 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,1280x720,4,12,5.0521,405.37,11.63,775.99
|
| 42 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_thor,1920x1080,2,6,3.5969,71.17,11.52,412.00
|
| 43 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_thor,1920x1080,4,12,3.5756,71.60,11.39,415.89
|
| 44 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,1920x1080,2,6,8.2949,246.90,15.34,1742.22
|
| 45 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,1920x1080,4,12,8.2769,247.43,15.30,1741.64
|
| 46 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_thor,854x480,2,6,2.5015,102.34,9.06,113.30
|
| 47 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,agx_thor,854x480,4,12,2.5516,100.33,9.23,116.53
|
| 48 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,854x480,2,6,3.8613,530.39,10.92,350.04
|
| 49 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,8,agx_thor,854x480,4,12,3.9974,512.34,11.43,349.00
|
| 50 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,orin_nano_super,1280x720,N/A,N/A,5.5010,42.36,20.87,105.69
|
| 51 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,orin_nano_super,1920x1080,N/A,N/A,5.4421,42.81,20.88,105.89
|
| 52 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,image,1,orin_nano_super,854x480,N/A,N/A,5.5183,42.22,20.88,107.25
|
| 53 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,text,1,orin_nano_super,N/A,N/A,N/A,4.5489,56.28,17.42,84.61
|
| 54 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,1280x720,4,12,5.8635,43.66,20.80,334.08
|
| 55 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,1280x720,2,6,5.8696,43.61,20.79,324.38
|
| 56 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,1920x1080,2,6,4.8353,31.02,25.20,650.74
|
| 57 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,1920x1080,4,12,4.8483,30.94,25.23,657.56
|
| 58 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,854x480,2,6,5.1020,50.18,18.89,154.79
|
| 59 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16,video,1,orin_nano_super,854x480,4,12,5.1017,50.18,18.88,154.10
|
| 60 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,agx_orin,1280x720,N/A,N/A,3.5585,71.94,11.69,57.02
|
| 61 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,agx_orin,1280x720,N/A,N/A,10.3196,198.46,21.81,170.71
|
| 62 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,agx_orin,1920x1080,N/A,N/A,3.4224,74.80,11.68,54.49
|
| 63 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,agx_orin,1920x1080,N/A,N/A,9.8926,207.02,21.15,160.66
|
| 64 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,agx_orin,854x480,N/A,N/A,3.5028,73.08,11.67,56.27
|
| 65 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,agx_orin,854x480,N/A,N/A,11.6759,175.40,21.40,182.25
|
| 66 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,text,1,agx_orin,N/A,N/A,N/A,2.5640,99.84,9.86,36.08
|
| 67 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,text,8,agx_orin,N/A,N/A,N/A,2.8152,727.47,10.67,67.26
|
| 68 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,1280x720,4,12,3.4165,74.93,11.57,248.51
|
| 69 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,1280x720,2,6,3.4151,74.96,11.61,247.64
|
| 70 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,1280x720,4,12,7.7852,263.06,19.56,914.51
|
| 71 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,1280x720,2,6,7.6469,267.82,19.09,913.91
|
| 72 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,1920x1080,2,6,4.3864,58.36,13.93,504.30
|
| 73 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,1920x1080,4,12,4.4294,57.80,13.95,505.19
|
| 74 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,1920x1080,2,6,11.4902,178.24,22.12,2020.67
|
| 75 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,1920x1080,4,12,11.5039,178.03,22.19,2020.49
|
| 76 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,854x480,2,6,2.9761,86.02,10.62,141.70
|
| 77 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,agx_orin,854x480,4,12,2.9778,85.97,10.62,143.88
|
| 78 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,854x480,2,6,6.4896,315.58,19.83,422.90
|
| 79 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,agx_orin,854x480,4,12,6.4374,318.14,19.69,423.10
|
| 80 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,orin_nano_super,1280x720,N/A,N/A,6.0481,42.33,20.90,110.47
|
| 81 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,orin_nano_super,1280x720,N/A,N/A,26.8477,76.28,22.36,8962.49
|
| 82 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,orin_nano_super,1920x1080,N/A,N/A,5.7896,44.22,20.88,101.76
|
| 83 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,orin_nano_super,1920x1080,N/A,N/A,27.6012,74.20,22.41,8993.50
|
| 84 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,1,orin_nano_super,854x480,N/A,N/A,5.9725,42.86,20.92,109.79
|
| 85 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,image,8,orin_nano_super,854x480,N/A,N/A,26.7869,76.46,22.36,8956.04
|
| 86 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,text,1,orin_nano_super,N/A,N/A,N/A,4.4947,56.96,17.24,77.06
|
| 87 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,text,8,orin_nano_super,N/A,N/A,N/A,18.4232,111.16,17.55,7032.02
|
| 88 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,1280x720,4,12,5.8692,43.62,20.82,335.23
|
| 89 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,1280x720,2,6,5.8388,43.84,20.77,336.45
|
| 90 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,1280x720,4,12,25.2331,81.16,22.34,8713.41
|
| 91 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,1280x720,2,6,25.2252,81.19,22.34,8712.80
|
| 92 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,1920x1080,2,6,7.5462,33.92,25.29,648.85
|
| 93 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,1920x1080,4,12,7.5770,33.79,25.35,666.99
|
| 94 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,1920x1080,2,6,35.2481,58.10,29.46,11375.65
|
| 95 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,1920x1080,4,12,35.0017,58.51,29.46,11354.12
|
| 96 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,854x480,2,6,5.1049,50.15,18.91,151.20
|
| 97 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,1,orin_nano_super,854x480,4,12,5.1000,50.20,18.90,152.69
|
| 98 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,854x480,2,6,21.5985,94.82,19.83,7764.67
|
| 99 |
+
Cosmos-Reason2-2B,embedl/Cosmos-Reason2-2B-W4A16-Edge2,video,8,orin_nano_super,854x480,4,12,21.5877,94.87,19.80,7750.95
|
| 100 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_orin,1280x720,N/A,N/A,8.6497,26.47,23.64,68.63
|
| 101 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_orin,1920x1080,N/A,N/A,5.9558,38.45,23.63,57.30
|
| 102 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_orin,854x480,N/A,N/A,6.0213,38.03,23.66,58.22
|
| 103 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,text,1,agx_orin,N/A,N/A,N/A,5.6196,45.55,21.79,36.40
|
| 104 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,1280x720,4,12,6.4673,39.58,23.56,249.17
|
| 105 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,1280x720,2,6,6.4872,39.46,23.58,250.17
|
| 106 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,1920x1080,2,6,7.4784,34.23,25.92,521.39
|
| 107 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,1920x1080,4,12,7.5190,34.05,25.93,523.36
|
| 108 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,854x480,2,6,6.0471,42.33,22.59,146.10
|
| 109 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_orin,854x480,4,12,6.0397,42.39,22.63,145.79
|
| 110 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_thor,1280x720,N/A,N/A,4.8338,52.96,16.96,28.90
|
| 111 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,8,agx_thor,1280x720,N/A,N/A,10.6920,191.55,25.67,74.92
|
| 112 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_thor,1920x1080,N/A,N/A,4.9062,52.18,16.89,28.89
|
| 113 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,8,agx_thor,1920x1080,N/A,N/A,11.3606,180.27,25.21,76.51
|
| 114 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,agx_thor,854x480,N/A,N/A,4.6755,54.75,16.79,27.95
|
| 115 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,8,agx_thor,854x480,N/A,N/A,10.4721,195.57,25.16,73.86
|
| 116 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,text,1,agx_thor,N/A,N/A,N/A,3.9263,65.20,15.27,16.72
|
| 117 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,text,8,agx_thor,N/A,N/A,N/A,5.9494,344.24,22.92,65.90
|
| 118 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_thor,1280x720,4,12,4.5537,56.22,16.73,192.67
|
| 119 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,1280x720,2,6,7.0704,289.66,19.80,778.89
|
| 120 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,1280x720,4,12,7.0242,291.56,19.61,779.39
|
| 121 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_thor,1920x1080,2,6,5.2182,49.06,18.16,408.99
|
| 122 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_thor,1920x1080,4,12,5.2752,48.53,18.38,409.24
|
| 123 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,1920x1080,2,6,10.1481,201.81,22.92,1749.06
|
| 124 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,1920x1080,4,12,10.4564,195.86,23.66,1746.96
|
| 125 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_thor,854x480,2,6,5.0284,50.91,18.87,124.78
|
| 126 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,agx_thor,854x480,4,12,4.5504,56.26,17.01,123.61
|
| 127 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,854x480,2,6,5.6951,359.61,18.47,351.83
|
| 128 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,agx_thor,854x480,4,12,5.6608,361.79,18.33,354.19
|
| 129 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,1,orin_nano_super,OOM,N/A,N/A,OOM,OOM,OOM,OOM
|
| 130 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,text,1,orin_nano_super,N/A,N/A,N/A,OOM,OOM,OOM,OOM
|
| 131 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,1,orin_nano_super,OOM,OOM,OOM,OOM,OOM,OOM,OOM
|
| 132 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,image,8,orin_nano_super,OOM,N/A,N/A,OOM,OOM,OOM,OOM
|
| 133 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,text,8,orin_nano_super,N/A,N/A,N/A,OOM,OOM,OOM,OOM
|
| 134 |
+
Cosmos-Reason2-2B,nvidia/Cosmos-Reason2-2B,video,8,orin_nano_super,OOM,OOM,OOM,OOM,OOM,OOM,OOM
|
embedl_logo_black_bg.svg
ADDED
|
|
embedl_logo_white_bg.svg
ADDED
|
|
index.html
CHANGED
|
@@ -1,19 +1,90 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
</html>
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8"/>
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
| 6 |
+
<title>Edge Inference Benchmarks β Embedl</title>
|
| 7 |
+
<link rel="stylesheet" href="style.css"/>
|
| 8 |
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
|
| 9 |
+
</head>
|
| 10 |
+
<body>
|
| 11 |
+
|
| 12 |
+
<div class="page">
|
| 13 |
+
<!-- Sidebar -->
|
| 14 |
+
<aside class="sidebar" id="sidebar">
|
| 15 |
+
<a href="https://embedl.com" target="_blank" class="sidebar-logo">
|
| 16 |
+
<img src="embedl_logo_black_bg.svg" alt="Embedl" height="28">
|
| 17 |
+
</a>
|
| 18 |
+
<nav class="sidebar-nav" id="family-nav"></nav>
|
| 19 |
+
</aside>
|
| 20 |
+
|
| 21 |
+
<!-- Main -->
|
| 22 |
+
<main class="main">
|
| 23 |
+
<div class="main-inner">
|
| 24 |
+
<!-- Hero -->
|
| 25 |
+
<header class="hero">
|
| 26 |
+
<div class="hero-badge"><span>Embedl Models</span></div>
|
| 27 |
+
<h1 id="hero-title">Edge Inference <span class="accent">Benchmarks</span></h1>
|
| 28 |
+
<p class="hero-sub" id="hero-sub">Compare throughput and latency across devices and model variants.</p>
|
| 29 |
+
</header>
|
| 30 |
+
|
| 31 |
+
<!-- Filters -->
|
| 32 |
+
<section class="filters-bar" id="filters-bar"></section>
|
| 33 |
+
|
| 34 |
+
<!-- Charts -->
|
| 35 |
+
<section id="charts-section"></section>
|
| 36 |
+
|
| 37 |
+
<!-- Tables -->
|
| 38 |
+
<section id="tables-section"></section>
|
| 39 |
+
|
| 40 |
+
<!-- Metric Legend -->
|
| 41 |
+
<section class="legend-section">
|
| 42 |
+
<div class="legend-grid" id="legend-grid"></div>
|
| 43 |
+
<div class="experiment-setup" id="experiment-setup"></div>
|
| 44 |
+
</section>
|
| 45 |
+
</div>
|
| 46 |
+
</main>
|
| 47 |
+
</div>
|
| 48 |
+
|
| 49 |
+
<footer class="footer">
|
| 50 |
+
<div class="footer-inner">
|
| 51 |
+
<div class="footer-grid">
|
| 52 |
+
<div class="footer-col">
|
| 53 |
+
<a href="https://embedl.com" target="_blank" class="footer-logo-img">
|
| 54 |
+
<img src="embedl_logo_black_bg.svg" alt="Embedl" height="24">
|
| 55 |
+
</a>
|
| 56 |
+
<div class="footer-logo">© 2026 Embedl All rights reserved. <a href="https://www.embedl.com/contact" target="_blank">Contact Us.</a></div>
|
| 57 |
+
<div class="footer-social">
|
| 58 |
+
<a href="https://www.linkedin.com/company/13991327/" target="_blank" rel="noopener" aria-label="LinkedIn">
|
| 59 |
+
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
|
| 60 |
+
</a>
|
| 61 |
+
<a href="https://www.instagram.com/embedl_/" target="_blank" rel="noopener" aria-label="Instagram">
|
| 62 |
+
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>
|
| 63 |
+
</a>
|
| 64 |
+
<a href="https://www.facebook.com/people/Embedl-AB/100088717652886/" target="_blank" rel="noopener" aria-label="Facebook">
|
| 65 |
+
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
|
| 66 |
+
</a>
|
| 67 |
+
<a href="https://www.youtube.com/channel/UCR2uU2PnTzr4D1hOn3nsBwg" target="_blank" rel="noopener" aria-label="YouTube">
|
| 68 |
+
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M23.498 6.186a3.016 3.016 0 00-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 00.502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 002.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 002.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
|
| 69 |
+
</a>
|
| 70 |
+
<a href="https://github.com/embedl" target="_blank" rel="noopener" aria-label="GitHub">
|
| 71 |
+
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
| 72 |
+
</a>
|
| 73 |
+
</div>
|
| 74 |
+
</div>
|
| 75 |
+
<div class="footer-col">
|
| 76 |
+
<div class="footer-col-title">Sweden</div>
|
| 77 |
+
<p>Gamla AlmedalsvΓ€gen 21,<br>412 63 Gothenburg, Sweden</p>
|
| 78 |
+
<p>SE +46 31 105 891</p>
|
| 79 |
+
</div>
|
| 80 |
+
<div class="footer-col">
|
| 81 |
+
<div class="footer-col-title">USA</div>
|
| 82 |
+
<p>470 Ramona Street,<br>Palo Alto, CA 94301, USA</p>
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
</div>
|
| 86 |
+
</footer>
|
| 87 |
+
|
| 88 |
+
<script src="app.js"></script>
|
| 89 |
+
</body>
|
| 90 |
</html>
|
style.css
CHANGED
|
@@ -1,28 +1,378 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 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 |
}
|
|
|
|
| 1 |
+
/* ββ Palette ββββββββββββββββββββββββββββββββββββββββββββ */
|
| 2 |
+
:root {
|
| 3 |
+
--bg: #0B1527;
|
| 4 |
+
--bg-opaque: rgba(11, 21, 39,0.45);
|
| 5 |
+
--bg-surface: #1a1a2e;
|
| 6 |
+
--teal: #58b1c3;
|
| 7 |
+
--green: #6fcf97;
|
| 8 |
+
--red: #ff4d6d;
|
| 9 |
+
--pink: #ff6ec7;
|
| 10 |
+
--purple: #9b5de5;
|
| 11 |
+
--blue: #007F9E;
|
| 12 |
+
--neutral: #667788;
|
| 13 |
+
--text: #e8e8e8;
|
| 14 |
+
--text-muted: #8899aa;
|
| 15 |
+
--text-dim: #5a6a7a;
|
| 16 |
+
--border: rgba(255,255,255,0.06);
|
| 17 |
+
--chart-grid: rgba(255,255,255,0.06);
|
| 18 |
+
--btn-hover-bg: rgba(255,255,255,0.03);
|
| 19 |
+
--btn-active-bg: rgba(88,177,195,0.12);
|
| 20 |
+
--btn-active-border: rgba(88,177,195,0.3);
|
| 21 |
+
--sidebar-hover-bg: rgba(255,255,255,0.02);
|
| 22 |
+
--sidebar-active-bg: rgba(88,177,195,0.04);
|
| 23 |
+
--row-hover-bg: rgba(255,255,255,0.02);
|
| 24 |
+
--row-border: rgba(255,255,255,0.03);
|
| 25 |
+
--code-bg: rgba(88,177,195,0.1);
|
| 26 |
+
--tooltip-bg: #2c3e50;
|
| 27 |
+
--tooltip-text: #f1f1f1;
|
| 28 |
+
--tooltip-body: #d9d9d9;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
/* ββ Reset & Base βββββββββββββββββββββββββββββββββββββββ */
|
| 32 |
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
| 33 |
+
html { font-size: 16px; }
|
| 34 |
body {
|
| 35 |
+
font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
| 36 |
+
background: var(--bg);
|
| 37 |
+
color: var(--text);
|
| 38 |
+
line-height: 1.6;
|
| 39 |
+
-webkit-font-smoothing: antialiased;
|
| 40 |
+
position: relative;
|
| 41 |
+
}
|
| 42 |
+
body::before {
|
| 43 |
+
content: "";
|
| 44 |
+
position: fixed;
|
| 45 |
+
top: -260px;
|
| 46 |
+
left: 50%;
|
| 47 |
+
transform: translateX(-50%);
|
| 48 |
+
width: 69rem;
|
| 49 |
+
height: 42rem;
|
| 50 |
+
background: radial-gradient(circle, rgba(0,226,213,0.25) 0%, rgba(18,208,254,0.15) 30%, transparent 70%);
|
| 51 |
+
filter: blur(80px);
|
| 52 |
+
pointer-events: none;
|
| 53 |
+
z-index: 0;
|
| 54 |
+
}
|
| 55 |
+
code {
|
| 56 |
+
background: var(--code-bg);
|
| 57 |
+
color: var(--teal);
|
| 58 |
+
padding: 0.15em 0.45em;
|
| 59 |
+
border-radius: 4px;
|
| 60 |
+
font-size: 0.95em;
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/* ββ Page Layout βββββββββββββββββββββββββββββββββββββββ */
|
| 64 |
+
.page {
|
| 65 |
+
position: relative;
|
| 66 |
+
z-index: 1;
|
| 67 |
+
display: flex;
|
| 68 |
+
flex-direction: row;
|
| 69 |
+
min-height: 100vh;
|
| 70 |
+
max-width: 1440px;
|
| 71 |
+
margin: 0 auto;
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
/* ββ Sidebar βββββββββββββββββββββββββββββββββββββββββββ */
|
| 75 |
+
.sidebar {
|
| 76 |
+
width: 280px;
|
| 77 |
+
max-width: 300px;
|
| 78 |
+
flex-shrink: 0;
|
| 79 |
+
padding: 2rem 0;
|
| 80 |
+
position: sticky;
|
| 81 |
+
top: 0;
|
| 82 |
+
height: 100vh;
|
| 83 |
+
overflow-y: auto;
|
| 84 |
+
}
|
| 85 |
+
.sidebar-logo {
|
| 86 |
+
display: block;
|
| 87 |
+
padding: 0 1.25rem 3.25rem;
|
| 88 |
+
}
|
| 89 |
+
.sidebar-nav {
|
| 90 |
+
display: flex;
|
| 91 |
+
flex-direction: column;
|
| 92 |
+
}
|
| 93 |
+
.sidebar-item {
|
| 94 |
+
display: block;
|
| 95 |
+
padding: 0.5rem 1.25rem;
|
| 96 |
+
font-size: 1.25rem;
|
| 97 |
+
font-weight: 400;
|
| 98 |
+
color: var(--text-dim);
|
| 99 |
+
text-decoration: none;
|
| 100 |
+
cursor: pointer;
|
| 101 |
+
border-left: 2px solid transparent;
|
| 102 |
+
transition: color 0.15s, background 0.15s, border-color 0.15s;
|
| 103 |
+
}
|
| 104 |
+
.sidebar-item:hover {
|
| 105 |
+
color: var(--text-muted);
|
| 106 |
+
}
|
| 107 |
+
.sidebar-item.active {
|
| 108 |
+
color: var(--teal);
|
| 109 |
+
font-weight: 600;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
/* ββ Main Column βββββββββββββββββββββββββββββββββββββββ */
|
| 113 |
+
.main {
|
| 114 |
+
flex: 1;
|
| 115 |
+
min-width: 0;
|
| 116 |
+
}
|
| 117 |
+
.main-inner {
|
| 118 |
+
max-width: 1100px;
|
| 119 |
+
width: 100%;
|
| 120 |
+
padding: 0 2rem 2rem;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
/* ββ Hero ββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 124 |
+
.hero {
|
| 125 |
+
position: relative;
|
| 126 |
+
padding: 2rem 0 2.5rem;
|
| 127 |
+
}
|
| 128 |
+
.hero-badge {
|
| 129 |
+
display: inline-block;
|
| 130 |
+
padding: 1px;
|
| 131 |
+
border-radius: 999px;
|
| 132 |
+
background: linear-gradient(90deg, var(--teal),var(--blue));
|
| 133 |
+
margin-bottom: 1rem;
|
| 134 |
+
}
|
| 135 |
+
.hero-badge span {
|
| 136 |
+
display: inline-block;
|
| 137 |
+
padding: 0.35rem 1rem;
|
| 138 |
+
border-radius: 999px;
|
| 139 |
+
background: var(--bg-opaque);
|
| 140 |
+
color: var(--teal);
|
| 141 |
+
font-size: 1rem;
|
| 142 |
+
font-weight: 600;
|
| 143 |
+
letter-spacing: 0.03em;
|
| 144 |
+
text-transform: uppercase;
|
| 145 |
+
}
|
| 146 |
+
.hero h1 {
|
| 147 |
+
font-size: clamp(1.8rem, 3.5vw, 3.0rem);
|
| 148 |
+
font-weight: 700;
|
| 149 |
+
margin-bottom: 0.5rem;
|
| 150 |
+
letter-spacing: -0.02em;
|
| 151 |
+
}
|
| 152 |
+
.hero .accent { color: var(--teal); }
|
| 153 |
+
.hero-sub {
|
| 154 |
+
color: var(--text-muted);
|
| 155 |
+
font-size: 1.1rem;
|
| 156 |
+
max-width: 620px;
|
| 157 |
+
line-height: 1.6;
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
/* ββ Filters βββββββββββββββββββββββββββββββββββββββββββ */
|
| 161 |
+
.filters-bar {
|
| 162 |
+
display: flex;
|
| 163 |
+
flex-wrap: wrap;
|
| 164 |
+
gap: 1.25rem;
|
| 165 |
+
padding: 1rem 0;
|
| 166 |
+
top: 0;
|
| 167 |
+
z-index: 10;
|
| 168 |
+
}
|
| 169 |
+
.filter-group label {
|
| 170 |
+
display: block;
|
| 171 |
+
font-size: 0.8rem;
|
| 172 |
+
font-weight: 600;
|
| 173 |
+
text-transform: uppercase;
|
| 174 |
+
letter-spacing: 0.08em;
|
| 175 |
+
color: var(--text-dim);
|
| 176 |
+
margin-bottom: 0.25rem;
|
| 177 |
+
}
|
| 178 |
+
.btn-group { display: flex; gap: 0; }
|
| 179 |
+
.btn {
|
| 180 |
+
background: transparent;
|
| 181 |
+
border: 1px solid var(--border);
|
| 182 |
+
color: var(--text-muted);
|
| 183 |
+
font-size: 1rem;
|
| 184 |
+
font-weight: 400;
|
| 185 |
+
padding: 0.45rem 1rem;
|
| 186 |
+
cursor: pointer;
|
| 187 |
+
transition: all 0.15s;
|
| 188 |
+
}
|
| 189 |
+
.btn:first-child { border-radius: 6px 0 0 6px; }
|
| 190 |
+
.btn:last-child { border-radius: 0 6px 6px 0; }
|
| 191 |
+
.btn:not(:first-child) { margin-left: -1px; }
|
| 192 |
+
.btn:hover {
|
| 193 |
+
color: var(--text);
|
| 194 |
+
background: var(--btn-hover-bg);
|
| 195 |
+
}
|
| 196 |
+
.btn.active {
|
| 197 |
+
background: var(--btn-active-bg);
|
| 198 |
+
color: var(--teal);
|
| 199 |
+
border-color: var(--btn-active-border);
|
| 200 |
+
font-weight: 600;
|
| 201 |
+
z-index: 1;
|
| 202 |
+
position: relative;
|
| 203 |
}
|
| 204 |
|
| 205 |
+
/* ββ Chart βββββββββββββββββββββββββββββββββββββββββββββ */
|
| 206 |
+
.chart-block {
|
| 207 |
+
margin: 1.5rem 0;
|
| 208 |
+
}
|
| 209 |
+
.chart-heading {
|
| 210 |
+
font-size: 1.25rem;
|
| 211 |
+
font-weight: 600;
|
| 212 |
+
color: var(--text);
|
| 213 |
+
margin-bottom: 0.25rem;
|
| 214 |
+
}
|
| 215 |
+
.chart-subtitle {
|
| 216 |
+
font-size: 1rem;
|
| 217 |
+
color: var(--text-muted);
|
| 218 |
+
margin-bottom: 0.75rem;
|
| 219 |
+
}
|
| 220 |
+
.chart-wrap {
|
| 221 |
+
height: 340px;
|
| 222 |
}
|
| 223 |
|
| 224 |
+
/* ββ Tables ββββββββββββββββββββββββββββββββββββββββββββ */
|
| 225 |
+
.table-card {
|
| 226 |
+
margin: 1.5rem 0 2rem;
|
| 227 |
+
}
|
| 228 |
+
.table-card h3 {
|
| 229 |
+
font-size: 1.15rem;
|
| 230 |
+
font-weight: 600;
|
| 231 |
+
color: var(--text);
|
| 232 |
+
margin-bottom: 0.5rem;
|
| 233 |
+
padding-bottom: 0.5rem;
|
| 234 |
+
border-bottom: 1px solid var(--border);
|
| 235 |
+
}
|
| 236 |
+
.table-scroll {
|
| 237 |
+
overflow-x: auto;
|
| 238 |
+
scrollbar-color: var(--text-dim) var(--border);
|
| 239 |
+
scrollbar-width: thin;
|
| 240 |
+
}
|
| 241 |
+
.table-scroll::-webkit-scrollbar { height: 8px; }
|
| 242 |
+
.table-scroll::-webkit-scrollbar-track { background: var(--border); border-radius: 4px; }
|
| 243 |
+
.table-scroll::-webkit-scrollbar-thumb { background: var(--text-dim); border-radius: 4px; }
|
| 244 |
+
.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
|
| 245 |
+
table { width: 100%; border-collapse: collapse; font-size: 1rem; }
|
| 246 |
+
thead th {
|
| 247 |
+
text-align: left;
|
| 248 |
+
font-weight: 600;
|
| 249 |
+
font-size: 0.8rem;
|
| 250 |
+
text-transform: uppercase;
|
| 251 |
+
letter-spacing: 0.05em;
|
| 252 |
+
color: var(--text-dim);
|
| 253 |
+
padding: 0.5rem 0.75rem;
|
| 254 |
+
border-bottom: 1px solid var(--border);
|
| 255 |
+
white-space: nowrap;
|
| 256 |
+
}
|
| 257 |
+
tbody td {
|
| 258 |
+
padding: 0.5rem 0.75rem;
|
| 259 |
+
border-bottom: 1px solid var(--row-border);
|
| 260 |
+
white-space: nowrap;
|
| 261 |
+
color: var(--text-muted);
|
| 262 |
+
}
|
| 263 |
+
tbody tr:last-child td { border-bottom: none; }
|
| 264 |
+
tbody tr:hover { background: var(--row-hover-bg); }
|
| 265 |
+
.model-cell { display: flex; align-items: center; gap: 0.5rem; font-weight: 500; color: var(--text); }
|
| 266 |
+
.model-cell a { color: var(--teal); text-decoration: none; transition: color 0.15s; }
|
| 267 |
+
.model-cell a:hover { text-decoration: underline; }
|
| 268 |
+
.model-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
|
| 269 |
+
.oom { color: var(--red); font-weight: 600; }
|
| 270 |
+
tbody tr.row-group-break td { border-top: 2px solid var(--border); }
|
| 271 |
+
|
| 272 |
+
/* ββ Legend βββββββββββββββββββββββββββββββββββββββββββββ */
|
| 273 |
+
.legend-section {
|
| 274 |
+
margin: 2rem 0;
|
| 275 |
+
padding-top: 1.5rem;
|
| 276 |
+
}
|
| 277 |
+
.legend-grid {
|
| 278 |
+
display: grid;
|
| 279 |
+
grid-template-columns: 1fr;
|
| 280 |
+
gap: 0.25rem;
|
| 281 |
+
font-size: 0.8rem;
|
| 282 |
+
color: var(--text-dim);
|
| 283 |
+
}
|
| 284 |
+
.legend-grid strong { color: var(--text-muted); font-weight: 500; }
|
| 285 |
+
.experiment-setup {
|
| 286 |
+
margin-top: 0.75rem;
|
| 287 |
+
font-size: 0.95rem;
|
| 288 |
+
color: var(--text-dim);
|
| 289 |
+
font-style: italic;
|
| 290 |
+
line-height: 1.6;
|
| 291 |
}
|
| 292 |
+
.experiment-setup p { margin-bottom: 0.25rem; }
|
| 293 |
|
| 294 |
+
/* ββ Footer ββββββββββββββββββββββββββββββββββββββββββββ */
|
| 295 |
+
.footer {
|
| 296 |
+
padding: 2.5rem 0;
|
| 297 |
+
margin-top: 2rem;
|
| 298 |
+
}
|
| 299 |
+
.footer-inner {
|
| 300 |
+
max-width: 1440px;
|
| 301 |
+
margin: 0 auto;
|
| 302 |
+
padding: 0 2rem;
|
| 303 |
+
}
|
| 304 |
+
.footer-grid {
|
| 305 |
+
display: flex;
|
| 306 |
+
gap: 3rem;
|
| 307 |
+
flex-wrap: wrap;
|
| 308 |
+
}
|
| 309 |
+
.footer-col {
|
| 310 |
+
font-size: 1rem;
|
| 311 |
+
color: var(--text-dim);
|
| 312 |
+
line-height: 1.7;
|
| 313 |
+
}
|
| 314 |
+
.footer-col p { margin: 0; }
|
| 315 |
+
.footer-col-title {
|
| 316 |
+
font-size: 0.85rem;
|
| 317 |
+
font-weight: 600;
|
| 318 |
+
text-transform: uppercase;
|
| 319 |
+
letter-spacing: 0.08em;
|
| 320 |
+
color: var(--text);
|
| 321 |
+
}
|
| 322 |
+
.footer-logo-img {
|
| 323 |
+
display: block;
|
| 324 |
+
margin-bottom: 0.5rem;
|
| 325 |
+
}
|
| 326 |
+
.footer-logo {
|
| 327 |
+
font-size: 1rem;
|
| 328 |
+
color: var(--text-muted);
|
| 329 |
+
margin-bottom: 1.2rem;
|
| 330 |
+
}
|
| 331 |
+
.footer-logo a { color: var(--text-muted); text-decoration: none; }
|
| 332 |
+
.footer-logo a:hover { text-decoration: underline; }
|
| 333 |
+
.footer-social {
|
| 334 |
+
display: flex;
|
| 335 |
+
gap: 0.75rem;
|
| 336 |
+
}
|
| 337 |
+
.footer-social a {
|
| 338 |
+
color: var(--text-dim);
|
| 339 |
+
transition: color 0.15s;
|
| 340 |
+
display: flex;
|
| 341 |
+
align-items: center;
|
| 342 |
+
}
|
| 343 |
+
.footer-social a:hover {
|
| 344 |
+
color: var(--teal);
|
| 345 |
}
|
| 346 |
|
| 347 |
+
/* ββ Responsive ββββββββββββββββββββββββββββββββββββββββ */
|
| 348 |
+
@media (max-width: 768px) {
|
| 349 |
+
.page { flex-direction: column; }
|
| 350 |
+
.sidebar {
|
| 351 |
+
width: 100%;
|
| 352 |
+
max-width: none;
|
| 353 |
+
height: auto;
|
| 354 |
+
position: static;
|
| 355 |
+
border-right: none;
|
| 356 |
+
border-bottom: 1px solid var(--border);
|
| 357 |
+
padding: 0.75rem 0;
|
| 358 |
+
}
|
| 359 |
+
.sidebar-nav {
|
| 360 |
+
flex-direction: row;
|
| 361 |
+
flex-wrap: wrap;
|
| 362 |
+
padding: 0 0.75rem;
|
| 363 |
+
}
|
| 364 |
+
.sidebar-item {
|
| 365 |
+
border-left: none;
|
| 366 |
+
border-bottom: 2px solid transparent;
|
| 367 |
+
padding: 0.4rem 0.75rem;
|
| 368 |
+
font-size: 0.9rem;
|
| 369 |
+
}
|
| 370 |
+
.sidebar-item.active {
|
| 371 |
+
border-left-color: transparent;
|
| 372 |
+
border-bottom-color: var(--teal);
|
| 373 |
+
}
|
| 374 |
+
.main-inner { padding: 0 1rem 2rem; }
|
| 375 |
+
.filters-bar { gap: 0.75rem; }
|
| 376 |
+
.btn { font-size: 0.85rem; padding: 0.35rem 0.7rem; }
|
| 377 |
+
.chart-wrap { height: 260px; }
|
| 378 |
}
|