【免费下载链接】wmkeyboardA modern, privacy-first Android keyboard: offline intelligence, 600 languages, themes, tools and an addon ecosystem.项目地址https://gitcode.com/gh_mirrors/wm/wmkeyboard点击查看免费下载WM Keyboard 的预测引擎是这款开源 Android 输入法「打字即预测、错字即修正」能力的核心。它用 Trie 字典树 束搜索beam search一次走遍所有候选词再用 n-gram 语言模型结合上下文重排序全程离线完成。本文用尽量少的代码带你从零看懂 core/prediction/ 模块里的关键数据结构与算法以及它们对应的 Rust 实现 native/wm-engine/。一、预测引擎在用户端是什么体验先建立一个直觉。你在 WM Keyboard 上打字时引擎其实同时在干两件事补全你敲了skil候选条上出现skill、skills纠错你敲了skll候选条上依然出现skill——哪怕这个「词」根本不在词典里。这两件事看似无关WM Keyboard 的设计精髓在于它们被统一成同一次搜索。此外敲空格时还会根据前一个词调整候选顺序——「I want to _」后面buy会压过by升到第一位。下面按「数据 → 搜索 → 重排」三层拆开讲。二、数据基础Trie 字典树与它的压缩版2.1 为什么选 Trie引擎的底层是「带频率的单词索引」。Trie.kt 中定义了经典的节点式字典树每个节点存子节点表、词频frequency和isWord标记关键设计是maxSubtreeFreq——记录「该节点子树内最高词频」。这不是装饰它是后面束搜索剪枝的「上界估计器」让查找成本近似O(limit)而非O(词表大小)见 Trie.kt#L50-L51用户每次接受一个建议词就通过reinforce()被「强化」进这棵树——这就是键盘「越用越懂你」的数据来源Trie.kt#L82-L92。2.2 PackedTrie把 6.5 MiB 压进 1 MiB内置词表是只读的节点树对它太浪费。PackedTrie.kt 把同样的语义改写成扁平数组CSR 布局数组作用childStart节点 i 的出边在边数组中的起止偏移edgeLabel/edgeChild边表按字符排序查找用二分freq/isWord/maxSubtree每个节点上的词频信息效果约 1.7 万词的英文内置表堆内存从约 6.5 MiB 降到 1 MiB 以内见 PackedTrie.kt#L4-L14。两者对外都是同一个接口WordSource前缀补全 精确查频可以无缝互换——运行时可变的学习词典用节点式Trie打包/导入的只读列表用PackedTrie。三、Trie 引导的束搜索一次走遍补全和纠错这是整个预测引擎最精巧的部分定义在 FuzzyBeamSearch.kt。3.1 思路反转不猜词走树传统拼写纠错是「生成-测试」把输入的所有变体删一个字母、换一个、换序……生成出来再逐个查词典。变体随长度指数爆炸。WM Keyboard 反过来让搜索直接沿着 Trie 往下走。因为树上每个分支都是词典里真实存在的词所以永远只考虑词典可达的字符串天然免去了无效变体「两步编辑」的纠错如skll→skill依然负担得起替换候选直接取自树边上的真实字母任何文字系统不只英文都能用补全与纠错是同一条路径前缀零编辑走完是「补全」中途偏一下再走是「纠错」。3.2 打分对数空间里的加法每个候选的得分是一条简单公式FuzzyBeamSearch.kt#L12-L17score 来源权重 ln(1 词频) − 编辑代价编辑代价是一张精心调校过的价目表FuzzyBeamSearch.kt#L110-L150编辑类型代价含义相邻键替换 / 换位最便宜「手滑」级错误删重击字母helllo与换位同级长按重复很常见同手换位比跨手换位贵远处插入 / 替换较贵第二次编辑加收附加费两个错的词必须明显更常用才排得上去全部用「负对数」表示乘法权重变加法且与旧版引擎的相对排序严格一致可无缝替换。3.3 束搜索贪心但「可容错」的剪枝最优先best-first扩展时每个状态的上界是bound 来源权重 ln(1 maxSubtree(节点)) − 当前代价maxSubtree保证这个上界只会高估、不会低估因此「剪掉所有上界低于当前第 K 名的状态」永远不会丢掉任何本应进前 K 的候选——这就是注释里说的admissible best-firstFuzzyBeamSearch.kt#L19-L22。3.4 生产实现跑在 Rust 里手机端的行走实际由 Rust 引擎执行native/wm-engine/src/fuzzy.rs 与 Kotlin 版逐行对应通过 NativeFuzzySearch.kt 走 JNI 调用Kotlin 版保留为参考实现由一致性测试保证两边「同样的候选、同样的分数、同样的编辑数逐位一致」。连ln()都特意用StrictMath.logFuzzyBeamSearch.kt#L29-L37——因为差 1 个 ulp 就可能在某台机器上把两个候选调了个顺序。四、Lattice中日韩输入法的同一个解码器「束搜索」不是 WM Keyboard 自创的术语——它和经典 CJK 输入法的lattice晶格解码同源。native/wm-engine/src/cjk/lattice.rs 的实现说明了这个结构把输入缓冲区变成一张图节点是输入位置弧是一段输入可能的「读音」原样输入、模糊变体、简拼展开、错字修复逐弧扩展出候选词用一个读音立刻排除掉「没有词以它开头」的分支在词图上做Viterbi 搜索用词对word-pair模型打分找最优读音序列。拉丁语系的模糊束搜索第三节的 trie 行走和 CJK 的 lattice 走的是同一套思想在受词典约束的图上做受限束搜索用语言模型做最终裁决。理解了这个图模型两边就都能看懂了。五、n-gram 重排序用上下文「翻盘」的那一步束搜索解决「哪个词最像输入」但解决不了「哪个词更符合这句话」。这一步由 n-gram 重排序完成代码在 NgramReranker.kt。它只用键盘已经拥有的数据没有网络、没有模型文件证据来源文件说明用户个人 n-gramUserLexicon.kt你打过的词对/词三元是最强证据语料 n-gram 包NgramPack.kt二/三元组计数内存映射只读加载种子词对SeedBigrams.kt内置的高置信词对近期词袋—最近几个已提交词的主题倾向几个值得注意的设计NgramReranker.kt#L32-L71只在有证据时才动如果没有任何候选拥有上下文证据返回null引擎原始顺序原样保留——重排永远只能由证据驱动skip-gram 回退上一词是词典不认识的名字或错字时用「上上个词」来背书——met Priya at _里虽然Priya没人认识at之后依然能正确偏好the取最强而非求和多个 n-gram 包对同一词对的计数取最大值因为「同一个词对出现在两个来源」是同一条证据被看到两次而不是两条证据NgramPack.kt#L7-L12实际的分数插值计算同样落在 Rust 端native/wm-engine/src/rerank.rs每个词条一次调用CJK 侧的 n-gram 打包在 cjk/ngrams.rs。六、把三层串起来suggest() 全流程入口在 SuggestionEngine.kt 的 suggest()一次击键背后的完整流水线是判已知输入在词典/用户词典里吗已知词只保留最近的手滑候选未知词放行全部纠错路径SuggestionEngine.kt#L3000-L3033束搜索一次rankedFor()走遍所有 Trie 来源补全 纠错合并进同一个分数表取每个词的最高分max-merge上下文模型混合语言模型在「分数空间」里小幅拉动候选但被设了上限——它「重排但不埋没高频精确匹配」SuggestionEngine.kt#L3093-L3101n-gram 重排 近因加成前一个词的统计证据、本应用里刚用过的词各给一个有界的加成SuggestionEngine.kt#L3103-L3129输出候选条用户接受后词回流到用户 Trie 与 n-gram 存储闭环开始下一轮。值得强调的一点整套引擎完全离线。所有「智能」都来自设备上的词表、词频、你的个人统计和可下载的 n-gram 包——这也呼应了 WM Keyboard 隐私优先的定位参见 docs/src/content/docs/privacy/offline.mdx。七、想深入源码按这个顺序读主题入口文件词典树KotlinTrie.kt、PackedTrie.kt束搜索Kotlin 参考实现FuzzyBeamSearch.kt束搜索Rust 生产实现fuzzy.rsCJK 晶格解码lattice.rs、ngrams.rsn-gram 重排NgramReranker.kt、NgramPack.kt、rerank.rs总装流水线SuggestionEngine.kt一句话总结Trie 约束搜索空间束搜索把补全和纠错合成一次带剪枝的最优先遍历n-gram 重排最后用上下文定夺名次——三层各司其职又共用同一套「频率 对数代价」的数学语言这就是 WM Keyboard 预测引擎的完整骨架。赞分享【免费下载链接】wmkeyboardA modern, privacy-first Android keyboard: offline intelligence, 600 languages, themes, tools and an addon ecosystem.项目地址https://gitcode.com/gh_mirrors/wm/wmkeyboard点击查看免费下载相关推荐如何看懂 MCP 服务器打分排序awesome-mcp-servers 搜索与过滤原理完整解析如何看懂 MCP 服务器打分排序awesome mcp servers 搜索与过滤原理完整解析 awesome mcp servers 是一个收录了数千个 MIndra OCR 如何提升手写识别n-gram 语言模型束搜索技巧完全解读Indra OCR 如何提升手写识别n gram 语言模型束搜索技巧完全解读 Indra OCR 是一个只有 1M 参数的 CPU OCR 模型速度约为 T搜索引擎原理实战解析从倒排索引到 Elasticsearch 的完整技术栈搜索引擎原理实战解析从倒排索引到 Elasticsearch 的完整技术栈 导读 在电商站内搜索、Web 全文检索、日志分析等场景中搜索引擎是互联网最核心的教程Vibe CodingAI 应用上一篇8GB 还是 192GB 内存JevK5-chat-mlx-8bit 的 4/8/16-bit 量化选型完全指南下一篇OpenMDW-1.1 许可证与商用边界NVIDIA-Nemotron-Labs-Dory1.0-4B-BF16 生产部署前必须知道的安全与合规要点创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
5 分钟上手 Browser Use Terminal:从一行安装命令到跑通第一个浏览器自动化任务 【免费下载链接】terminal Terminal UI to get stuff done in the browser 项目地址: https://gitcode.com/gh_mirrors/terminal53/terminal 点击查看 免费下载 Browser Use Terminal 是一款基于 Rust 的终端浏览器自动化工具(Browser Agent TUI&#x… · 2026/11/5 3:44:17
Scenario Skills游戏资产实战:精灵图、PBR贴图、天空盒与可交互3D房间的一键生成方案 【免费下载链接】skills Get production-ready images, video, audio, and 3D from any AI agent: skills that pick the right model, price before spending, and keep characters and brands consistent through the Scenario MCP, plus expert teams that drive Blender, M… · 2026/11/5 3:43:17
码匠教育:一份 Python 脚本,从写完到执行经历了哪些步骤 许多人对于纯解释型语言所形成的印象是, 认为书写完毕的代码就是完全交由解释器以逐行读取的方式来直接执行。但实际上这并非真实情况, 一份脚本文件从编写完成到最终输出运行结果, 其间会经历若干不同的处理环节, 并且甚至也包含了编译这样的步骤, 只是因为整个处理流程对使用… · 2026/11/5 3:43:17
TED精读如何训练高阶英语思维与认知能力 1. 项目概述:这不是一节普通英语课,而是一次认知升级的实操训练“跟TED演讲学英文:How AI can save our humanity by Kai-Fu Lee”——这个标题乍看是语言学习类内容,但真正懂行的人一眼就能看出,它根本不是在教“how … · 2026/11/5 4:39:54
PostgreSQL INSERT操作全面指南与性能优化 1. PostgreSQL INSERT 操作深度解析PostgreSQL 作为一款功能强大的开源关系型数据库,其 INSERT 语句提供了远超基础数据插入的丰富功能。在实际开发中,合理运用这些特性可以显著提升数据操作效率和可靠性。1.1 基础语法与核心组件INSERT 语句的基础结构包… · 2026/11/5 4:39:54
Python在线考试系统开发:微服务架构与大数据分析实践 1. 项目概述与设计背景在线考试系统作为教育信息化的重要载体,正在经历从传统纸质考试向智能化评估的转型。我们团队基于Python技术栈开发的这套系统,核心目标是解决三个行业痛点:一是人工阅卷效率低下,二是考试过程监管困难&… · 2026/11/5 4:39:54
MySQL执行机制解析与性能优化实战 1. 项目概述MySQL作为最流行的开源关系型数据库之一,其内部执行机制一直是开发者们关注的焦点。在实际工作中,我们经常遇到这样的困惑:为什么这条SQL执行这么慢?索引为什么没生效?连接池配置多少合适?要真正… · 2026/11/5 4:39:54
小波阈值去噪五种改进变体:原理、MATLAB实现与避坑指南 简介:面向信号处理初学者与工程实践者的MATLAB小波阈值去噪工具包,聚焦软阈值、硬阈值及五种改进阈值方法的快速实现。作者在wden、thselect与wthresh三个函数基础上进行改造,并进一步封装为filterWaveletTh函数,延续专栏一贯的代… · 2026/11/5 4:39:54
从NRZ到PAM4:SerDes高速链路调制选型、均衡与眼图调试 高速串行链路这个圈子,做得久了你会发现一个很有意思的现象:真正决定一个系统能不能跑通的,往往不是那几百页的协议栈,而是最底层那一对差分线上的信号到底长什么样。SerDes 系统里 NRZ 和 PAM4 这两种调制方式的取舍,… · 2026/11/5 4:38:47
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38