跳到主要內容
AI 原理與協定

Temperature、Top-K、Top-P:三個參數,其實在管同一件事

同樣的提問,為什麼模型每次回答都不一樣?因為它不是在「想答案」,而是在抽籤。Temperature、Top-K、Top-P 這三個參數,控制的就是這場抽籤怎麼抽——本文用一個具體例子把它們講清楚。

你大概調過這幾個參數。OpenAI、Claude、還是本地跑的 Llama,API 文件裡總會列著 temperaturetop_ptop_k,旁邊寫一句「控制隨機性」就沒了。

於是你把 temperature 調高一點,輸出真的變亂了;調低一點,又變得死板。但到底發生了什麼事?這三個東西看起來都在「控制隨機性」,那它們是不是在做同一件事?只是換個旋鈕?

不是。它們動的是同一條生產線上的不同工序。要看懂差別,得先知道一件事:模型生成文字的時候,根本不是在「想答案」,而是在抽籤。


模型每吐一個字,都在抽一次籤

語言模型一次只產生一個 token。它的運作方式是這樣:給定目前已經有的文字,模型會對「下一個 token 可能是什麼」算出一整張機率表。

假設你輸入「今天天氣真」,模型內部算出來的可能長這樣:

好    → 60%
熱    → 20%
不錯  → 12%
糟    → 5%
藍    → 0.5%
香蕉  → 0.0001%
...(後面還有幾萬個 token,機率趨近於 0)

注意,模型給的是一整張機率分布,不是一個答案。真正決定「這次到底要選哪個字」的,是另一個步驟——取樣(sampling)

最笨的取樣法是「永遠選機率最高的」,也就是每次都挑「好」。這叫 greedy decoding(貪婪解碼)。問題是,這樣模型會變得完全固定:同樣的輸入,永遠吐同樣的輸出,毫無變化,而且很容易卡進重複的鬼打牆。

所以實務上會「按機率抽」——機率 60% 的「好」有六成機會中籤,20% 的「熱」有兩成機會。這樣輸出才有變化。

Temperature、Top-K、Top-P 三個參數,全都是在動這張機率表,或動這場抽籤怎麼抽。 搞清楚這點,剩下的就好懂了。


Temperature:把機率表拉平還是拉尖

temperature(溫度) 控制的是這張機率表的「對比度」。

想像那張表是一座山。機率高的字是山峰,機率低的字是山腳。temperature 做的事,就是調整這座山的陡峭程度。

  • 溫度低(例如 0.2):山變得又高又尖。本來 60% 的「好」可能變成 90%,其他選項被壓到趨近於 0。抽到「好」幾乎是必然——輸出變得保守、可預測。
  • 溫度高(例如 1.5):山被壓扁攤平。「好」從 60% 掉到剩 35%,原本沒機會的「藍」「糟」開始浮上來。輸出變得發散、有創意,但也更容易語無倫次。
原始分布        低溫 (0.2)       高溫 (1.5)
好   60%        好   90%         好   35%
熱   20%        熱    8%         熱   22%
不錯 12%        不錯  2%         不錯 18%
糟    5%        糟  ~0%          糟   14%
藍  0.5%        藍  ~0%          藍   11%

關鍵在於:temperature 不刪掉任何選項,它只是調整大家的相對機率。 「香蕉」就算在高溫下,機率還是低到幾乎不可能中——它只是把每個選項之間的差距放大或縮小。

一個常見的特例:temperature = 0。這等於把山拉到無限尖,永遠只剩機率最高的那個,效果就跟 greedy decoding 一樣。所以你想要模型「每次都給一樣的答案」,就把溫度設成 0。


Top-K:只留前 K 名,其他直接淘汰

Temperature 是調整每個選項的機率,但所有選項都還在牌桌上。top-k 換了個思路:先把候選名單砍短。

Top-K = 5 的意思是:只保留機率最高的前 5 個 token,剩下幾萬個全部丟掉,然後只在這 5 個裡面抽籤。

Top-K = 3,只留前三名再抽:

好    60%  ✓ 留下
熱    20%  ✓ 留下
不錯  12%  ✓ 留下
─────────────── 砍掉這條線以下全部
糟     5%  ✗ 淘汰
藍   0.5%  ✗ 淘汰
香蕉 ...   ✗ 淘汰

被留下的前三名會重新算一次比例(讓三者加起來等於 100%),然後在它們之間按機率抽。

