Repository navigation
Make learned words count, boundedly, without a second baseline copy - #30
Merged
Merged
Conversation
At 5x, learned counts were negligible beside the baseline: on a synthetic person, learned words reached the six slots for 16.7% of queries. At 500x they reach 53.8%, while general English with that learning present is unchanged (71.0% without learning, 71.5% and 71.3% light and heavy). Adds the synthetic fixture and evaluator to reproduce this. Closes #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Learned counts were added to a copy of the baseline at a fixed weight. A fixed 500x let one misspelling become the top suggestion, let heavy use outgrow the baseline, and could overflow on crafted counts. Now: - learned counts are kept apart and combined when predicting, in floating point, so stored counts cannot overflow when weighted; - one learned occurrence counts as 500 / (1 + learned words / 2000), so learned counts approach a bounded share of the baseline; - a word the baseline lacks is suggested once learned twice; - the baseline is no longer copied: peak predictor memory falls from 362 MiB to 134 MiB, with or without a personal database. With no or an empty personal database, predictions are bit-identical. On the synthetic person with four misspellings, top six rises from 50.3% to 60.4%, personal words from 1.3% to 46.2%, and no misspelling is suggested. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prediction was about twice as slow because every candidate and learned entry was checked on each call. What prediction uses of the learned counts, with per-context totals and the current weight, is now rebuilt only when they change: an empty-sentence prediction takes 5.3 ms against 7.5 ms before. The baseline itself holds thousands of rare misspellings, so learned counts of a word are used once it is learned twice unless the baseline has it at least three times. Learning "hav" once no longer suggests it. Adds an exact bit-for-bit check of the no-learning formula and a timing test. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rebuilding every usable learned count on each learn cost about 350 ms at 40,000 learned words. A learned sentence now adds its usable counts in place, and a word reaching its second use adds its existing counts in one pass; counts are whole numbers, so totals equal a full rebuild, which a test checks. One learn at 40,000 learned words takes 190-270 ms against 180 ms before #30. The timing test now learns letter-only words, since digits split words, and the docs state measured costs instead of a claimed speedup. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The in-place update test now covers words the baseline trusts, an import and a duplicate import. The timing test also times a learn that makes a new word usable. Measured against #28 on the same workload, prediction and learning costs match within noise, so the docs say so. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closed
Both tests that claimed to cover trusted words passed with the trusted path disabled, because the word had already been learned once. They now check a word's first learned use, and fail if trust is ignored. Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
enaboapps
pushed a commit
to switchifyapp/switchify-pc
that referenced
this pull request
Oct 12, 2026
switchifyapp/switchify-prediction#30 keeps learned counts apart from the baseline. One learned use counts as up to 500 baseline uses, less as more is learned, and a word the baseline lacks or has seen fewer than three times counts once learned twice. On a synthetic person, learned words reach the suggestions for 46% of queries instead of 1%, with no misspelling suggested. The library no longer copies the English model, so the prediction worker's peak memory falls from about 362 MiB to 134 MiB. Worker assets are unchanged. Refs #1029 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 12, 2026
Merged
Refs #29 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #29
Stacked on #28 (base
claude/incremental-learning).Learned counts were added to a copy of the baseline at 5×. That is negligible beside a baseline of millions of words, so a name or care term typed a few times hardly ever surfaced. A first version of this PR raised the fixed multiplier to 500. Review found real problems with that: one misspelling learned once became the top suggestion, heavy use would outgrow the baseline, and crafted counts could overflow. This version fixes all three:
huge_stored_personal_counts_do_not_overflow).500 / (1 + learned words / 2000). Learned counts approach a bounded share of the baseline however much is learned.updating_in_place_matches_rebuilding). Prediction and learning costs match Make personal learning incremental #28 within noise on the production baseline, measured by the ignored testprediction_cost_on_production_baselineand independently against Make personal learning incremental #28 by review:an_empty_personal_database_predicts_exactly_like_none). The schema and API are unchanged, and existing personal databases keep working. Make personal learning incremental #28's incremental learning now merges into the separate counts, and a reload reloads only the personal counts.Results
These were measured on a synthetic person,
neural/fixtures/personal.json, which is not user data. They learned 44 sentences, four of them containing one misspelling each. The 25 held-out sentences reuse their vocabulary: 445 queries, 78 of them on personal words. Measured on this branch:General English was checked with that person's learning present, on 600 frozen-workload queries: 70.3% with no learning, 70.7% light, 70.2% heavy (×10). The differences are within noise.
Offering learned words to the neural generator as candidates was also tried. It added under half a point and nearly doubled generation latency, so it is left out. Details are in
docs/personal-learning.md.Validation
cargo fmt --check,cargo clippy --locked --all-targets -D warningsandcargo test --lockedpass.prediction_cost_on_production_baselinetest gives the timings above. The incremental-versus-reload, trigger, schema and concurrency tests from Make personal learning incremental #28 still pass.python -m unittestpasses, andscripts/personal_evaluate.pyruns end to end.🤖 Generated with Claude Code