LLM 為什麼停不下來?從 Stanford CME295 看懂特殊 token 和 chat template
簡單紀錄一下最近看今年九月出的 Stanford CME295 Transformers & LLMs 開放課程中,我比較印象深刻的內容。
目前看到 Word2vec (CBOW, Skip-gram),發現 LLM 的底層邏輯真的好有趣!也發現我消化的速度已經跟不上出影片的速度了QQ
1. 特殊 token
用在三個地方:(1) 訓練、(2) 推論,以及現在最常碰到的對話格式。其中除了 BOS (序列開始)、EOS (序列結束),還有 PAD (補齊) 和 UNK (未知)。
① 前兩者分別代表生成的起點和結束的代表符號,模型會輸出它,代表推論迴圈就要停下來了。也就是說,如果模型一直不輸出 EOS,LLM 就會一直講,直到到達 max tokens。
② PAD 顧名思義是要補齊,原來是因為一個 batch 裡的句子長度不同,短的要補齊成一樣長才能疊成矩形 tensor,否則長度不一的序列會影響運算效率。
UNK 代表的是詞彙表查不到的片段的代替者,不過現代 BPE(尤其 byte-level)幾乎能把任何字拆到 byte,所以 UNK 已經很少出現了。
③ 對話格式的舉例:在 API 送出的 messages,實際上會被 chat template 攤平成一長串文字,像這樣(ChatML 格式,Qwen 等模型使用):
<|im_start|>system
你是一個助理<|im_end|>
<|im_start|>user
特殊 token 用在哪?<|im_end|>
<|im_start|>assistant
模型看到最後的 assistant 就知道輪到自己說話;說完時輸出 <|im_end|>,等於這一輪的 EOS。
tool call、思考區塊等,很多模型也是用專屬的特殊 token 包起來的。不過目前還沒有一個統一的寫法,每個模型的特殊 token 和 template 都不同(Llama 3 用 <|begin_of_text|>、<|eot_id|> 等)。
實務上自己拼 prompt 時用錯 template,模型可能停不下來或角色錯亂,所以通常交給 tokenizer 內建的 apply_chat_template 處理。
2. one-hot 和 Word2vec 是 LLM 表示方式的「前身」
LLM 繼承了它們的形式,但目前做法已經不同。一開始是用一個叫 one-hot 的方式。
兩者最大的差別是:他們是怎麼得來的?
one-hot 是直接編號而來,Word2vec 則是上下文訓練出來的,所以相關的詞彼此會接近,不像 one-hot 任兩個內積都是 0。
但後來發現 Word2vec 遇到多義(打籃球 vs 打電話)、語氣、詞序或未見詞會失靈,這些限制正是 RNN 和 Attention 要解決的。