news 2026/10/16 6:35:27

LeanType 建议引擎详解:如何预测下一个词?评分流水线与 Ngram 上下文原理完整解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeanType 建议引擎详解:如何预测下一个词?评分流水线与 Ngram 上下文原理完整解析

【免费下载链接】LeanType

LeanType is an Open-source keyboard, fork of HeliBoard with additional features and customisation

项目地址:https://gitcode.com/gh_mirrors/le/LeanType
点击查看免费下载

LeanType 是一款开源、可深度定制的 Android 智能键盘(HeliBoard 分支),内置离线预测输入引擎:你每敲一个字母,它都能实时算出最可能的词并显示在建议条上,甚至在你还没打空格前就预判出下一个词。本文带你走读它的 C++ 评分流水线与 Ngram 上下文模型,搞懂"键盘为什么这么聪明"。

一张图看懂:从指尖到建议条的 3 步流水线 🎯

LeanType 的建议引擎继承自 AOSP LatinIME 并做了深度优化,核心代码全部运行在设备本地(libjni_latinime.so),无需联网。整体流程可以拆成三步:

  1. 触摸建模:把每次按键的坐标、时间、指针 ID 封装成输入事件,并通过 ProximityInfo 计算"这个坐标附近还有哪些键可能被误按"——这是容忍手抖的关键。
  2. Trie 词库搜索:C++ 层 Suggest::getSuggestions() 以词典 Trie(前缀树)为骨架,逐字符展开搜索节点(DicNode),同时容忍替换、漏敲、多敲、换位等错误类型。
  3. 评分与排序:所有搜索完的"终点节点"(terminal)进入评分流水线,按"复合距离"从低到高排序,产出建议条上的候选词。

Kotlin 侧的总入口是 Suggest.kt 中的getSuggestedWords(),它把词库、上下文和键盘布局组装好,再通过 JNI 调用 BinaryDictionary.kt 中的getSuggestionsNative()进入 C++ 引擎。

评分流水线:空间距离 + 语言距离如何合成"置信度" 📐

每个 DicNode 在扩展过程中会持续累加两类距离,定义在 dic_node_state_scoring.h:

复合距离 = 空间距离(spatial) + 语言距离(language) × 语言权重(weightOfLangModelVsSpatialModel)
距离类型来源含义
空间距离proximity_info.h你实际按的键,与目标词所需键在键盘上的物理偏差(按偏了、漏按了都要扣分)
语言距离词典概率目标词(及其上下文组合)在语言模型中"不常见"的程度,频率越低扣分越多

搜索阶段的规则集中在 suggest.cpp 的expandCurrentDicNodes()中,每个输入点会尝试多种"修正假设":

  • MATCH_CHAR / PROXIMITY_CHAR:命中或邻键命中(比如把w按成了相邻的键);
  • SUBSTITUTION / OMISSION / INSERTION / TRANSPOSITION:替换、漏敲、多敲、换位,代价参数全部集中在 scoring_params.h,如SUBSTITUTION_COST、OMISSION_COST、TRANSPOSITION_COST;
  • DIGRAPH:ch、sh等双字母组合整体匹配;
  • NEW_WORD / SPACE_OMISSION:检测到词边界,回到 Trie 根节点继续搜下一个词,实现多词连改(如hevis→he is)。

低分节点会被优先扩展、高分节点提前剪枝,由 dic_nodes_cache.h 的优先级队列管理,保证在手机上也能毫秒级出结果。

Ngram 上下文原理:上文的词决定下一个词的"权重" 🧠

只靠单字概率远远不够——同样打出bank,前文是river还是salary,推荐的后继词完全不同。LeanType 用Ngram 概率表解决这个问题:

  • 上下文载体:Kotlin 侧的 NgramContext.kt 记录"前面若干词 + 是否句首"(句首用<S>标记),C++ 侧对应 ngram_context.h。
  • 下一个词预测:当你敲完一个词、还没开始下一个词时,dictionary.cpp 中的getPredictions()会遍历词典里以当前上文为前缀的所有 Ngram 条目,通过NgramListenerForPrediction把高概率后继词推给建议条。这就是"空格后立刻冒出一排词"的来源。
  • 纠错中的上下文加权:搜索进行到一半时,getNgramProbability()会用前文词 ID 查询组合概率(底层由 multi_bigram_map.h 管理 bigram 映射),让"符合语境"的词排到前面。
  • 性能优化:Suggest.kt用容量 50 的LruCache<NgramContext, SuggestionResults>缓存预测结果,切应用/切输入框时自动清空,避免重复查表。

最终打分:精确匹配加成与错误惩罚如何平衡 ⚖️

