跳到主要內容

LV.04

文字接龍與 Token

LLM 只會猜下一個字

BOSS
自信幻覺史萊姆
時間
約 35 分鐘
建議先過
LV.03

LLM 其實只做一件事

你一定用過手機輸入法的「聯想字」:打「今天」,鍵盤列出「天氣」「晚上」「早上」讓你選。LLM 的核心,就是一個大到誇張的聯想字機器:給它前面的文字,它算出「下一個 token 最可能是什麼」,挑一個,接上去,再繼續算下一個。

台大李宏毅老師在「生成式人工智慧與機器學習導論」課程中,用「文字接龍」來說明這件事,這個說法很適合入門(來源:研究筆記 02 §1-C,二手整理,本站未逐字引用)。

這也是本關 Boss「自信幻覺史萊姆」的來源。你問它病史,它流暢地回答,但那段病史可能是編出來的。理由不是它在說謊,而是它的訓練目標,是讓接續的文字像訓練資料,而不是保證為真。流暢和正確,是兩個獨立的維度。

用醫學生的語言說:它像一個讀過非常多病歷的實習生,被要求補完一份病歷的下一句。補得很像病歷,不代表補的內容是這位病人真正的狀況。這個類比的好處是提醒你,每一句產出都應該核對。Thirunavukarasu 等人的綜述也把這類限制,列在 LLM 用於臨床時的重要議題(PMID 37460753)。

Token 是什麼

模型不是一個字一個字讀,而是先把文字切成小片段,這些片段叫 token,負責切的工具叫 tokenizer(分詞器)。常見的方法叫 BPE(byte pair encoding,位元組對編碼):從單一字元開始,統計哪些相鄰組合在語料裡最常出現,就把它們合併成一個新的片段,重複很多次,得到一份詞彙表。

結果是:

  • 常見的英文單字,常常整個是一個 token。
  • 少見的字(例如罕見藥名)會被拆成好幾塊。
  • 中文常見的字可能一字一 token,也可能把常見的詞組合在一起,要看這個 tokenizer 的訓練語料。
  • 數字、標點、縮寫(HbA1c)的切法也不一定符合人的直覺。

為什麼要在意?因為 token 數決定成本與容量:模型一次能看的上限(下一關的 context window)是用 token 計算,不是用字數。一份中英夾雜的病歷,不同模型的 token 數可能差很多。具體差多少,下面的實作有作者的實測小表,你也可以自己量一次。

取樣:模型怎麼「挑」下一個 token

模型每一步輸出的是一個機率分布:每個可能的 token 有多少機率。要挑哪一個,由取樣設定決定:

  • temperature:調整分布的尖或平。低(接近 0)時,大多挑最高機率的 token,結果較穩定;高時,機率較低的選項也有機會被選中,輸出較多變。
  • top-k:只在機率最高的 k 個選項裡挑。
  • top-p(又稱 nucleus sampling):只在「累積機率達到 p」的最小集合裡挑。

類比:開立同一種藥,低 temperature 像是「照 guideline 的第一線」,高 temperature 像是「也考慮第二、第三線的選擇」。對需要穩定格式的任務,例如要輸出 JSON,通常傾向保守的設定;對腦力激盪,則可以放寬。但保守不等於正確:模型可能很穩定地講錯。

