Windows 10 / 11 · TSF 原生 · GPL-3.0 开源

翩若惊鸿,
言如泉涌。

言泉是一个开源的 Windows 拼音输入法。没有广告,不捆绑软件,也不会上传你的输入记录——词库、设置和学习数据都只存在本机。代码全部公开,它做了什么,你随时可以查证。

Cassotis IME 状态浮窗与候选列表截图
状态浮窗与候选列表:输入状态、拼音方案和候选配色,一目了然。

开源

代码、词库、构建脚本都在 GitHub 上,任何人都能查看,也能自己编译。

本地

输入内容全部在本机处理,没有云端联想,也没有遥测上报。

干净

安装时不带别的软件,不改浏览器首页;卸载干净,词库和设置留不留由你决定。

它能做什么

不联网、不上传是底线。在这之上,每一项功能都只为把字打准、打顺。

01

一口气打完一句话

整句拼音连着打,不用逐词确认。引擎先在词库里找出完整的句子,本地语言模型从中挑选,再对照你打的拼音和前文,修正个别同音错字。一键一键打出来,和一次输完,得到的候选是一样的。

02

同音词看前文

同一个拼音对应好几个词时,语言模型会结合刚上屏的文字来判断该用哪个。没有前文可参考,或者把握不够,就按词库和你平时的选择来排,不乱改。

03

词库里没有的说法

三到五个音节、词库没有收录的短语,比如 jiuguize,会由语言模型结合前文拼成「旧规则」,而不是把常用字硬凑在一起。首选不对时,选一次后面的,它就记住了。

04

原创的一键补全

言泉原创的候选窗补全:输入至少两个完整音节后,把握足够时底部只给出一个方案,按 Tab 或反引号接受。它能补完正在打的词,也能续上一小段后文;拿不准就不提示,被你拒绝过的也不会再冒出来。

05

越用越顺手

常打的词会排得越来越靠前,分几段确认出来的词组也记得住。在可以读取的编辑窗口里,当前文档中反复出现的术语和人名会得到照顾;这些临时信息只留在内存中,密码框不会读取。学习数据可以在设置里一键清空。

06

全拼、双拼与模糊拼音

除了全拼和首字母简拼,还内置六种双拼:微软、小鹤、自然码、搜狗、紫光和拼音加加,并可分别启用 11 组常见声母、韵母模糊规则。不管用哪种方案,简繁词库、候选排序和学习数据都是同一套。

07

快捷输入与标点

ufh 出符号,uxh 出序号,usx 出数学符号,urq、usj 出当前日期和时间;i123.45 转成中文数字和金额大写。连着打数字时,句号键自动给出小数点。中文标点下,# * - 等 Markdown 符号默认保持半角,可在设置里调整。这些都由本地规则生成,不占用户词。

08

可展开的三行候选

想多看一些候选时,可在设置中开启「翻页时展开多行候选」。翻页或按上下箭头,候选窗最多同时显示三行;当前行高亮并显示数字编号,数字键只选择当前行,底部的补全区保持不变。

09

中文状态下直接打英文

不用切换中英文:打 markdown、pro、Effie 这类英文单词和名字,或者带大写字母的词,原样的字母会排到候选最前面,按空格就上屏。bug、mac 这种同时也是拼音的输入,由语言模型结合前文判断你更可能要哪个;选过一次字母,下次会优先考虑。中文候选的数字编号不变,双拼仍按中文处理,不需要时可在设置里关闭。

10

自定义短语

常用的句子、签名、地址或多行模板,可以在设置里配一个字母快捷码。打完快捷码,短语出现在底部补全区,按 Tab 原样上屏,换行也保留。短语单独保存,不进学习数据,可以用 JSON 导入导出。

11

古诗词随手补全

收入中小学课本、《唐诗三百首》《千家诗》《宋词三百首》中的 7,747 句诗词,多音字按诗意定读音。打 chunmi 就能按 Tab 补出「春眠不觉晓」;整句打完,再按 Tab 连同标点接上下一句。

