TwinkleTokenizer / README.md
lianghsun's picture
TwinkleTokenizer v1: Traditional Chinese (Taiwan) BPE tokenizer, 201,069 vocab
0f46cf7 verified
|
Raw
History Blame Contribute Delete
19.2 kB
metadata
license: apache-2.0
language:
  - zh
  - en
library_name: tokenizers
tags:
  - Taiwan
  - R.O.C
  - zhtw
  - tokenizer
  - BPE
  - traditional-chinese
datasets:
  - twinkle-ai/tw-tokenizer-bench
extra_gated_prompt: 請說明您的使用目的。本詞表以台灣繁體中文為主要目標,開放供研究與開發使用。
extra_gated_fields:
  姓名或組織: text
  使用目的: text
  我同意僅將本詞表用於合法用途: checkbox

Model Card for TwinkleTokenizer

TwinkleTokenizer 是專為中華民國台灣語境從零訓練的 byte-level BPE 詞表。不是在既有詞表上加字、也不是把別人的詞表做繁體對映,而是以 19.27 億字元的純繁中為主語料重新訓練出來的。

在自建的 tw-tokenizer-bench(24,294 筆)上,本詞表的 tokens/char 為 0.4395 ,較 Qwen3.8-27B 的 0.7120 低 38% ,而詞表規模只有它的 81%

⚠️ 規格重點: 本倉庫只提供 tokenizer ,不含模型權重。詞表大小 201,069(含 1,069 個特殊 token),normalizer 為 NFC (非 NFKC),純漢字 token 上限 6 字

Model Details

Formosa-1 Series 與 T1 系列之後,Twinkle AI 一直在處理同一個結構性問題:繁體中文在主流詞表裡是二等公民

國際模型的中文詞表幾乎都以簡體語料訓練。以 Qwen3.8-27B 為例,它有 47,929 個多字漢字 token,其中 27,364 個是簡體專屬 ——佔其全部詞表的 11%,對繁體中文完全無用。這些名額不是「用不到」而已,是在訓練詞表時就把預算花掉了 ,繁中詞彙因此擠不進去。續訓(continued pretraining)改不了這件事:詞表在預訓練前就已固定。

唯一的解法是從零訓練。用純繁中語料訓練,那個浪費從源頭就不會產生——這就是為什麼 201K 的可用名額能勝過 Qwen 的 248K。

Twinkle ,取自 Twinkle AI;本詞表定位為 Twinkle AI 後續模型系列的共用詞表基礎。

核心特點 (Key Features)

  1. 繁中優先的詞表配置 (Traditional-First Vocabulary):

    • 全部 201,069 個 token 逐一稽核:含異體字 0 個 ,含簡體專屬字僅 55 個(0.04%),逐筆判讀後真簡體約 8 個。
    • 語料前處理做了 12.7 萬處異體字正規化(爲→為、裏→裡、麽→麼),並對 55 個無歧義陸用語(質量、身份、通脹、網絡…)整列丟棄 ——不改寫、不用 OpenCC 整段轉換,避免把「制作」(刑事訴訟法第 39 條)這類法定用語改壞。
  2. 切得對,不只切得少 (Segmentation Quality):

    • 壓縮率高不代表切分正確。以 jieba 繁中斷詞為參考,本詞表的切點命中詞邊界 85.6% ,Qwen3.8 為 77.8%、DeepSeek-V4 為 74.9%。
    • 單字 token 佔比 17.6% (Qwen 41.7%、DeepSeek 49.6%)——代表詞表真的在處理「詞」,而不是逐字拆。
  3. 多模態預留與思考通道 (Multi-modal & Thinking Ready):

    • 具名特殊 token 45 個,涵蓋對話、思考(<|think_start|> )、工具呼叫、語音(ASR/TTS/duplex)、視覺(image/video/OCR)、文件結構(page/table/cite)。
    • 另保留 1,024 個 reserved token ,未來新增功能可直接改名,不必擴充 embedding 重訓。
  4. 實證驗證,不只報壓縮率 (Validated Three Ways):

    • 近年文獻對「壓縮率 = 品質」是存疑的(Schmidt et al., EMNLP 2024;Lotz et al., 2025 量到 ρ = −0.59)。
    • 因此除壓縮率外,另做了切分品質下游從零訓練 270M 模型比 bits-per-character 兩層驗證。