一個不用寫程式就能親眼看到這些的方法:Georgia Tech 的 Polo Club 團隊做了 Transformer Explainer,在瀏覽器內執行 GPT-2 small,你可以輸入自己的句子,並拉動 temperature、top-k、top-p 的滑桿看機率分布怎麼變(https://poloclub.github.io/transformer-explainer/)。請花 5 分鐘試一下,尤其觀察:把 temperature 拉到很低與很高,同一句話的下一個字有什麼不同。這個工具以連結方式使用,本站不內嵌。

想往下挖的人:Sebastian Raschka 的《LLMs from Scratch》第 2 章有 BPE 的逐步實作(https://github.com/rasbt/LLMs-from-scratch);Andrej Karpathy 的「Deep Dive into LLMs like ChatGPT」影片(約 3.5 小時,2025-02 發布)涵蓋 tokenization 與 hallucination 的成因。以上都是選讀。

為什麼這對本站主線很重要

主線專案要把「中英夾雜的病歷」交給模型,並要求它輸出每個 PHI 的原文字串與類型(遮蔽交給程式,見 LV11)。有兩點與 token 直接相關:

  1. 成本與長度:中英夾雜、含數字與縮寫的病歷,token 數可能比你想像的多,會影響訓練時能放進多長的序列,也影響記憶體(LV05、LV06 會講)。
  2. 格式穩定:輸出是逐 token 產生的,任何一個位置都可能偏掉。所以後面評估時,我們不只看抓到多少個 PHI,也會單獨看「輸出是不是合法的 JSON」。作者在 Gemma 4 E2B 上的冒煙測試(非正式數字)就看到:不關閉「思考模式」時,輸出的 JSON 有效率為 0%(思考文字耗盡了 500 token 的額度);關掉思考後,有效率提升到約 45%。這個數字只是流程測試,不是正式結果,也說明了「模型逐 token 生成,格式需要被量測」。

實作:看 tokenizer 怎麼切

先做準備:🍎 Mac 在 Terminal 執行 python3 -m pip install transformers(建議在虛擬環境中)。☁️ Colab 已經內建 transformers,免安裝。

from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("Qwen/Qwen3-4B-Instruct-2507")
text = "病人 HbA1c 8.2%,目前使用 metformin 500 mg BID。"
ids = tok.encode(text)
print(len(ids), "tokens")
print(tok.convert_ids_to_tokens(ids))

逐行解釋:

  1. 從 transformers 載入 AutoTokenizer,它會依模型名稱自動挑對的分詞器。
  2. 下載並載入 Qwen3 的 tokenizer(只下載分詞器的檔案,不會下載模型本體)。第一次執行需要網路。
  3. 準備一句中英夾雜的虛構句子,裡面有中文、縮寫、藥名、數字、單位。
  4. encode 把文字變成一串整數編號(token id)。
  5. 印出 token 總數。
  6. 把編號翻回片段,讓你看到每一塊長什麼樣子。有些片段看起來像亂碼,那是因為某些中文字被拆成位元組層級的片段,屬於正常現象。

☁️ Colab 加碼:把模型名稱換成 google/gemma-4-E2B-it,再跑一次,比較兩個 tokenizer 的 token 數。Gemma 4 採 Apache-2.0 授權,截至 2026-10 不需申請即可下載(模型名稱以 Hugging Face 頁面為準)。下表是作者在本機實測的結果(tokenizer 來自 Qwen3-4B-Instruct-2507 與 Gemma 4 E2B,不含特殊 token),你換一句話再量一次,結果會不同:

文字Qwen3 token 數Gemma 4 token 數
病人 HbA1c 8.2%,目前使用 metformin 500 mg BID。2420
糖尿病11
metformin3(met / form / in)2(met / formin)
diabetes mellitus42
acetaminophen42

兩個觀察:常見醫學中文詞(糖尿病)在兩個 tokenizer 都只是 1 個 token;英文藥名與病名在 Gemma 4 通常切得比較少塊。這只是 5 個例子,不能推論哪個模型「比較懂醫學」,只說明 token 成本會因 tokenizer 而異。

試著回答:中文詞比英文詞貴嗎?罕見的藥名被拆成幾塊?這些會是你之後替模型設定序列長度的依據。

本關重點

  1. LLM 的核心是「下一個 token 預測」:流暢不等於正確,hallucination 就是這樣來的。
  2. Token 是模型看文字的單位,由 tokenizer 切出;中英夾雜與罕見詞通常切得比較碎。
  3. temperature、top-k、top-p 控制「怎麼從機率分布挑下一個 token」;低 temperature 較穩定,但不保證正確。
  4. 輸出逐 token 生成,所以格式(例如 JSON)也需要被評估,不能假設一定符合。
  5. 下一站:注意力森林,看模型怎麼決定「讀病歷時眼睛放在哪裡」。

BOSS 戰:自信幻覺史萊姆

HP0/4
  1. 「LLM 只是在做下一個 token 預測」這句話,最能解釋下列哪個現象?

  2. 同一句「病人 HbA1c 8.2%」,為什麼在不同的 tokenizer 下 token 數可能不同?

  3. 把 temperature 調得很低(接近 0),通常會發生什麼?

  4. 在 PHI 抽取任務中,輸出需要是格式固定的 JSON。從本章的角度,為什麼取樣設定與 token 切分都值得注意?