David Pomerenke
Fix speed issues
9aa08d7
raw
history blame
5.23 kB
<!DOCTYPE html>
<html>
<head>
<title>Language Bench</title>
<style>
body {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
font-family: sans-serif;
}
.language-header {
margin-bottom: 10px;
}
.speaker-count {
font-size: 0.8em;
color: #666;
font-weight: normal;
margin: 0;
}
</style>
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22 fill=%22black%22>🌍</text></svg>">
</head>
<body>
<h1>Language Bench</h1>
<div id="charts"></div>
<script type="module">
// Import Plot using ESM
import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";
async function init() {
const chartsDiv = document.getElementById('charts');
const summary = await fetch('results_summary.json');
const summaryData = await summary.json();
const formatTitle = d => d.target_language_name + "\n" + parseInt(d.speakers / 1_000_00) / 10 + "M speakers\nBLEU score: " + d.bleu.toFixed(1)
// Create summary plot
const summaryPlot = Plot.plot({
width: 800,
height: 400,
marginBottom: 100,
x: { label: "Number of speakers", axis: null },
y: { label: "BLEU Score (average across models)" },
marks: [
Plot.rectY(summaryData, Plot.stackX({
x: "speakers",
order: "bleu",
reverse: true,
y2: "bleu", // y2 to avoid stacking by y
title: formatTitle,
tip: true,
})),
Plot.rectY(summaryData, Plot.pointerX(Plot.stackX({
x: "speakers",
order: "bleu",
reverse: true,
y2: "bleu", // y2 to avoid stacking by y
fill: "grey",
}))),
Plot.text(summaryData, Plot.stackX({
filter: (d) => d.speakers > 5_000_000,
x: "speakers",
y2: "bleu",
order: "bleu",
reverse: true,
text: "target_language_name",
frameAnchor: "bottom",
textAnchor: "end",
dy: 10,
rotate: 270,
}))
]
});
// Add summary plot at the top
chartsDiv.insertBefore(summaryPlot, chartsDiv.firstChild);
const response = await fetch('results.json');
const results = await response.json();
// Get unique languages with their speaker counts
const languageMap = new Map();
results.forEach(r => {
if (!languageMap.has(r.target_language_name)) {
languageMap.set(r.target_language_name, r.speakers);
}
});
// Sort languages by speaker count (descending)
const languages = [...languageMap.entries()]
.sort((a, b) => b[1] - a[1])
.map(([lang]) => lang);
languages.forEach(language => {
const headerDiv = document.createElement('div');
headerDiv.className = 'language-header';
const h2 = document.createElement('h2');
h2.textContent = language;
h2.style.marginBottom = '5px';
const speakerP = document.createElement('p');
speakerP.className = 'speaker-count';
const speakerCount = (languageMap.get(language) / 1_000_000).toFixed(1);
speakerP.textContent = `${speakerCount}M speakers`;
headerDiv.appendChild(h2);
headerDiv.appendChild(speakerP);
chartsDiv.appendChild(headerDiv);
const languageData = results.filter(r => r.target_language_name === language);
const descriptor = code => {
let [org, model] = code.split("/")
return model.split("-")[0]
}
// Create plot using the more idiomatic Observable Plot approach
const plot = Plot.plot({
width: 400,
height: 200,
margin: 30,
y: {
domain: [0, 100],
label: "BLEU"
},
marks: [
Plot.barY(languageData, {
x: d => descriptor(d.model),
y: "bleu"
})
]
});
chartsDiv.appendChild(plot);
});
}
init();
</script>
</body>
</html>