OptimismBench / app /src /content /embeds /robustness.html
seonglae's picture
hero: restore 'only Anthropic is pessimistic'; revert bias-stability plane to original size
4e92688
Raw
History Blame Contribute Delete
8.73 kB
<div id="ob-rb" role="img" aria-label="Bias-stability plane: mean Skew across six languages on the x-axis versus inter-language standard deviation on the y-axis, for 17 models. Most models sit to the right of zero (optimist) and low (robust); only Anthropic's Opus and Sonnet are robust pessimists.">
<div class="rb-head"><span class="rb-title">Bias-stability plane</span><span class="rb-sub">how big, and how stable across languages</span></div>
<div class="rb-wrap"></div>
<div class="rb-cap">Mean Skew across six native-prompt languages (horizontal) against the spread across those languages (vertical). Right of the line is optimist, left is pessimist; below the dashed line is language-robust. Hover for values.</div>
</div>
<style>
#ob-rb { font:13px/1.4 system-ui,sans-serif; color:var(--text-color,#222); width:100%; max-width:540px; margin:0 auto; position:relative; }
#ob-rb .rb-head { display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
#ob-rb .rb-title { font-weight:650; font-size:15px; }
#ob-rb .rb-sub { font-size:12px; color:var(--muted-color,#666); margin-left:auto; }
#ob-rb svg { display:block; width:100%; height:auto; overflow:visible; }
#ob-rb .rb-cap { margin-top:8px; font-size:12px; color:var(--muted-color,#666); }
#ob-rb .rb-tip { position:absolute; pointer-events:none; z-index:20; opacity:0; transform:translate(-50%,-100%); transition:opacity .1s; background:var(--surface-bg,#fff); color:var(--text-color,#222); border:1px solid var(--border-color,#ccc); border-radius:8px; padding:7px 9px; font-size:12px; line-height:1.5; box-shadow:0 6px 24px rgba(0,0,0,.18); white-space:nowrap; }
#ob-rb .rb-tip b { font-weight:650; }
</style>
<script>
(function () {
var root = document.getElementById("ob-rb");
if (!root || !window.d3) { return; }
var d3 = window.d3, wrap = root.querySelector(".rb-wrap");
var tip = document.createElement("div"); tip.className = "rb-tip"; root.appendChild(tip);
function cssVar(n, fb) { var v = getComputedStyle(document.documentElement).getPropertyValue(n); return (v && v.trim()) || fb; }
// paper PROVIDER_PALETTE (fig_alignment_stability)
var PROV = { OpenAI: "#2a8f82", Anthropic: "#a66e4e", Google: "#3d5a80", Mistral: "#c4553a", Alibaba: "#c49a3a", DeepSeek: "#5c6b73", Zhipu: "#8a8478", NVIDIA: "#4a4540", Meta: "#1877f2" };
var ICON = { OpenAI: "openai", Anthropic: "anthropic", Google: "google", Mistral: "mistral", Alibaba: "alibaba", DeepSeek: "deepseek", Meta: "meta", NVIDIA: "nvidia", Zhipu: "zhipu" };
var DATA = null;
function draw() {
if (!DATA) { return; }
wrap.innerHTML = "";
var OPT = cssVar("--opt", "#e07a5f"), PES = cssVar("--pes", "#3d5a80"),
MUT = cssVar("--muted-color", "#666"), TXT = cssVar("--text-color", "#222"),
SF = cssVar("--surface-bg", "#fff"), BD = cssVar("--border-color", "#e7e2dc");
var S = Math.min(root.clientWidth || 520, 520); // square
var m = { t: 30, b: 40, l: 30, r: 14 };
var W = S, H = S;
var XL = 18, YMAX = 4;
var x = d3.scaleLinear().domain([-XL, XL]).range([m.l, W - m.r]);
var y = d3.scaleLinear().domain([-0.3, YMAX]).range([H - m.b, m.t]);
var MED = 1.5; // robust/volatile split (between Qwen3-235B σ1.31 and DeepSeek-V3.2 σ1.69)
var svg = d3.select(wrap).append("svg").attr("viewBox", "0 0 " + W + " " + H).attr("width", W).attr("height", H);
// four quadrant tints (robust band richer)
function rect(x0, x1, y0, y1, c, op) { svg.append("rect").attr("x", x(x0)).attr("y", y(y1)).attr("width", x(x1) - x(x0)).attr("height", y(y0) - y(y1)).attr("fill", c).attr("opacity", op); }
rect(0, XL, MED, YMAX, OPT, 0.05); rect(-XL, 0, MED, YMAX, PES, 0.05);
rect(0, XL, -0.3, MED, OPT, 0.11); rect(-XL, 0, -0.3, MED, PES, 0.11);
// dividers
svg.append("line").attr("x1", x(0)).attr("x2", x(0)).attr("y1", y(-0.3)).attr("y2", y(YMAX)).attr("stroke", MUT).attr("stroke-width", 1).attr("opacity", 0.65);
svg.append("line").attr("x1", x(-XL)).attr("x2", x(XL)).attr("y1", y(MED)).attr("y2", y(MED)).attr("stroke", MUT).attr("stroke-width", 1).attr("stroke-dasharray", "5 4").attr("opacity", 0.5);
// quadrant labels
[[XL - 0.5, YMAX - 0.15, "VOLATILE OPTIMIST", OPT, "end", "hanging"],
[-XL + 0.5, YMAX - 0.15, "VOLATILE PESSIMIST", PES, "start", "hanging"],
[XL - 0.5, -0.18, "ROBUST OPTIMIST", OPT, "end", "auto"],
[-XL + 0.5, -0.18, "ROBUST PESSIMIST", PES, "start", "auto"]].forEach(function (q) {
svg.append("text").attr("x", x(q[0])).attr("y", y(q[1])).attr("text-anchor", q[4]).attr("dominant-baseline", q[5]).attr("fill", q[3]).attr("opacity", 0.82).attr("font-size", 10).attr("font-weight", 700).attr("letter-spacing", "0.02em").text(q[2]);
});
// y ticks
[0, 1, 2, 3, 4].forEach(function (t) {
svg.append("text").attr("x", m.l - 5).attr("y", y(t) + 3).attr("text-anchor", "end").attr("fill", MUT).attr("font-size", 9).text(t);
});
// x ticks
[-15, -10, -5, 0, 5, 10, 15].forEach(function (t) {
svg.append("text").attr("x", x(t)).attr("y", H - m.b + 15).attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 9).text(t > 0 ? "+" + t : t);
});
// ---- label placement with vertical declutter ----
var lbls = DATA.models.map(function (d) {
var px = x(d.skew), py = y(d.sigma);
var FORCE = { "Llama-3.3-70B": 1 }; // override to dodge same-σ neighbour
var side = FORCE[d.name] || (px > W * 0.6 ? -1 : 1); // -1 = label left, 1 = label right
var w = d.name.length * 5.7 + 4;
var lx = px + side * 12, ly = py - 2;
var x0 = side < 0 ? lx - w : lx, x1 = side < 0 ? lx : lx + w;
return { d: d, px: px, py: py, side: side, anchor: side < 0 ? "end" : "start", lx: lx, ly: ly, x0: x0, x1: x1 };
});
lbls.sort(function (a, b) { return a.ly - b.ly; });
for (var i = 0; i < lbls.length; i++) {
for (var j = 0; j < i; j++) {
var a = lbls[j], b = lbls[i];
if (b.x0 < a.x1 && a.x0 < b.x1 && Math.abs(b.ly - a.ly) < 12.5) { b.ly = a.ly + 12.5; }
}
}
// points + connectors + labels
lbls.forEach(function (L) {
var d = L.d, c = PROV[d.provider] || MUT;
if (Math.abs(L.ly - (L.py - 2)) > 6) {
svg.append("line").attr("x1", L.px).attr("y1", L.py).attr("x2", L.lx).attr("y2", L.ly - 3).attr("stroke", MUT).attr("stroke-width", 0.6).attr("opacity", 0.4);
}
var slug = ICON[d.provider], rr = 9;
svg.append("circle").attr("cx", L.px).attr("cy", L.py).attr("r", rr).attr("fill", SF).attr("stroke", c).attr("stroke-width", 1.2);
var gm = svg.append("g").style("cursor", "pointer")
.on("mousemove", function (ev) { var pr = root.getBoundingClientRect(); tip.innerHTML = "<b>" + d.name + "</b><br>mean Skew " + (d.skew > 0 ? "+" : "") + d.skew.toFixed(1) + " pp<br>inter-language σ " + d.sigma.toFixed(2) + " pp"; tip.style.left = (ev.clientX - pr.left) + "px"; tip.style.top = (ev.clientY - pr.top - 8) + "px"; tip.style.opacity = 1; })
.on("mouseleave", function () { tip.style.opacity = 0; });
gm.append("circle").attr("cx", L.px).attr("cy", L.py).attr("r", rr).attr("fill", "transparent");
if (slug) { gm.append("image").attr("href", "icons/" + slug + ".svg").attr("x", L.px - 6.5).attr("y", L.py - 6.5).attr("width", 13).attr("height", 13).attr("preserveAspectRatio", "xMidYMid meet"); }
else { gm.append("circle").attr("cx", L.px).attr("cy", L.py).attr("r", 4).attr("fill", c); }
svg.append("text").attr("x", L.lx).attr("y", L.ly).attr("text-anchor", L.anchor).attr("fill", TXT).attr("font-size", 9.5).attr("font-weight", 500).text(d.name);
});
// axis labels
svg.append("text").attr("x", m.l).attr("y", m.t - 14).attr("text-anchor", "start").attr("fill", MUT).attr("font-size", 10.5).text("Mean Skew across 6 languages (pp) →");
svg.append("text").attr("transform", "translate(13," + ((m.t + H - m.b) / 2) + ")rotate(-90)").attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 10.5).text("Inter-language σ (pp)");
}
fetch("data/robustness.json").then(function (r) { if (!r.ok) { throw new Error("x"); } return r.json(); })
.then(function (j) { DATA = j; draw(); })
.catch(function () { wrap.innerHTML = '<div class="rb-cap">Could not load data/robustness.json.</div>'; });
if (window.ResizeObserver) { var t = null; new ResizeObserver(function () { clearTimeout(t); t = setTimeout(draw, 130); }).observe(root); } else { window.addEventListener("resize", draw); }
new MutationObserver(draw).observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
})();
</script>