ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

青简整句转换实现原理:词图 + bigram Viterbi + 束搜索,每键 3 毫秒内出整句

青简整句转换实现原理:词图 + bigram Viterbi + 束搜索,每键 3 毫秒内出整句 青简整句转换实现原理词图 bigram Viterbi 束搜索每键 3 毫秒内出整句【免费下载链接】qingjian青简 Qingjian用 Rust 写的拼音输入法候选词旁多一条正在学的语言的译词项目地址: https://gitcode.com/gh_mirrors/qi/qingjian青简 Qingjian 是一个用 Rust 写的开源拼音输入法它的招牌能力之一就是把woxiangqu这样的连续拼音整句转换成「我想去」。整句转换是中文输入法里最容易被低估的难点xiang单独看可以是想、向、像、象只有放在整条路径里语言模型才知道你要的是哪个。青简的解法是三层结构——词图lattice bigram Viterbi 动态规划 束搜索配合按格缓存把每键的整句耗时压到 3 毫秒左右。下面完整拆解这套机制全部源码都在 crates/qingjian-core/src/sentence/ 模块里。一、整句转换要解决什么问题输入wo xiang qu候选空间是这样的音节可能的单字wo我、卧、握、恶……xiang想、向、像、象、翔……qu去、取、区、曲、趣……如果逐字独立选词你拿到的大概率是「我象取」。整句转换的目标是把所有音节切成若干词选出整条路径上概率最高的那个分词方案比如我想 / 去或我 / 想 / 取。二、第一层词图Word Lattice词图是一张有向图每个音节位置是一个节点每段连续音节上放恰好覆盖这几个音节的词作为边。每个格子只留词频最高的几个词全拼格子保留 SPAN_CANDIDATES 6 个简拼格子比如wxq里的w按前缀取词h下面有和、好、会、还、很几十个常用字所以放宽到 ABBREVIATED_SPAN_CANDIDATES 20同音消歧交给后面的语言模型在路径上分辨词最多 8 个音节MAX_WORD_SYLLABLES词图规模因此可控。核心实现在 crates/qingjian-core/src/sentence/viterbi.rs 的span_candidates函数先给每个候选算好得分再排序——注释里记着一条教训单字母简拼的格子能命中几千条比较器里每次查两张表会让排序占掉十几毫秒。三、第二层bigram Viterbi 选最优路径词图建好后问题变成找得分最高的路径。每个词的概率来自 crates/qingjian-lm/ 里的词级 bigram 语言模型概率用插值平滑P(w|v) 0.8·c(v,w)/c(v) 0.2·c(w)/Nbigram 部分占大头一元词频兜底见 bigram_model.rs 的log_prob模型没见过的词退回词库词频并扣 4.0 分FALLBACK_PENALTY让模型见过的词更可信完全查不到词的音节比如打错或生僻音节不中断整句而是用拼音本身占位、扣 30 分你会看到我zhuang去这样能上屏的结果。Viterbi 本身很朴素nodes[i]存覆盖前 i 个音节、以某个词结尾的部分路径每个新词只在前驱路径里挑得分最高的那条接上best_predecessor最后回溯即得整句。用户选过的词还有选择加分且加分封顶——单元测试明确验证了卧再被你选 500 次也翻不过词频差 450 倍的我但只差 4 倍的区选十几次就能翻盘viterbi.rs 测试。性能上一个关键细节bigram 表不是 300 万对扁平数组二分一次要跳二十来个缓存行而是按前词分组的 CSR 布局——查我→想时只在一两条后继里二分落在 1~2 个缓存行内bigram_model.rs 的注释。四、第三层束搜索控制爆炸纯 Viterbi 每步只留最优解遇到当前不占优、后面会翻盘的路径会直接剪死。束搜索的修正很简单每个位置按得分降序最多保留 8 条部分路径BEAM_WIDTH 8 的prune函数。需要备选路径时比如接了神经重打分器convert_paths会取前 k 条按得分降序的不同整句供上层重新排序见 converting.rs。五、每键 3 毫秒的关键只算新的格子打woxiangqu时每多敲一个键词图上只新增以这个键结尾的至多 8 个格子其余格子上一键都算过了。而格子查词恰恰是整句转换里最贵的一步——单字母简拼格子要在词库里逐音节块收窄。所以青简加了 SpanCache键是格子的模式串各位置写法 是否完整如z…|zh…值是排好序、截好数的候选敲键时绝大多数格子直接命中缓存只有新格子的查词要真跑一遍上屏、用户词变化时整个缓存清空保证结果一致。这一项单独把 15 字母全简拼的整句耗时从12 ms 降到 1 ms。更多优化过程见 docs/notes/performance.md。六、实测性能数据以下是 release 构建、89 万条词库 300 万对 bigram 的 M 系列 Mac 实测摘自 performance.md场景改前最慢一键改后全拼长句woxiangquchifan3.8 ms3.1 ms全简拼 15 字母10.8 ms3.4 ms极端简拼zhzhzh…16 字母44 ms8 mssss…15 字母21 ms4.5 ms单字母首键9 ms5 ms对照输入法的性能预算——每键候选必须 10 ms 内算完超过 30 ms 用户就能感觉到黏——常规输入稳定在预算的三分之一以内。七、顺手带出的两个彩蛋敲错字是带代价的边gan xi在原样凑不出像样的句子时会走guan xi → 关系代价 4.5 分原样说得通gan xie → 感谢时代价让它输typo 测试。纠错和整句在同一个词图上完成。越用越像你自己个人 n-gram二元 三元与静态模型按置信度插值前词见过 8 次时个人数据与静态模型各占一半且封顶 0.5——一次误选翻不过静态模型选两次才翻interpolation 常量。八、源码导读清单想动手读的话按这个顺序crates/qingjian-core/src/sentence/mod.rs — 模块总览和全部常量100 行讲清设计crates/qingjian-core/src/sentence/viterbi.rs — 词图 Viterbi 束搜索主循环crates/qingjian-lm/src/bigram_model.rs — bigram 模型与 CSR 内存布局crates/qingjian-core/src/sentence/span/cache.rs — 按格缓存docs/notes/performance.md — 四轮优化的完整记录含两次猜错的弯路词图负责有哪些词bigram Viterbi 负责哪个组合最通顺束搜索负责别把翻盘的路剪掉SpanCache 负责每键只算增量——四件事各管一段才有了标题里那个每键 3 毫秒的数字。【免费下载链接】qingjian青简 Qingjian用 Rust 写的拼音输入法候选词旁多一条正在学的语言的译词项目地址: https://gitcode.com/gh_mirrors/qi/qingjian创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表