12

Windows 原生集成

基于 TSF(文本服务框架)开发,同时支持 64 位和 32 位程序,在 Windows 10 和 11 上原生运行。候选窗口适配高分屏和多显示器,切换快捷键可以自行设置。安装一次,同一台电脑的所有账户都能用,用户词库和设置各自独立。首次切换时先给出基础候选,语言模型在后台加载,不拖慢当前应用。

现在的输入法功能越来越多,但很多人想要的其实很简单:
打字准一点,别弹广告,别偷偷传数据。
言泉就是照着这个想法做的。

一个模型,管全部选词

同样的拼音可以拆出很多种结果:yanquan 是「言泉」,也可以是「眼圈」「烟圈」。句子越长,可能的组合越多,引擎要在几十条路径里挑出你想说的那条。从 v2.0.0 起,这件事交给同一个本地语言模型,全程不联网。

  1. 第一阶段 v1.1 – v1.29

    一路加模型

    v1.x 的每个版本几乎都靠「再加一个模型」来改进:先是统计语言模型,然后是神经网络重排器、参与路径搜索的模型、受约束的 Transformer,再到拼音约束的局部纠错。每一步都让选词更准,也让整套东西越来越重:动一处,要重新校准一串。

  2. 第二阶段 v1.30 – v1.31

    共享语言模型出现

    v1.30.0 引入基于独立中文语料训练的共享字符级语言模型,把整句连贯性和前文语境用于长句选词、上下文短词和 Tab 续写;v1.31.0 升级模型,并让它参与补全的选择。到这时,安装包里有 11 个神经模型文件,引擎里还编译进 43 组模型参数,一次选词往往要依次经过其中好几个。

  3. 第三阶段 v2.0 起

    只留一个

    v2.0.0 把它们清掉了:神经模型从 11 个减到 1 个,引擎里的模型参数从 43 组减到 7 组。留下的是一个约 1.5 亿参数的字符级语言模型,由本项目自己训练,长句、短词、补全和同音纠错都问它;加载模型占用的内存从约 447 MiB 降到约 183 MiB。

    这不是一次功能堆叠,而是一次收拾:以后的改进只需要做在一处,语言模型变好,所有输入场景一起受益。

详细改动见各版本发布说明。

01

发布前:离线训练

语言模型在发布前训练完成:从独立的中文语料学习字与字的接续,同时学会对照拼音修正同音字。另有四个很小的决策策略,用引擎的实际运行记录拟合,决定什么时候听模型的。基准测试语料不参与训练,发布产物不附带训练语料原文。

02

安装时:随包部署

模型随安装包一并提供,量化后由外部 Host 进程加载;统计先验写入本地 SQLite 词库,其余排序参数直接编译进引擎。无需另装模型或推理环境,使用时不联网、不下载数据。

03

打字时:按输入分路

长句由受词库约束的搜索给出完整候选,模型从中选择,再对照拼音和前文修正。短词默认保持词库顺序,模型有明确理由时才调整。词库里没有的短语,先由词库词拼出整句方案,再交给模型挑选。字母串既像英文又像拼音时,也由模型结合前文比较两种读法。补全先显示有把握的方案,模型随后在后台重排。

模型只在外部 Host 进程中加载,后台就绪、仅用 CPU;未就绪或超时的时候,候选照常给出,只是不经过模型排序。代价是延迟:每个决定现在都要经过一个更大的模型,下面各项基准的耗时大多高于 v1.31.0(长句整句解码平均 72 ms 对 61 ms);日常逐键输入时,每个按键的响应通常仍在几十毫秒以内。以下各套基准测试的语料都与训练数据隔离,成绩里没有「背题」的水分。

基准测试

长句、短词与一键补全测试语料都取材于开发者自己的小说《永恒的舞动》,并与模型训练数据保持隔离。测试方法、案例构造和指标定义见 BENCHMARK.CN.md。

