語言模型每走一步,都會對整個詞彙表產出一組機率,接著由三道裁決器把它收窄。temperature 縮放 logits——小於 1 會拉開強弱差距,大於 1 則把差距壓平;top_k 只留機率最高的 k 個並重新正規化;top_p 由高到低累加,直到累積值達到 p 為止,跨過門檻的那一個仍然留下。這裡的四個階段就是這四個時點,被淘汰的候選會留在原位,帶著砍掉它的那個參數名稱。
這三道裁決器不可交換。先縮放,代表截斷看到的是已經被重塑過的分布——調高 temperature 會把曲線壓平,於是 top_p 更晚才達到門檻、留下更多候選;先截斷,則是用原始機率來判定去留,temperature 只重塑倖存下來的那些。各家 SDK 選的順序不同,所以這個工具把選擇攤開來,而不是把其中一種藏在預設值後面、暗示存在單一標準行為。
這裡的起始分布是構造的,不是擷取來的:三種形狀各自挑來讓一道裁決器現形——一枝獨秀、勢均力敵、長尾。畫面上會標明它們是構造的,因為一個要展示因果的工具,沒有資格對「哪一半是真的」含糊其辭。而真的那一半正好是重要的那一半:temperature、top_k、top_p 的實作與真實取樣器裡的完全相同,所以你看到的每一次變化都是貨真價實的運算。構造分布給不了的是真實詞彙表的手感,這也是為什麼「載入瀏覽器內的小模型」被當成下一步,而不是可有可無的附加功能。
關於這個主題的常見疑問與實用解答。
它們作用的對象不同。temperature 重塑整條分布但不刪掉任何人——它決定強的候選看起來比弱的強多少;top_p 則是直接刪人,累積機率一達到你設的門檻就切線。之所以不建議一起調,是因為兩者會互相干擾:調高 temperature 會把曲線壓平,同一個 top_p 就需要更多候選才累積到門檻,於是留下你以為已經排除掉的字。只動一個、看著裁決鏈,就能直接看見這種干擾。
top_k 是固定人數:留下機率最高的 k 個、其餘丟掉、重新正規化。top_p 是固定的機率份額,常稱為核取樣(nucleus sampling):從最可能的開始往下累加,累積值一達到 p 就停。把總和推過 p 的那一個會被留下,因為少了它就湊不到門檻——這也是為什麼 p 設得小的時候可能只剩一個字。top_k 永遠留同樣數量的選項;top_p 留下的數量則隨模型在那一步有多確定而變。
因為最後一步是抽籤,不是決策。三個參數只決定哪些候選還有資格、各自的權重是多少;真正吐出來的那個字,是從這組加權集合裡抽出來的。所以參數完全相同的兩次執行共用同一個候選池,仍然可能落在不同的字上。在這裡按「再抽一次」,會看到裁決鏈完全不動、結果卻換人——那就是剩下的隨機性的全部。把 temperature 設成 0 會讓候選池收成單一候選,這也是它表現得像確定性行為的原因。
一次只動一個,並且看它對裁決鏈做了什麼,而不是去找一個建議數值。太發散通常代表低機率的候選還有資格留下,這時收緊裁切——把 top_p 或 top_k 調小——可以刪掉它們,而不動到剩下那些的形狀。一直重複通常代表候選池已經塌縮到一兩個強勢候選上,這時調高 temperature 才是把差距拉開的那根槓桿。一個實用的方法:固定其中兩個,把第三個從保守掃到積極,停在存活集合看起來符合你任務的地方。沒有一組普遍正確的數值,這也是這個工具展示機制而不推薦設定的原因。
起始分布是為了演示而構造的,畫面上也這樣標示,所以它不是來自模型。但它下游的一切都是在你瀏覽器裡即時運算,而且與真實取樣器的做法一致。所以機制可以帶到你自己的呼叫上,具體數字不行。你的呼叫用的是不同的 prompt,可能還是不同的模型、tokenizer 與裁決器順序,而且供應商可能加上這個頁面沒有模擬的步驟,例如重複或頻率懲罰。想要一組真實分布來實驗,可以載入瀏覽器內的小模型,同一條鏈會跑在它真正的輸出上。
三種,每一種都刻意讓不同的裁決器成為主角。一枝獨秀時,截斷幾乎沒東西可刪,只有 temperature 動得出可見的效果。勢均力敵時,top_p 稍微一動就換一批存活者,這是體會「為什麼同一個問題會有不同答案」最直接的方式。長尾時,做粗活的是 top_k——它砍掉的是整條尾巴而不是幾個落單的。依形狀而不是依主題挑情境是刻意的:形狀才決定哪個參數值得動,而那正是值得學的東西。