Skip to content

Commit 8681712

Browse files
committed
docs: sync ledger/blog with corrected numbers and the Arabic releases
1 parent e7c9b20 commit 8681712

2 files changed

Lines changed: 84 additions & 41 deletions

File tree

src/content/blog/2026-08-24-phonological-layer-shipped.adoc

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
= The phonological layer: ten models, three wrong turns, and one correction
1+
= The phonological layer: eleven models, three wrong turns, and one correction
22
Ronald Tse
33
v1.0, 2026-08-24
44
:doctype: book
@@ -13,7 +13,7 @@ haraqat a scribe left out. Turning unwritten Thai into phonemes.
1313
Reading Urdu aloud. Those are learned — and for two years they lived
1414
in a research branch, promising and unshipped.
1515

16-
This August we shipped the phonological layer: ten neural models under
16+
This August we shipped the phonological layer: eleven neural models under
1717
the same discipline as the maps — one artifact format, checksums
1818
verified on every load, identical output from Ruby, Python, and
1919
TypeScript, and a measured number next to every claim. This post is
@@ -32,11 +32,13 @@ The catalog now spans four languages and two tiers:
3232
|urd-g2p-1.0 |grapheme→phoneme |CER 14.77 |fp32, 1.3 GiB
3333
|urd-diac-1.0 |diacritization |CER 3.74 |fp32, 1.3 GiB
3434
|heb-diac-1.0 |diacritization |DER 29.0 greedy / 17.5 beam-4 |fp32, parts
35-
|tha-g2p-base-1.0 |grapheme→phoneme |PER 9.19 (teacher 4.43) |fp32, parts
36-
|fas-g2p-1.0 |grapheme→phoneme |CER ≈1.6 — above published SOTA on SentenceBench |fp32, parts
35+
|tha-g2p-base-1.0 |grapheme→phoneme |PER 3.53 greedy (teacher 1.25) |fp32, parts
36+
|ara-diac-1.0 |diacritization |DER 2.58 — best dedicated on SadeedDiac-25 |fp32, parts
37+
|fas-g2p-1.0 |grapheme→phoneme |CER ≈1.6 — above the published best on the SentenceBench homograph benchmark |fp32, parts
3738
|tha-g2p-small-1.0 |grapheme→phoneme |PER 2.85 greedy |int8, 246 MiB
3839
|tha-g2p-small-1.0-int4 |same student, 4-bit |byte-identical decode |int4, 193 MiB
3940
|heb-diac-small-1.0 |diacritization |DER 30.37 (teacher 24.79) |fp32, 1.3 GiB
41+
|ara-diac-small-1.0 |diacritization |DER 8.26 full-set (see update below) |fp32, 1.3 GiB
4042
|===
4143

4244
Every student was distilled from a frozen, independently evaluated
@@ -131,3 +133,31 @@ Try it: `pip install secryst` —
131133
Python, the same in TypeScript. The catalog lives at
132134
https://github.com/interscript/interscript-ml[interscript-ml]; the
133135
measured story behind every number lives in its results log.
136+
137+
== Update, 2026-08-26: two Arabic releases and one subset lesson
138+
139+
The catalog grew to eleven: `ara-diac-1.0` (server) and
140+
`ara-diac-small-1.0` (client) shipped for Arabic haraqat restoration.
141+
142+
*ara-diac-1.0* is the r6 teacher — and on the full SadeedDiac-25
143+
benchmark, under the benchmark's own Misraj evaluator protocol, it is
144+
the best dedicated model measured: 2.5793% DER, ahead of GLM-5.2
145+
(2.6911), Gemini Flash (3.1926), GPT-4 (3.8645), and Sadeed's own
146+
1.5B model (7.2915); only Claude 3.7 Sonnet's published 1.3941 sits
147+
above it. At 580M parameters, runnable locally from a checksummed zip.
148+
149+
*ara-diac-small-1.0* taught us a measurement lesson the hard way. Its
150+
first published number, 3.66% DER, came from the benchmark's first 300
151+
paragraphs; the full 1,200-paragraph run scores 8.26%. The teacher
152+
reproduces its documented value on the same run (2.5815 vs 2.5793), so
153+
the harness was sound — the subset simply sat in the student's
154+
training-domain neighborhood and hid a domain-generalization gap. The
155+
subset figure is withdrawn, the full-set number ships in the metadata,
156+
and two standing rules follow: student-tier numbers publish from full
157+
benchmark sets only, and a subset figure is labeled as such at first
158+
publication.
159+
160+
Also corrected above: the Thai server-tier row now carries the greedy
161+
numbers (3.53, teacher 1.25) measured under the runtime protocol — the
162+
decode section earlier in this post explains why the beam-4 figures
163+
overstated the error.

