| |
| |
| |
| (function () { |
| var saved = localStorage.getItem('unbias-theme') || 'dark'; |
| document.documentElement.setAttribute('data-theme', saved); |
|
|
| var MOON_ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>'; |
| var SUN_ICON = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>'; |
|
|
| function updateIcon(theme) { |
| var btn = document.getElementById('theme-toggle'); |
| if (!btn) return; |
| btn.innerHTML = theme === 'dark' ? MOON_ICON : SUN_ICON; |
| btn.title = theme === 'dark' ? 'Switch to light theme' : 'Switch to dark theme'; |
| } |
|
|
| window.toggleTheme = function () { |
| var current = document.documentElement.getAttribute('data-theme') || 'dark'; |
| var next = current === 'dark' ? 'light' : 'dark'; |
| document.documentElement.setAttribute('data-theme', next); |
| localStorage.setItem('unbias-theme', next); |
| updateIcon(next); |
| }; |
|
|
| function init() { updateIcon(saved); } |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', init); |
| } else { init(); } |
| })(); |
|
|
| |
| |
| |
| window.showTab = function (tabId, btn) { |
| document.querySelectorAll('.tab-panel').forEach(function (p) { p.classList.remove('active'); }); |
| document.getElementById(tabId).classList.add('active'); |
| document.querySelectorAll('.tab-btn').forEach(function (b) { b.setAttribute('aria-selected', 'false'); }); |
| btn.setAttribute('aria-selected', 'true'); |
| }; |
|
|
| |
| |
| |
| var MODELS = [ |
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct-V2", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 98.6, bias_reduction_pct: 56.4, bias_reduction: 1.884, contextual_relevance: 4.023, global_rewrite_quality: 2.936, |
| rouge_l: 0.726, length_ratio: 0.937, latency_median: 5.711, correct_id_mean: 3.308, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 3.913, unnecessary_rewrite_median: 3.0, recall_at_words: 0.842, segment_replace_quality: 3.770, |
| hallucination_rate: 4.54, duplicate_rate: 0.22 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct-V2 (D1)", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 98.3, bias_reduction_pct: 55.7, bias_reduction: 1.868, contextual_relevance: 4.052, global_rewrite_quality: 2.960, |
| rouge_l: 0.718, length_ratio: 0.946, latency_median: 6.654, correct_id_mean: 3.447, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 3.965, unnecessary_rewrite_median: 3.0, recall_at_words: 0.872, segment_replace_quality: 3.751, |
| hallucination_rate: 3.51, duplicate_rate: 0.37 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct-V2 (D2)", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 94.3, bias_reduction_pct: 55.5, bias_reduction: 1.873, contextual_relevance: 4.018, global_rewrite_quality: 2.922, |
| rouge_l: 0.723, length_ratio: 0.983, latency_median: 5.577, correct_id_mean: 3.939, correct_id_median: 5.0, |
| unnecessary_rewrite_mean: 4.293, unnecessary_rewrite_median: 5.0, recall_at_words: 0.890, segment_replace_quality: 3.704, |
| hallucination_rate: 3.40, duplicate_rate: 0.85 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct-V2 (D3)", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 98.9, bias_reduction_pct: 57.0, bias_reduction: 1.897, contextual_relevance: 4.040, global_rewrite_quality: 2.960, |
| rouge_l: 0.715, length_ratio: 0.929, latency_median: 5.477, correct_id_mean: 3.663, correct_id_median: 5.0, |
| unnecessary_rewrite_mean: 4.105, unnecessary_rewrite_median: 5.0, recall_at_words: 0.898, segment_replace_quality: 3.793, |
| hallucination_rate: 3.77, duplicate_rate: 0.22 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct-V2 (D4)", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 99.4, bias_reduction_pct: 54.3, bias_reduction: 1.851, contextual_relevance: 3.977, global_rewrite_quality: 2.891, |
| rouge_l: 0.717, length_ratio: 0.930, latency_median: 5.956, correct_id_mean: 3.543, correct_id_median: 5.0, |
| unnecessary_rewrite_mean: 4.064, unnecessary_rewrite_median: 5.0, recall_at_words: 0.907, segment_replace_quality: 3.687, |
| hallucination_rate: 2.92, duplicate_rate: 0.0 }, |
|
|
| { name: "Qwen3-4B-UnBias-Plus-SFT-Instruct-V2 (D3)", base: "Qwen3-4B", params: "4B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 98.3, bias_reduction_pct: 56.2, bias_reduction: 1.878, contextual_relevance: 4.029, global_rewrite_quality: 2.936, |
| rouge_l: 0.695, length_ratio: 0.931, latency_median: 6.325, correct_id_mean: 3.006, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 3.680, unnecessary_rewrite_median: 3.0, recall_at_words: 0.872, segment_replace_quality: 3.705, |
| hallucination_rate: 4.38, duplicate_rate: 0.19 }, |
|
|
| { name: "Qwen3-4B-UnBias-Plus-SFT-Instruct-ORPO", base: "Qwen3-4B", params: "4B", tag: "new", dataset: "UnBias-Plus (train_4)", |
| parse_rate: 80.9, bias_reduction_pct: 52.7, bias_reduction: 1.898, contextual_relevance: 4.020, global_rewrite_quality: 2.925, |
| rouge_l: 0.629, length_ratio: 0.938, latency_median: 8.046, correct_id_mean: 2.007, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 2.985, unnecessary_rewrite_median: 3.0, recall_at_words: 0.476, segment_replace_quality: 3.759, |
| hallucination_rate: 5.36, duplicate_rate: 0.0 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct", base: "Qwen3-8B", params: "8B", tag: "new", dataset: "UnBias-Plus (train_3)", |
| parse_rate: 100.0, bias_reduction_pct: 53.1, bias_reduction: 1.811, contextual_relevance: 4.074, global_rewrite_quality: 3.200, |
| rouge_l: 0.635, length_ratio: 1.294, latency_median: 22.2, correct_id_mean: 2.451, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 3.309, unnecessary_rewrite_median: 3.0, recall_at_words: 0.900, segment_replace_quality: 3.823, |
| hallucination_rate: 8.5, duplicate_rate: 4.4 }, |
|
|
| { name: "Qwen3.5-4B-UnBias-Plus-SFT-Instruct", base: "Qwen3.5-4B", params: "4B", tag: "new", dataset: "UnBias-Plus (train_3)", |
| parse_rate: 99.1, bias_reduction_pct: 57.5, bias_reduction: 1.908, contextual_relevance: 4.087, global_rewrite_quality: 3.145, |
| rouge_l: 0.709, length_ratio: 1.001, latency_median: 19.8, correct_id_mean: 3.443, correct_id_median: 2.0, |
| unnecessary_rewrite_mean: 3.966, unnecessary_rewrite_median: 3.0, recall_at_words: 0.847, segment_replace_quality: 3.878, |
| hallucination_rate: 5.3, duplicate_rate: 0.0 }, |
|
|
| { name: "Qwen3-8B-UnBias-Plus-SFT-Instruct (Legacy)", base: "Qwen3-8B", params: "8B", tag: "legacy", dataset: "UnBias-Plus (train_1)", |
| parse_rate: 99.4, bias_reduction_pct: 60.6, bias_reduction: 1.943, contextual_relevance: 4.178, global_rewrite_quality: 3.080, |
| rouge_l: 0.722, length_ratio: 0.993, latency_median: 27.4, correct_id_mean: 4.155, correct_id_median: 5.0, |
| unnecessary_rewrite_mean: 4.437, unnecessary_rewrite_median: 5.0, recall_at_words: 0.714, segment_replace_quality: 3.576, |
| hallucination_rate: 3.6, duplicate_rate: 0.7 }, |
| ]; |
|
|
| |
| |
| |
| |
| function formatScore(value, decimals) { |
| if (decimals === undefined) decimals = 2; |
| if (value === null || value === undefined) return "N/A"; |
| return value.toFixed(decimals); |
| } |
| function formatPercentage(value, decimals) { |
| if (decimals === undefined) decimals = 1; |
| if (value === null || value === undefined) return "N/A"; |
| return value.toFixed(decimals) + "%"; |
| } |
|
|
| |
| |
| |
| function modelCell(m) { |
| var tagCls = m.tag === "new" ? "pill-new" : "pill-legacy"; |
| var tagTxt = m.tag === "new" ? "new" : "legacy"; |
| |
| |
| return '<span class="model-name">' + m.name + '</span>' + |
| '<div class="model-sub"><span class="pill ' + tagCls + '">' + tagTxt + '</span> ' + |
| m.base + ' · ' + m.params + ' · ' + m.dataset + '</div>'; |
| } |
|
|
| function bestCls(vals, idx, lowerIsBetter) { |
| var best = lowerIsBetter ? Math.min.apply(null, vals) : Math.max.apply(null, vals); |
| var worst = lowerIsBetter ? Math.max.apply(null, vals) : Math.min.apply(null, vals); |
| if (vals[idx] === best) return "val-best"; |
| if (vals[idx] === worst) return "val-low"; |
| return "val-mid"; |
| } |
|
|
| function td(val, cls) { |
| cls = cls || "val-mid"; |
| return '<td class="right"><span class="' + cls + '">' + val + '</span></td>'; |
| } |
|
|
| function tdModel(m) { return '<td>' + modelCell(m) + '</td>'; } |
|
|
| |
| |
| |
| function overallTable() { |
| var parseVals = MODELS.map(function (m) { return m.parse_rate; }); |
| var biasVals = MODELS.map(function (m) { return m.bias_reduction_pct; }); |
| var relVals = MODELS.map(function (m) { return m.contextual_relevance; }); |
| var cidVals = MODELS.map(function (m) { return m.correct_id_median; }); |
| var segVals = MODELS.map(function (m) { return m.segment_replace_quality; }); |
| var latVals = MODELS.map(function (m) { return m.latency_median; }); |
|
|
| var rows = ""; |
| MODELS.forEach(function (m, i) { |
| rows += "<tr>" + tdModel(m) + |
| td(formatPercentage(m.parse_rate), bestCls(parseVals, i)) + |
| td(formatPercentage(m.bias_reduction_pct), bestCls(biasVals, i)) + |
| td(formatScore(m.contextual_relevance), bestCls(relVals, i)) + |
| td(formatScore(m.correct_id_median, 1), bestCls(cidVals, i)) + |
| td(formatScore(m.segment_replace_quality), bestCls(segVals, i)) + |
| td(m.latency_median + "s", bestCls(latVals, i, true)) + |
| "</tr>"; |
| }); |
|
|
| return '<div class="lb-table-wrap"><table class="lb-table"><thead><tr>' + |
| '<th>Model</th><th class="right">Parse rate</th><th class="right">Bias reduction</th><th class="right">Relevance</th>' + |
| '<th class="right">Correct ID (med)</th><th class="right">Seg. replacement</th><th class="right">Latency (med)</th>' + |
| '</tr></thead><tbody>' + rows + '</tbody></table></div>' + |
| '<p class="table-note">All judge scores 0-5. Green = best in column, red = lowest.</p>'; |
| } |
|
|
| function biasedTable() { |
| var biasVals = MODELS.map(function (m) { return m.bias_reduction_pct; }); |
| var biasRawVals = MODELS.map(function (m) { return m.bias_reduction; }); |
| var relVals = MODELS.map(function (m) { return m.contextual_relevance; }); |
| var grqVals = MODELS.map(function (m) { return m.global_rewrite_quality; }); |
| var rlVals = MODELS.map(function (m) { return m.rouge_l; }); |
| var lrVals = MODELS.map(function (m) { return Math.abs(m.length_ratio - 1.0); }); |
| var latVals = MODELS.map(function (m) { return m.latency_median; }); |
|
|
| var rows = ""; |
| MODELS.forEach(function (m, i) { |
| var lrCls = m.length_ratio > 1.2 ? "val-warn" : bestCls(lrVals, i, true); |
| rows += "<tr>" + tdModel(m) + |
| td(formatPercentage(m.bias_reduction_pct), bestCls(biasVals, i)) + |
| td(formatScore(m.bias_reduction), bestCls(biasRawVals, i)) + |
| td(formatScore(m.contextual_relevance), bestCls(relVals, i)) + |
| td(formatScore(m.global_rewrite_quality), bestCls(grqVals, i)) + |
| td(formatScore(m.rouge_l), bestCls(rlVals, i)) + |
| td(formatScore(m.length_ratio), lrCls) + |
| td(m.latency_median + "s", bestCls(latVals, i, true)) + |
| "</tr>"; |
| }); |
|
|
| return '<div class="lb-table-wrap"><table class="lb-table"><thead><tr>' + |
| '<th>Model</th><th class="right">Bias red. %</th><th class="right">Bias red. (mean)</th>' + |
| '<th class="right">Relevance</th><th class="right">Global rewrite</th><th class="right">ROUGE-L</th>' + |
| '<th class="right">Length ratio</th><th class="right">Latency (med)</th>' + |
| '</tr></thead><tbody>' + rows + '</tbody></table></div>' + |
| '<p class="table-note">Length ratio: ideal value is 1.0. Values above 1.2 flagged in orange.</p>'; |
| } |
|
|
| function unbiasedTable() { |
| var ciVals = MODELS.map(function (m) { return m.correct_id_median; }); |
| var urVals = MODELS.map(function (m) { return m.unnecessary_rewrite_median; }); |
| var ciMeanVals = MODELS.map(function (m) { return m.correct_id_mean; }); |
| var urMeanVals = MODELS.map(function (m) { return m.unnecessary_rewrite_mean; }); |
|
|
| var rows = ""; |
| MODELS.forEach(function (m, i) { |
| rows += "<tr>" + tdModel(m) + |
| td(formatScore(m.correct_id_mean), bestCls(ciMeanVals, i)) + |
| td(formatScore(m.correct_id_median, 1), bestCls(ciVals, i)) + |
| td(formatScore(m.unnecessary_rewrite_mean), bestCls(urMeanVals, i)) + |
| td(formatScore(m.unnecessary_rewrite_median, 1), bestCls(urVals, i)) + |
| "</tr>"; |
| }); |
|
|
| return '<div class="lb-table-wrap"><table class="lb-table"><thead><tr>' + |
| '<th>Model</th><th class="right">Correct ID (mean)</th><th class="right">Correct ID (median)</th>' + |
| '<th class="right">Unnec. rewrite (mean)</th><th class="right">Unnec. rewrite (median)</th>' + |
| '</tr></thead><tbody>' + rows + '</tbody></table></div>' + |
| '<p class="table-note">Score of 5.0 = model correctly preserved unbiased text unchanged. Score of 2.0 = model rewrote or mislabeled unbiased text as biased.</p>'; |
| } |
|
|
| function segmentTable() { |
| var recVals = MODELS.map(function (m) { return m.recall_at_words; }); |
| var srqVals = MODELS.map(function (m) { return m.segment_replace_quality; }); |
| var halVals = MODELS.map(function (m) { return m.hallucination_rate; }); |
| var dupVals = MODELS.map(function (m) { return m.duplicate_rate; }); |
|
|
| var rows = ""; |
| MODELS.forEach(function (m, i) { |
| rows += "<tr>" + tdModel(m) + |
| td(formatScore(m.recall_at_words), bestCls(recVals, i)) + |
| td(formatScore(m.segment_replace_quality), bestCls(srqVals, i)) + |
| td(formatPercentage(m.hallucination_rate), bestCls(halVals, i, true)) + |
| td(formatPercentage(m.duplicate_rate), bestCls(dupVals, i, true)) + |
| "</tr>"; |
| }); |
|
|
| return '<div class="lb-table-wrap"><table class="lb-table"><thead><tr>' + |
| '<th>Model</th><th class="right">Recall at words</th><th class="right">Seg. replacement quality</th>' + |
| '<th class="right">Hallucination rate</th><th class="right">Duplicate rate</th>' + |
| '</tr></thead><tbody>' + rows + '</tbody></table></div>' + |
| '<p class="table-note">Recall at words: % of ground-truth biased words covered by at least one model segment. Lower is better for hallucination and duplicate rates.</p>'; |
| } |
|
|
| |
| |
| |
| function render() { |
| document.getElementById("overall-table-container").innerHTML = overallTable(); |
| document.getElementById("biased-table-container").innerHTML = biasedTable(); |
| document.getElementById("unbiased-table-container").innerHTML = unbiasedTable(); |
| document.getElementById("segment-table-container").innerHTML = segmentTable(); |
| } |
|
|
| if (document.readyState === "loading") { |
| document.addEventListener("DOMContentLoaded", render); |
| } else { |
| render(); |
| } |