OptimismBench / app /src /content /embeds /alignment-slope.html
seonglae's picture
article: interactive research piece for OptimismBench
1df44e8
Raw
History Blame Contribute Delete
5.84 kB
<div id="ob-as" role="img" aria-label="Base versus chat Skew across eleven architectures. Every Qwen pair shifts down toward pessimism, every Llama pair shifts up toward optimism, and Gemma flips: alignment installs the direction.">
<div class="as-head">
<span class="as-title">Base → Chat Skew shift</span>
<span class="as-tog">
<button class="as-btn" data-f="Qwen" aria-pressed="true">Qwen</button>
<button class="as-btn" data-f="Llama" aria-pressed="false">Llama</button>
<button class="as-btn" data-f="Gemma" aria-pressed="false">Gemma</button>
</span>
</div>
<div class="as-wrap"></div>
<div class="as-cap">Each line is one architecture: where alignment moves its Skew from base checkpoint to chat. Qwen down, Llama up, Gemma flips.</div>
</div>
<style>
#ob-as { font:13px/1.4 system-ui,sans-serif; color:var(--text-color,#222); width:100%; position:relative; }
#ob-as .as-head { display:flex; align-items:baseline; gap:10px; margin-bottom:8px; }
#ob-as .as-title { font-weight:650; font-size:15px; }
#ob-as .as-tog { display:inline-flex; gap:6px; margin-left:auto; }
#ob-as .as-btn { font:inherit; font-size:12px; cursor:pointer; padding:4px 10px; border-radius:7px; border:1px solid var(--border-color,#ccc); background:transparent; color:var(--muted-color,#666); }
#ob-as .as-btn:hover { color:var(--text-color,#222); }
#ob-as .as-btn[aria-pressed="true"] { background:var(--primary-color,#2d2926); color:#fff; border-color:var(--primary-color,#2d2926); }
#ob-as svg { display:block; width:100%; height:auto; }
#ob-as .as-cap { margin-top:8px; font-size:12px; color:var(--muted-color,#666); }
#ob-as .as-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; box-shadow:0 6px 24px rgba(0,0,0,.18); white-space:nowrap; }
</style>
<script>
(function () {
var root = document.getElementById("ob-as");
if (!root || !window.d3) { return; }
var d3 = window.d3, wrap = root.querySelector(".as-wrap");
var tip = document.createElement("div"); tip.className = "as-tip"; root.appendChild(tip);
var FAM = { Qwen: "#7c3aed", Llama: "#2563eb", Gemma: "#0891b2", Mistral: "#ea580c" };
function cssVar(n, fb) { var v = getComputedStyle(document.documentElement).getPropertyValue(n); return (v && v.trim()) || fb; }
var DATA = null, FILT = "Qwen";
function draw() {
if (!DATA) { return; }
wrap.innerHTML = "";
var MUT = cssVar("--muted-color", "#666"), BD = cssVar("--border-color", "#ccc"), TXT = cssVar("--text-color", "#222");
var W = root.clientWidth || 680, H = 330, m = { t: 22, b: 30, l: 44, r: 128 };
var xl = m.l + 64, xr = W - m.r;
var y = d3.scaleLinear().domain([-38, 40]).range([H - m.b, m.t]);
var svg = d3.select(wrap).append("svg").attr("viewBox", "0 0 " + W + " " + H).attr("width", W).attr("height", H);
svg.append("line").attr("x1", xl).attr("x2", xr).attr("y1", y(0)).attr("y2", y(0)).attr("stroke", BD).attr("stroke-dasharray", "4 4");
[["Base", xl], ["Chat", xr]].forEach(function (d) { svg.append("text").attr("x", d[1]).attr("y", m.t - 7).attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 12).attr("font-weight", 600).text(d[0]); });
[-30, -15, 0, 15, 30].forEach(function (t) { svg.append("text").attr("x", m.l).attr("y", y(t) + 3).attr("fill", MUT).attr("font-size", 9.5).text(t > 0 ? "+" + t : t); });
svg.append("text").attr("transform", "translate(15," + H / 2 + ")rotate(-90)").attr("text-anchor", "middle").attr("fill", MUT).attr("font-size", 11).text("Skew");
DATA.pairs.forEach(function (p) {
if (p.family === "Mistral") { return; }
var c = FAM[p.family], on = (FILT === "all" || p.family === FILT);
var g = svg.append("g").style("cursor", "pointer").attr("opacity", on ? 1 : 0.12);
g.append("line").attr("x1", xl).attr("y1", y(p.base)).attr("x2", xr).attr("y2", y(p.chat)).attr("stroke", c).attr("stroke-width", 1.8).attr("opacity", 0.82);
g.append("circle").attr("cx", xl).attr("cy", y(p.base)).attr("r", 3.4).attr("fill", c);
g.append("circle").attr("cx", xr).attr("cy", y(p.chat)).attr("r", 3.4).attr("fill", c);
g.append("text").attr("x", xr + 8).attr("y", y(p.chat) + 3.5).attr("fill", TXT).attr("font-size", 10).text(p.arch + " (" + (p.delta > 0 ? "+" : "") + p.delta + ")");
g.on("mousemove", function (ev) { var pr = root.getBoundingClientRect(); tip.innerHTML = "<b>" + p.arch + "</b><br>base " + (p.base > 0 ? "+" : "") + p.base + " → chat " + (p.chat > 0 ? "+" : "") + p.chat + "<br>Δ " + (p.delta > 0 ? "+" : "") + p.delta + " 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; });
});
}
root.querySelectorAll(".as-btn").forEach(function (b) { b.addEventListener("click", function () { FILT = b.getAttribute("data-f"); root.querySelectorAll(".as-btn").forEach(function (o) { o.setAttribute("aria-pressed", o === b ? "true" : "false"); }); draw(); }); });
fetch("data/alignpair.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="as-cap">Could not load data/alignpair.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>