1# Универсальная in-place автозамена + крошечная нейросеть-«мозг» 2 3> Ответ на запрос: **вариант 2 (универсальная in-place правка)** по образцу системных автозамен, плюс 4> продвинутый «мозг» на **уже существующей** супер-маленькой нейросети, и мнение об алгоритме их работы. 5 6--- 7 8## 1. По образцу какой системы (три референса) 9 10| Система | «Мозг» (что выбирает слово) | Размер | Как доставляется в поле | 11|---|---|---|---| 12| **Apple iOS 17** (WWDC 2023) | трансформер-LM, правит **на каждое нажатие**, на уровне предложения, учит привычки пользователя | **~34M параметров, hidden 512** (Neural Engine) | системно (клавиатура — часть ОС); EN/FR/ES | 13| **Google Gboard** | **FST-декодер** + нейро-«spatial model» (касание→клавиша, как акустическая модель в ASR) + LM; в 2024 «Neural Search Space» вшивает NN-LM прямо в FST на лету | сети «×10 меньше, ×6 быстрее» после итераций | системно | 14| **Windows TSF** | — (TSF = **канал**, не мозг) | — | text-service (TIP) DLL грузится `ctfmon`-ом **в каждый процесс**, имеет доступ к буферу документа | 15 16**Главный вывод:** «умная автозамена крошечной сетью» (Apple) и «универсальная in-place доставка» 17(TSF) — **ортогональны**. TSF — это *как* доставить правку в любое приложение; нейросеть — это *что* 18исправлять. Полная система = **TSF (доставка) + крошечная LM (мозг)**. 19 20--- 21 22## 2. Мнение об алгоритме их работы 23 24Все три — **один и тот же 3-ступенчатый noisy-channel конвейер**. Различаются лишь начинкой ступеней: 25 261. **Генерация кандидатов** — «что человек мог иметь в виду». 27 - Сенсорная клавиатура → нейро-spatial model (вероятности касаний по клавишам). 28 - Физическая клавиатура → edit-distance + соседство клавиш (ЙЦУКЕН) + фонетика. 29 - **У нас это уже есть и сильное:** `Helpers/SpellScore.cs` + `CompactSpell.Lookup` (62% на батарее). 30 - Кандидаты берутся **только из словаря** ⇒ система не может выдумать несуществующее слово. 31 322. **Контекстное переранжирование** — «что осмысленно именно здесь». Тут живёт LM, считающая 33 P(слово | контекст): n-gram (старые) → трансформер 34M (Apple) → NN-LM-в-FST (Gboard 2024). 34 - **У нас тут пусто** — только грубый bigram-нудж. ← **узкое место.** 35 363. **Решение / гейт точности** — «стоит ли вообще трогать». Авто-замена только при большом margin 37 между лучшим и вторым кандидатом; обучение на отменах пользователя; отступление для сленга/аббревиатур. 38 - **Это и есть вся «безотказность».** Именно консервативный гейт сделал iOS 17 «менее агрессивным». 39 - У нас есть зачатки (precision-first gate), но без настоящей ступени 2 он слепой. 40 41**Моё мнение по существу:** все смотрят на нейросеть (ступень 2), но качество продукта живёт в 42**ступенях 1 и 3**. Сеть Apple **крошечная (34M) именно потому**, что кандидаты уже ограничены словарём 43(ступень 1), а гейт консервативен (ступень 3). Большая модель + слабый гейт = бесит и портит текст. 44Вывод для WindowCapture: у нас сильная ступень 1 и зачаток ступени 3 — **не хватает ступени 2**. 45Поставить туда крошечную контекстную LM = **самый высокорычажный апгрейд**, и он ставит нас в тот же 46архитектурный класс, что и iOS 17 — только двусторонний (для *исправления* лучше) и русскоязычный. 47 48--- 49 50## 3. Существующая супер-маленькая нейросеть (мозг) — РЕАЛИЗОВАНО 51 52**`cointegrated/rubert-tiny2`** — **~29M параметров** (embed 312, vocab 83828), русская, MLM. 53Это **тот же класс размера, что и боевой автокорректор Apple (34M)**, только уже существует и русская. 54(Ещё меньше — `cointegrated/rubert-tiny`, 12M/45МБ, для CPU-only.) 55 56Используется как **masked-LM переранжировщик** (НЕ генератор): 57- подаём `левый_контекст [MASK] правый_контекст`, считаем pseudo-log-likelihood каждого кандидата 58 из ступени 1 (по сабвордам, length-normalized, один батч-проход); 59- **двусторонний контекст** (Apple — только левый) → для исправления лучше: видим и слово справа; 60- **ноль галлюцинаций** — сеть только *оценивает* словарные кандидаты; 61- **быстро** — один батч-forward на ~5 кандидатов; ~единицы мс на RTX 4080, десятки мс на CPU; 62- это честный множитель P(слово|контекст), который мы раньше грубо заменяли биграммой. 63 64### Что именно сделано (ветка fix/audit-phase2) 65- `Spell/wc_spell_server.py`: эндпоинт **`/rescore`** — lazy-load rubert-tiny2 (env `WC_RESCORE_MODEL`), 66 батч-PLL, авто-устройство cuda/cpu с откатом. SAGE (`/`) и rescore (`/rescore`) живут в **одном** 67 тёплом процессе; модель ступени-2 грузится только при первом обращении. 68- `Helpers/RescoreClient.cs`: клиент `/rescore` (переиспользует процесс `SageClient` через 69 `SageClient.EnsurePort()`); `Rescore(left,right,cands)` → `double[]`; `null` на любой сбой; не бросает. 70- `Helpers/TextProcessor.cs` (`ProcessWord`): ступень 2 — после bigram-нуджа, при `Settings.ContextNnRescore` 71 и валидном контексте, топ-6 кандидатов переранжируются по P(слово|контекст). Кандидаты только из словаря. 72- `Models/Settings.cs`: флаг `ContextNnRescore` (по умолч. **выкл**) + Load/Save/Reset. 73- `App/TrayApp.cs`: тумблер «Контекстная нейро-правка слов (rubert-tiny2, эксп.)» + прогрев. 74 75### Эмпирическая проверка (`Spell/test_rescore.py`, rubert-tiny2, CPU) — 6/8 76Ранжирование неоднозначных пар по контексту: 77- ✓ `мама мыла`→**раму**>рому; `я ел суп`→**ложкой**>лодкой; `он играл на`→**гитаре**>гитари; `я выпил стакан`→**воды**>моды. 78- ✓ **склонение переключается контекстом:** `я думаю о`→**тебе**, `я люблю`→**тебя** (это и есть «учёт склонения» из запроса). 79- ✗ `кот поймал`→мошь>мышь — но «мошь» **не слово**, в конвейере кандидаты только из словаря (такого кандидата нет). 80- ✗ `мы плыли на`→ложке>лодке — **реальный предел 29M-модели** (оба слова существуют). 81 82Вывод: модель доказанно ловит контекст/склонение; промахи 29M ожидаемы и **смягчены тем, что NN-оценка 83складывается с noisy-channel (ступень 1) и проходит гейт (ступень 3), а не решает единолично**. Для большей 84точности — `WC_RESCORE_MODEL=cointegrated/rubert-base-cased` (≈178M) ценой размера/скорости. 85 86⚠️ Честно: флаг по умолчанию выключен; **живьём в GUI не протестировано** (computer-use отключён). 87Эффект ступени-2 не виден в `Tools/TestSpellCheck` (тот без контекста) — проверяется отдельным 88тестом эндпоинта `/rescore`. Доставка пока — инъекция в каретку (уже универсальна и неинвазивна). 89 90--- 91 92## 4. Универсальная in-place правка (вариант 2) = TSF TIP 93 94> **СТАТУС: Milestone 1 СДЕЛАН** — TIP пишется на C++ (`Tip/WCTip.cpp` + `Tip/Correct.h` + `Tip/WCTip.def`), 95> собирается (`build_tip.ps1` → `bin\WCTip.dll`, MSVC 2022 + Windows SDK, EXIT=0) и проходит **headless 96> self-test 12/12** (`Tip/_selftest.cpp`: кодировка таблицы + class factory + создание `ITfTextInputProcessorEx` 97> + QueryInterface по обоим интерфейсам + баланс ref-count `DllCanUnloadNow==S_OK`). Сам in-place edit через 98> `ITfRange` не протестирован вживую (нужно TSF-приложение). Сборка/регистрация/тест — `Tip/README_TSF.md`. 99> 100> **СТАТУС: Milestone 2 ТОЖЕ СДЕЛАН** — TIP подключён к настоящему мозгу. На границе слова `BrainCorrect` 101> (WinHTTP) POST-ит «слово\nлевый_контекст» в C#-мост (`Helpers/TipBridge.cs`, localhost TCP :8766, 102> `POST /correctword`), который зовёт `TextProcessor.CorrectWordForTip` (RulesEngine/forcedFix + noisy-channel 103> `CompactSpell` + rubert-tiny2 rescore + precision-gate — тот же мозг, что при живом наборе), и заменяет слово 104> на месте. Мост недоступен → откат на встроенную таблицу. Тумблер «TSF-мост для in-place правки» 105> (`Settings.TsfBridge`, выкл по умолч.). Собирается: C# `EXIT=0`, TIP `EXIT=0`, self-test 12/12. 106> C#-плечо моста проверено headless (`Tools/TestTipBridge.cs`): **5/5** (ответ моста == прямому вызову; 107> `превет`→`Привет` через мост — реальный мозг, не таблица). Сам in-place edit через `ITfRange` и 108> WinHTTP-вызов из C++ вживую не тестированы (нужен GUI). 109 110Чтобы править «на месте в любом приложении как системная автозамена», надо стать **TSF Text Input 111Processor (TIP)** — текст-сервис, который `ctfmon` грузит в процессы и который имеет доступ к буферу 112документа (`ITfContext`/`ITfRange`) и может менять текст без буфера обмена и без смены фокуса. 113 114**Шаги:** 1151. **C++ COM-DLL** (TIP практически всегда C++; .NET-TIP неподдерживаем/болезнен): реализовать 116 `ITfTextInputProcessor(Ex)`, `ITfThreadMgrEventSink`, `ITfTextEditSink`, `ITfKeyEventSink`. 1172. Регистрация языкового профиля (`ITfInputProcessorProfiles`) + CLSID в реестре → пользователь 118 выбирает «WindowCapture» как метод ввода (как IME). 1193. На правках/границах слов — читать диапазон через `ITfRange`, прогонять через **тот же** мозг 120 (ступени 1–3 выше; вызов нашего тёплого сервера), писать обратно через `ITfRange::SetText` 121 в составе edit-session (атомарно, корректно для undo приложения). 1224. Подсказки/реконверсия через UI TSF; учёт композиции (важно для CJK, нам — упрощённо). 123 124**Честная оценка стоимости/риска:** 125- Это **самый рискованный и крупный компонент проекта**: отдельный C++/COM-проект, системный метод 126 ввода, регистрация в реестре, тестирование только живьём. 127- **Не тестируется без живого GUI** (computer-use сейчас отключён). 128- Совместимость: TSF-aware приложения — да; чистый Win32 EDIT без TSF — деградация на keystroke-доставку. 129 130**Рекомендация по последовательности:** 1311. **Сейчас:** мозг (ступень 2, rubert-tiny2) на текущей доставке keystroke-в-каретку — уже универсально 132 и неинвазивно, даёт основной прирост качества, дни а не недели, без рискованного системного компонента. 1332. **Потом, по «го»:** TSF TIP как отдельный трек, когда keystroke-доставки окажется мало на практике. 134 135--- 136 137## Источники 138- Apple iOS 17 transformer autocorrect — [NPR](https://www.npr.org/2023/06/07/1180791069/apple-autocorrect-ducking), [Michael Tsai blog (34M, hidden 512, per-keystroke)](https://mjtsai.com/blog/2023/09/18/apples-new-transformer-powered-predictive-text-model/), [MacRumors](https://www.macrumors.com/guide/ios-17-keyboard/) 139- Gboard — [The Machine Intelligence Behind Gboard (Google Research)](https://research.google/blog/the-machine-intelligence-behind-gboard/), [Neural Search Space in Gboard Decoder (arXiv 2410.15575)](https://arxiv.org/abs/2410.15575) 140- Windows TSF — [Microsoft Learn: Text Services Framework](https://learn.microsoft.com/en-us/windows/win32/tsf/text-services-framework), [MS Edge TSF1 explainer](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/TSF1/explainer.md) 141- rubert-tiny2 — [cointegrated/rubert-tiny2 (HF)](https://huggingface.co/cointegrated/rubert-tiny2), [cointegrated/rubert-tiny (12M/45MB)](https://huggingface.co/cointegrated/rubert-tiny)