src/pages/ml.astro

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,15 @@ const serverModels = [
3838
id: "tha-g2p-base-1.0",
3939
task: "g2p",
4040
pair: "Thai → IPA",
41-
metric: "PER 9.19 (teacher 4.43)",
41+
metric: "PER 3.53 greedy (teacher 1.25)",
42+
artifact: "fp32 · 2.6 GiB · parts",
43+
status: "released",
44+
},
45+
{
46+
id: "ara-diac-1.0",
47+
task: "diacritization",
48+
pair: "Arabic → haraqat",
49+
metric: "DER 2.58 — best dedicated model on SadeedDiac-25",
4250
artifact: "fp32 · 2.6 GiB · parts",
4351
status: "released",
4452
},
@@ -73,10 +81,18 @@ const clientModels = [
7381
id: "fas-g2p-1.0",
7482
task: "g2p",
7583
pair: "Persian → IPA",
76-
metric: "CER ≈1.6 · homograph 77.34%",
84+
metric: "CER ≈1.6 · SentenceBench homograph 77.34 (published best 76.89)",
7785
artifact: "fp32 · 2.6 GiB · parts",
7886
status: "released",
7987
},
88+
{
89+
id: "ara-diac-small-1.0",
90+
task: "diacritization",
91+
pair: "Arabic → haraqat",
92+
metric: "DER 8.26 full-set (300-para subset had read 3.66)",
93+
artifact: "fp32 · 1.3 GiB",
94+
status: "released",
95+
},
8096
]
8197
---
8298