Model Description

  • Developed by: Liang Hsun Huang
  • Model type: byte-level BPE tokenizer(tokenizers / transformers 相容)
  • Vocabulary size: 200,000 + 1,069 特殊 token = 201,069
  • Normalizer: NFC(非 NFKC)
  • Language(s) (NLP): Traditional Chinese & English
  • License: apache-2.0
演算法 byte-level BPE
純漢字 token 上限 6 字
訓練語料 19.27 億字元
語料組成 繁中 60.6% / 英文 22.8% / 程式碼 10.4% / 數學 6.2%
對話格式 ChatML

Model Sources

Evaluation

tw-tokenizer-bench(主要評測)

tw-tokenizer-bench 為本團隊建置的台灣繁中詞表評測集,24,294 筆 / 1,844 萬字元 ,涵蓋 5 個正式文體領域。指標為 tokens/char,越低越好

subset 🌟TwinkleTokenizer (ours) Pangolin Qwen3.8-27B DeepSeek-V4 gemma-4-31B
law_judgment 0.3380 0.7622 0.7570 0.7924 0.8395
law_statute 0.4355 0.7267 0.7316 0.7681 0.7767
web_translated 0.4403 0.6780 0.6496 0.6711 0.7152
gov_news 0.4967 0.7055 0.7020 0.7327 0.7771
encyclopedia 0.5557 0.7292 0.7239 0.7298 0.7835
OVERALL 0.4395 0.7200 0.7120 0.7402 0.7785
vocab 201,069 114,688 248,044 128,000 262,144
單字 token 率 18.0% 46.0% 44.4% 52.5% 60.6%

關於往返正確性 :本詞表與 Qwen3.8 各有 62 筆「嚴格往返失敗」,Pangolin 與 DeepSeek 為 0。 根因是來源文本含 CJK 相容表意文字 (U+F900–FAFF,如 U+F98E「年」),而 NFC 的定義就是要把它們折疊成標準碼位 (U+5E74)。 有做 NFC 的全部「失敗」,沒做的全部「通過」——但不折疊才是缺陷,那會讓同一個字佔兩個 token。 以 NFC 為基準時,本詞表往返失敗 0 筆 。詳見 benchmark 的 dataset card。

壓縮率(held-out,訓練語料零重疊)

單位為字元/token,越高越省 (與上表的 tokens/char 互為倒數)。

tokenizer vocab 中文平均 英文
🌟TwinkleTokenizer (ours) 201,069 2.026 4.657
Qwen3.8-27B 248,044 1.388 4.674
DeepSeek-V4 128,000 1.369 4.855
OpenFormosa/PangolinTokenizer 114,688 1.339 2.658
gemma-4-31B 262,144 1.282 4.735

中文提升 46% 的同時,英文效率幾乎持平 (4.657 vs Qwen 4.674,差距 0.4%)——這是刻意的取捨,繁中詞表不應該以犧牲英文為代價。

中文各領域細分:判決書 2.516 / 翻譯繁中 2.267 / 中文網頁 1.983 / 文言 1.796 / 政府文書 1.481。

PangolinBench

PangolinBench 是 OpenFormosa 為台灣語境設計的詞表評測,10 個 subset 共 30 筆樣本。指標同為 tokens/char,越低越好。

以下為本地實測(非引用官方數字)。所有詞表的往返正確率皆為 30/30。

subset 🌟ours Pangolin Qwen3.8 gemma-4 DeepSeek-V4
traditional_zh_formal 0.4902 0.6765 0.6765 0.7157 0.7353
taiwan_named_entities 0.4595 0.7297 0.7568 0.8919 0.8919
taiwan_mandarin_colloquial 0.6458 0.7083 0.7500 0.7500 0.7500
bopomofo 0.7273 1.0682 1.3864 0.7955 1.1136
taigi_han_roman_mixed 0.5495 0.7143 0.6154 0.5824 0.6374
hakka_romanized 0.4567 0.5591 0.5118 0.4724 0.5039
taiwan_code_switching 0.3696 0.4783 0.4130 0.3804 0.4022
unicode_edge_cases 0.5396 0.5827 0.5755 0.6187 0.5324
rich_transcription_json 0.4518 0.4003 0.4405 0.4277 0.3939
rich_transcription_structured_text 0.4508 0.1844 0.4631 0.4467 0.4467
OVERALL 0.4765 0.4852 0.5407 0.5259 0.5222

