spellman / README.md
vpermilp's picture
Upload README.md with huggingface_hub
04bce66 verified
|
Raw
History Blame Contribute Delete
4.01 kB
---
license: mit
tags:
- language-detection
- cyrillic
- fasttext
- text-classification
language:
- rus
- ukr
- bel
- bul
- mkd
- srp
- kaz
- kir
- tgk
- uzn
- tat
- bak
- chv
- sah
- tyv
- mon
- oss
- che
- udm
- mhr
- kpv
- eng
- spa
- fra
- por
- deu
- cmn
- jpn
- hin
- ara
---
# spellman model
Runtime model for **spellman** — a Cyrillic-optimized language detector.
30 classes: the G10 world languages plus ~20 Cyrillic-script languages,
built for the regime general-purpose detectors fail at — closely-related
Cyrillic pairs (ru/be/uk, bg/mk/sr, kk/ky/tt/ba) on wild, short, real
internet text — at single-digit µs/sample CPU speed.
## Languages (30)
- **Cyrillic group (21):** rus ukr bel bul mkd srp kaz kir tgk uzn tat
bak chv sah tyv mon oss che udm mhr kpv
- **Latin group (5):** eng spa fra por deu
- **Script-routed, no model columns (4):** cmn jpn hin ara
## Files
- `model.json` — the runtime contract (`version: 3`): language order
(model columns), hash id/seed, char n-gram config (1..=5),
canonicalization + lexical flags, calibrated confidence threshold θ.
- `model.safetensors``P` `[131073×30]` f16 (the algebraic fold
`P = E·W` of a fastText-style model) + `bias` `[30]` f16. Inference is
pure table lookups — no embedding gathers, no matmul.
The feature space is char n-grams **plus a lexical channel**: every word
also contributes its whole-word FNV-1a-64 key and an adjacent-word bigram
key (fastText's word / wordNgram features) hashed into the same bucket
space.
## Storage formats
The same model in every folded-table storage format; the runtime
dequantizes at load and the graph is unchanged — every variant is
accuracy-identical to the f16 original within ±0.02pp.
| ref | format | size |
|---|---|---|
| `vpermilp/spellman` (root) | f16 | 7.86 MB |
| `vpermilp/spellman/int8-row` | int8, per-row scales | 4.46 MB |
| `vpermilp/spellman/int8-col` | int8, per-column scales | 3.93 MB |
| `vpermilp/spellman/fp8-row` | fp8 e4m3, per-row scales | 4.46 MB |
| `vpermilp/spellman/fp8-col` | fp8 e4m3, per-column scales | 3.93 MB |
The spellman CLI fetches any of them straight from the Hub:
```bash
spellman detect --model hf:vpermilp/spellman/int8-col < text.txt
```
## Usage
This is not a standalone checkpoint: the featurizer (canonicalizing char
n-grams + lexical word n-grams + signed feature hashing) lives in the
runtime, so the model is consumed by the spellman Rust workspace
(detector crate + CLI):
```bash
hf download vpermilp/spellman --local-dir model
echo "Съешь ещё этих мягких французских булок" | spellman detect # rus
printf 'Қазақша\nHello\n' | spellman detect --lines # kaz / eng
```
## Metrics
| eval | accuracy |
|---|---|
| held-out mix (85,283 rows, pristine test) | 98.28% |
| Tatoeba (37,051, out-of-domain) | 98.66% |
| Tatoeba granularity ladder (word / pair / triple) | 68.5 / 87.1 / 94.1 |
| wild Russian tweets (2,679; 61% @mentions, 20% URLs) | 93.73% |
| throughput | ~3.5 µs/sample (fp16 JIT plan, CPU) |
On identical eval rows it beats fastText lid.176 (Tatoeba 94.90% →
98.66%) and lingua 1.8 high-accuracy on the shared Cyrillic close pairs
at ~30× its speed; whichlang and lingua cover only 10 and 17 of these 30
classes respectively. Against open-LID SOTA GlotLID v3 it wins the wild
held-out workload (98.28 vs 96.43) and the single-word rung (68.5 vs
43.9) while running ~100× faster; GlotLID's much larger training set
still wins clean out-of-domain sentences (99.25 vs 98.66).
## Training data
FineWeb-2 per-language configs sampled as line-windows (ODC-BY) +
FineWeb (English), ~104k Tatoeba sentences (CC BY 2.0 FR), and
per-language community/parallel corpora for the weak classes (Tatar,
Bashkir, Chuvash, Tuvan, Kyrgyz, Udmurt, Mari, Macedonian, Chechen, …),
hygiene-filtered with twin-language protection. Training methodology and
the full recipe are documented in the spellman repository (design doc +
training guide).