|
1 | | -# interscript/ml-models |
| 1 | +# interscript-ml |
2 | 2 |
|
3 | | -Unified training framework for Interscript ML-powered maps. |
| 3 | +The **contract** for Interscript's phonological layer — the normative |
| 4 | +definition of what a "hidden reading" model is, and the zoo that |
| 5 | +publishes models conforming to it. |
4 | 6 |
|
5 | | -**Status:** skeleton (P0 in TODO.rababa/10). Framework abstractions |
6 | | -implemented and tested. Task data modules + configs ready; full |
7 | | -training requires GPU + dataset fetch. |
| 7 | +This repo owns three things and nothing else: |
8 | 8 |
|
9 | | -## What this is |
| 9 | +1. **The `models.yaml` index** — the stable URL every runtime resolves |
| 10 | + model ids against (with per-artifact sha256s and split-part support). |
| 11 | +2. **The IMF v1 model-zip format** — the artifact contract: |
| 12 | + `metadata.yaml` + ONNX graphs + member sha256 manifest. The normative |
| 13 | + text is [SPEC.md](SPEC.md); the reference loader now lives in the |
| 14 | + [Python crystal](https://github.com/secryst/secryst-py). |
| 15 | +3. **The model zoo + publish pipeline** — teachers from |
| 16 | + [interscript-ml-train](https://github.com/interscript/interscript-ml-train) |
| 17 | + are distilled, gated (parity written into the artifact), and released |
| 18 | + as index entries here. |
10 | 19 |
|
11 | | -One training repo for every ML map in Interscript: |
| 20 | +## The system |
12 | 21 |
|
13 | | -- **rababa_arabic** — Arabic diacritization (adds harakat) |
14 | | -- **rababa_hebrew** — Hebrew diacritization (adds nikud) |
15 | | -- **secryst_thai_ipa** — Thai → IPA transliteration |
16 | | - |
17 | | -Each task is a **config + data module**. The training framework is |
18 | | -shared. Adding a new transliteration pair (Khmer → IPA, Japanese → |
19 | | -Romaji) is one new directory under `src/tasks/` — zero edits to |
20 | | -framework code. |
21 | | - |
22 | | -## Architecture |
23 | | - |
24 | | -``` |
25 | | -src/ |
26 | | -├── framework/ # SHARED abstractions (MECE) |
27 | | -│ ├── config.py # TaskConfig loaded from YAML |
28 | | -│ ├── registry.py # Plugin registry (OCP) |
29 | | -│ ├── data.py # DataModule ABC |
30 | | -│ ├── model.py # ModelModule ABC (teacher + student) |
31 | | -│ ├── trainer.py # BaseTrainer + FineTune + Distill (DRY) |
32 | | -│ ├── evaluator.py # BaseEvaluator + edit_distance + DER/PER utils |
33 | | -│ ├── exporter.py # OnnxExporter ABC |
34 | | -│ └── pipeline.py # TrainingPipeline orchestrator |
35 | | -├── tasks/ |
36 | | -│ ├── rababa_arabic/ # config.yaml + data.py + student.py + metrics.py |
37 | | -│ ├── rababa_hebrew/ |
38 | | -│ └── secryst_thai_ipa/ |
39 | | -└── cli.py # python -m src.cli train --task rababa_arabic |
40 | | -``` |
41 | | - |
42 | | -## Design principles (project conventions) |
43 | | - |
44 | | -- **OCP** — adding a task = one new directory. Adding a metric, model |
45 | | - architecture, or data source = one new subclass + `@register_*` |
46 | | - decorator. Framework code is never edited. |
47 | | -- **MECE** — each module owns one concern. Data has no knowledge of |
48 | | - model architecture. Model has no knowledge of trainer. Trainer has |
49 | | - no knowledge of evaluator. |
50 | | -- **DRY** — the epoch loop, edit-distance math, and ONNX export |
51 | | - wrapper are written once. |
52 | | -- **Model-driven, semantically-driven** — class names mirror domain |
53 | | - concepts (`RababaArabicData`, `DEREvaluator`, `SecrystThaiIpaStudent`). |
54 | | -- **Performance** — frozen dataclasses for config; lazy imports for |
55 | | - torch so framework tests run without GPU deps. |
56 | | - |
57 | | -## Quick start |
58 | | - |
59 | | -```bash |
60 | | -scripts/setup_env.sh # creates .venv, installs deps |
61 | | -scripts/fetch_data.sh # fetch raw datasets (set env vars first) |
62 | | -scripts/train.sh rababa_arabic # full training pipeline |
63 | | -scripts/export.sh rababa_arabic # export student to ONNX |
64 | | -scripts/publish.sh rababa_arabic # upload to HuggingFace Hub |
65 | 22 | ``` |
66 | | - |
67 | | -Or via the CLI directly: |
68 | | - |
69 | | -```bash |
70 | | -python -m src.cli list |
71 | | -python -m src.cli train --task rababa_arabic --data-root data --out-root models |
72 | | -python -m src.cli evaluate --task secryst_thai_ipa |
73 | | -python -m src.cli export --task rababa_hebrew |
| 23 | +interscript deterministic transliteration maps + engines |
| 24 | +(ruby · js · py) │ maps that need vocalization dispatch to a |
| 25 | + │ crystal through stdlib adapters (optional) |
| 26 | + ▼ |
| 27 | +secryst crystals Ruby gem · pip install secryst · npm i secryst |
| 28 | +(secryst org) implement IMF v1 + models.yaml — nothing else |
| 29 | + │ |
| 30 | + ▼ |
| 31 | +interscript-ml ◄────── models/zips resolve through this index |
| 32 | +(THIS repo) ──────► golden sets: crystals diffed against each other |
| 33 | +
|
| 34 | +interscript-ml-train teachers (arabic · persian · urdu + hebrew docs); |
| 35 | +(interscript org) students distilled here enter the zoo above |
74 | 36 | ``` |
75 | 37 |
|
76 | | -## Adding a new task |
77 | | - |
78 | | -1. Create `src/tasks/<name>/config.yaml` (copy from an existing task). |
79 | | -2. Create `src/tasks/<name>/data.py` extending `DataModule`, decorated |
80 | | - with `@register_data_module("<name>_data")`. |
81 | | -3. Create `src/tasks/<name>/student.py` extending `ModelModule`, |
82 | | - decorated with `@register_model_module("<name>_student")`. |
83 | | -4. Create `src/tasks/<name>/metrics.py` extending `BaseEvaluator`, |
84 | | - decorated with `@register_evaluator("<metric>")`. |
85 | | -5. Run `python -m src.cli train --task <name>`. |
86 | | - |
87 | | -That's it. No framework edits. |
88 | | - |
89 | | -## Tests |
90 | | - |
91 | | -```bash |
92 | | -pytest -v |
93 | | -``` |
94 | | - |
95 | | -Framework tests run without torch (CPU-only, fast). Training and ONNX |
96 | | -export tests are gated behind `@pytest.mark.gpu` and require the |
97 | | -`[train]` and `[export]` extras. |
98 | | - |
99 | | -## Distribution |
| 38 | +Dependency directions, stated once: |
100 | 39 |
|
101 | | -Models ship as **IMF v1** zips (Interscript Model Format — spec in |
102 | | -[`docs/imf-v1.md`](./docs/imf-v1.md)): byte-level tokenizer only, ONNX |
103 | | -opset 14, sha256-verified graphs, metrics traceable to `RESULTS.md` |
104 | | -anchors. Build/validate with `PYTHONPATH=src python -m imf pack|validate`. |
| 40 | +- **interscript-ml depends on nothing.** It is the contract: an index, |
| 41 | + a format, golden sets, and release tooling. |
| 42 | +- **Crystals depend only on the contract.** A crystal has zero |
| 43 | + interscript-core dependency — a TTS front-end can phonemize Khmer |
| 44 | + with `pip install secryst` and nothing else. |
| 45 | +- **Engines depend on crystals only optionally.** An engine without a |
| 46 | + crystal simply cannot execute maps that declare a vocalization step. |
| 47 | +- **Training depends on nothing downstream.** Teachers never import the |
| 48 | + contract; they're consumed by it (via the export gate). |
105 | 49 |
|
106 | | -Models reach end users through three channels (full plan in |
107 | | -[`TODO.distribution/`](./TODO.distribution/)): |
| 50 | +## Repositories |
108 | 51 |
|
109 | | -| Channel | Audience | Why | |
110 | | -|---|---|---| |
111 | | -| **GitHub Releases** (primary) | All consumers | Versioned, immutable, checksums, tied to source tags | |
112 | | -| **HuggingFace Hub** (canonical) | Researchers | Model cards, datasets, auto-conversion, inference API | |
113 | | -| **jsdelivr CDN** (edge) | Browser | Edge-cached, CORS-friendly, no rate limits | |
| 52 | +| repo | role | |
| 53 | +|---|---| |
| 54 | +| [interscript/interscript-ml](https://github.com/interscript/interscript-ml) | this — contract + zoo | |
| 55 | +| [secryst/secryst](https://github.com/secryst/secryst) | Ruby crystal (the original, est. 2020) | |
| 56 | +| [secryst/secryst-py](https://github.com/secryst/secryst-py) | Python crystal — reference, owns golden generation | |
| 57 | +| [secryst/secryst-ts](https://github.com/secryst/secryst-ts) | TypeScript crystal (npm `secryst`) | |
| 58 | +| [secryst/secryst.github.io](https://www.secryst.org) | the crystals' documentation site | |
| 59 | +| [interscript/interscript-ml-train](https://github.com/interscript/interscript-ml-train) | training monorepo (arabic/persian/urdu) | |
| 60 | +| [interscript/rababa](https://github.com/interscript/rababa) · [rababa-farsi](https://github.com/interscript/rababa-farsi) · [rababa-urdu](https://github.com/interscript/rababa-urdu) | archived origins of the train monorepo (full history merged there) | |
114 | 61 |
|
115 | | -Per-task versioning: `rababa_arabic-v1.0.0`, `secryst_thai_ipa-v1.2.0`, |
116 | | -etc. Each release ships fp32 + int8 + int4 variants with SHA256 |
117 | | -sidecars, SLSA provenance, and Sigstore signatures. |
| 62 | +`runtime/` in this repo is the **frozen origin** of the Python crystal — |
| 63 | +kept for provenance; live code and releases are in secryst-py. |
118 | 64 |
|
119 | | -Distribution phases (P2–P8) are tracked in `TODO.distribution/`. The |
120 | | -first production release lands when phase P6 (first trained model) |
121 | | -completes. |
| 65 | +## Environment (as implemented by every crystal) |
122 | 66 |
|
123 | | -## License |
| 67 | +`SECRYST_INDEX` (index URL or path; default: `models.yaml` on this |
| 68 | +repo's main) · `SECRYST_CACHE` (default `~/.cache/secryst`). Cache hits |
| 69 | +are re-verified against the index on every load. |
124 | 70 |
|
125 | | -BSD-3-Clause, for code and model weights alike (see `LICENSE`). |
| 71 | +License: BSD-3-Clause. |
0 commit comments