我們輸的兩格輸得有道理。 rich_transcription_structured_text 上 Pangolin 是 0.1844、本詞表 0.4508,差距來自特殊 token 命名而非壓縮能力——那個 subset 的內容就是 <|transcript_start|><|speaker|><|non_speech_event|> 這些標記,Pangolin 詞表內建它們(各算 1 個 token),本詞表沒有(要拆成十幾個)。PangolinBench 有一道硬性關卡要求詞表必須含這 10 個 token,本詞表是以 --no-fail-on-quality-gate 跳過該關卡才完成評測的。

樣本量很小。 10 個 subset 共 30 筆,平均一個 subset 3 筆,單筆差異就足以翻轉排名。原作者也註明這「still a synthetic test set, not enough to represent the full distribution of Taiwan text」。這張表不宜過度解讀 ——這也是我們另建 tw-tokenizer-bench 的原因。

執行正確性的佐證 :原作者報告的 Pangolin overall 為 0.485,本地實測 0.4852;其 Qwen 3.6 為 0.541,本地實測 Qwen3.8 為 0.5407——兩者皆吻合。

切分品質

以 jieba 繁中斷詞為參考,量切點是否落在詞邊界。

tokenizer 字/token 切點命中詞邊界 單字 token 佔比
🌟ours 2.169 85.6% 17.6%
Qwen3.8-27B 1.475 77.8% 41.7%
PangolinTokenizer 1.441 77.8% 45.1%
DeepSeek-V4 1.391 74.9% 49.6%
專業素養、特質或經公告審查優勝
  ours:['專業素養', '、', '特質', '或經', '公告', '審查', '優勝']
  Qwen:['專業', '素', '養', '、', '特質', '或', ...] ← 「素養」被拆成兩字

下游驗證(bits-per-character)

用兩個詞表各從零訓練一顆 270M 模型(同架構、同資料來源),以 bits-per-character 比較——BPC 以字元數為分母,是唯一能跨詞表公平比較的指標(perplexity 不行,token 單位不同)。

條件 🌟ours Qwen 詞表
等算力 (各 200M token) 4.434 4.591 ours 低 3.4%
等文字量(各 4 億字元) 4.595 4.379 Qwen 低 4.7%(但多花 43% 算力)

等算力下本詞表勝出,且是在參數少 13% 的條件下(229M vs 259M,因 vocab 較小 → embedding 較小)。同一個 token 預算下,本詞表的模型看到 4.4 億字元,Qwen 只看到 3.08 億——多看 43% 的資料

等文字量下 Qwen 勝出屬預期:它用了 43% 更多的算力跑同樣內容,多花算力本來就該贏。實務上算力才是限制,所以等算力那組是主要結論。

詞表污染稽核

逐一檢查全部 201,069 個 token。

數量 佔比
含漢字 token 146,339 72.8%
含異體字 0 0%
含簡體專屬字 55 0.04%

那 55 個逐一判讀後多數為誤報: (大寫數字,判決書與契約的法定寫法)、 (人名)、 (咨文)、 (合卺)。真簡體約 8 個單字 token。

各家的多字漢字 token 中,對繁體中文可用的比例:

tokenizer 多字漢字 token 繁中可用 簡體專屬 繁體專屬
Qwen3.8-27B 47,929 17,568(36.7%) 27,364(57.1%) 2,997(6.3%)
DeepSeek-V4 29,920 12,167(40.7%) 16,458(55.0%) 1,295(4.3%)
PangolinTokenizer 30,164 11,310(37.5%) 9,490(31.5%) 9,364(31.0%)

Qwen 有 27,364 個多字 token 對繁體中文完全無用——那是它 248K 詞表的 11%。它仍能拿到不錯的中文壓縮率,是靠「詞表夠大,浪費得起」。

PangolinTokenizer 的繁體專屬比例最高(31.0%),方向與本詞表一致;差別在於總量較小(114,688),且英文效率為 2.658——那是為語音模型(Barbet 1B、BlueMagpie-TTS)做的取捨,中英混雜或需保留英文能力的用途要留意。

特殊 Token

具名 45 個 + 保留 1,024 個,ChatML 風格。

類別 內容
核心 <|pad|> <|bos|> <|eos|> <|unk|>
對話 <|im_start|> <|im_end|> <|system|> <|user|> <|assistant|> <|tool|>
思考 <|think_start|> <|think_end|> <|no_think|>
工具 <|tool_call_start|> <|tool_result_start|> <|tool_schema_start|>
語音 <|audio_start|> <|task:asr|> <|task:tts|> <|duplex_user|>
視覺 <|image_start|> <|video_start|> <|task:ocr|>
文件 <|doc_start|> <|page_sep|> <|table_start|> <|cite_start|>
保留 <|reserved_0000|><|reserved_1023|>