@@ -94,12 +110,11 @@ const clientModels = [
94110
Where maps end,<br /><em>models</em> begin.
95111
</h1>
96112
<p class="hero-lead">
97-
The 289 authority-backed maps cover romanization systems that a
98-
committee has published. Some conversions have no committee: restoring
99-
the haraqat a scribe left out, turning unwritten Thai into phonemes,
100-
reading Urdu aloud. Those are learned — and they ship under the same
101-
discipline as the maps: one artifact format, checksums verified on
102-
every load, byte-identical output from every runtime.
113+
The 289 authority-backed maps cover romanization systems that a committee has published.
114+
Some conversions have no committee: restoring the haraqat a scribe left out, turning
115+
unwritten Thai into phonemes, reading Urdu aloud. Those are learned — and they ship under
116+
the same discipline as the maps: one artifact format, checksums verified on every load,
117+
byte-identical output from every runtime.
103118
</p>
104119
</div>
105120
</section>
@@ -113,12 +128,11 @@ const clientModels = [
113128
<p class="eyebrow">The catalogue</p>
114129
<h2>Every model, with its number.</h2>
115130
<p class="section-deck">
116-
No model is published without a measured metric next to its
117-
teacher's, on the same harness, in the open. Students are distilled
118-
from frozen teachers and gated at a pre-agreed error budget. Each
119-
entry resolves from the models.yaml index; artifacts above GitHub's
120-
2&nbsp;GiB cap ship as sha256-verified parts that the runtimes
121-
reassemble transparently.
131+
No model is published without a measured metric next to its teacher's, on the same
132+
harness, in the open. Students are distilled from frozen teachers and gated at a
133+
pre-agreed error budget. Each entry resolves from the models.yaml index; artifacts above
134+
GitHub's 2&nbsp;GiB cap ship as sha256-verified parts that the runtimes reassemble
135+
transparently.
122136
</p>
123137
</header>
124138

@@ -162,8 +176,11 @@ const clientModels = [
162176
}
163177
</ul>
164178
<p class="ledger-note">
165-
“Releasing” = passing its parity gate now, entering the release
166-
pipeline. Distillation budgets and per-model provenance: <a href="https://github.com/interscript/interscript-ml/blob/main/docs/RESULTS.md">interscript-ml/docs/RESULTS.md</a>.
179+
“Releasing” = passing its parity gate now, entering the release pipeline. Distillation
180+
budgets and per-model provenance: <a
181+
href="https://github.com/interscript/interscript-ml/blob/main/docs/RESULTS.md"
182+
>interscript-ml/docs/RESULTS.md</a
183+
>.
167184
</p>
168185
</div>
169186
</section>
@@ -177,12 +194,11 @@ const clientModels = [
177194
<p class="eyebrow">The contract</p>
178195
<h2>One artifact. Any runtime.</h2>
179196
<p class="section-deck">
180-
A model is a zip — the Interscript Model Format, IMF v1. Anything
181-
that can read a zip, hash a file, and run two ONNX sessions can
182-
serve it; no Interscript training code required. Every member is
183-
sha256-verified against metadata.yaml on load; tampering raises
184-
loudly. The tokenizer is raw UTF-8 bytes — no vocabulary to
185-
download, no sentencepiece to drift.
197+
A model is a zip — the Interscript Model Format, IMF v1. Anything that can read a zip,
198+
hash a file, and run two ONNX sessions can serve it; no Interscript training code
199+
required. Every member is sha256-verified against metadata.yaml on load; tampering raises
200+
loudly. The tokenizer is raw UTF-8 bytes — no vocabulary to download, no sentencepiece to
201+
drift.
186202
</p>
187203
<ul class="contract-facts">
188204
<li>Byte tokenizer — token id = byte + 3, trailing EOS</li>
@@ -211,11 +227,10 @@ const clientModels = [
211227
<p class="eyebrow">The crystals</p>
212228
<h2>Three runtimes, same bytes out.</h2>
213229
<p class="section-deck">
214-
The neural layer is served by <em>secryst</em> — the same
215-
cross-runtime contract as the map layer. Ruby, Python, and
216-
TypeScript resolve a model id against the index, fetch (or reuse
217-
the cache), verify every checksum, and decode with the KV-cache
218-
graph. Golden sets pin the three implementations to each other.
230+
The neural layer is served by <em>secryst</em> — the same cross-runtime contract as the map
231+
layer. Ruby, Python, and TypeScript resolve a model id against the index, fetch (or reuse the
232+
cache), verify every checksum, and decode with the KV-cache graph. Golden sets pin the three
233+
implementations to each other.
219234
</p>
220235
</header>
221236
<div class="crystal-code">
@@ -230,12 +245,12 @@ npm install secryst</code></pre>
230245
<pre><code>require "secryst"
231246
model = Secryst::Model.load("tha-g2p-small-1.0")
232247
model.translate("สวัสดี")
233-
# => "sa˨˩.wat̚˨˩.diː˧"</code></pre>
248+
# =&gt; "sa˨˩.wat̚˨˩.diː˧"</code></pre>
234249
</div>
235250
<p class="env-note">
236-
Point deployments at a mirror with <code>SECRYST_INDEX</code>; pin the
237-
cache with <code>SECRYST_CACHE</code>. Both are read at call time in
238-
all three runtimes.
251+
Point deployments at a mirror with <code>SECRYST_INDEX</code>; pin the cache with <code
252+
>SECRYST_CACHE</code
253+
>. Both are read at call time in all three runtimes.
239254
</p>
240255
</div>
241256
</section>
@@ -249,10 +264,9 @@ model.translate("สวัสดี")
249264
<p class="eyebrow eyebrow-accent">Provenance</p>
250265
<h2>Measured, or it doesn't ship.</h2>
251266
<p class="cta-deck">
252-
Teachers are frozen before distillation and never LLM-generated —
253-
language-model teachers hallucinate diacritics. Every number in the
254-
ledger links to a protocol in the open results log. BSD-3-Clause,
255-
code and weights.
267+
Teachers are frozen before distillation and never LLM-generated — language-model teachers
268+
hallucinate diacritics. Every number in the ledger links to a protocol in the open results
269+
log. BSD-3-Clause, code and weights.
256270
</p>
257271
</div>
258272
<div class="cta-code">
@@ -277,7 +291,6 @@ github.com/secryst # runtimes + training</code></pre>
277291
.page-headline em {
278292
font-style: italic;
279293
color: var(--color-brand);
280-
font-variation-settings: "SOFT" 100, "WONK" 1;
281294
}
282295
.hero-lead {
283296
font-size: var(--text-lead);
@@ -318,7 +331,7 @@ github.com/secryst # runtimes + training</code></pre>
318331
color: var(--color-stone);
319332
text-transform: none;
320333
letter-spacing: 0;
321-
font-family: var(--font-serif);
334+
font-family: var(--font-sans);
322335
font-style: italic;
323336
}
324337
.ledger {

0 commit comments

Comments
 (0)