[RFC] 新酷音輸入法第四代架構更新提案

91 views
Skip to first unread message

Kan-Ru Chen

unread,
Jul 5, 2026, 5:26:24 AMJul 5
to chewin...@googlegroups.com
大家好,

我想提出 libchewing 的第四代詞庫與語言模型架構,以下是簡要的演進背景與這次的改變。

## 小歷史

* 第 1 代:原始 2002 年技術報告的結構(fonetree.dat, ph_index.dat, dict.dat),
採 trie + word index + word text 分離設計,但 binary 不跨平台、檔案長度
寫死在 C 程式碼中。
* 第 1.5 代:為第 1 代檔案加上長度資訊,支援跨平台 mmap 讀取。
* 第 2 代:引入 SQLite 儲存使用者詞庫,以及預設未啟用的 trie index。
* 第 3 代:統一以 binary trie 格式儲存靜態詞庫與使用者詞庫。

## 為什麼需要更新

目前的架構源自 2002 年的技術報告,第 3 代雖然改善了效能,但仍有結構性限制:

* 詞頻與使用者偏好混淆,導致靜態詞庫難以重現、難以合併
* 語言模型與注音輸入緊密耦合,無法簡單支援拼音、倉頡等其他輸入方式
* 語言模型僅支援 unigram,缺乏上下文能力

## 第 4 代的主要改變

1. 分離字典與語言模型:static_dict.bin(注音/字形查詢)與
static_lm.bin(bigram/unigram 語言模型)分離,讓同一個語言模型可
服務多種輸入法。

2. 使用者詞彙改為 append-only log:user_vocab.bin 以 log entry 追加
寫入,取代整檔重寫的 Trie 格式,提供穩定 ID 供外部索引。

3. 使用者習慣改為衰減計數表:user_history.bin 以固定大小的衰減計數表記錄
使用頻率。

4. 新增 user_freq.csv 手動偏好微調:以人類可讀的 CSV 支援雙向調整
(正值 boost / 負值 deboost)。

5. 靜態詞條來源改為 static_words.txt:以純文字檔作為詞庫與語言模型的共同
生成基準,方便稽核與重建。

## 完整文件

詳細的架構說明、檔案格式、ID 空間分配、解碼器評分公式、遷移流程請見:

https://hackmd.io/@kanru/rkuK9SvXzx

歡迎直接回覆郵件或在 hackmd 上註解討論。謝謝!

Kan-Ru

Jim Huang

unread,
Jul 31, 2026, 1:34:18 AM (4 days ago) Jul 31
to Chewing-Dev, Kan-Ru Chen
感謝 kanru 的提案,我依據這三十年內的文獻予以調整和補充相關資訊,請參見附件。

對應的 HackMD 筆記: https://hackmd.io/@sysprog/libchewing-rfc
(可直接編輯)

更動部分:
* 回顧 2002 年技術報告
* 修訂目標,補充以字素 (grapheme) 為處理單位
* 借鏡 gramambular2
* 修訂解碼器評分
* 分析 bigram 作為邊上的轉移成本

-jserv

Kan-Ru Chen <ka...@kanru.info> 於 2026年7月5日週日 下午5:26寫道:
> 我想提出 libchewing 的第四代詞庫與語言模型架構,以下是簡要的演進背景與這次的改變。
chewing.md

Kan-Ru Chen

unread,
Jul 31, 2026, 7:55:02 PM (3 days ago) Jul 31
to Jim Huang, chewin...@googlegroups.com
On Fri, Jul 31, 2026, at 2:34 PM, Jim Huang wrote:
> 感謝 kanru 的提案,我依據這三十年內的文獻予以調整和補充相關資訊,請參見附件。
>
> 對應的 HackMD 筆記: https://hackmd.io/@sysprog/libchewing-rfc
> (可直接編輯)
>
> 更動部分:
> * 回顧 2002 年技術報告
> * 修訂目標,補充以字素 (grapheme) 為處理單位
> * 借鏡 gramambular2
> * 修訂解碼器評分
> * 分析 bigram 作為邊上的轉移成本
>
> -jserv

感謝整理!跟 2002 年技術報告作比較真是太棒了!

其實可以發現新提案的靜態資料有點類似回到第一代的三個檔案模式:

* fontree.dat -> static_dict.bin
* ph_index.dat -> static_words.txt + runtime index
* dict.dat -> static_words.txt

有點忘記原本詞頻資料是存在 fontree.dat 還是 ph_index.dat 了,新的獨立 static_lm.bin
讓資料與索引明確拆開。

實做上,目前 https://codeberg.org/chewing/libchewing/src/branch/bigram-arch
branch 裡面已有基本的資料結構,計算機率的部份還有 bug 之後會解決。下一步是先利用 tsi.src
bootstrap unigram 的 static_lm.bin,然後用同一個斷詞模組來計算 bigram count。
資料來源預計採用 C-100 語料加上 Wikipedia 語料,不過要先用小量資料測試驗證。目前計畫
static_lm.bin 中只儲存 u8 quantized 的 log10 機率,來縮小所需空間。

順序:

1. 分離 tsi.src 為僅有注音的 tsi.csv 以及 unigram 的 tsi_unigram.arpa
(預計會使用 ARPA 格式這樣以後如要用其他通用工具來後製也方便)

2. 用新的工具程式將 tsi.csv 轉為 static_dict.bin 與 static_words.txt
用新的工具程式將 tsi_unigram.arpa 轉為 static_lm.bin

3. 用新的工具程式,讀入上一動的靜態資料後,多工處理語料資料為新的 tsi_lm.arpa
應該會分為一個斷詞程式,跟一個統計程式,或是直接用 KenLM
把 tsi_lm.arpa 存入 libchewing-data 儲存庫作為原始資料供下游重製使用

4. 使用 tsi_lm.arpa 重新編譯 static_lm.bin

以上實做計畫以及實際的資料結構跟驗算法都有可能因為實做的方便性,或是中途遇到的問題而作調整,
之後還需要整理回 RFC 檔案作為新版的技術報告。

kanru
Reply all
Reply to author
Forward
0 new messages