长句与短词上下文基准从 v1.11.0 起,将同一位置的“他”和“她”视为等价;表中斜体数字为严格区分二者的旧口径结果。后续版本统一使用新口径,两套一键补全基准的评分规则另见各表说明。v2.2.0 改正了 43 条测试案例中读错的多音字拼音(长句 38 条、短词 5 条,两套补全基准随之沿用),此前版本的结果基于改正前的案例。

长句基准测试-16300

对 16300 条长句一次性设置完整拼音,检查完整候选的准确率与引擎解码耗时。

版本 Top1 Top2 Mean (ms) P95 (ms) Max (ms)
v2.2.0 13397 / 16300 82.19% 14281 / 16300 87.61% 72.10 110 328
v2.1.0 13381 / 16300 82.09% 14270 / 16300 87.55% 75.28 125 343
v2.0.0 13380 / 16300 82.09% 14268 / 16300 87.53% 74.79 125 344
v1.31.0 12940 / 16300 79.39% 13534 / 16300 83.03% 61.29 94 282
v1.30.0 12828 / 16300 78.70% 13514 / 16300 82.91% 55.25 94 266
v1.29.0 11997 / 16300 73.60% 12970 / 16300 79.57% 39.89 63 234
v1.28.0 11987 / 16300 73.54% 12964 / 16300 79.53% 63.72 109 484
v1.27.0 11978 / 16300 73.48% 12955 / 16300 79.48% 63.08 109 468
v1.26.0 11974 / 16300 73.46% 12947 / 16300 79.43% 62.83 109 453
v1.25.0 11698 / 16300 71.77% 12830 / 16300 78.71% 57.49 94 438
v1.24.0
v1.23.0
11679 / 16300 71.65% 12813 / 16300 78.61% 57.09 94 438
v1.22.0 11672 / 16300 71.61% 12809 / 16300 78.58% 55.17 94 407
v1.21.1 11080 / 16300 67.98% 12395 / 16300 76.04% 59.33 109 407
v1.20.0 11065 / 16300 67.88% 12376 / 16300 75.93% 59.53 110 406
v1.19.0 10917 / 16300 66.98% 12248 / 16300 75.14% 55.99 94 437
v1.18.0 10731 / 16300 65.83% 12128 / 16300 74.40% 51.78 93 454
v1.17.0 10595 / 16300 65.00% 12023 / 16300 73.76% 42.68 78 406
v1.16.0
v1.15.0
10553 / 16300 64.74% 11921 / 16300 73.13% 41.5 78 484
v1.14.0 10345 / 16300 63.47% 11903 / 16300 73.02% 58.78 172 766
v1.13.0 10131 / 16300 62.15% 11320 / 16300 69.45% 65.94 203 1047
v1.12.0 9767 / 16300 59.92% 10996 / 16300 67.46% 63.03 187 1062
v1.11.0 9760 / 16300 59.88%
旧口径 9340 / 16300(57.30%)
10990 / 16300 67.42%
旧口径 10773 / 16300(66.09%)
59.82 187 1031
v1.10.0 9279 / 16300 56.93% 10708 / 16300 65.69% 60.39 188 1046
v1.9.0 9121 / 16300 55.96% 10685 / 16300 65.55% 59.65 187 1172
v1.8.1 8285 / 16300 50.83% 9067 / 16300 55.63% 72.44 281 1594
v1.7.0 7940 / 16300 48.71% 8642 / 16300 53.02% 71.55 235 2047
v1.6.0 7936 / 16300 48.69% 8637 / 16300 52.99% 66.99 219 1687
v1.5.0 7459 / 16300 45.76% 7966 / 16300 48.87% 63.42 203 2140
v1.4.0 7168 / 16300 43.98% 7617 / 16300 46.73% 66.23 218 2578
v1.3.0 7155 / 16300 43.90% 7601 / 16300 46.63% 64.54 203 2188
v1.2.0 6895 / 16300 42.30% 7303 / 16300 44.80% 59.89 188 2078
v1.1.0 6677 / 16300 40.96% 7067 / 16300 43.36% 73.18 234 2750
v1.0.0 6106 / 16300 37.46% 6857 / 16300 42.07% 71.49 219 5344
v0.8.5 6097 / 16300 37.40% 6847 / 16300 42.01% 520.05 1203 13297
v0.7.0 5368 / 16300 32.93% 6110 / 16300 37.48% — — —
v0.6.0 4905 / 16300 30.09% 5378 / 16300 32.99% — — —
v0.5.0 4834 / 16300 29.66% 5243 / 16300 32.17% — — —
v0.4.0 4371 / 16300 26.82% 4744 / 16300 29.10% — — —
v0.3.1 3845 / 16300 23.59% 4651 / 16300 28.53% — — —
v0.2.0 2671 / 16300 16.39% 2863 / 16300 17.56% — — —

