| --- |
| license: mit |
| language: |
| - zh |
| tags: |
| - chinese |
| - traditional-chinese |
| - taiwan |
| - text-normalization |
| - zh-tw |
| - opencc |
| library_name: twlat |
| pipeline_tag: translation |
| --- |
| |
| # Twinity-1 |
|
|
| **中國大陸中文 → 臺灣正體中文的確定性轉換器。8.86M 參數,CPU 單執行緒 11,300 字/秒。** |
|
|
| Twinity-1 不生成文字。字典編譯成 conversion lattice,界定「哪些位置可以改、可以改成什麼」; |
| 模型只在每個歧義位點裁決「這個語境該不該改」;Viterbi 選出全域一致的編輯集合, |
| 最後對原文做**最小 splice**——編輯範圍以外的每一個位元組原樣保留。 |
|
|
| 因此它結構上**不可能**改寫語句、增刪內容、或破壞外語片段與程式碼。 |
|
|
| ```python |
| import twlat |
| twlat.convert("这个程序有bug,请在服务器上重新部署。") |
| # '這個程式有 bug,請在伺服器上重新部署。' |
| ``` |
|
|
| ## 為什麼不用查表或 LLM |
|
|
| | | 查表(OpenCC) | LLM 改寫 | **Twinity-1** | |
| | --- | --- | --- | --- | |
| | 語境判斷 | ✗ 無 | ✓ | ✓ | |
| | 確定性 | ✓ | ✗ | ✓ 100% | |
| | 只改該改的 | ✓ | ✗ 會潤飾/增刪 | ✓ 最小 splice | |
| | 外語/程式碼保留 | ✓ | ✗ | ✓ 1,248/1,248 | |
| | 成本 | $0 | API | $0 | |
| | 延遲(p95) | <1 ms | 秒級 | 23 ms | |
|
|
| 「程序」在軟體語境是**程式**、在法律語境就是**程序**;「里」在「那里」該轉**裡**、 |
| 在「公里」不能動。查表沒有語境;LLM 有語境但不確定且會多改。 |
|
|
| ## 評測 |
|
|
| TWBench-Neutral(1,496 題/8,438 個歧義位點,gold = 臺灣正體語料原文, |
| 不由任何系統產生;gold 自身誤差經分層盲審量測並逐條修正): |
|
|
| | 系統 | site accuracy | 維持 | 改動 | |
| | --- | --- | --- | --- | |
| | OpenCC | 0.9176 | 0.9411 | 0.8604 | |
| | zhtw-mcp(規則層) | 0.9263 | 0.9510 | 0.8661 | |
| | 前代 V1(6.06M) | 0.9456 | 0.9694 | 0.8877 | |
| | 前代 V2(3.32M) | 0.9445 | 0.9565 | 0.9153 | |
| | **Twinity-1(8.86M)** | **0.9712** | **0.9941** | **0.9153** | |
|
|
| 對前代顯著勝出(+2.7pp/+2.6pp,paired bootstrap p < 0.001)。 |
| 與 frontier LLM 基線在 320 題子集上**無顯著差異**(0.9782 vs 0.9709,p = 0.34)—— |
| 本模型不主張比 LLM 更準,而是在同等準確度下提供確定性、零成本與 23 ms 延遲。 |
|
|
| 盲測排序(103 題、14 位獨立評審、匿名、正反序雙輪):Twinity-1 平均名次 **1.296**, |
| 優於 V2(1.612)與 V1(2.199)。 |
|
|
| ## 怎麼訓練的 |
|
|
| **Confusion-set cloze 自監督**,在 6.5 億字真實臺灣正體語料上: |
| 每個 lattice 位點收合成單一 `[MASK]`,模型預測臺灣書寫者實際用了哪個形式。 |
| 這把無標註語料變成上億個監督事件,且消除了「相信輸入表面形式」的捷徑。 |
|
|
| 雙 pass 架構:masked pass 提供無洩漏的語境證據,clean pass(陸式汙染文本) |
| 提供表面證據與文件級領域向量。候選一律由**與文本共用的字元 embedding** |
| 動態編碼,沒有 per-candidate 查表參數——這是字典熱更新的前提。 |
|
|
| 架構:d=256,8 層(6 層 dilated TCN dilation 1..128 + 2 層 local attention), |
| 預訓練 120k 步 + finetune 8k 步,RTX 4080 約 2.8 小時。 |
|
|
| ## 操作點 |
|
|
| 模型與字典相同,只差「要多少證據才動手」(τ 是對數勝算比門檻): |
|
|
| | preset | 語意 | site acc | |
| | --- | --- | --- | |
| | `accuracy` | 20:1 勝算才改,benchmark 最佳 | 0.9712 | |
| | `balanced` | 2.7:1 即改,**預設** | 0.9668 | |
| | `taiwanize` | 額外壓制陸式專用詞(視頻/博客/實時) | 0.9640 | |
| | `aggressive` | 只靠字典硬過濾把關 | 0.9631 | |
|
|
| ```python |
| conv = twlat.Converter(preset="taiwanize") |
| r = conv.explain("这个视频的信息量很大") |
| for d in r.decisions: |
| print(d) # Decision('視頻'→'影片' @[2,4) cross_strait u=2.75) |
| ``` |
|
|
| ## 熱更新 |
|
|
| 新增字典條目只需重新編譯 `data/dict/lattice_lexicon.json`,**模型權重不動**。 |
| 實測:訓練時完全沒見過的 50 條規則,zero-shot change accuracy **0.71** |
| (前代架構同一量測為 0.12)。 |
|
|
| ## 檔案 |
|
|
| | 檔案 | 用途 | |
| | --- | --- | |
| | `twinity-1.pt` | 模型權重(8.86M 參數) | |
| | `data/dict/lattice_lexicon.json` | 編譯後的字典(1,780 confusion group/3,977 詞形)——熱更新入口 | |
| | `data/dict/char_vocab_v3.json` | 字元表(4,096),OOV 走 hash bucket | |
| | `data/dict/rules/` | 簡繁字表、臺標變體表、必轉字表 | |
| | `data/model/tau.json` | 部署操作點的決策門檻 | |
| | `twlat/` | 推論程式碼(純 Python,相依:torch、numpy、regex、pyahocorasick、opencc) | |
|
|
| ## 使用 |
|
|
| ```bash |
| pip install torch numpy regex pyahocorasick opencc-python-reimplemented |
| ``` |
|
|
| ```python |
| from huggingface_hub import snapshot_download |
| import os, sys |
| |
| path = snapshot_download("JacobLinCool/Twinity-1") |
| os.environ["TWLAT_HOME"] = f"{path}/data" |
| sys.path.insert(0, path) |
| |
| import twlat |
| conv = twlat.Converter(ckpt=f"{path}/twinity-1.pt", device="cpu") |
| print(conv.convert("这个程序有bug,请在服务器上部署")) |
| ``` |
|
|
| CPU 單執行緒最快(`torch.set_num_threads(1)`):11,300 字/秒、p95 23 ms。 |
| 執行緒開多反而慢 3–24 倍(小矩陣的執行緒同步成本壓倒運算)。 |
|
|
| ## 已知限制 |
|
|
| 1. **陸式專用詞的漏轉**:`服務器→伺服器`、`搜索→搜尋` 等在訓練語料中缺少 |
| change 方向訊號(網爬語料原生大量出現且被標為保留),模型高信心保留。 |
| 約佔殘餘 change 錯誤的 25%。修正路徑明確但需重訓。 |
| 2. **INT8 量化未達標**(−1.33pp),交付 FP32。 |
| 3. **台/臺 由語境決定**而非固定政策——多數語境正確,但官方機關名語域仍有殘餘錯誤。 |
| 若你的場景要求一律「臺」,請在後處理強制。 |
| 4. 訓練語料含 CC-100 網爬文本,可能帶有其偏誤。 |
| 5. 輸入超過 512 字會以滑動視窗處理(stride 384),跨窗的一致性未特別最佳化。 |
|
|
| ## 授權與致謝 |
|
|
| 模型權重 MIT。字典衍生自 [zhtw-mcp](https://github.com/sysprog21/zhtw-mcp)(MIT) |
| 與 [OpenCC](https://github.com/BYVoid/OpenCC)(Apache-2.0)——本專案的核心主張之一 |
| 正是「這些字典裡的語意資訊被嚴重低估」。訓練語料:維基百科 zh-tw(CC BY-SA 4.0)、 |
| 臺灣立法院法律研究資料(OGDL-1.0)、CC-100 繁體。 |
|
|