今天理解到 GPT 產生下一個 token 的最後階段,叫做 output logit。
一開始我以為 Transformer 裡面既然是 token 彼此互看,那最後應該是整串 token 一起拿去預測下一個 token。可是後來才搞懂,實際上不是那麼直覺。
在 Transformer 裡,每個 token 都會經過 attention、MLP、layer 等矩陣運算,每個位置都會產生自己的 output vector。也就是說,不是只有最後一個 token 有結果,而是每個 token 都有自己的結果。
只是 GPT 這種 decoder-only 模型有 causal mask,所以每個 token 只能看自己和前面的 token。越後面的 token,看過的上下文越完整。
例如:
[I] 只能看 [I]
[love] 可以看 [I] [love]
[Taiwan] 可以看 [I] [love] [Taiwan]
所以最後一個 token 的 output vector,其實已經吸收了前面所有 token 的語境。它不是單純代表最後那個字,而是代表「目前整段文字走到這裡的狀態」。
因此,當模型要預測下一個 token 時,就只需要拿最後一個 token 的 output vector 去算。
數學上大概是:
最後 token 的 output vector × output weight matrix = logits
這個 logits 會是一大串數字。以 GPT-2 來說,vocabulary 有 50,257 個 token,所以每次預測下一個 token 時,就會產生 50,257 個 logit 分數。
每個分數都代表某個 token 接在後面的可能性。不過 logit 還不是機率,它只是原始分數。後面還要經過 softmax,才會轉成機率分布,最後再選出下一個 token。
這樣想之後,我覺得整個流程清楚很多:
所有 token 都進模型
→ 每個 token 都產生自己的 output vector
→ 最後 token 的 vector 擁有最完整上下文
→ 拿最後 token 的 vector 算 logits
→ logits 轉成機率
→ 選出下一個 token
所以重點不是「只有最後 token 在運算」,而是「所有 token 都有運算結果,只是生成下一個 token 時,我們只需要最後位置的結果」。
一句話總結:
Transformer 會讓每個 token 整理自己看得到的上下文,而最後一個 token 因為看過目前完整內容,所以它的 output vector 就被拿來預測下一個 token。
我一開始看到 GPT-2 的 vocabulary 只有五萬多個 token,直覺上覺得很疑惑:世界上有這麼多語言、文字、詞彙、概念,五萬多個 token 真的夠嗎?
後來我理解到,vocab 不是「概念表」,而是「文字零件表」。
也就是說,token 不一定是一個完整單字,更不是一個完整概念。它可能是一個字、一段字根、一個空格加單字、一個中文字、一段常見文字片段,甚至是更底層的 byte 片段。
所以 vocab 五萬多,不代表模型只能理解五萬多個概念。比較像是模型有五萬多種文字積木,可以把這些積木組合成非常多句子。
就像英文字母只有 26 個,卻可以拼出大量單字;樂高零件種類有限,卻可以組出無數東西。
如果某個詞不在 vocab 裡,也不是不能處理。它可以被拆成更小的 token。只是拆得越碎,token 數越多,計算越貴,也比較不有效率。
所以 tokenizer 比較像是一種壓縮策略:
常見的文字片段直接用一個 token 表示,冷門的文字就拆成多個 token 組合。
而且 vocab 不只處理輸入,也同時處理輸出。
輸入時,tokenizer 會把文字轉成 token ids:
文字 → tokenizer → token ids
輸出時,模型其實也不是直接吐出文字,而是從同一套 vocab 裡選出下一個 token id,再把 token 還原成文字:
output logits → 選出 token id → detokenizer → 文字
所以可以這樣理解:
既然這套 vocab 可以把文本拆成 token 給模型處理,它自然也可以讓模型用同一套 token 拼回文本。
vocab 就像是模型輸入與輸出的共同文字介面。人類文字進模型前,要先被翻譯成 token;模型輸出時,也只能從這套 token 裡選東西,再轉回人類看得懂的文字。
不過,「能表示」不等於「真的懂」,也不等於「生成得自然」。
某些冷門語言、罕見符號、特殊專業詞,tokenizer 也許可以拆出來,所以模型理論上可以輸入與輸出。但如果訓練資料很少,模型還是可能生成得很怪,或者理解得不好。
真正讓模型理解概念的,也不是 vocab 本身,而是後面的 embedding table、attention weights、MLP weights、output weights 等大量訓練參數。
token 本身只是入口,是文字被轉成數字的方式。真正的語意,是 token 變成 vector 之後,在模型裡經過一層一層矩陣運算慢慢形成的。
所以我現在比較能理解:
vocab 是文字零件庫,也是模型輸入與輸出的共同語言,但不是概念上限。
五萬多個 token 可以透過排列組合,表達非常大量的語言內容。真正限制模型能力的,不是 vocab 只有五萬多,而是 tokenizer 切得好不好、訓練資料夠不夠、模型參數夠不夠,以及模型有沒有學到那些語言和概念之間的關係。