Top1:整句首选即正确的比例;Top2:前两个候选中含正确结果的比例。Mean、P95、Max 为引擎整句直设解码耗时(ms),不代表逐键输入到候选窗口显示的端到端延迟。v2.0.0 起所有决定都经过同一个更大的语言模型,耗时高于此前版本。

短词上下文基准测试-65000

65000 个二至四字词案例保留输入位置之前已经上屏的文本,用于评估短词精确候选和上下文消歧。Contested 是同一拼音对应至少两个目标词的歧义子集。

版本 Top1 Top2 Contested Top1 Contested Top2 Mean (ms) P50 (ms) P95 (ms) Max (ms)
v2.2.0 63364 / 65000 97.48% 64292 / 65000 98.91% 10533 / 11728 89.81% 11244 / 11728 95.87% 4.509 2.201 12.289 41.085
v2.1.0
v2.0.0
63363 / 65000 97.48% 64291 / 65000 98.91% 10533 / 11728 89.81% 11244 / 11728 95.87% 4.637 2.205 12.621 40.883
v1.31.0 63036 / 65000 96.98% 64104 / 65000 98.62% 10491 / 11728 89.45% 11196 / 11728 95.46% 4.582 3.262 10.352 22.327
v1.30.0 62926 / 65000 96.81% 64073 / 65000 98.57% 10449 / 11728 89.09% 11169 / 11728 95.23% 3.525 3.192 7.660 21.122
v1.29.0 61971 / 65000 95.34% 63568 / 65000 97.80% 9675 / 11728 82.49% 10776 / 11728 91.88% 2.999 2.198 7.316 27.596
v1.28.0 61860 / 65000 95.17% 63562 / 65000 97.79% 9596 / 11728 81.82% 10775 / 11728 91.87% 4.453 3.908 9.214 34.468
v1.27.0
v1.26.0
61860 / 65000 95.17% 63549 / 65000 97.77% 9596 / 11728 81.82% 10775 / 11728 91.87% 4.474 3.908 9.310 35.645
v1.25.0 61859 / 65000 95.17% 63549 / 65000 97.77% 9596 / 11728 81.82% 10775 / 11728 91.87% 4.705 4.103 9.817 40.027
v1.18.0 - v1.24.0 61827 / 65000 95.12% 63517 / 65000 97.72% 9596 / 11728 81.82% 10775 / 11728 91.87% 4.584 3.985 9.653 39.36
v1.15.0 - v1.17.0 61827 / 65000 95.12% 63516 / 65000 97.72% 9596 / 11728 81.82% 10775 / 11728 91.87% 3.817 3.239 8.376 39.881
v1.14.0 61782 / 65000 95.05% 63516 / 65000 97.72% 9560 / 11728 81.51% 10775 / 11728 91.87% 3.998 3.132 8.665 68.147
v1.13.0 61515 / 65000 94.64% 63516 / 65000 97.72% 9384 / 11728 80.01% 10775 / 11728 91.87% 4.748 3.652 10.337 103.689
v1.12.0 61343 / 65000 94.37% 63474 / 65000 97.65% 9304 / 11728 79.33% 10745 / 11728 91.62% 4.400 3.417 9.462 104.316
v1.11.0 61343 / 65000 94.37%
旧口径 61227 / 65000(94.20%)
63474 / 65000 97.65%
旧口径 63461 / 65000(97.63%)
9304 / 11728 79.33%
旧口径 9191 / 11728(78.37%)
10745 / 11728 91.62%
旧口径 10732 / 11728(91.51%)
4.217 3.284 9.110 75.503
v1.10.0 61214 / 65000 94.18% 63448 / 65000 97.61% 9191 / 11728 78.37% 10732 / 11728 91.51% 4.425 3.446 9.591 84.68
v1.9.0 61215 / 65000 94.18% 63448 / 65000 97.61% 9191 / 11728 78.37% 10732 / 11728 91.51% 4.214 3.268 9.113 71.004
v1.8.1 61206 / 65000 94.16% 63430 / 65000 97.58% 9182 / 11728 78.29% 10725 / 11728 91.45% 4.85 3.721 10.413 107.714
v1.7.0 61053 / 65000 93.93% 63424 / 65000 97.58% 9154 / 11728 78.05% 10723 / 11728 91.43% 4.668 3.468 10.013 158.471
v1.6.0 61043 / 65000 93.91% 63414 / 65000 97.56% 9154 / 11728 78.05% 10723 / 11728 91.43% 4.455 3.295 9.580 160.817
v1.5.0 61045 / 65000 93.92% 63364 / 65000 97.48% 9159 / 11728 78.10% 10677 / 11728 91.04% 5.033 4.113 9.968 142.372
v1.4.0 60676 / 65000 93.35% 63251 / 65000 97.31% 8993 / 11728 76.68% 10602 / 11728 90.40% 5.573 4.521 11.157 158.687
v1.3.0 59078 / 65000 90.89% 62881 / 65000 96.74% 8326 / 11728 70.99% 10386 / 11728 88.56% 5.460 4.396 10.939 176.912

