Token Classification
GGUF
Safetensors
Chinese
input-method
zhuyin
bopomofo
traditional-chinese
ternary
bitnet
Instructions to use Luigi/sloth-ime-models with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use Luigi/sloth-ime-models with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf Luigi/sloth-ime-models # Run inference directly in the terminal: llama cli -hf Luigi/sloth-ime-models
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf Luigi/sloth-ime-models # Run inference directly in the terminal: llama cli -hf Luigi/sloth-ime-models
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf Luigi/sloth-ime-models # Run inference directly in the terminal: ./llama-cli -hf Luigi/sloth-ime-models
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf Luigi/sloth-ime-models # Run inference directly in the terminal: ./build/bin/llama-cli -hf Luigi/sloth-ime-models
Use Docker
docker model run hf.co/Luigi/sloth-ime-models
- LM Studio
- Jan
- Ollama
How to use Luigi/sloth-ime-models with Ollama:
ollama run hf.co/Luigi/sloth-ime-models
- Unsloth Studio
How to use Luigi/sloth-ime-models with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for Luigi/sloth-ime-models to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for Luigi/sloth-ime-models to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for Luigi/sloth-ime-models to start chatting
- Docker Model Runner
How to use Luigi/sloth-ime-models with Docker Model Runner:
docker model run hf.co/Luigi/sloth-ime-models
- Lemonade
How to use Luigi/sloth-ime-models with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull Luigi/sloth-ime-models
Run and chat with the model
lemonade run user.sloth-ime-models-{{QUANT_TAG}}List all available models
lemonade list
- Atomic Chat
File size: 9,209 Bytes
f0f7133 20af279 f0f7133 215e9e9 1d1f376 215e9e9 1d1f376 215e9e9 f0f7133 20af279 16893f3 20af279 62fb7a7 20af279 62fb7a7 20af279 62fb7a7 20af279 f0f7133 0e3a542 1d1f376 f0f7133 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | ---
license: apache-2.0
language:
- zh
tags:
- input-method
- zhuyin
- bopomofo
- traditional-chinese
- ternary
- bitnet
- gguf
library_name: gguf
pipeline_tag: token-classification
---
# Sloth IME models — Zhuyin → Traditional Chinese, fully on-device
**The model family behind Slothing (樹懶智慧輸入法)**, all trained from scratch:
| file | role | size |
|---|---|---|
| `slothe-t-12m-256x12.gguf` (+ `12m/` fp32) | **conversion encoder — shipping default** | 9.65 MB |
| `slothe-t-25m.gguf` (+ fp32 master) | conversion encoder — accuracy reference | 18 MB |
| `pred_q35_60m-q4.gguf` (+ `pred_q35_60m/` fp32) | **next-word decoder v2.1** (neural 聯想, TW-chat register FT) | 46 MB |
The sections below document the 25M reference encoder in depth; the 12M shipping
encoder and the 60M decoder are covered in the latency/files sections.
## 60M next-word decoder (v2.1)
Dense-Qwen3.5 (Gated DeltaNet + full attention every 4th layer), 16k word-piece vocab
(next word = one forward, 8.5 ms/word on BOOX @4t). Trained on 6.1M zh-TW sentences,
then register-fine-tuned on 149k PTT/Dcard chat sentences (`--init-from`, 2ep):
| eval (n=3000) | v2 | **v2.1 (shipped)** |
|---|---|---|
| TW chat held-out | 10.9 / 21.2 | **18.3 / 31.2** |
| fresh-C4 | 34.0 / 46.0 | 33.5 / 45.2 |
> **Honesty note.** Earlier versions reported 47.3/75.8 — that held-out was saturated with
> near-duplicates of the (small) training set and rewarded memorization; on genuinely fresh
> text that model scored 4.6/12.0. All predictor numbers here use never-seen fresh corpora.
> Reproduce: `predictor_qwen35.py` + `build_corpus_big.py` (in the GitHub repo) — see the
> Reproducibility section of the [project README](https://github.com/vieenrose/sloth-zhuyin-linux#reproducibility).
## SlothE-T — Ternary Zhuyin → Traditional Chinese conversion encoder
The conversion model behind **Slothing (懶音輸入法)**: a libchewing-free, on-device
LLM-powered 注音 (Bopomofo) input method that does **免選字** (candidate-free)
whole-sentence conversion — you type the phonetic keystream, it emits the sentence,
with no candidate list to scroll.
- **25M parameters**, ternary weights (W1.58A8), bidirectional encoder.
- **~7 MB** ternary-packed GGUF (TQ2_0) · 99 MB fp32 master.
- Runs on-device across four frontends: **fcitx5, IBus, Android, web**.
## What it does
Given a sequence of Zhuyin **syllables** (the input keystream, e.g. `ㄋㄧˇ ㄏㄠˇ`),
the model emits the **Traditional Chinese characters** for each position as an
aligned sequence-labeling task. The output head is **phonetic-legality-masked**:
at each position only the ~1–50 characters that are legal readings of that
syllable are scored, out of the full 8342-char vocabulary. This is what replaces
the traditional IME 選字 (candidate-selection) step.
## Architecture
| | |
|---|---|
| encoder | bidirectional (BERT-like), 16 layers |
| dim / ffn | 352 / 960 |
| heads | 8 query, 2 KV (GQA), head_dim 44, QK-norm |
| norm | RMSNorm, embed-norm, **SubLN** pre-norm before each ternary linear |
| quantization | ternary weights {−1, 0, +1} × per-output-channel **absmedian** scale; **int8** activations; QAT via STE |
| fp islands | boundary blocks (0 and 15) kept fp16 for stability (`fp_boundary=1`) |
| vocab | 1539 syllables (in) · 8342 characters (out) |
## Evaluation — honest held-out
Measured on **500 fresh zh-TW sentences** (C4-zh-TW, offset far past the training
window, filtered to be **absent from the training corpus**), then g2pW-labeled.
| metric | **this model** | 12M int8 (previous ship) | 32M fp teacher |
|---|---|---|---|
| **免選字** (whole-sentence exact) | **76 %** | 72 % | — |
| **homophone-hard** | **86 %** | 82 % | 83 % |
| **toneless** | **77 %** | 79 % | 81 % |
> **Note on 免選字.** Earlier project numbers (~84 %) were inflated by a benchmark
> leak — the reference set had been sampled from the training corpus, rewarding
> memorization. **76 %** is the honest whole-sentence held-out figure.
> *homophone-hard* and *toneless* are leak-clean throughout. On honest data this
> 25M ternary model **beats the previously-shipped 12M int8 on 免選字 and
> homophone-hard** while being smaller and faster.
### Quality vs. latency

Latency is per-6-syllable decode on a **BOOX (Snapdragon 662, no-dotprod ARM)**.
4M and 12M are measured (ORT int8). **Update (2026-07-17): the 25M ternary's ~9 ms was a
projection that real-device measurement later corrected** — measured on the BOOX
(ggml/libslothe, single 6-syllable forward): **18.5 ms at 4 threads / 31.9 ms at 2 threads**
(the projection missed that the per-kernel TQ2_0 speedup does not compound at full-model
scale on a no-dotprod core, and an early 8-thread default dragged the A53 little cores —
fixed). The Pareto story survives in a different form: a **12M ternary sibling
(dim 256×12 layers, zero TQ2_0 padding tax, in this repo)**
measures **9.3 ms @4t / 15.8 ms @2t** on the same device at 84 % 免選字 / 84 % homophone —
the honest heir to the "~9 ms" claim.
| model | params | 免選字 | homophone | toneless | latency (BOOX) |
|---|---|---|---|---|---|
| 4M int8 | 4M | 70 % | 83 % | 74 % | 9.1 ms |
| 12M int8 | 12M | 72 % | 82 % | 79 % | 13.3 ms |
| **25M ternary** | **25M** | **76 %** | **86 %** | **77 %** | **18.5 ms\*** |
| **12M ternary 256×12** | **12M** | **84 %†** | **84 %†** | — | **9.3 ms\*** |
<sub>\* measured on-device (BOOX SD662, ggml/TQ2_0, 4 threads; the 25M's earlier "~9 ms" was a
projection — see the note above). † 230-sentence reference set (the 25M measures 85.7 % on that
same set on-device); the 免選字 columns above it use the 500-sentence held-out set.</sub>
## Training recipe (teacher-free)
- **Direct cross-entropy** on a g2pW-labeled zh-TW corpus, with **label smoothing 0.1**.
- **Long OneCycleLR schedule (32 epochs), early-stopped at the peak (epoch 24)** —
the model overfits after (73 % 免選字 by ep32).
- **8-adjacency keyboard-error noise** (TAAI-2024 error model): simulated mis-keys
are constrained to the QWERTY physical 8-neighbourhood rather than any
edit-distance-1 syllable.
- DDP on 2× RTX 5090.
Knowledge distillation from a 32M teacher was tried and only **matched** (never
beat) this teacher-free recipe, so the teacher was dropped — simpler and ~2.4×
faster to train. The two levers that carry the quality are (a) label smoothing
(a teacher-free regularizer; +5 免選字 over plain CE) and (b) enough epochs to
exploit the no-overfit headroom.
## Deployment / inference
The ternary weights are shipped as a **GGUF** using ggml's mainline **TQ2_0**
ternary type, so the model runs on stock llama.cpp CPU kernels (ARM NEON, x86
AVX2, and the generic/WASM path). Measured `vec_dot` throughput on x86 AVX2:
**TQ2_0 ≈ 2.3× int8 (Q8_0)** — the fastest quant type in the table — and ~2× on
a no-dotprod ARM (Snapdragon 662). The ternary win is partly memory-bandwidth
(2 bits/weight = 4× fewer weight bytes), so it holds on both weak and
accelerator-equipped CPUs.
> **256-alignment note.** TQ2_0 uses 256-element blocks, so the model's
> in-features (352, 960) are zero-padded up to the next multiple of 256 in the
> GGUF (352 → 512, 960 → 1024). The padding is exact ternary-zero (loss-free) but
> costs some MACs; a future model with 256-aligned dims removes the tax.
## Files
| file | what |
|---|---|
| `slothe-t-25m.gguf` | 25M ternary GGUF — TQ2_0 blocks (layers 1–14) + fp16 islands/embed/head |
| `slothe-t-12m-256x12.gguf` | **12M ternary GGUF (shipping default)** — dim256×12, zero TQ2_0 padding tax, 9.65 MB |
| `12m/model.safetensors` | 12M fp32 master weights |
| `12m/slothe_config.json` / `12m/roles.json` | 12M config + ternary/fp tensor roles |
| `pred_q35_60m-q4.gguf` | 60M Q4 next-word predictor **v2.1** (qwen35 GDN hybrid; llama.cpp-loadable; chat-register FT) |
| `model.safetensors` | fp32 master weights (HF-native, non-pickle) |
| `slothe.pt` | fp32 master checkpoint with embedded `config` |
| `syl_vocab.json` | syllable tokenizer (input vocab) |
| `syl2legal.npz` | phonetic legality mask, 1539 syllables × 8342 chars (bool) |
| `train_slothe_ternary.py` | training script |
| `gate_slothe_ternary.py` | evaluation / gating script |
| `REPRODUCE.md` | end-to-end reproduction recipe |
| `NAMES.md` | GGUF tensor-name ↔ checkpoint-name map |
## Intended use & limits
- **Intended:** on-device Traditional-Chinese Bopomofo input (Taiwan readings).
- **Out of scope:** Simplified Chinese, mainland pinyin readings, free-form
generation. The model only scores per-position legal characters — it is a
converter, not a chat model.
- The whole-sentence (免選字) metric is honest-held-out and modest (76 %) by
design: it is measured on unseen sentences, not the training distribution.
## Citation / related work
The keyboard-error model and the 免選字-vs-選字 framing are discussed in the
project's `docs/RELATED-WORK.md`, which positions this work against the TAAI-2024
cross-multi-IME system (李偉安, 葉展維, 張嘉惠, National Central University).
|