thai-llm-leaderboard / index.html
kobkrit's picture
Thai LLM Leaderboard v0 — single-protocol scores from arXiv:2504.01789
63f93cb verified
Raw
History Blame Contribute Delete
9.99 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Thai LLM Leaderboard</title>
<style>
:root {
color-scheme: light;
--surface: #ffffff; --surface-2: #f4f6fa;
--ink: #17202e; --ink-2: #4b5665; --ink-3: #8a94a4;
--line: #e3e8ef; --accent: #2a78d6; --accent-soft: #2a78d61f;
}
:root[data-theme="dark"] {
color-scheme: dark;
--surface: #0f172a; --surface-2: #16213a;
--ink: #e8edf5; --ink-2: #aab6c6; --ink-3: #6c7a8e;
--line: #24324d; --accent: #3987e5; --accent-soft: #3987e529;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
color-scheme: dark;
--surface: #0f172a; --surface-2: #16213a;
--ink: #e8edf5; --ink-2: #aab6c6; --ink-3: #6c7a8e;
--line: #24324d; --accent: #3987e5; --accent-soft: #3987e529;
}
}
* { box-sizing: border-box; }
body {
margin: 0; background: var(--surface); color: var(--ink);
font: 15px/1.55 -apple-system, "Segoe UI", Roboto, "Noto Sans Thai", sans-serif;
}
.wrap { max-width: 1080px; margin: 0 auto; padding: 2rem 1.25rem 4rem; }
header.top { display: flex; align-items: flex-start; gap: 1rem; justify-content: space-between; flex-wrap: wrap; }
h1 { font-size: 1.7rem; margin: 0 0 .2rem; }
.sub { color: var(--ink-2); margin: 0 0 .4rem; }
.links { color: var(--ink-3); font-size: .92rem; }
.links a { color: var(--accent); text-decoration: none; }
.links a:hover { text-decoration: underline; }
#themeBtn {
border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2);
border-radius: 8px; padding: .4rem .7rem; cursor: pointer; font-size: .9rem;
}
.note {
margin: 1.4rem 0; padding: .9rem 1.1rem; border: 1px solid var(--line);
border-left: 3px solid var(--accent); border-radius: 8px; background: var(--surface-2);
color: var(--ink-2); font-size: .95rem;
}
.note strong { color: var(--ink); }
h2 { font-size: 1.15rem; margin: 2.2rem 0 .3rem; }
.h2sub { color: var(--ink-3); font-size: .9rem; margin: 0 0 .8rem; }
.tblwrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; }
table { border-collapse: collapse; width: 100%; min-width: 860px; font-size: .92rem; }
thead th {
position: sticky; top: 0; background: var(--surface-2); color: var(--ink-2);
font-weight: 600; text-align: right; padding: .55rem .65rem; cursor: pointer;
border-bottom: 1px solid var(--line); white-space: nowrap; user-select: none;
}
thead th:first-child { text-align: left; }
thead th[aria-sort="descending"]::after { content: " ▾"; color: var(--accent); }
thead th[aria-sort="ascending"]::after { content: " ▴"; color: var(--accent); }
tbody td { padding: .5rem .65rem; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--accent-soft); }
td.model { text-align: left; font-weight: 500; }
.chip {
display: inline-block; margin-left: .5rem; padding: .05rem .45rem; font-size: .74rem;
color: var(--ink-3); border: 1px solid var(--line); border-radius: 99px;
text-decoration: none; vertical-align: 1px;
}
.chip:hover { color: var(--accent); border-color: var(--accent); }
.cell { display: flex; align-items: center; gap: .5rem; justify-content: flex-end; }
.bar { width: 72px; height: 7px; background: var(--line); border-radius: 4px; overflow: hidden; flex: none; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: 4px 0 0 4px; }
.best { font-weight: 700; }
.avgcol { background: color-mix(in srgb, var(--surface-2) 55%, transparent); }
footer { margin-top: 2.5rem; color: var(--ink-3); font-size: .88rem; }
footer a { color: var(--accent); text-decoration: none; }
.foot-note { margin-top: .35rem; }
</style>
</head>
<body>
<div class="wrap">
<header class="top">
<div>
<h1>📊 Thai LLM Leaderboard</h1>
<p class="sub">ผลทดสอบโมเดลภาษาไทยภายใต้มาตรฐานเดียวกัน — Thai language models, one identical protocol.</p>
<p class="links">
<a href="https://openthai.aieat.or.th">OpenThai</a> ·
<a href="https://github.com/OpenThaiGPT/openthaigpt_eval">Eval harness</a> ·
<a href="https://arxiv.org/abs/2504.01789">Technical report</a> ·
<a href="https://discord.gg/7KDdKkBGUs">Submit a model (Discord)</a>
</p>
</div>
<button id="themeBtn" aria-label="Toggle theme">◐ Theme</button>
</header>
<div class="note">
<strong>How to read this.</strong> Every score below comes from a <strong>single evaluation run</strong>
on the SkyThought harness, published in the
<a href="https://arxiv.org/abs/2504.01789" style="color:var(--accent)">OpenThaiGPT 1.6 &amp; R1 technical report</a>
(April 2025) — same prompts, same protocol, every model. Scores are 0–100, higher is better;
<em>-TH</em> marks Thai-language variants. The leaderboard is maintained by OpenThai and includes
models that beat ours on individual benchmarks — the boldface best-in-column is computed, not chosen.
OpenThaiEval is our own exam benchmark; treat that column accordingly.
</div>
<h2>Reasoning models</h2>
<p class="h2sub">Step-by-step reasoning models, evaluated with thinking enabled.</p>
<div class="tblwrap"><table id="t1"></table></div>
<h2>General instruction models</h2>
<p class="h2sub">General-purpose chat models. Language Accuracy = replies in the language it was asked in.</p>
<div class="tblwrap"><table id="t2"></table></div>
<footer>
<div>Maintained by <a href="https://openthai.aieat.or.th">OpenThai</a> (AIEAT · iApp Technology).
Next revision: fresh re-runs under one protocol including ThaiLLM consortium models, newer Typhoon
releases and closed APIs (GPT, Gemini) — see the
<a href="https://github.com/OpenThaiGPT/openthaigpt_eval">open harness</a> to reproduce or submit.</div>
<div class="foot-note">โมเดลของเราไม่ได้ชนะทุกหมวด และเราตั้งใจแสดงผลตามจริง — that is the point.</div>
</footer>
</div>
<script>
const ORG = {
openthai: { label: "OpenThai", url: "https://huggingface.co/openthaigpt" },
deepseek: { label: "DeepSeek", url: "https://huggingface.co/deepseek-ai" },
scb10x: { label: "SCB 10X", url: "https://huggingface.co/scb10x" },
nectec: { label: "NECTEC", url: "https://huggingface.co/nectec" },
};
const REASONING = {
cols: ["AIME24-TH","AIME24","MATH500-TH","MATH500","LiveCodeBench-TH","LiveCodeBench","OpenThaiEval","Average"],
rows: [
{ m: "OpenThaiGPT R1 32B", org: "openthai", v: [56.67,63.36,83.80,89.40,62.16,69.67,76.05,71.58] },
{ m: "DeepSeek R1 Distill 70B", org: "deepseek", v: [33.33,53.33,75.40,88.88,53.15,64.97,74.17,63.31] },
{ m: "Typhoon R1 Distill 70B", org: "scb10x", v: [53.33,53.33,81.00,90.20,47.75,54.79,77.59,65.42] },
],
};
const GENERAL = {
cols: ["AIME24-TH","AIME24","MATH500-TH","MATH500","LiveCodeBench-TH","LiveCodeBench","OpenThaiEval","Lang. Accuracy","Average"],
rows: [
{ m: "OpenThaiGPT 1.6 72B", org: "openthai", v: [6.67,23.33,43.20,82.00,32.43,54.21,78.70,98.20,52.34] },
{ m: "OpenThaiGPT 1.5 72B", org: "openthai", v: [6.67,23.33,62.00,83.20,12.61,46.38,77.16,99.40,51.34] },
{ m: "OpenThaiGPT 1.5 14B", org: "openthai", v: [0.00,10.00,26.20,47.40,21.62,37.96,71.26,98.40,39.11] },
{ m: "OpenThaiGPT 1.5 7B", org: "openthai", v: [0.00,6.67,24.20,40.40,22.52,31.12,64.50,97.60,35.88] },
{ m: "Typhoon2 Llama3.1 70B", org: "scb10x", v: [13.33,10.00,55.80,67.40,27.03,37.38,72.54,99.80,47.91] },
{ m: "Typhoon2 Qwen2.5 7B", org: "scb10x", v: [3.33,6.67,51.80,65.40,9.91,0.98,64.76,99.40,37.78] },
{ m: "Typhoon2 Llama3.1 8B", org: "scb10x", v: [3.33,3.33,31.00,49.60,8.11,5.87,56.63,98.60,32.06] },
{ m: "Pathumma LLM Text 1.0.0 7B", org: "nectec", v: [0.00,0.00,21.80,42.80,0.00,0.00,65.27,98.60,28.56] },
],
};
function render(el, data, sortCol, asc) {
const avgIdx = data.cols.length - 1;
if (sortCol === undefined) { sortCol = avgIdx; asc = false; }
const rows = [...data.rows].sort((a, b) =>
sortCol < 0 ? (asc ? a.m.localeCompare(b.m) : b.m.localeCompare(a.m))
: (asc ? a.v[sortCol] - b.v[sortCol] : b.v[sortCol] - a.v[sortCol]));
const best = data.cols.map((_, i) => Math.max(...data.rows.map(r => r.v[i])));
el.innerHTML =
"<thead><tr><th data-c='-1'>Model</th>" +
data.cols.map((c, i) =>
`<th data-c="${i}" ${i === sortCol ? `aria-sort="${asc ? "ascending" : "descending"}"` : ""} class="${i === avgIdx ? "avgcol" : ""}">${c}</th>`
).join("") + "</tr></thead><tbody>" +
rows.map(r =>
`<tr><td class="model">${r.m}<a class="chip" href="${ORG[r.org].url}">${ORG[r.org].label}</a></td>` +
r.v.map((v, i) =>
`<td class="${i === avgIdx ? "avgcol " : ""}${v === best[i] ? "best" : ""}">
<span class="cell"><span class="bar"><i style="width:${v}%"></i></span>${v.toFixed(2)}</span></td>`
).join("") + "</tr>"
).join("") + "</tbody>";
el.querySelectorAll("th").forEach(th => th.onclick = () => {
const c = +th.dataset.c;
render(el, data, c, c === sortCol ? !asc : false);
});
}
render(document.getElementById("t1"), REASONING);
render(document.getElementById("t2"), GENERAL);
const btn = document.getElementById("themeBtn");
btn.onclick = () => {
const cur = document.documentElement.dataset.theme ||
(matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
document.documentElement.dataset.theme = cur === "dark" ? "light" : "dark";
};
</script>
</body>
</html>