延迟为启用上下文轨道后的引擎单次完整查询耗时,不包含 TSF 调用、候选窗口渲染和真实按键间隔。

一键补全上下文基准测试-12831

从固定短词语料构造 12831 个逐音节拼音前缀机会,读取候选窗实际显示的唯一补全方案,评估补全是否准确、能节省多少按键,以及继续输入时是否保持稳定。

版本 补全命中率 平均节省按键 逐键稳定率 按键 P95 (ms) 最终显示 P95 (ms)
v2.2.0 10456 / 12831 81.49% 2.632 2131 / 2193 97.17% 1.508 19.728
v2.1.0
v2.0.0
10440 / 12831 81.37% 2.633 2124 / 2186 97.16% 1.521 20.445
v1.31.0 10336 / 12831 80.55% 2.638 2123 / 2185 97.16% 1.238 11.881
v1.30.0
v1.29.0
9420 / 12831 73.42% 2.548 1691 / 1749 96.68% 0.968 0.968
v1.18.0 - v1.28.0 9419 / 12831 73.41% 2.549 1691 / 1749 96.68% 2.026 2.026
v1.17.0 9273 / 12831 72.27% 2.554 1652 / 1718 96.16% 1.880 1.880
v1.16.0 8752 / 12831 68.21% 2.570 1649 / 1676 98.39% 1.509 1.509
v1.15.0 7265 / 12831 56.62% 2.542 1278 / 1323 96.60% 0.777 0.777

补全命中率按唯一参考目标严格统计;平均节省按键已扣除一次接受补全的按键。按键 P95 不包含后台重排等待;最终显示 P95 在提示发生替换时计入后台重排耗时。v1.30.0 及更早版本没有这一异步阶段,两项延迟相同,均不包含候选窗口渲染和实际按键间隔。

长句一键补全基准测试-16300

固定保留每条长句末尾四个完整拼音音节不输入,评估候选窗实际显示的唯一局部续写。正确结果必须扩展目标前缀,并且仍是参考句的前缀。