好處很直接:那些超低機率的離譜選項,從一開始就沒機會出現。 模型不會突然蹦出一個「香蕉」。它砍掉的是長尾的雜訊。

但 top-k 有個先天的笨拙——K 是個固定數字,不管當下情況。 這會在兩種極端情況下出問題:

  • 模型很確定的時候(例如「2 + 2 =」後面幾乎篤定是「4」),其實只有 1 個合理答案,但 top-k = 5 還是硬留了 5 個,等於放進 4 個不該考慮的雜選項。
  • 模型很不確定的時候(例如寫小說的下一句,幾十個詞都通順),合理選項明明很多,top-k = 5 卻硬砍到只剩 5 個,扼殺了該有的多樣性。

固定的 K,沒辦法同時應付這兩種狀況。這就是 top-p 想解決的事。


Top-P:不數人頭,改看累積機率

top-p,又叫 nucleus sampling(核心取樣),做的事跟 top-k 很像——都是砍候選名單——但它的砍法聰明在:不固定留幾個,而是固定留多少「機率總量」。

Top-P = 0.9 的意思是:從機率最高的開始往下加,加到累積超過 90% 為止,後面的全部砍掉。

回到原本那張表,看看同一個 P 值在不同情況下會留下幾個:

情況 A:模型很確定(top_p = 0.9)
好    92%  ← 加到這裡就破 90% 了
─────────────── 後面全砍
熱     5%  ✗
其他 ...   ✗
結果:只留 1 個

情況 B:模型很發散(top_p = 0.9)
好    25%  累積 25%
熱    20%  累積 45%
不錯  18%  累積 63%
還行  15%  累積 78%
普通  12%  累積 90%  ← 加到這裡才破 90%
─────────────── 後面才砍
結果:留了 5 個

看出差別了嗎?同樣是 top_p = 0.9,模型有把握時自動只留 1 個,模型發散時自動留 5 個。 候選名單的長度,是隨著當下這張機率表的「形狀」動態伸縮的。

這正好補上 top-k 的死穴。Top-k 數的是「人頭」,永遠固定幾個;top-p 看的是「機率總量」,名單該長就長、該短就短。所以現在主流的設定,多半是 top-p 為主、top-k 為輔,甚至直接不開 top-k。


放在一起:它們是一條生產線

講到這你可能會問:那這三個到底要怎麼搭?是三選一嗎?

不是三選一——它們會依序套用,像一條生產線。實際生成一個 token 的順序通常是:

1. 模型算出原始機率分布(幾萬個 token)
2. Temperature  → 把整張表拉尖或拉平
3. Top-K        → 砍到只剩前 K 名
4. Top-P        → 再從累積機率切一刀
5. 在剩下的候選裡,按機率抽一個籤

每一道工序都在縮減或重塑候選池,最後才抽。所以它們不衝突,是接力。

用一個比喻收尾——這像在一群人裡選一個代表:

Temperature 決定大家的呼聲差距要拉多開(有人特別突出,還是勢均力敵); Top-K 說「只有排名前 K 的有資格」; Top-P 說「從最高票開始點名,點到累積過半就截止」。 最後,在剩下的候選人裡抽籤。


那實際上該怎麼設

規則沒有絕對,但有幾個堪用的起點:

你想要TemperatureTop-P場景
穩定、可重現0 ~ 0.31.0程式碼、翻譯、抽取結構化資料
平衡0.7 ~ 0.80.9一般對話、問答
發散、有創意1.0 ~ 1.30.95寫作、發想、腦力激盪

兩個實務提醒:

別同時把 temperature 和 top-p 都調到很激進。 兩個都放很開,輸出容易直接崩成亂碼。要嘛靠 temperature 主導,要嘛靠 top-p 主導,動一個就好。

要完全確定性,temperature 設 0 就夠了。 這時候 top-k、top-p 設什麼都沒差——反正只剩機率最高的那一個,沒得抽。


小結

這三個參數看起來都在「控制隨機性」,但它們其實站在生產線的不同位置:temperature 重塑整張機率表的對比度,top-k 用固定人數砍候選名單,top-p 用累積機率動態砍候選名單。一個在調形狀,兩個在切範圍,切法不同。

所以下次你在調這些旋鈕,不會再覺得是三個都在「控制亂度」的重複開關。你會知道自己正站在哪道工序上:是要把那座機率的山拉尖一點,還是要把山腳的雜訊掃掉幾個。模型從頭到尾都在抽籤——你只是在決定,籤筒裡該放哪些籤。