搜索结束后的输出与最终分计算在 suggestions_output_utils.cpp 和 typing_scoring.h。核心公式:

最终分 = 基础分 - 复合距离 / 最大距离

在此基础上做加减分(常量见 scoring_params.h):

  • 精确匹配加成EXACT_MATCH_PROMOTION:你原样打出的词优先保留,避免"好心改坏";
  • 完美匹配加成PERFECT_MATCH_PROMOTION:对零概率词(如缩写Mt)仅在"完美匹配"时提升,防止输入mt被强推成my;
  • 大小写/重音/双字母惩罚:CASE_ERROR_PENALTY_FOR_EXACT_MATCH、ACCENT_ERROR_PENALTY_FOR_EXACT_MATCH等,精确匹配但大小写或重音不符时扣分;
  • 自动纠正阈值AUTOCORRECT_OUTPUT_THRESHOLD:多词建议置信度足够高时(长度 ≥16),强制自动替换输入。

Kotlin 侧shouldBeAutoCorrected()再结合用户设置的阈值做最后一道把关:建议分足够高且与输入词不同,才会在你空格时静默替换。

个性化词典:它记得你敲过的每个词 ✍️

除了内置词典(assets/dicts/main_en-US.dict等 19 种语言),LeanType 还有用户词典:

  • 每次你确认某个词,updateEntriesForWordWithNgramContext()会把"该词 + 当前上文"的频率写回 UserBinaryDictionary;
  • 长期不用的词会按遗忘曲线衰减(forgetting_curve_utils.h),让建议始终保持"新鲜";
  • 因此你自创的项目名、人名打几次后,就会稳定出现在建议条前排。

想深入源码?从这里看起 📂

模块路径
搜索主流程app/src/main/jni/src/suggest/core/suggest.cpp
结果输出与打分app/src/main/jni/src/suggest/core/result/suggestions_output_utils.cpp
打分参数表app/src/main/jni/src/suggest/policyimpl/typing/scoring_params.h
词典与 Ngram 查询app/src/main/jni/src/suggest/core/dictionary/dictionary.cpp
Ngram 上下文(C++)app/src/main/jni/src/dictionary/property/ngram_context.h
Ngram 上下文(Kotlin)app/src/main/java/helium314/keyboard/latin/NgramContext.kt
JNI 桥接层app/src/main/java/com/android/inputmethod/latin/BinaryDictionary.kt
单元测试app/src/main/jni/tests/suggest/

总结

LeanType 的建议引擎本质上是一个**"键盘布局空间模型 × Ngram 语言模型"的联合评分系统**:

  1. 用邻近键信息容忍手误,用 Trie + 优先级队列高效搜索候选词;
  2. 用空间距离 + 语言距离合成复合距离,精确匹配加成保证"尊重你的输入";
  3. 用 Ngram 上下文预测下一个词,让建议条领先你的手指半拍;
  4. 用个性化词典持续学习你的用词习惯,且全程本地运行、零隐私泄露。

理解了这套评分流水线,你也就理解了为什么 LeanType 在弱网甚至完全离线的场景下,依然能给出又快又准的预测输入体验。

【免费下载链接】LeanType

LeanType is an Open-source keyboard, fork of HeliBoard with additional features and customisation

项目地址:https://gitcode.com/gh_mirrors/le/LeanType
点击查看免费下载

相关推荐

上一篇:Cursor Pro完整功能破解限制:机器ID重置与配置管理技术深度解析
下一篇:3步实现Windows变身苹果设备AirPlay接收器的完整方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 6:35:08

FreeRTOS任务调度实战:从任务创建到状态迁移的完整解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 6:34:35

诺贝尔经济学奖回顾(1969—2026)

诺贝尔经济学奖回顾&#xff08;1969—2026&#xff09; 概述 瑞典中央银行纪念阿尔弗雷德诺贝尔经济学奖&#xff08;The Sveriges Riksbank Prize in Economic Sciences in Memory of Alfred Nobel&#xff09;自 1969 年首次颁发以来&#xff0c;截至 2026 年共颁发 58 次…

作者头像 李华
网站建设 2026/10/16 6:31:59

Fiori My inbox App看不到工作流待办消息问题修复

1.症状工作流基础配置完成后&#xff0c;生成的工作流待办事务码SBWP能看到待办&#xff0c;但Fiori My inbox App看不到2.原因原因是我们S4 2023 op版本启用了工作流过滤功能导致的启用任务过滤器用途此操作可激活或停用任务过滤器。过滤器默认处于停用状态。功能行为任务过滤…

作者头像 李华