youcoded commited on
Commit
d8ef65e
·
verified ·
1 Parent(s): 454a283

First release: model, model card, methods, credits

Browse files
Files changed (6) hide show
  1. METHODS.md +223 -0
  2. NOTICE.md +61 -0
  3. ODC-By-1.0.txt +195 -0
  4. README.md +220 -0
  5. TATOEBA-CC-BY-2.0-FR.txt +17 -0
  6. es.nwp.bin +3 -0
METHODS.md ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # How we measured everything
2
+
3
+ Draft, not published. Every number is traced to a file in the repository in an HTML comment next to it. Where a number does not exist in our records, this page says "not measured" instead of estimating one.
4
+
5
+ Models trained and released by Destin Moss via youcoded.ai, 2026. Project: https://github.com/itsdestin/swipe-keyboard. Model cards: [docs/models/](https://huggingface.co/youcoded).
6
+
7
+ ## Why this page exists
8
+
9
+ We say our next-word and swipe models are good in some places and not in others. That is only believable if you can see exactly what was counted, on which text, against what, and what we got wrong along the way. This page is that account. It includes a measurement error we made and retracted ([the devhold incident](#the-devhold-contamination-incident)).
10
+
11
+ Plain rules we follow:
12
+
13
+ - Every figure says its denominator (how many sentences or swipes, and which ones).
14
+ - A change ships only if no language got worse on any scoreboard measure beyond noise: about 1 point on sets of roughly 700 words, wider sets where a decision hinges on a smaller gap.
15
+ - Test data never feeds training (see [safeguards](#data-leak-safeguards)).
16
+ - Results are reported with the places where we lose, not only where we win.
17
+
18
+ ## The three tasks
19
+
20
+ | Task | What the user does | What we count |
21
+ |---|---|---|
22
+ | **Next word** | A sentence is partly typed; no letters of the next word yet. | The word the writer actually typed next is among the 3 suggestions ("top 3"). |
23
+ | **Completion after N letters** | The first N letters (1, 2 or 3) of the next word are typed. | The word is among the suggestions. We report **top 2** because the keyboard (and Gboard) show the typed letters themselves in one of the three slots. Words with N letters or fewer are skipped. |
24
+ | **Swipe decoding** | A finger path across the keyboard. | **First guess**: the first suggestion is the target word. **Top 3**: it is among the first three. |
25
+
26
+ Matching is case-insensitive for typing tasks (capitals are display, not prediction). For swipes, the ASCII benchmark compares letters only; the HeliBoard sets are case-insensitive with accents kept.
27
+
28
+ ## Test sets
29
+
30
+ ### Next word and completion
31
+
32
+ All three sets are built by `scripts/lm/make-nextword-testsets.py` with a fixed seed so every model is scored on the same text; 2,000 sentences each by default, 4 to 30 words per sentence, no URLs or code-like text. The routine scoreboard uses the **first 300 sentences** of each set (about 2,000 scored words per measure); blend tuning uses sentences 1000 and beyond so the reported ones stay untouched.
33
+
34
+ | Set | Source | Licence | Notes |
35
+ |---|---|---|---|
36
+ | **everyday** | Common Voice's community-written sentences, minus any that also appear in Tatoeba | CC0 | Read-aloud style, not texting. Never trained on. |
37
+ | **web** | Sentences from the FineWeb-2 official test split, at most one per web page (English: a FineWeb sample shard kept out of training) | ODC-By 1.0 | Partly "home ground" for models trained on web text. |
38
+ | **tatoeba** | Tatoeba sentences whose id ends in 0 | CC BY 2.0 FR | The tenth the packs never trained on. Home ground for models that train on the other nine tenths. |
39
+
40
+ No single source is neutral. A model built from web text should win on web text; we read a model as "better" only if it also wins on sets it was not built from. We say so next to each result.
41
+
42
+ ### Swipes, English, real
43
+
44
+ FUTO's public swipe recordings (MIT licence; swipe.futo.org). Splits we use:
45
+
46
+ | Name | What it is | Use |
47
+ |---|---|---|
48
+ | `bench-2000` | 2,000 swipes spread evenly across FUTO's test split (every k-th line, so many different people; `bench/make-slice.py`) | final scoring only |
49
+ | `test-extra-10000` | 10,000 further swipes of the test split (how they were picked is not recorded in the repository) | final scoring only |
50
+ | `test.jsonl` | FUTO's full test split | clean3000 below is drawn from it |
51
+ | clean3000 | 3,000 swipes from `test.jsonl` excluding bench-2000 and test-extra-10000 | diagnostic; never trained on or tuned against |
52
+ | trv8k | 7,198 swipes: a 5 % session-level slice of FUTO's training file that keeps its sentence text | validation, and the sentence-context experiment |
53
+ | validation sessions | 10 % of `dev.jsonl` by whole recording session (6,637 swipes) | model selection |
54
+
55
+ bench-2000 is scored the same way for FUTO's engine and ours. Two denominators are always reported: **all swipes** (including those whose target is not in the word list and so can never be found) and **in-dictionary** (only swipes whose target is in the word list). FUTO's own tool skips about 3 % of swipes it cannot score; we state the count where we compare.
56
+
57
+ ### Swipes, Spanish, French, German
58
+
59
+ - **HeliBoard real multilingual swipes** (from the HeliBoard project's gesture test data; CC BY-SA): 5,000 real swipes per language, with each swipe's real board geometry. **Test only. Never trained on** (the share-alike licence is the reason we kept it out of training).
60
+ - **Synthetic noisy swipes** (`bench/languages/synthetic-noisy-v1-{es,fr,de}.json`): 400 words each, sampled by frequency from our everyday and web test text, traced by a noise model fitted on real English swipes, then scaled so synthetic English matched real English on bench-2000 (92.3 vs 92.8 first guess). They only cover dictionary words and assume people swipe other languages like English. They are **not human swipes** and are never marked as reviewed by native speakers. A different generator (`scripts/swipe/synth_swipes.py`) makes training swipes, so the model is never scored on its own generator's output.
61
+ - **Real swipes from FUTO's `swipe-5`**: real French, German and Spanish swipes on their own layouts, used for training; validation slices of it are a development check only.
62
+ - **Hand-authored fixtures** (`synthetic-centered-v1.json`, 30 seeds): not reviewed by native speakers, no thresholds attached, used for code regression checks, not accuracy claims.
63
+
64
+ Real volunteer swipes for Spanish, French and German from people who speak them: **still missing**.
65
+
66
+ ## How Gboard was measured from the outside
67
+
68
+ We compare with Gboard only by using the app, as a user would. Full procedure: `bench/gboard/README.md`.
69
+
70
+ - **What:** Gboard 14.2 (the copy built into Google's Android 35 x86_64 emulator image; the repository records no fuller build number), learning from typing **off**, one language at a time with multilingual typing off. Measured 2026-10-22.
71
+ - **Sentences:** 100 per language per set, from our own test sets (everyday and web).
72
+ - **Method:** for every word, the words before it plus its first 0, 1, 2 or 3 letters are put into a Messages text box, and the three suggestions are read off the screen. The three slots are recorded left, middle, right; middle is Gboard's best guess. This "text fill" method is much faster than tapping every key.
73
+ - **Check that text fill matches real typing:** 30 random phrases typed with real key taps gave the same suggestions as text fill in **27 of 30** cases; the 3 differences were single words with no direction (`validate_taps.py`).
74
+ - **Slot rule:** once letters are typed, Gboard spends one slot on the typed letters (95 to 100 % of rows), so the fair figure for us is "right word in our top 2". Before typing, both get 3. Sentence starts are not scored because Gboard shows shortcut chips there instead of words.
75
+ - **Frozen answers:** Gboard's replies are saved in `bench/gboard/reference/LANG-SET.tsv` (one row per query: sentence number, word number, letters typed, text before the word, the word, left / middle / right suggestion). `bench/scoreboard.sh` replays our predictor over exactly those queries, so anyone can compare without an Android device. English, Spanish, French and German references are committed.
76
+ - **Limits:** one Gboard version (current Gboard is newer and may differ); Gboard with learning on was not measured; learning off, so this is Gboard's out-of-the-box model, not what it does after weeks of use; 100 sentences per set gives roughly +-2 points of noise; the emulator is Google's and we have no view inside Gboard.
77
+ - **Gboard swipe typing: not measured.**
78
+
79
+ ## How FUTO's engine was measured
80
+
81
+ FUTO's swipe engine is shipped with the keyboard as the default and used as the reference for swipe accuracy. We run it through two paths:
82
+
83
+ 1. FUTO's own `infer_jsonl` program on the bench-2000 slice (beam width 100, top 3). With the stock dictionary this gave 92.50 first guess / 95.43 top 3 on 2,000 swipes.
84
+ 2. Through our own recogniser harness with FUTO's models and our current dictionary: 93.32 first guess / 96.56 top 3 on bench-2000. This is the "FUTO 93.32 / 96.56" figure used in the model card.
85
+
86
+ The two differ because of the dictionary and ranking used, not the same code path; when we compare, we name which one. On clean3000, FUTO's tool scores the 2,909 swipes it can read: 92.5 / 96.3.
87
+
88
+ FUTO's code and model weights were **not used** in our own swipe engine (see below). FUTO's public swipe data (MIT) was used for training, with its licence text kept. FUTO's next-word model was the keyboard's English suggestion engine before 2026-10-22; we measured it as the "before" baseline for English (see results).
89
+
90
+ ## Reproducing everything: the scoreboard
91
+
92
+ `bench/scoreboard.sh` is one command that rebuilds the typing table for all four languages: next word, completion after 1 and 3 letters, speed, pack size, and the same against Gboard's frozen answers. It appends rows to `bench/scoreboard.tsv`; `--check` fails if any accuracy measure fell more than 1 point below the previous run (about 2,000 scored words per measure, so smaller moves are noise). A full run takes a few minutes.
93
+
94
+ Rows in `bench/scoreboard.tsv` (commit and label are recorded per row):
95
+
96
+ | Label | Commit | What it is |
97
+ |---|---|---|
98
+ | installed packs (Tatoeba-only) | 7f53d8c | The keyboard's n-gram files before 2026-10-22 (es / fr / de) |
99
+ | new web+Tatoeba packs (mix30-S) | 7f53d8c | First web + Tatoeba packs |
100
+ | published language files 2026-10-22 (XS) | fd59e68 | The published XS n-gram files |
101
+ | open word lists 2026-10-22 | a2041d8 | Same, with the open (non-share-alike) word lists |
102
+ | AI models + open word lists 2026-10-23 | d63a2ce | The above plus the four neural next-word models |
103
+
104
+ Swipe accuracy comes from `tools/swipekb-swipenet-bench` (our engine) and `bench/score.sh` (FUTO's), described in the model card.
105
+
106
+ ## Data-leak safeguards
107
+
108
+ 1. **8-word-run exclusion (next word).** Any training sentence that shares a run of 8 consecutive words with any sentence of the three test sets is dropped, for both the n-gram files and the neural models. The same rule applies to the counts behind the word lists. This removes verbatim overlap, not paraphrases.
109
+ 2. **Tatoeba tenths.** Test set = ids ending in 0; training uses the other nine tenths only.
110
+ 3. **Test-only data stays test-only.** Common Voice sentences (CC0) and the HeliBoard swipes are never trained on.
111
+ 4. **Tuning on other sentences.** Blend weights for the neural models were tuned on test-file sentences 1000 and beyond; reported scores use the first 300.
112
+ 5. **Session-level splits (swipe).** Swipes from one person look alike, so a random split would leak that person into validation. Validation is 10 % of `dev.jsonl` by whole session (a stable SHA-1 of the session id).
113
+ 6. **Overlap check against every evaluation file.** Before training on FUTO's other collections, every swipe whose (session, timestamp) key, or whose session, appears in bench-2000, test-extra-10000, `test.jsonl` or the validation sessions is dropped, with counts printed. Checked: 56,005 swipe keys and 768 sessions; no overlapping swipe or session occurred in any collection (counts kept: `swipe-1` 901,908; `swipe-2` 23,774; `swipe-3` 34,769; `swipe-4` 43,909; `swipe-5` 50,507).
114
+ 7. **Different generators for training and test synthetic swipes.** (`synth_swipes.py` vs `make-noisy-swipes.py`.)
115
+ 8. **Final sets are scored rarely.** bench-2000 and test-extra-10000 are scored once per final model, not used for selection.
116
+
117
+ ## The devhold contamination incident
118
+
119
+ On 2026-10-22 we reported swipe results from validation sets called `devhold-5000`, `tune-2000` and `tune-10000`. They looked excellent: a first GPU-trained model scored 93.02 / 96.07, apparently tying FUTO's 93.3 / 96.6, and an earlier CPU model scored 91.5.
120
+
121
+ They were wrong. Those validation sets were **entirely contained in `dev.jsonl`, the training file** (100 % of ids and sessions). Every figure measured on them was a score on training swipes. We found it (the swipe helper noticed), verified it by comparing ids and sessions, and **retracted all devhold numbers**. The corrected first read, on 3,000 fresh swipes from `test.jsonl` that were never trained on, put our model at 88.6 / 93.9 (all swipes counted) versus FUTO's 92.5 / 96.3: a gap of roughly 2 to 4 points, not zero.
122
+
123
+ What we changed: validation is now whole recording sessions held out of `dev.jsonl`; model selection uses only that; bench-2000 and test-extra-10000 are final-only; and `split_by_session.py` documents the incident in its header so nobody reuses the old sets. The geometric decoder's 82.0 / 90.0 result never trained on `dev.jsonl` and stands.
124
+
125
+ ## What we deliberately did not use
126
+
127
+ - **FUTO code.** The own swipe engine (CTC network, lexicon beam search, geometric fallback) was written from published literature (Graves et al. 2006 on CTC; Alsharif et al. 2015 and follow-ups on gesture decoding; Kristensson and Zhai 2004; dynamic time warping), by a writer who had not read FUTO's source. Our authorship audit separately marks which older files of the repository are FUTO-derived (53 files, mostly glue for calling FUTO's engine) so they can be removed.
128
+ - **FUTO model weights.** None are in our models. FUTO's engine is still the keyboard's default swipe engine for now and keeps its own licence and notice.
129
+ - **A Gboard study report.** Early in the project a static study of Gboard 18.5's app code was written. It was withdrawn at the owner's request on 2026-10-23 and removed from the current tree (it remains in older git history); nothing in our models, data or numbers depends on it. Gboard is compared only by using the app from the outside, as described above.
130
+ - **HeliBoard data for training.** Its gesture data is CC BY-SA (share-alike); we use it for testing only.
131
+ - **wordfreq.** Replaced by word lists counted from FineWeb / FineWeb-2 and Tatoeba (share-alike term removed).
132
+ - **Real users' typing.** Nothing is collected from users. The opt-in swipe recorder in the plugin exists but its recordings are not part of any model here.
133
+
134
+ ## Results summary
135
+
136
+ All typing figures: percent, 300 sentences per set, `bench/scoreboard.tsv` commit d63a2ce (n-gram files plus neural models); "vs Gboard" = points ahead (+) or behind (-) Gboard 14.2 (the copy built into Google's Android 35 x86_64 emulator image, learning off, tested 2026-10-22) on its recorded queries, 100 sentences per set, top 3 before typing and top 2 after. Compare with caution: web and Tatoeba sets are partly home ground.
137
+
138
+ ### Typing
139
+
140
+ | Language | Next word, top 3: everyday / web / Tatoeba | After 1 letter, top 2: everyday / web / Tatoeba | After 3 letters, top 2: everyday / web / Tatoeba | vs Gboard 14.2 (emulator copy, learning off), 1 letter: everyday / web |
141
+ |---|---|---|---|---|
142
+ | English | 29.36 / 31.62 / 43.83 | 51.96 / 52.89 / 67.82 | 71.97 / 73.53 / 88.97 | +11.95 / +12.87 |
143
+ | Spanish | 26.27 / 33.25 / 31.32 | 49.93 / 56.57 / 58.58 | 67.08 / 75.10 / 77.24 | +6.58 / +17.46 |
144
+ | French | 22.10 / 31.97 / 32.79 | 46.46 / 54.07 / 59.35 | 65.44 / 73.70 / 74.47 | +4.29 / +12.70 |
145
+ | German | 25.04 / 24.22 / 31.57 | 48.70 / 47.46 / 57.87 | 70.01 / 66.69 / 78.40 | +5.88 / +10.76 |
146
+
147
+ The neural models add (against the n-gram files alone, commit a2041d8): between +0.36 (English, Tatoeba, after 1 letter) and +9.32 (Spanish, web, after 3 letters) points depending on set and measure, largest on web text and after 3 letters; 3 of the 36 measures moved by less than 1 point, i.e. within noise. See each [model card](https://huggingface.co/youcoded) for the per-measure tables. Before the 2026-10-22 open files, the keyboard trailed or tied Gboard on several French and German web measures (French web: -5.11 points after 1 letter, -13.22 after 3 letters), and on the recorded 0- and 1-letter measures its lead over Gboard was never larger than 2.33 points (Spanish, French and German, everyday text).
148
+
149
+ ### Swipe (model T1; English real swipes, FUTO's test split)
150
+
151
+ | Set | Denominator | Ours first / top 3 | FUTO first / top 3 |
152
+ |---|---|---|---|
153
+ | bench-2000 | all 2,000 swipes | 90.40 / 94.95 | 93.32 / 96.56 |
154
+ | bench-2000 | in-dictionary (1,958) | 92.34 / 96.99 | not restricted this way |
155
+ | test-extra-10000 | all 10,000 | 90.77 / 94.97 | not measured |
156
+ | test-extra-10000 | in-dictionary (9,781) | 92.80 / 97.10 | not measured |
157
+ | clean3000 | in-dictionary | 93.13 / 97.37 | 92.5 / 96.3 (2,909 swipes it can score) |
158
+
159
+ ### Swipe, other languages (HeliBoard real swipes, test only, 5,000 each, first / top 3)
160
+
161
+ | Language | Ours (T1, 260k word lists) | FUTO engine today (older, smaller packs; not like-for-like) |
162
+ |---|---|---|
163
+ | English | 82.1 / 91.5 | 84.5 / 93.4 |
164
+ | Spanish | 81.1 / 89.8 | 77.7 / 85.1 |
165
+ | French | 71.7 / 85.9 | 64.6 / 76.9 |
166
+ | German | 73.3 / 82.3 | 69.7 / 76.4 |
167
+
168
+ ### What is not measured
169
+
170
+ - Gboard swipe accuracy; Gboard English next word with its learning on; any newer Gboard.
171
+ - Real volunteer swipes for Spanish, French and German (HeliBoard's are real but from a different population; synthetic ones are model-made).
172
+ - Our swipe model on the synthetic Spanish, French and German sets (those sets were scored only with the older FUTO-engine keyboard: es 89.00 / 98.25, fr 83.25 / 93.00, de 87.75 / 97.00).
173
+ - FUTO's English next-word model on completion after letters; FUTO against the HeliBoard sets with the new open word lists.
174
+ - Validation perplexity and training curves of the next-word models.
175
+ - Speed on ARM or Steam Deck hardware (no device available).
176
+ - Texting-style text (all next-word sets are read-aloud, web or example-sentence text).
177
+
178
+ ## Known limits of the whole method
179
+
180
+ - Small sets: 300 sentences (about 2,000 words) per typing measure, 100 sentences against Gboard. Differences under about 1 to 2 points are noise.
181
+ - One Gboard version (14.2, emulator copy), learning off, tested 2026-10-22; newer versions may differ and learning-on behaviour was not measured. We make no general claim about Gboard.
182
+ - Synthetic swipes are provisional; non-English real-swipe evidence comes from HeliBoard (test) and FUTO's `swipe-5` (training).
183
+ - The home-ground effect on web and Tatoeba sets.
184
+ - A single hardware setup: one desktop with an RTX 4070 Super for training; swipe speed measured on a loaded desktop CPU.
185
+ - We do not know a user's real-life accuracy; none of these are field trials.
186
+ - The incident above shows measurements here can be wrong. Corrections are recorded in git history and the roadmap.
187
+
188
+ ## How to reproduce
189
+
190
+ From a checkout of https://github.com/itsdestin/swipe-keyboard, build the tools (the Qt build produces `build/tools/swipekb-nextword-eval` and `build/tools/swipekb-swipenet-bench`).
191
+
192
+ ```
193
+ # Typing: build the three test sets (needs the Tatoeba export, Common Voice sentences, a FineWeb-2 test parquet)
194
+ python -I scripts/lm/make-nextword-testsets.py LANG TATOEBA.tsv.bz2 COMMONVOICE.txt FINEWEB2-TEST.parquet OUTDIR
195
+
196
+ # Typing: the scoreboard (all four languages; add --check to fail on a regression of more than 1 point)
197
+ SWIPEKB_NEXTWORD_EVAL=build/tools/swipekb-nextword-eval SWIPEKB_TESTSETS=<dir with LANG/test/*.txt> \
198
+ SWIPEKB_PACKS=<dir with LANG.ngram, LANG.vocab.tsv, LANG.nwp.bin> \
199
+ bench/scoreboard.sh --label "my run"
200
+
201
+ # Typing: one measure by hand, e.g. completion after 1 letter on the web set, first 300 sentences
202
+ build/tools/swipekb-nextword-eval --model es.ngram --vocab es.vocab.tsv --nwp es.nwp.bin \
203
+ --sentences OUTDIR/web.txt --limit 300 --letters 1
204
+
205
+ # Gboard: replay frozen answers (no device needed) -- run by the scoreboard; or by hand
206
+ build/tools/swipekb-nextword-eval --model es.ngram --vocab es.vocab.tsv --gboard bench/gboard/reference/es-everyday.tsv
207
+
208
+ # Gboard: re-record (needs the Android SDK emulator, uiautomator2; see bench/gboard/README.md)
209
+ python -I bench/gboard/gboard_probe.py LANG SENTENCES OUT.tsv --count 100 --serial emulator-5554
210
+
211
+ # Swipe: FUTO's data, filtered and overlap-checked, then score our engine
212
+ python -I scripts/swipe/holdout_ids.py holdout-final.json bench-2000.jsonl test-extra-10000.jsonl test.jsonl
213
+ python -I scripts/swipe/assemble_futo.py DATA_DIR OUT_DIR holdout-final.json holdout-val.json
214
+ build/tools/swipekb-swipenet-bench --model swipe-model.bin --words words.tsv --layout scripts/swipe/layouts/qwerty.tsv bench-2000.jsonl
215
+
216
+ # Swipe: FUTO's engine on the same slice (needs the FUTO build)
217
+ bench/score.sh --runner futo --label "FUTO reference"
218
+
219
+ # Synthetic noisy swipes for es / fr / de
220
+ python -I bench/languages/make-noisy-swipes.py gen --lang es --params bench/languages/noisy-params-v1.json --text-dir <dir> --out OUT.json
221
+ ```
222
+
223
+ Inputs we cannot redistribute from the repository (download them yourself): Tatoeba exports (CC BY 2.0 FR), Common Voice sentences (CC0), FineWeb / FineWeb-2 parquet files (ODC-By 1.0), FUTO's swipe collections (MIT), HeliBoard's gesture sets (CC BY-SA). The language files and trained models are published as GitHub releases `language-files-2026-10-22-open-words` and `models-2026-10-23`, pinned by SHA-256 in `packaging/assets.lock.json`.
NOTICE.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Swipe Keyboard trained models, 2026-10-23
2
+
3
+ Models trained and released by Destin Moss via youcoded.ai, 2026.
4
+ SPDX-FileCopyrightText: 2026 Destin Moss <https://youcoded.ai>
5
+
6
+ Four neural next-word models (English, Spanish, French, German) and one swipe-recognition model. They sit beside the
7
+ language files published in release `language-files-2026-10-22-open-words` and are checked by SHA-256 against
8
+ `packaging/assets.lock.json` in github.com/itsdestin/swipe-keyboard before use. A missing or damaged file only turns
9
+ that model off (suggestions fall back to the n-gram files; swipes fall back to the geometric matcher); it never
10
+ disables a language.
11
+
12
+ | File | What it is | Declared licence |
13
+ |---|---|---|
14
+ | `LANG.nwp.bin` (en, es, fr, de) | next-word model: a small recurrent network (one LSTM layer, integer weights, about 4.7 MB), used together with `LANG.ngram` | ODC-By-1.0 AND CC-BY-2.0-FR |
15
+ | `swipe-model.bin` | swipe recognition: small convolution + recurrent network (about 0.5 million weights, 2.1 MB) shared by all four languages | MIT |
16
+
17
+ ## How they were built
18
+
19
+ Scripts in github.com/itsdestin/swipe-keyboard (commit `14f9722` and its ancestors on branch `feature/179-engine-in-keyboard`):
20
+
21
+ - Next-word models: `scripts/lm/nwp/prepare.py` (tokenise, vocabulary), `train.py` (train), `tune.py` (blend with the
22
+ n-gram), `export.py` (write `LANG.nwp.bin`). Training text: the same FineWeb (English, sample-10BT) / FineWeb-2
23
+ (Spanish, French, German) text and Tatoeba sentences as the n-gram files, with test sentences held out (Tatoeba ids
24
+ ending in 0, and sentences sharing an 8-word run with the test sets).
25
+ - Swipe model: `scripts/swipe/prep_data.py`, `assemble_futo.py`, `synth_swipes.py`, `train.py`. Training data: real
26
+ swipes from FUTO's swipe.futo.org dataset (MIT) plus synthetic swipes generated from our open word lists
27
+ (our own noise model, no FUTO code or model weights). Sessions used for validation or final scoring were held out.
28
+
29
+ ## Sources and licences
30
+
31
+ - **Web text** (next-word models) - FineWeb and FineWeb-2 by Hugging Face, Open Data Commons Attribution License v1.0
32
+ (`ODC-By-1.0.txt`); built from Common Crawl, whose terms of use also apply. The models contain learned weights, never text.
33
+ - **Short everyday sentences** (next-word models) - Tatoeba (tatoeba.org), CC BY 2.0 FR (`TATOEBA-CC-BY-2.0-FR.txt`).
34
+ The contributors are credited in `en-CONTRIBUTORS.txt`, `es-CONTRIBUTORS.txt`, `fr-CONTRIBUTORS.txt`,
35
+ `de-CONTRIBUTORS.txt` in release `language-files-2026-10-22-open-words`.
36
+ - **Real swipes** (swipe model) - the swipe.futo.org dataset, https://huggingface.co/datasets/futo-org/swipe.futo.org,
37
+ MIT licence, reproduced below and in `FUTO-SWIPE-DATA-LICENSE.txt`:
38
+
39
+ MIT License
40
+
41
+ Copyright (c) 2025 FUTO
42
+
43
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
44
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation
45
+ the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
46
+ to permit persons to whom the Software is furnished to do so, subject to the following conditions:
47
+
48
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions
49
+ of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
52
+ THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
54
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
55
+ IN THE SOFTWARE.
56
+
57
+ - **Synthetic swipes** (swipe model) - generated by us from the open word lists above; no third-party terms.
58
+
59
+ Changes made: text was split into sentences and reduced to letter words before training; swipes were resampled and
60
+ normalised to key positions; the trained weights were converted to the compact formats the keyboard reads.
61
+ These models contain no FUTO model weights and no FUTO code. https://github.com/itsdestin/swipe-keyboard
ODC-By-1.0.txt ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ODC Attribution License (ODC-By)
2
+
3
+ ### Preamble
4
+
5
+ The Open Data Commons Attribution License is a license agreement intended to allow users to freely share, modify, and use this Database subject only to the attribution requirements set out in Section 4.
6
+
7
+ Databases can contain a wide variety of types of content (images, audiovisual material, and sounds all in the same database, for example), and so this license only governs the rights over the Database, and not the contents of the Database individually. Licensors may therefore wish to use this license together with another license for the contents.
8
+
9
+ Sometimes the contents of a database, or the database itself, can be covered by other rights not addressed here (such as private contracts, trademark over the name, or privacy rights / data protection rights over information in the contents), and so you are advised that you may have to consult other documents or clear other rights before doing activities not covered by this License.
10
+
11
+ ------
12
+
13
+ The Licensor (as defined below)
14
+
15
+ and
16
+
17
+ You (as defined below)
18
+
19
+ agree as follows:
20
+
21
+ ### 1.0 Definitions of Capitalised Words
22
+
23
+ "Collective Database" – Means this Database in unmodified form as part of a collection of independent databases in themselves that together are assembled into a collective whole. A work that constitutes a Collective Database will not be considered a Derivative Database.
24
+
25
+ "Convey" – As a verb, means Using the Database, a Derivative Database, or the Database as part of a Collective Database in any way that enables a Person to make or receive copies of the Database or a Derivative Database. Conveying does not include interaction with a user through a computer network, or creating and Using a Produced Work, where no transfer of a copy of the Database or a Derivative Database occurs.
26
+
27
+ "Contents" – The contents of this Database, which includes the information, independent works, or other material collected into the Database. For example, the contents of the Database could be factual data or works such as images, audiovisual material, text, or sounds.
28
+
29
+ "Database" – A collection of material (the Contents) arranged in a systematic or methodical way and individually accessible by electronic or other means offered under the terms of this License.
30
+
31
+ "Database Directive" – Means Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended or succeeded.
32
+
33
+ "Database Right" – Means rights resulting from the Chapter III ("sui generis") rights in the Database Directive (as amended and as transposed by member states), which includes the Extraction and Re-utilisation of the whole or a Substantial part of the Contents, as well as any similar rights available in the relevant jurisdiction under Section 10.4.
34
+
35
+ "Derivative Database" – Means a database based upon the Database, and includes any translation, adaptation, arrangement, modification, or any other alteration of the Database or of a Substantial part of the Contents. This includes, but is not limited to, Extracting or Re-utilising the whole or a Substantial part of the Contents in a new Database.
36
+
37
+ "Extraction" – Means the permanent or temporary transfer of all or a Substantial part of the Contents to another medium by any means or in any form.
38
+
39
+ "License" – Means this license agreement and is both a license of rights such as copyright and Database Rights and an agreement in contract.
40
+
41
+ "Licensor" – Means the Person that offers the Database under the terms of this License.
42
+
43
+ "Person" – Means a natural or legal person or a body of persons corporate or incorporate.
44
+
45
+ "Produced Work" – a work (such as an image, audiovisual material, text, or sounds) resulting from using the whole or a Substantial part of the Contents (via a search or other query) from this Database, a Derivative Database, or this Database as part of a Collective Database.
46
+
47
+ "Publicly" – means to Persons other than You or under Your control by either more than 50% ownership or by the power to direct their activities (such as contracting with an independent consultant).
48
+
49
+ "Re-utilisation" – means any form of making available to the public all or a Substantial part of the Contents by the distribution of copies, by renting, by online or other forms of transmission.
50
+
51
+ "Substantial" – Means substantial in terms of quantity or quality or a combination of both. The repeated and systematic Extraction or Re-utilisation of insubstantial parts of the Contents may amount to the Extraction or Re-utilisation of a Substantial part of the Contents.
52
+
53
+ "Use" – As a verb, means doing any act that is restricted by copyright or Database Rights whether in the original medium or any other; and includes without limitation distributing, copying, publicly performing, publicly displaying, and preparing derivative works of the Database, as well as modifying the Database as may be technically necessary to use it in a different mode or format.
54
+
55
+ "You" – Means a Person exercising rights under this License who has not previously violated the terms of this License with respect to the Database, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
56
+
57
+ Words in the singular include the plural and vice versa.
58
+
59
+ ### 2.0 What this License covers
60
+
61
+ 2.1. Legal effect of this document. This License is:
62
+
63
+ a. A license of applicable copyright and neighbouring rights;
64
+
65
+ b. A license of the Database Right; and
66
+
67
+ c. An agreement in contract between You and the Licensor.
68
+
69
+ 2.2 Legal rights covered. This License covers the legal rights in the Database, including:
70
+
71
+ a. Copyright. Any copyright or neighbouring rights in the Database. The copyright licensed includes any individual elements of the Database, but does not cover the copyright over the Contents independent of this Database. See Section 2.4 for details. Copyright law varies between jurisdictions, but is likely to cover: the Database model or schema, which is the structure, arrangement, and organisation of the Database, and can also include the Database tables and table indexes; the data entry and output sheets; and the Field names of Contents stored in the Database;
72
+
73
+ b. Database Rights. Database Rights only extend to the Extraction and Re-utilisation of the whole or a Substantial part of the Contents. Database Rights can apply even when there is no copyright over the Database. Database Rights can also apply when the Contents are removed from the Database and are selected and arranged in a way that would not infringe any applicable copyright; and
74
+
75
+ c. Contract. This is an agreement between You and the Licensor for access to the Database. In return you agree to certain conditions of use on this access as outlined in this License.
76
+
77
+ 2.3 Rights not covered.
78
+
79
+ a. This License does not apply to computer programs used in the making or operation of the Database;
80
+
81
+ b. This License does not cover any patents over the Contents or the Database; and
82
+
83
+ c. This License does not cover any trademarks associated with the Database.
84
+
85
+ 2.4 Relationship to Contents in the Database. The individual items of the Contents contained in this Database may be covered by other rights, including copyright, patent, data protection, privacy, or personality rights, and this License does not cover any rights (other than Database Rights or in contract) in individual Contents contained in the Database. For example, if used on a Database of images (the Contents), this License would not apply to copyright over individual images, which could have their own separate licenses, or one single license covering all of the rights over the images.
86
+
87
+ ### 3.0 Rights granted
88
+
89
+ 3.1 Subject to the terms and conditions of this License, the Licensor grants to You a worldwide, royalty-free, non-exclusive, terminable (but only under Section 9) license to Use the Database for the duration of any applicable copyright and Database Rights. These rights explicitly include commercial use, and do not exclude any field of endeavour. To the extent possible in the relevant jurisdiction, these rights may be exercised in all media and formats whether now known or created in the future.
90
+
91
+ The rights granted cover, for example:
92
+
93
+ a. Extraction and Re-utilisation of the whole or a Substantial part of the Contents;
94
+
95
+ b. Creation of Derivative Databases;
96
+
97
+ c. Creation of Collective Databases;
98
+
99
+ d. Creation of temporary or permanent reproductions by any means and in any form, in whole or in part, including of any Derivative Databases or as a part of Collective Databases; and
100
+
101
+ e. Distribution, communication, display, lending, making available, or performance to the public by any means and in any form, in whole or in part, including of any Derivative Database or as a part of Collective Databases.
102
+
103
+ 3.2 Compulsory license schemes. For the avoidance of doubt:
104
+
105
+ a. Non-waivable compulsory license schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
106
+
107
+ b. Waivable compulsory license schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
108
+
109
+ c. Voluntary license schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
110
+
111
+ 3.3 The right to release the Database under different terms, or to stop distributing or making available the Database, is reserved. Note that this Database may be multiple-licensed, and so You may have the choice of using alternative licenses for this Database. Subject to Section 10.4, all other rights not expressly granted by Licensor are reserved.
112
+
113
+ ### 4.0 Conditions of Use
114
+
115
+ 4.1 The rights granted in Section 3 above are expressly made subject to Your complying with the following conditions of use. These are important conditions of this License, and if You fail to follow them, You will be in material breach of its terms.
116
+
117
+ 4.2 Notices. If You Publicly Convey this Database, any Derivative Database, or the Database as part of a Collective Database, then You must:
118
+
119
+ a. Do so only under the terms of this License;
120
+
121
+ b. Include a copy of this License or its Uniform Resource Identifier (URI) with the Database or Derivative Database, including both in the Database or Derivative Database and in any relevant documentation;
122
+
123
+ c. Keep intact any copyright or Database Right notices and notices that refer to this License; and
124
+
125
+ d. If it is not possible to put the required notices in a particular file due to its structure, then You must include the notices in a location (such as a relevant directory) where users would be likely to look for it.
126
+
127
+ 4.3 Notice for using output (Contents). Creating and Using a Produced Work does not require the notice in Section 4.2. However, if you Publicly Use a Produced Work, You must include a notice associated with the Produced Work reasonably calculated to make any Person that uses, views, accesses, interacts with, or is otherwise exposed to the Produced Work aware that Content was obtained from the Database, Derivative Database, or the Database as part of a Collective Database, and that it is available under this License.
128
+
129
+ a. Example notice. The following text will satisfy notice under Section 4.3:
130
+
131
+ Contains information from DATABASE NAME which is made available under the ODC Attribution License.
132
+
133
+ DATABASE NAME should be replaced with the name of the Database and a hyperlink to the location of the Database. "ODC Attribution License" should contain a hyperlink to the URI of the text of this License. If hyperlinks are not possible, You should include the plain text of the required URI's with the above notice.
134
+
135
+ 4.4 Licensing of others. You may not sublicense the Database. Each time You communicate the Database, the whole or Substantial part of the Contents, or any Derivative Database to anyone else in any way, the Licensor offers to the recipient a license to the Database on the same terms and conditions as this License. You are not responsible for enforcing compliance by third parties with this License, but You may enforce any rights that You have over a Derivative Database. You are solely responsible for any modifications of a Derivative Database made by You or another Person at Your direction. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License.
136
+
137
+ ### 5.0 Moral rights
138
+
139
+ 5.1 Moral rights. This section covers moral rights, including any rights to be identified as the author of the Database or to object to treatment that would otherwise prejudice the author's honour and reputation, or any other derogatory treatment:
140
+
141
+ a. For jurisdictions allowing waiver of moral rights, Licensor waives all moral rights that Licensor may have in the Database to the fullest extent possible by the law of the relevant jurisdiction under Section 10.4;
142
+
143
+ b. If waiver of moral rights under Section 5.1 a in the relevant jurisdiction is not possible, Licensor agrees not to assert any moral rights over the Database and waives all claims in moral rights to the fullest extent possible by the law of the relevant jurisdiction under Section 10.4; and
144
+
145
+ c. For jurisdictions not allowing waiver or an agreement not to assert moral rights under Section 5.1 a and b, the author may retain their moral rights over certain aspects of the Database.
146
+
147
+ Please note that some jurisdictions do not allow for the waiver of moral rights, and so moral rights may still subsist over the Database in some jurisdictions.
148
+
149
+ ### 6.0 Fair dealing, Database exceptions, and other rights not affected
150
+
151
+ 6.1 This License does not affect any rights that You or anyone else may independently have under any applicable law to make any use of this Database, including without limitation:
152
+
153
+ a. Exceptions to the Database Right including: Extraction of Contents from non-electronic Databases for private purposes, Extraction for purposes of illustration for teaching or scientific research, and Extraction or Re-utilisation for public security or an administrative or judicial procedure.
154
+
155
+ b. Fair dealing, fair use, or any other legally recognised limitation or exception to infringement of copyright or other applicable laws.
156
+
157
+ 6.2 This License does not affect any rights of lawful users to Extract and Re-utilise insubstantial parts of the Contents, evaluated quantitatively or qualitatively, for any purposes whatsoever, including creating a Derivative Database (subject to other rights over the Contents, see Section 2.4). The repeated and systematic Extraction or Re-utilisation of insubstantial parts of the Contents may however amount to the Extraction or Re-utilisation of a Substantial part of the Contents.
158
+
159
+ ### 7.0 Warranties and Disclaimer
160
+
161
+ 7.1 The Database is licensed by the Licensor "as is" and without any warranty of any kind, either express, implied, or arising by statute, custom, course of dealing, or trade usage. Licensor specifically disclaims any and all implied warranties or conditions of title, non-infringement, accuracy or completeness, the presence or absence of errors, fitness for a particular purpose, merchantability, or otherwise. Some jurisdictions do not allow the exclusion of implied warranties, so this exclusion may not apply to You.
162
+
163
+ ### 8.0 Limitation of liability
164
+
165
+ 8.1 Subject to any liability that may not be excluded or limited by law, the Licensor is not liable for, and expressly excludes, all liability for loss or damage however and whenever caused to anyone by any use under this License, whether by You or by anyone else, and whether caused by any fault on the part of the Licensor or not. This exclusion of liability includes, but is not limited to, any special, incidental, consequential, punitive, or exemplary damages such as loss of revenue, data, anticipated profits, and lost business. This exclusion applies even if the Licensor has been advised of the possibility of such damages.
166
+
167
+ 8.2 If liability may not be excluded by law, it is limited to actual and direct financial loss to the extent it is caused by proved negligence on the part of the Licensor.
168
+
169
+ ### 9.0 Termination of Your rights under this License
170
+
171
+ 9.1 Any breach by You of the terms and conditions of this License automatically terminates this License with immediate effect and without notice to You. For the avoidance of doubt, Persons who have received the Database, the whole or a Substantial part of the Contents, Derivative Databases, or the Database as part of a Collective Database from You under this License will not have their licenses terminated provided their use is in full compliance with this License or a license granted under Section 4.8 of this License. Sections 1, 2, 7, 8, 9 and 10 will survive any termination of this License.
172
+
173
+ 9.2 If You are not in breach of the terms of this License, the Licensor will not terminate Your rights under it.
174
+
175
+ 9.3 Unless terminated under Section 9.1, this License is granted to You for the duration of applicable rights in the Database.
176
+
177
+ 9.4 Reinstatement of rights. If you cease any breach of the terms and conditions of this License, then your full rights under this License will be reinstated:
178
+
179
+ a. Provisionally and subject to permanent termination until the 60th day after cessation of breach;
180
+
181
+ b. Permanently on the 60th day after cessation of breach unless otherwise reasonably notified by the Licensor; or
182
+
183
+ c. Permanently if reasonably notified by the Licensor of the violation, this is the first time You have received notice of violation of this License from the Licensor, and You cure the violation prior to 30 days after your receipt of the notice.
184
+
185
+ 9.5 Notwithstanding the above, Licensor reserves the right to release the Database under different license terms or to stop distributing or making available the Database. Releasing the Database under different license terms or stopping the distribution of the Database will not withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
186
+
187
+ ### 10.0 General
188
+
189
+ 10.1 If any provision of this License is held to be invalid or unenforceable, that must not affect the validity or enforceability of the remainder of the terms and conditions of this License and each remaining provision of this License shall be valid and enforced to the fullest extent permitted by law.
190
+
191
+ 10.2 This License is the entire agreement between the parties with respect to the rights granted here over the Database. It replaces any earlier understandings, agreements or representations with respect to the Database.
192
+
193
+ 10.3 If You are in breach of the terms of this License, You will not be entitled to rely on the terms of this License or to complain of any breach by the Licensor.
194
+
195
+ 10.4 Choice of law. This License takes effect in and will be governed by the laws of the relevant jurisdiction in which the License terms are sought to be enforced. If the standard suite of rights granted under applicable copyright law and Database Rights in the relevant jurisdiction includes additional rights not granted under this License, these additional rights are granted in this License in order to meet the terms of this License.
README.md ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: other
3
+ license_name: odc-by-1.0-and-cc-by-2.0-fr
4
+ license_link: https://huggingface.co/youcoded/next-word-spanish/blob/main/NOTICE.md
5
+ language:
6
+ - es
7
+ library_name: custom
8
+ pipeline_tag: text-generation
9
+ tags:
10
+ - next-word-prediction
11
+ - keyboard
12
+ - on-device
13
+ - lstm
14
+ - int8
15
+ - swipe-keyboard
16
+ datasets:
17
+ - HuggingFaceFW/fineweb-2
18
+ model-index:
19
+ - name: next-word-spanish
20
+ results:
21
+ - task:
22
+ type: text-generation
23
+ name: Next-word suggestion (model blended with the n-gram pack)
24
+ dataset:
25
+ name: Common Voice everyday sentences, first 300 (CC0)
26
+ type: custom
27
+ metrics:
28
+ - type: accuracy
29
+ value: 26.27
30
+ name: right word in top 3 (word-level, case-insensitive)
31
+ - task:
32
+ type: text-generation
33
+ name: Next-word suggestion (model blended with the n-gram pack)
34
+ dataset:
35
+ name: FineWeb-2 test pages, first 300 sentences
36
+ type: custom
37
+ metrics:
38
+ - type: accuracy
39
+ value: 33.25
40
+ name: right word in top 3 (word-level, case-insensitive)
41
+ - task:
42
+ type: text-generation
43
+ name: Next-word suggestion (model blended with the n-gram pack)
44
+ dataset:
45
+ name: Tatoeba held-out tenth (id % 10 == 0), first 300 sentences
46
+ type: custom
47
+ metrics:
48
+ - type: accuracy
49
+ value: 31.32
50
+ name: right word in top 3 (word-level, case-insensitive)
51
+ ---
52
+
53
+ # youcoded/next-word-spanish: Spanish next-word model for the Swipe Keyboard
54
+
55
+ > **Result:** used together with its n-gram pack, this model offered the right word more often than Gboard 14.2 on every measure we recorded: 4.89 to 19.59 points ahead, from before typing to three letters typed, on everyday and web sentences (100 sentences per set). Gboard 14.2 here is the copy built into Google's Android 35 x86_64 emulator image, with learning off, tested on 22 October 2026. Newer Gboard versions, and Gboard after it has learned from a user, were not measured.
56
+
57
+ A small neural network that predicts the next word of a sentence in Spanish. It is one of four (English, Spanish, French, German) and runs on the user's own computer inside the Swipe Keyboard, an open-source swipe-typing and word-prediction add-on for KDE Plasma's on-screen keyboard.
58
+
59
+ Models trained and released by Destin Moss via youcoded.ai, 2026.
60
+
61
+ Code, scripts and tests: https://github.com/itsdestin/swipe-keyboard/tree/feature/179-engine-in-keyboard (development branch; it moves to the main branch when merged). How every number below was measured: [methods page](METHODS.md) (published copy: METHODS.md).
62
+
63
+ ## What it is, and what it is not
64
+
65
+ - It is a one-layer LSTM with a projection layer and tied word vectors: the same size class as the next-word models Google describes in its published paper on Gboard ([arXiv 2305.18465](https://arxiv.org/abs/2305.18465)). It is our own model, trained from scratch; no Google or FUTO weights or data were used.
66
+ - Header values read from the shipped file: word-vector size 128, LSTM hidden size 1024, vocabulary 24,002 tokens (23,999 words plus three special tokens), int8 weights. That is about 4.3 million numbers (computed from those sizes). The file is 4,709,920 bytes (4.71 MB).
67
+ - It is **not** a chat model, cannot write text, and has no memory of anything a user typed. It only returns a probability for each of its 23,999 known words, given the words so far in the current sentence.
68
+ - It is **not** meant to be used alone. The keyboard always blends it with a separate word-pair/word-triple (n-gram) pack for the same language; the n-gram knows a larger word list and exact word pairs and triples, this model knows only the most common words (up to 24,000) but reads the whole sentence so far.
69
+ - It needs a vocabulary that matches the keyboard's word list for the language; the keyboard refuses to use it if fewer than half of its words match.
70
+
71
+ ## Intended use
72
+
73
+ On-device keyboard suggestions only. How the keyboard uses it (`engine/src/nwp_predictor.cpp`):
74
+
75
+ 1. **Next word** (nothing typed yet): the model reads the sentence so far (up to the last 20 words), and the keyboard shows the best three suggestions after blending.
76
+ 2. **Completion** (some letters typed): the same blend, restricted to words that start with the typed letters.
77
+ 3. **Blend:** for words both sources know, score = lambda x model log-probability + (1 - lambda) x n-gram log-probability. For words only the n-gram knows, the n-gram score plus a fixed offset. This file carries lambda = 0.7 and offset = 0.0.
78
+ 4. **Fallback:** if the model file is missing or damaged, the keyboard silently uses the n-gram pack only. If the model's word list matches the keyboard's by less than half, it is ignored.
79
+ 5. It sees only words typed in the current field. Password and other private fields are blocked by the keyboard before any text reaches it. The model does not learn from or store anything.
80
+
81
+ Not intended for: generating text, content moderation, speech recognition, any use that needs its probabilities to be calibrated across contexts, or languages other than Spanish.
82
+
83
+ ## File format
84
+
85
+ One plain binary file, `es.nwp.bin`, read by our own small C++ runner (`engine/src/nwp_model.cpp`, about 250 lines, no machine-learning library). All numbers little-endian.
86
+
87
+ | Part | Content |
88
+ |---|---|
89
+ | Magic | the 8 bytes `SWKBNWP1` |
90
+ | Header | version (1), data type (0 = float32, 1 = int8 with one scale per row), vocabulary size V, vector size D, hidden size H, byte length of the word list, blend weight lambda (float), out-of-vocabulary offset (float) |
91
+ | Words | the V-3 words, one per line, letters only, padded to a multiple of 16 bytes (token 0 = unknown, 1 = sentence start, 2 = sentence end; words are tokens 3 and up) |
92
+ | Tensors | word vectors [V x D] (also used as the output layer), output bias [V], LSTM input weights [4H x D], recurrent weights [4H x D], gate bias [4H], projection [D x H]; gate order input, forget, cell, output (PyTorch's) |
93
+ | Checksum | FNV-1a 64-bit hash of everything before it |
94
+
95
+ The loader refuses a file with a wrong magic, an unknown version, out-of-range sizes, a length that does not match the header exactly, or a wrong checksum. The keyboard additionally checks the file's SHA-256 against a pinned value before using it: `fb051d4cb06e96c351ce232bc0a65cac22d477fcc982838ee37585d1f266c4a8`.
96
+
97
+ Arithmetic at run time: int8 weights, dot products in whole numbers with the input vector rounded to 13 bits; own exp/tanh approximations (relative error about 3e-6). A test checks the C++ runner against PyTorch on a small random model.
98
+
99
+ Written by `scripts/lm/nwp/export.py`.
100
+
101
+ ## Training data and licences
102
+
103
+ | Source | What was taken | Licence |
104
+ |---|---|---|
105
+ | FineWeb-2 (spa_Latn) by Hugging Face (derived from Common Crawl) | web text, sentences split and lower-cased to letter words; pages whose URL looks like a forum, Q&A or discussion page counted twice | ODC-By 1.0 (and Common Crawl's terms of use) |
106
+ | Tatoeba (spa) | sentences whose id does **not** end in 0 | CC BY 2.0 France; every contributing author is listed in the language pack's `es-CONTRIBUTORS.txt` |
107
+
108
+ Text was never kept in the model files; the model holds weights only.
109
+
110
+ Which slice of the web text was read for the shipped runs (the n-gram pack of the same language used the first 300 million words plus Tatoeba) was not logged; `prepare.py` reads up to 400 million words by default.
111
+
112
+ Vocabulary: the most frequent words, up to 24,000, that are also in the keyboard's word list (so every suggestion is something the keyboard can show).
113
+
114
+ **Test-set exclusion.** Any training sentence that shares a run of 8 words with any sentence of the three test sets (everyday, web, Tatoeba) is dropped. The Tatoeba test set is the id-ending-in-0 tenth, which is never trained on.
115
+
116
+ Not used: Gboard, FUTO or HeliBoard data of any kind; the Common Voice sentences are test-only.
117
+
118
+ ## Training procedure and hardware
119
+
120
+ - Script: `scripts/lm/nwp/train.py` (PyTorch). Whole sentences, each starting from the sentence-start token with zero state, because the keyboard only ever feeds the model the current sentence. Sentences are bucketed by length (up to 40 words).
121
+ - Script defaults: AdamW, peak learning rate 2e-3 (betas 0.9, 0.98), 300 warm-up steps then cosine decay to 3 %, about 24,576 tokens per step, gradient clipping 1.0, bfloat16 autocast, 1 pass over the data, seed 1. 20,000 randomly chosen sentences held back to compute perplexity.
122
+ - Blend weights chosen afterwards by `scripts/lm/nwp/tune.py` on test-set sentences 1000 and beyond, which the scoreboard (first 300 sentences) never uses. Result for this language: best of the script's default 5 x 5 grid, mean of nine measures 48.28.
123
+ - Hardware: one desktop NVIDIA RTX 4070 Super. Time: the four exports were written about 20 to 25 minutes apart on 2026-10-23 (file timestamps; this includes data preparation), so training took minutes, not hours.
124
+ - **Not recorded:** the exact command-line flags of the shipped runs (epochs, minutes cap, number of web words read, Tatoeba weight), the final validation perplexity, and the loss curves. The shipped file header confirms the vector and hidden sizes above. Anyone reproducing the model should treat the script defaults as the starting point, not as a guarantee of identical results.
125
+
126
+ ## Evaluation
127
+
128
+ Measured by `bench/scoreboard.sh` (the keyboard's own prediction code, replayed sentence by sentence) on **300 sentences per test set**, which is roughly 2,000 scored words per measure. All figures are percentages; "top 3" means the right word was among three suggestions; "top 2" is used after letters are typed because the keyboard (like Gboard) spends one of its three slots on the typed letters. Typical noise is about +-1 point on these sets (the project's own rule for a real change). Words no longer than the number of typed letters are skipped in the completion measures, and sentence-initial words are not scored against Gboard. Case-insensitive.
129
+
130
+ Test sets: see the [methods page](METHODS.md). Short version: everyday = Common Voice sentences (CC0); web = FineWeb-2's official test split, one sentence per page; Tatoeba = the id-ending-in-0 tenth. The web and Tatoeba sets are partly "home ground" for a model trained on web text and Tatoeba.
131
+
132
+ ### What the model adds to the n-gram pack
133
+
134
+ Same n-gram pack in both columns (the published 2026-10-22 files); only the neural model differs.
135
+
136
+ | Test set | Measure | n-gram pack only | n-gram + this model | Change |
137
+ |---|---|---|---|---|
138
+ | Common Voice everyday sentences (CC0) | next word, right word in top 3 | 25.01 | 26.27 | +1.26 |
139
+ | Common Voice everyday sentences (CC0) | after 1 letter, top 2 | 47.85 | 49.93 | +2.08 |
140
+ | Common Voice everyday sentences (CC0) | after 3 letters, top 2 | 60.73 | 67.08 | +6.35 |
141
+ | FineWeb-2 test pages | next word, right word in top 3 | 27.49 | 33.25 | +5.76 |
142
+ | FineWeb-2 test pages | after 1 letter, top 2 | 49.77 | 56.57 | +6.80 |
143
+ | FineWeb-2 test pages | after 3 letters, top 2 | 65.78 | 75.10 | +9.32 |
144
+ | Tatoeba held-out tenth | next word, right word in top 3 | 30.06 | 31.32 | +1.26 |
145
+ | Tatoeba held-out tenth | after 1 letter, top 2 | 56.02 | 58.58 | +2.56 |
146
+ | Tatoeba held-out tenth | after 3 letters, top 2 | 73.77 | 77.24 | +3.47 |
147
+
148
+ ### Against the keyboard before the open files
149
+
150
+ "Before" means the keyboard as it shipped until 2026-10-22 (for Spanish, French and German a Tatoeba-only n-gram file; for English FUTO's neural next-word model). Measured on the same sentences with the same tool.
151
+
152
+ | Test set (300 sentences) | Measure | Keyboard before the open files (Tatoeba-only pack) | n-gram + this model |
153
+ |---|---|---|---|
154
+ | Common Voice everyday sentences (CC0) | next word, top 3 | 21.22 | 26.27 |
155
+ | Common Voice everyday sentences (CC0) | after 1 letter, top 2 | 43.83 | 49.93 |
156
+ | FineWeb-2 test pages | next word, top 3 | 21.20 | 33.25 |
157
+ | FineWeb-2 test pages | after 1 letter, top 2 | 41.63 | 56.57 |
158
+ | Tatoeba held-out tenth | next word, top 3 | 31.73 | 31.32 |
159
+ | Tatoeba held-out tenth | after 1 letter, top 2 | 57.23 | 58.58 |
160
+
161
+ ### Against Gboard 14.2 (emulator copy, learning off, tested 2026-10-22)
162
+
163
+ Points **ahead of** (+) or behind (-) Gboard's own suggestions on the exact queries Gboard was asked (100 sentences per language per set, recorded once from an Android emulator; see the [methods page](METHODS.md)). 0 letters: our top 3 versus Gboard's three suggestions; 1 to 3 letters: our top 2 versus Gboard's suggestions after it spends one slot on the typed letters.
164
+
165
+ | Gboard query set | Letters typed | n-gram pack only | n-gram + this model |
166
+ |---|---|---|---|
167
+ | everyday (Common Voice) | 0 | +2.16 | +4.89 |
168
+ | everyday (Common Voice) | 1 | +2.99 | +6.58 |
169
+ | everyday (Common Voice) | 2 | +2.20 | +8.80 |
170
+ | everyday (Common Voice) | 3 | +4.54 | +12.88 |
171
+ | web (FineWeb-2) | 0 | +4.87 | +11.67 |
172
+ | web (FineWeb-2) | 1 | +8.92 | +17.46 |
173
+ | web (FineWeb-2) | 2 | +10.75 | +19.59 |
174
+ | web (FineWeb-2) | 3 | +11.05 | +19.53 |
175
+
176
+ How to read this: Gboard had its learning from the user turned off, so it shows Gboard's out-of-the-box model, not what it does after weeks of use. One Gboard version (14.2, from an Android 35 emulator image) was tested. With 100 sentences per set the noise is roughly +-2 points. The web set is partly home ground for our model. We make no claim about Gboard in general. We used none of Gboard's code or data. Newer Gboard versions may differ, and Gboard's behaviour with learning on was not measured. The repository records no fuller Gboard build number than 14.2. No broader claim about Gboard is made.
177
+
178
+ ## Known limitations
179
+
180
+ - **Web-text and Tatoeba style, not texting.** The training text is web pages and short example sentences. Slang, messaging style, emoji, code-switching and names are weak spots. The "everyday" set (Common Voice read-aloud sentences) is the closest we have to ordinary writing, and it is read-aloud style, not texting.
181
+ - **Vocabulary of about 24,000 words.** Rarer words are only ever suggested by the n-gram pack, never by this model.
182
+ - **Lower-cased letters only.** The model has no notion of capitals, accents-versus-base-letter handling beyond the vocabulary spelling, or punctuation; the keyboard handles those.
183
+ - **Test-set contamination was controlled but not eliminated:** the 8-word-run rule removes verbatim overlaps, not paraphrases. Perplexity (not recorded) was computed on random training sentences, not an independent set.
184
+ - **Tuned on the same sources as it is scored on:** blend weights were tuned on other sentences from the same three test files, not the 300 reported, but the style is the same.
185
+ - **Gain varies by test set and measure:** measured changes against the n-gram pack alone range from +1.26 (Common Voice everyday sentences (CC0), next word, right word in top 3) to +9.32 (FineWeb-2 test pages, after 3 letters, top 2) points; changes under about 1 point are within noise on 300 sentences.
186
+ - **The model reads only the current sentence** (at most the last 20 words); it does not use anything else on screen.
187
+ - No toxic-content filtering was applied to the model itself; the keyboard has a separate rule that never offers common swear words as an unprompted next word, and blocks suggestions in password fields.
188
+ - No fairness or bias evaluation has been done. Web-trained models reflect the web.
189
+
190
+ ## How to reproduce
191
+
192
+ From a checkout of https://github.com/itsdestin/swipe-keyboard/tree/feature/179-engine-in-keyboard (needs a CUDA GPU for training, the Qt build for scoring). Data: the FineWeb / FineWeb-2 parquet files and Tatoeba export named in the scripts' headers; test sets from `scripts/lm/make-nextword-testsets.py`.
193
+
194
+ ```
195
+ python -I scripts/lm/nwp/prepare.py es es.wordcounts.tsv es.vocab.tsv OUT/data \
196
+ --parquet <fineweb parquet files> --exclude <test set files> --tatoeba <tatoeba export>.bz2
197
+ python -I scripts/lm/nwp/train.py OUT/data OUT/model
198
+ python -I scripts/lm/nwp/export.py OUT/model/ckpt.pt OUT/data/lm_vocab.txt OUT/es.nwp.bin --lambda 0.7 --beta 0.0
199
+ python -I scripts/lm/nwp/tune.py build/tools/swipekb-nextword-eval es.ngram es.vocab.tsv OUT/es.nwp.bin <testsets dir> es
200
+ SWIPEKB_PACK_es=<folder with context.ngram + vocab.tsv> bench/scoreboard.sh --label "my run" --langs "es"
201
+ ```
202
+
203
+ The scoreboard needs the n-gram and word-list files from the GitHub release `language-files-2026-10-22-open-words` and the Gboard reference answers in `bench/gboard/reference/` (committed). The last command appends a row to `bench/scoreboard.tsv`.
204
+
205
+ ## Licence of the model file
206
+
207
+ `es.nwp.bin`: **ODC-By-1.0 AND CC-BY-2.0-FR** (SPDX-style expression; the file is derived from ODC-By 1.0 web text and CC BY 2.0 France Tatoeba sentences, and carries both attribution terms; no share-alike term applies).
208
+
209
+ Required credits when redistributing:
210
+
211
+ - **Models trained and released by Destin Moss via youcoded.ai, 2026**
212
+ - FineWeb / FineWeb-2 by Hugging Face, Open Data Commons Attribution License 1.0, derived from Common Crawl (Common Crawl's terms of use also apply).
213
+ - Tatoeba (tatoeba.org), CC BY 2.0 France. Keep the contributor list `es-CONTRIBUTORS.txt` and the notice `TATOEBA-CC-BY-2.0-FR.txt` with the model.
214
+ - Keep the project's notices: `MODELS-NOTICE.md` (release `models-2026-10-23`) and `LANGUAGE-FILES-NOTICE.md`.
215
+
216
+ The surrounding code is licensed separately (see the repository's `LICENSE` and `packaging/NOTICE`). If you want to publish this card on Hugging Face, the licence field above is `other` because the expression above is not one of Hugging Face's identifiers.
217
+
218
+ ## Credit
219
+
220
+ Models trained and released by Destin Moss via youcoded.ai, 2026.
TATOEBA-CC-BY-2.0-FR.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Tatoeba sentence data: CC BY 2.0 France
2
+
3
+ Source: https://tatoeba.org/en/downloads
4
+ The per-language sentence exports used to build these models are listed with
5
+ immutable URLs, SHA-256 digests, and byte sizes in packaging/assets.lock.json.
6
+ The sentences are adapted into deterministic, locale-specific word n-gram
7
+ models. The accompanying <language>-CONTRIBUTORS.txt files name every author
8
+ whose sentence ID was included in the training split. Tatoeba's Terms of Use
9
+ state that the BY condition requires citation of the sentence author's name:
10
+ https://tatoeba.org/en/terms_of_use
11
+
12
+ License text: https://creativecommons.org/licenses/by/2.0/fr/
13
+ Tatoeba attribution guide: https://tatoeba.org/en/terms_of_use
14
+
15
+ The models are compact baseline corpus models trained on Tatoeba; they are not
16
+ claims of broad or region-specific language coverage. Spanish Spain and Mexico
17
+ share the same Spanish model.
es.nwp.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fb051d4cb06e96c351ce232bc0a65cac22d477fcc982838ee37585d1f266c4a8
3
+ size 4709920