保留 1,024 個是為了讓未來加新功能時能直接改名,不必擴充 embedding 重訓。

🔧 Usage

1️⃣ 基本用法

from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("twinkle-ai/TwinkleTokenizer")

tok.tokenize("中華民國憲法增修條文第十條")
# ['中華民國憲法', '增修條文', '第十條']

2️⃣ 對話模板(含思考通道)

messages = [
    {"role": "user", "content": "刑法第 271 條的構成要件為何?"},
    {"role": "assistant",
     "reasoning": "先確認條文位置,再拆解構成要件……",
     "content": "刑法第 271 條規定殺人罪,構成要件為……"},
]

tok.apply_chat_template(messages, tokenize=False, enable_thinking=True)

reasoning 欄位會被渲染進 <|think_start|> … <|think_end|>enable_thinking=False 則整段略去。

3️⃣ 在 benchmark 上複驗

pip install datasets transformers
python evaluate.py --tokenizer twinkle-ai/TwinkleTokenizer

evaluate.py 附在 tw-tokenizer-bench repo 內。

語料前處理

順序不可顛倒:

  1. 異體字正規化 (12.7 萬處)——爲→為、裏→裡、麽→麼、着→著等。不做的話同一個詞會學出兩套 merge,白白吃掉詞表名額。
  2. 陸用語整列丟棄 ——55 個無歧義詞(質量、身份、通脹、網絡…),命中即丟整列。不改寫、不使用 OpenCC 整段轉換 ——整段轉換會把正確的繁中一起改壞。
  3. NFC 正規化 ——不用 NFKC,因為 NFKC 會把全形英數轉半形、拆解「㈠」,這兩者在繁中文本裡都是有意義的。
  4. 近似去重 ——判決書實測近似重複率 23%。

法律語料不套第 2 步 :「制作」(刑事訴訟法第 39 條)、「公安」(同法第 10 條)是法定用語,不是陸用語。

Bias, Risks, and Limitations

  • 台語與客語的支援未經充分驗證。 訓練語料中台語僅 4.7 萬字元。在以歇後語為主(漢字為主)的樣本上,台羅拼音(áîiann )確實會被拆得較碎;但在 PangolinBench 的 taigi_han_roman_mixed (0.5495)與 hakka_romanized (0.4567)兩個 subset 上表現優於各對照組。兩者的樣本量都很小,結論尚不穩固——需要更大的台羅/客語語料才能定論。
  • 下游驗證規模小。 270M 參數、200M token,遠低於實用規模。結果支持但不證明大模型上也成立。
  • vocab size 未達邊際遞減點。 64K→200K 的掃描顯示增益仍在遞減但尚未轉平,更大的 vocab 可能還有空間。
  • 主要 benchmark 由本團隊建置。 tw-tokenizer-bench 是我們自己做的,本詞表在全部 5 個 subset 領先。請把該表當作「作者自評」而非第三方評測。防範措施(固定字元窗格、排除訓練污染分片、指紋比對)與資料、評測腳本全部公開,歡迎複驗。
  • 純漢字 token 上限 6 字是刻意的取捨。 長 token 會遮蔽詞形資訊(Haslett, Computational Linguistics 2025:GPT-4 在字元配對任務上,文本被拆成 byte 時得分 .986,作為單一 token 時掉到 .219 )。代價是壓縮率少 0.9%。

Citation

@misc{twinkleai2026tokenizer,
  title = {TwinkleTokenizer: A Traditional Chinese (Taiwan) Tokenizer Trained from Scratch},
  author = {Huang, Liang Hsun},
  year = {2026},
  howpublished = {\url{https://huggingface.co/twinkle-ai/TwinkleTokenizer}},
  note = {Twinkle AI. 201,069 vocab, byte-level BPE, NFC.}
}

Acknowledge

  • 感謝 APMIC 贊助 CPU 算力,本詞表的語料處理與 BPE 訓練皆在 CPU 上完成。
  • 感謝 OpenFormosa 團隊公開 PangolinTokenizer 與 PangolinBench,讓繁中詞表這件事有了可對照的基準。

Model Card Authors

Twinkle AI

Model Card Contact

Twinkle AI