localaiforum
登入
指南 › 基礎概念

Token 與分詞器

模型從來看不到單字或字母。它們看到的是 token ID——指向固定子詞詞彙表的整數索引,這套詞彙表用位元組對編碼(BPE)或其近親變體建立。分詞是一切事物的邊境關卡:你的提示詞、回覆、上下文視窗、每秒 token 計量、API 帳單。一旦你開始用 token 思考,關於 LLM 行為的半數都市傳說就會消散。

詞彙表如何建立

BPE 從原始位元組出發,反覆合併出現最頻繁的相鄰配對,直到詞彙表達到預算。結果:常見單字成為單一 token,罕見單字成為 2–5 個片段,而且沒有任何字串無法表示——位元組回退涵蓋所有字串,包括錯字與 emoji。詞彙表規模從約 30k 條目(較舊的模型)到約 250k(現代多語模型):

分詞器 詞彙表大小 備註
GPT-2 ~50k 以英文/網頁為主
Llama 2 ~32k 韓文切得很痛苦
Llama 3 ~128k 大幅的多語升級
Qwen 2 / 2.5 / 3 ~151k 強大的 CJK 合併
Gemma ~256k 常見模型中最大的詞彙表

主要用英文訓練的分詞器會積極合併英文片段;韓文的音節配對能得到的有用合併少得多。早在模型本身韓文好不好之前,詞彙表就已決定你要繳的「韓文稅」。

實例:英文

"Tokenization turns text into pieces."

→ ["Token", "ization", " turns", " text", " into", " pieces", "."]
→ 37 characters → 7 tokens ≈ 5.3 chars/token

注意細節:常見單字 "Token" 是一個片段;字尾有自己的片段;前導空格屬於後面的 token(" turns",不是 "turns")。這就是為什麼 "hello"、" hello" 與 "Hello" 是不同的 token——只差一個空格或大小寫的提示詞,分詞結果就不同。

實例:韓文

同一句話,更糟的經濟學。諺文以音節塊書寫,而韓文的合併在英文為主的詞彙表中更罕見(下方的切分是合理示意,非精確結果):

"안녕하세요, 만나서 반가워요."        # 17 個字元

strong multilingual vocab (~150k entries):
["안녕", "하세요", ",", " 만나", "서", " 반", "가", "워", "요", "."]
→ ~10 tokens ≈ 1.7 chars/token

weak vocab (~32k entries, jamo-level splits):
["안", "녕", "하", "세", "요", ",", " 만", "나", "서", ...]
→ 15+ tokens ≈ 1.1 chars/token

英文平均約 4 個字元/token。韓文通常落在 1–1.5。同樣的語意,token 數是 3–4 倍。這就是為什麼:

  • CJK 提示詞消耗上下文視窗的速度快得驚人——8k token 的視窗能裝的英文大約是韓文的 3–4 倍。
  • 同樣的 tok/s 下,韓文生成「感覺」比較慢:每句要更多 token,每個 token 的文字更少。
  • 按 token 計費的 API 上韓文更貴,用韓文寫的推理軌跡也會以同樣方式燒掉預算。

為什麼字母計數問題會失敗

問「strawberry 裡有幾個 r」,連大模型都會出錯。原因:模型從來看不到字母。"strawberry" 進來時大致是 ["straw", "berry"]——兩個整數。整數裡沒有字母數,就像頁碼不會告訴你那一頁的拼法。模型可以背誦記過的拼法或逐步推理,但兩者都不可靠。如果真的需要:先強迫模型把單字一行一個字母拼出來,再數行數。

詞彙表隨模型一起出貨

  • 分詞器檔案(詞彙表、合併規則)是發布的一部分;GGUF 會嵌入它們,safetensors 存放庫則與權重放在一起。
  • 引擎(llama.cpp、LM Studio、vLLM……)會自動載入正確的分詞器。你永遠不用自己挑。
  • token 計數是相對於模型的:同一段文字在某個家族的詞彙表下可能是 1,000 個 token,在另一個家族下是 1,150 個。絕不要跨模型寫死 token 預算。
  • 詞彙表品質與模型品質是不同的軸:32k 詞彙表的模型也能處理韓文(它懂自己的 token);只是每句要花更多 token。

一切都以 token 計價

你在意什麼 以什麼計量
上下文視窗(4k → 128k+) 輸入 + 輸出 token 合計
生成速度 每秒 token 數
KV 快取記憶體 隨上下文中每個 token 增長(KV 快取)
API 定價 每百萬 token
輸出長度上限 最大輸出 token 數
推理/思考預算 模型回答前可花費的 token 數
為 RAG 嵌入文件 切塊後按百萬 token 計數

特殊 token 與對話模板

除了文字片段,詞彙表還保留控制用 ID:序列開頭、序列結束與角色標記。你的聊天 UI 送出訊息時,送的不是原始文字——它會填入對話模板,把 <|im_start|>user ... <|im_end|> 之類的特殊 token 交錯繞在你的文字外圍。這層包裝就是引擎回報的 token 數永遠比訊息文字本身多一點的原因,也是混用不同家族模板會讓模型混亂的原因。

估算規則:英文字元數 ÷ 4。韓文字元數 ÷ 1.0–1.5——往壞的方向估。模擬器 採用約 4 字元/token 的近似,以英文校準;韓文請自行在心中上調。

自己計算 token 數

pip install tiktoken
python -c "import tiktoken as t; e = t.get_encoding('o200k_base'); print(len(e.encode('hello world')))"
  • tiktoken(https://github.com/openai/tiktoken)涵蓋 OpenAI 家族的編碼;其他家族略有差異,但英文大概落在 ±15% 內。
  • Hugging Face 模型頁面附有分詞器檢視器;分詞器遊樂場讓你貼上文字、即時觀看切分。
  • 本機引擎會在日誌中印出提示詞 token 數——用你真實的提示詞對照一次,之後再用比例估算。

相關章節: transformer 內部 · 預填與解碼 · KV 快取