File size: 6,358 Bytes
6cc3500 edfb9ca 6cc3500 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | ---
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 繁體。
|