Hebrish-Models / index.html
danielrosehill's picture
Hebrish model family showcase
e836848 verified
Raw History Blame Contribute Delete
18.3 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hebrish Models</title>
<meta name="description" content="Every Hebrish speech model in one place: English-Hebrew code-switching fine-tunes, their variants and formats.">
<link rel="icon" href="mark.svg" type="image/svg+xml">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600;9..144,700&family=Inter:wght@400;500;600&display=swap">
<style>
/* Tokens copied from Hebrish-Mgmt/brand/tokens.css (2026-10-21). */
:root {
--bg: #fbf8f2; --surface: #ffffff; --band: #f1ece1;
--ink: #1d2422; --muted: #5b6662; --line: #e2dccf;
--accent: #0f6b5c; --accent-ink: #ffffff; --accent-soft: #d8efe7;
--warn-soft: #fbe3d9; --warn-ink: #9a3412; --gold: #c8901c;
--font-display: Fraunces, Georgia, serif;
--font-body: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #111615; --surface: #18201e; --band: #151c1a;
--ink: #e8ece9; --muted: #9aa7a2; --line: #2a3532;
--accent: #3fbf9f; --accent-ink: #0c1412; --accent-soft: #163a31;
--warn-soft: #3a2018; --warn-ink: #f4a582; --gold: #e0b14a;
}
}
:root[data-theme="dark"] {
--bg: #111615; --surface: #18201e; --band: #151c1a;
--ink: #e8ece9; --muted: #9aa7a2; --line: #2a3532;
--accent: #3fbf9f; --accent-ink: #0c1412; --accent-soft: #163a31;
--warn-soft: #3a2018; --warn-ink: #f4a582; --gold: #e0b14a;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 16px/1.55 var(--font-body); }
a { color: var(--accent); text-underline-offset: 2px; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 16px; }
header { padding: 48px 0 24px; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 600; color: var(--muted); font-size: 14px; }
.brand img { width: 28px; height: 28px; }
h1, h2, h3 { font-family: var(--font-display); line-height: 1.15; margin: 0; }
h1 { font-size: clamp(32px, 6vw, 52px); margin-top: 18px; }
h1 em { font-style: normal; color: var(--accent); }
.lede { color: var(--muted); font-size: 18px; max-width: 720px; margin: 14px 0 0; }
.cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.btn { display: inline-block; padding: 9px 16px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); text-decoration: none; font-weight: 500; font-size: 14px; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
section { padding: 28px 0; }
.band { background: var(--band); border-block: 1px solid var(--line); }
h2 { font-size: 28px; }
.sub { color: var(--muted); margin: 6px 0 18px; max-width: 760px; }
/* Speed-accuracy scale */
.scale { position: relative; height: 150px; margin: 8px 0 4px; }
.scale .axis { position: absolute; left: 0; right: 0; top: 74px; height: 4px; border-radius: 2px; background: linear-gradient(90deg, var(--gold), var(--accent)); }
.scale .dot { position: absolute; top: 68px; width: 16px; height: 16px; margin-left: -8px; border-radius: 50%; background: var(--surface); border: 3px solid var(--accent); }
.scale .lbl { position: absolute; font-size: 12px; line-height: 1.25; width: 100px; margin-left: -50px; text-align: center; color: var(--ink); text-decoration: none; }
.scale .lbl.up { bottom: 90px; } .scale .lbl.down { top: 92px; }
.scale-ends { display: flex; justify-content: space-between; font-size: 13px; color: var(--muted); }
.note { font-size: 13px; color: var(--muted); margin-top: 10px; }
/* Lines */
.line { margin-top: 26px; }
.line-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 14px; }
.line-head img { width: 52px; height: 52px; flex: none; }
.line-head .mono { width: 52px; height: 52px; flex: none; border-radius: 14px; display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); font-family: var(--font-display); font-size: 24px; font-weight: 700; }
.line-head p { margin: 2px 0 0; color: var(--muted); font-size: 15px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; }
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 18px; display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.card.rec { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.card h3 { font-size: 20px; overflow-wrap: anywhere; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tag { font-size: 12px; padding: 2px 9px; border-radius: 999px; background: var(--band); color: var(--muted); border: 1px solid var(--line); }
.tag.acc { background: var(--accent-soft); color: var(--accent); border-color: transparent; font-weight: 600; }
.tag.warn { background: var(--warn-soft); color: var(--warn-ink); border-color: transparent; }
.card .for { margin: 0; }
dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; font-size: 14px; }
dt { color: var(--muted); } dd { margin: 0; overflow-wrap: anywhere; }
.meters { display: flex; gap: 18px; font-size: 13px; color: var(--muted); }
.pips { letter-spacing: 2px; color: var(--accent); }
.pips .off { color: var(--line); }
.links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 4px; }
.links a { font-size: 13px; padding: 4px 10px; border-radius: 8px; background: var(--band); text-decoration: none; border: 1px solid var(--line); }
.links a.main { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
footer { padding: 32px 0 48px; color: var(--muted); font-size: 14px; }
@media (max-width: 820px) {
.scale { display: none; }
.scale-ends { display: none; }
#scale-list { display: block !important; }
}
#scale-list { display: none; margin: 0; padding-left: 20px; }
</style>
</head>
<body>
<header class="wrap">
<div class="brand"><img src="mark.svg" alt=""> Hebrish · עבריש</div>
<h1>Every <em>Hebrish</em> model in one place</h1>
<p class="lede">Speech recognition for English with Hebrew words mixed in. Each model writes the Hebrew words in one consistent romanized spelling (<i>arnona</i>, <i>kupat holim</i>, <i>teudat zehut</i>) and runs on your own device. Free and open, from a not-for-profit project.</p>
<div class="cta">
<a class="btn primary" href="https://hebrish.app/models/choose">Which model should I use?</a>
<a class="btn" href="https://hebrish.app/download">Get the apps</a>
<a class="btn" href="https://huggingface.co/spaces/Hebrish/Jachnun-Demo">Try it in the browser</a>
<a class="btn" href="https://hebrish.app/benchmarks">Benchmarks</a>
</div>
</header>
<section class="band">
<div class="wrap">
<h2>From small and fast to most accurate</h2>
<p class="sub">Where each speech model sits, from wearables on the left to desktop GPUs on the right.</p>
<div class="scale" id="scale" aria-hidden="true"><div class="axis"></div></div>
<div class="scale-ends"><span>Smaller, faster, runs anywhere</span><span>Larger, more accurate, needs a GPU</span></div>
<ol id="scale-list"></ol>
<p class="note">Positions are estimates from model size and each model's own evaluations. The models have not all been scored on the same test set, so read them as a rough order, not a ranking.</p>
</div>
</section>
<main class="wrap" id="lines"></main>
<section class="band">
<div class="wrap">
<h2>Access and terms</h2>
<p class="sub">The model repositories are gated: request access with the form on each repository page, and Daniel reviews every request. If you have not heard back after a few days, write to <a href="mailto:access@hebrish.app">access@hebrish.app</a>. Use is free for personal, research, education and not-for-profit work. Commercial use, including telephony, needs a commercial licence. Read the <a href="https://hebrish.app/terms">terms of use</a>. The Hebrish apps and the browser demo download models from Hebrish's own CDN, so they work without an access request.</p>
</div>
</section>
<footer class="wrap">
<a href="https://hebrish.app">hebrish.app</a> · <a href="https://huggingface.co/Hebrish">Hugging Face: Hebrish</a> · <a href="https://github.com/Hebrish-ASR">GitHub: Hebrish-ASR</a> · <a href="https://hebrish.app/whitepaper">White paper</a><br>
Developed by <a href="https://danielrosehill.com">Daniel Rosehill</a>. Figures as published on hebrish.app, checked 2026-10-21.
</footer>
<script>
// Model data. Mirrors hebrish.app data/variants.json and /models (2026-10-21). Update both together.
const HF = "https://huggingface.co/";
const SITE = "https://hebrish.app";
const LINES = [
{ id: "sabich", name: "Sabich", logo: "sabich.svg",
blurb: "The main line: code-switched speech plus tech vocabulary, brand names and numbers. The same training data on several base models, from wearables to desktop GPUs.",
variants: [
{ name: "Sabich", rec: true, base: "NVIDIA Parakeet TDT 0.6B v2", params: "0.6B", version: "v1.0 (2026-10-20)",
for: "Phones and computers without a GPU. The default in the Hebrish apps.",
result: "73.8% term recall, 3.3% WER on the public benchmark", size: "about 661 MB (sherpa-onnx int8)",
tags: ["Recommended", "In the apps"], speed: 3, accuracy: 4, gradient: 67, page: "/models/sabich",
repo: "Hebrish/Sabich", formats: [["sherpa-onnx int8", "Hebrish/Sabich-sherpa-onnx-int8"], ["ONNX", "Hebrish/Sabich-ONNX"], ["GGUF", "Hebrish/Sabich-GGUF"], ["MLX", "Hebrish/Sabich-MLX"]] },
{ name: "Sabich-Qwen3-ASR-1.7B", base: "Qwen3-ASR 1.7B", params: "2.0B", version: "v1.0 (2026-10-21)",
for: "Desktop GPUs. The most accurate model on code-switched speech.",
result: "5.4% code-switching WER (stock Qwen3-ASR 10.0%), held-out split", size: "4.1 GB bf16; GGUF Q8_0 about 2 GB",
tags: ["Desktop GPU", "Not in the apps yet"], speed: 2, accuracy: 5, gradient: 95, page: "/models/sabich-qwen3",
repo: "Hebrish/Sabich-Qwen3-ASR-1.7B", formats: [["GGUF", "Hebrish/Sabich-Qwen3-ASR-1.7B-GGUF"]] },
{ name: "Sabich-Canary-Qwen-2.5B", base: "NVIDIA Canary-Qwen 2.5B", params: "2.56B", version: "v1.0 (2026-10-21)",
for: "Desktop GPUs. The best plain English of the Sabich variants; second to Sabich-Qwen3-ASR-1.7B on code-switching.",
result: "6.9% code-switching WER, 2.4% on the speaker's own English, held-out split", size: "about 5 GB bf16, about 6 GB of VRAM; NeMo only",
tags: ["Desktop GPU", "Audio up to 40 s", "Not in the apps yet"], speed: 2, accuracy: 4, gradient: 88, page: "/models/sabich-canary-qwen",
repo: "Hebrish/Sabich-Canary-Qwen-2.5B", formats: [] },
{ name: "Sabich-Parakeet-110M", base: "NVIDIA Parakeet TDT-CTC 110M", params: "114M", version: "v1.0 (2026-10-21)",
for: "Low-end phones, watches and wearables. A fifth of Sabich's size: faster, with more mistakes.",
result: "Not benchmarked yet", size: "about 137 MB (sherpa-onnx int8)",
tags: ["Small devices", "In the apps"], speed: 4, accuracy: 3, gradient: 30, page: "/models/sabich-110m",
repo: "Hebrish/Sabich-Parakeet-110M", formats: [["sherpa-onnx int8", "Hebrish/Sabich-Parakeet-110M-sherpa-onnx-int8"], ["GGUF", "Hebrish/Sabich-Parakeet-110M-GGUF"]] },
{ name: "Sabich-asr4all-M", base: "FUTO asr4all M", params: "56M", version: "v1.0 (2026-10-21)",
for: "Wearables and low-power boards. A little more accurate than S. Streams on the CPU.",
result: "9.1% code-switching WER (stock asr4all-m 19.5%), held-out split", size: "223 MB fp32; ONNX about 214 MB",
tags: ["Streaming", "Numbers as words", "Not in the apps yet"], speed: 5, accuracy: 2, gradient: 14, page: "/models/sabich-asr4all",
repo: "Hebrish/Sabich-asr4all-M", formats: [] },
{ name: "Sabich-asr4all-S", base: "FUTO asr4all S", params: "28M", version: "v1.0 (2026-10-21)",
for: "Wearables and very low-power boards. The smallest Hebrish model. Streams on the CPU.",
result: "10.1% code-switching WER, held-out split", size: "113 MB fp32; ONNX about 108 MB",
tags: ["Streaming", "Numbers as words", "Not in the apps yet"], speed: 5, accuracy: 2, gradient: 4, page: "/models/sabich-asr4all",
repo: "Hebrish/Sabich-asr4all-S", formats: [] },
] },
{ id: "jachnun", name: "Jachnun", logo: "jachnun.svg",
blurb: "Code-switching only: English with the Hebrew words spelled right, without the tech vocabulary. In the apps next to Sabich.",
variants: [
{ name: "Jachnun", base: "NVIDIA Parakeet TDT 0.6B v2", params: "0.6B", version: "v1.0 (2026-10-19)",
for: "Code-switching only, for anyone who prefers it to Sabich.",
result: "73.3% term recall, 3.3% WER on the public benchmark", size: "about 660 MB (sherpa-onnx int8)",
tags: ["In the apps"], speed: 3, accuracy: 4, gradient: 61, page: "/models/jachnun",
repo: "Hebrish/Jachnun", formats: [["sherpa-onnx int8", "Hebrish/Jachnun-sherpa-onnx-int8"], ["ONNX", "Hebrish/Jachnun-ONNX"], ["GGUF", "Hebrish/Jachnun-GGUF"], ["MLX", "Hebrish/Jachnun-MLX"]] },
] },
{ id: "shakshuka", name: "Shakshuka", logo: "shakshuka.svg",
blurb: "The streaming line: the words appear while you are still talking. Trained on Sabich's data.",
variants: [
{ name: "Shakshuka", base: "NVIDIA Nemotron Speech Streaming EN 0.6B", params: "0.6B", version: "v1.0 (2026-10-21)",
for: "Live text while you speak: captions and live dictation.",
result: "v1.0 not benchmarked yet; PoC-2: 62.2% term recall, 4.7% WER (offline)", size: "about 662 MB (sherpa-onnx int8)",
tags: ["Streaming", "Not in the apps yet"], speed: 4, accuracy: 4, gradient: 54, page: "/models/shakshuka",
repo: "Hebrish/Shakshuka", formats: [["sherpa-onnx int8 (streaming)", "Hebrish/Shakshuka-sherpa-onnx-int8"], ["GGUF", "Hebrish/Shakshuka-GGUF"]] },
] },
{ id: "whisper", name: "Whisper Hebrish", mono: "W",
blurb: "Fine-tunes of OpenAI Whisper. This is where Hebrish started, in November 2025.",
variants: [
{ name: "Whisper Hebrish Small ACFT", base: "OpenAI Whisper small.en", params: "242M", version: "small-en-en30-acft (2026-10-17)",
for: "People who already use FUTO Keyboard on Android.",
result: "5.8% code-switching WER on its own test set (FUTO runtime)", size: "Transformers fp32, whisper.cpp GGML Q8_0",
tags: ["FUTO Keyboard"], page: "/models/whisper-small",
repo: "Hebrish/Whisper-Hebrish-Small-ACFT", formats: [] },
{ name: "Whisper Hebrish (large-v3-turbo)", base: "OpenAI Whisper large-v3-turbo", params: "809M", version: "Version 2 (2026-10-17)",
for: "A full fine-tune; the larger sibling of the Small ACFT model.",
result: "Version 1: 54.1% term recall, 6.5% WER on the public benchmark", size: "Transformers, whisper.cpp GGML",
tags: [], page: "/models/whisper-turbo",
repo: "danielrosehill/Whisper-Hebrish", formats: [] },
] },
{ id: "text", name: "Small text model", mono: "Aa",
blurb: "Not a speech model, but code-switching needs it. It finds Hebrew written in Latin letters inside English text.",
variants: [
{ name: "Hebrew-Latin Token Classifier", base: "XLM-RoBERTa base", params: "277M", version: "v1 (2026-10-15)",
for: "Marks each romanized Hebrew word in an English sentence, so text-to-speech can send it to a Hebrew voice.",
result: "Span F1 0.941 on terms it never saw in training", size: "Transformers (safetensors)",
tags: ["Text"], page: "/models/token-classifier",
repo: "Hebrish/Hebrew-Latin-Token-Classifier", formats: [] },
] },
];
const esc = s => String(s).replace(/[&<>"]/g, c => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c]));
const pips = n => "●".repeat(n) + `<span class="off">${"●".repeat(5 - n)}</span>`;
const tagClass = t => t === "Recommended" || t === "In the apps" ? "tag acc" : t.startsWith("Not in") ? "tag warn" : "tag";
function card(v) {
const meters = v.speed ? `<div class="meters"><span>Speed <span class="pips">${pips(v.speed)}</span></span><span>Accuracy <span class="pips">${pips(v.accuracy)}</span></span></div>` : "";
const fmts = v.formats.map(([label, repo]) => `<a href="${HF + repo}">${esc(label)}</a>`).join("");
return `<article class="card${v.rec ? " rec" : ""}" id="${esc(v.repo.split("/")[1])}">
<h3>${esc(v.name)}</h3>
${v.tags.length ? `<div class="tags">${v.tags.map(t => `<span class="${tagClass(t)}">${esc(t)}</span>`).join("")}</div>` : ""}
<p class="for">${esc(v.for)}</p>
<dl><dt>Base</dt><dd>${esc(v.base)}</dd><dt>Size</dt><dd>${esc(v.params)} params · ${esc(v.size)}</dd><dt>Version</dt><dd>${esc(v.version)}</dd><dt>Result</dt><dd>${esc(v.result)}</dd></dl>
${meters}
<div class="links"><a class="main" href="${HF + v.repo}">Weights on Hugging Face</a>${fmts}<a href="${SITE + v.page}">Model page</a></div>
</article>`;
}
document.getElementById("lines").innerHTML = LINES.map(l => `<section class="line" id="${l.id}">
<div class="line-head">${l.logo ? `<img src="${l.logo}" alt="">` : `<span class="mono">${esc(l.mono)}</span>`}<div><h2>${esc(l.name)}</h2><p>${esc(l.blurb)}</p></div></div>
<div class="grid">${l.variants.map(card).join("")}</div>
</section>`).join("");
// Speed-accuracy scale: labels alternate above and below the axis so neighbours don't collide.
const onScale = LINES.flatMap(l => l.variants).filter(v => v.gradient != null).sort((a, b) => a.gradient - b.gradient);
const scale = document.getElementById("scale");
onScale.forEach((v, i) => {
const x = 4 + v.gradient * 0.92; // keep end labels inside the box
const id = v.repo.split("/")[1];
scale.insertAdjacentHTML("beforeend", `<span class="dot" style="left:${x}%"></span><a class="lbl ${i % 2 ? "down" : "up"}" style="left:${x}%" href="#${esc(id)}">${esc(v.name)}</a>`);
});
document.getElementById("scale-list").innerHTML = onScale.map(v => `<li><a href="#${esc(v.repo.split("/")[1])}">${esc(v.name)}</a>: ${esc(v.for)}</li>`).join("");
</script>
</body>
</html>