版本 局部续写命中率 预测提示覆盖率 总节省按键 P95 (ms)
v2.2.0 3766 / 16300 23.10% 16121 / 16300 98.90% 9271 128.998
v2.1.0 3758 / 16300 23.06% 16123 / 16300 98.91% 9272 141.519
v2.0.0 3755 / 16300 23.04% 16123 / 16300 98.91% 9265 133.001
v1.31.0 3513 / 16300 21.55% 15815 / 16300 97.02% 7478 116.682
v1.30.0 855 / 16300 5.25% 7203 / 16300 44.19% 1822 77.819
v1.29.0 449 / 16300 2.75%
旧口径 424 / 16300(2.60%)
6778 / 16300 41.58% 1023
旧口径 987
53.085
v1.28.0 426 / 16300 2.61% 6776 / 16300 41.57% 989 78.689
v1.27.0 425 / 16300 2.61% 6769 / 16300 41.53% 987 80.099
v1.26.0 410 / 16300 2.52% 6488 / 16300 39.80% 967 80.437
v1.25.0 409 / 16300 2.51% 6489 / 16300 39.81% 959 74.936
v1.22.0 - v1.24.0 407 / 16300 2.50% 6474 / 16300 39.72% 953 77.103
v1.21.1
v1.20.0
357 / 16300 2.19% 6475 / 16300 39.72% 861 118.064
v1.19.0 202 / 16300 1.24% 3834 / 16300 23.52% 571 92.453
v1.18.0 143 / 16300 0.88% 3957 / 16300 24.28% 478 109.060

预测提示覆盖率表示出现预测补全的比例,并非提示准确率,不包含仅转换已输入拼音的词库拼接结果。该测试采用单参考答案评分,其他合理但不同于原文的续写仍计为未命中。v1.17.0 与 v1.16.0 使用旧的整句严格命中口径,仅保留为历史结果,不能与当前局部续写口径直接比较。

从 v1.30.0 起,本项基准将相同位置的“他”和“她”视为等价。v1.29.0 的常规数字为对已保存结果按新口径重评分的数据,斜体数字保留旧口径结果,预测提示覆盖率与延迟不变。v1.28.0 及更早版本仍为旧口径,后续版本只公布新口径结果。

名字的由来

Cassotis

Cassotis 是古希腊德尔斐(Delphi)神庙旁的一眼圣泉。传说女祭司皮媞亚在颁布神谕之前,会先饮下这眼泉水,人们相信预言便是从这泉中来的。

这个名字里还藏着一点巧合:言泉是用 Delphi 语言写的。泉眼与工具,恰好同出一地。

言泉

中文名取自「言如泉涌」——话语像泉水一样自然涌出,不必费力。做输入法,想达到的也就是这种状态:想到什么,打出来就是什么。

一个是预言之泉,一个是言语之泉,说的其实是同一件事。

开发计划

项目还在早期,更新比较频繁。v2.0.0 之后,改进集中在同一个语言模型上。

正在做的

  • 继续改进这一个语言模型:训练数据、规模和量化
  • 缩短从按键到候选出现的时间,尤其是长句
  • 把同音纠错和词库外短语扩展到繁体、模糊音等输入
  • 扩充词库覆盖,在更多编辑器、浏览器和 IDE 里测试兼容性

之后想做的

  • 让剩下的排序器和策略继续减少,语言模型能接管的就退役
  • 扩充独立基准,包括词库外短语,弄清各类出错的原因
  • 强化用户词库的质量控制和配套工具
  • 保持项目能被任何人检查、构建和接手维护

想跟进进展或者提建议,欢迎到 GitHub 仓库来。

下载安装

Windows 10 / 11 x64 安装包,约 290 MB,词库和语言模型都在里面,装上就能用,不用再下载或配置什么。旧版本用户直接运行新版安装包就能升级,不用先卸载,也不会要求重启系统;安装时还开着的应用,重新打开后即用上新版。卸载时词库和设置留不留,由你决定。