localaiforum
登入
指南 › 模型運用實務

取樣設定

取樣是推論的最後一吋:模型為詞彙表中的每個 token 打分,而你的設定決定那個分布如何變成一個 token。旋鈕會互動,所以運算順序比任何單一數值重要。

管線,按順序

多數引擎大致按這個順序套用取樣器:

  • Logits——原始分數,詞彙表每個 token 一個(5 萬到 15 萬條)。
  • 重複懲罰——最近見過的 token 被壓低 logits。
  • 溫度——logits 除以 T,把一切變尖或變平。
  • top_k——硬上限:只有前 k 個 token 存活。
  • top_p——核採樣:涵蓋 p 比例機率質量的最小前段集合。
  • min_p——相對地板:丟掉低於 min_p × P(最高 token)的 token。
  • 取樣——從剩下的挑一個 token,附加,重複。

早套用的過濾器會改變之後每個過濾器看到的東西。堆疊時記住這點。

溫度

溫度 T 在 softmax 前除以 logits。較低的 T 把分布往最高 token 收尖;較高的 T 把它往均勻壓平。具體例子:三個 token 的 logits [5.0, 3.0, 1.0]。

T P(最高) P(第二) P(第三)
0.5 98.1% 1.8% 0.03%
1.0 86.7% 11.7% 1.6%
1.5 75.0% 19.8% 5.2%

T → 0 時塌縮成貪婪:永遠取 argmax,完全確定。

抽取、分類、以及任何要逐次執行可重現的東西,用溫度 0(引擎不允許 0 時用 0.000001)。對話要 0.6–0.8;創意寫作容忍 0.9–1.2。

top_k:硬上限

只保留機率最高的 k 個 token 並在其中取樣。top_k 40 讓第 41 名以後不可能中選,無論如何。

它是鈍器。k=40 在「法國的首都是」之後很寬鬆,在只有兩個候選重要的罕見 token 位置則荒謬地浪費。常見預設:40。用 min_p 時停用它(0 或 -1,視引擎而定)。

top_p:核採樣

按機率排序,保留累積機率到達 p 的最小集合,重新正規化,取樣。

實例:機率 [0.867, 0.117, 0.016] 配 top_p 0.9。最高 token 自己涵蓋 0.867 < 0.9;加上第二個達到 0.984 ≥ 0.9。你從兩個 token 取樣,重新正規化為 [0.88, 0.12]。

模型有信心時候選集自動縮小、不確定時變大。典型範圍:0.9–0.95。

min_p:本機圈的最愛

只保留機率至少 min_p × P(最高 token)的 token。地板是相對尺度:

  • 模型 99% 有信心 → 地板=0.05 × 0.99 ≈ 0.05:只有真正的競爭者存活。
  • 最高 token 30% → 地板=0.05 × 0.30 = 0.015:多樣性存活。

那消除了 top_k/top_p 的經典失敗——對有信心的分布過度修剪、對平坦的修剪不足——而且 min_p 能與高溫安全組合。「有創意但連貫」配方:temp 1.0–1.5、min_p 0.05–0.1。常見本機設定:min_p 0.05,關掉 top_k 與 top_p。

repeat_penalty(llama.cpp 家族)

在套用溫度之前,最近上下文中出現過的 token,其 logits 會被懲罰值除。低於 1.0 的值反而助長重複。合理範圍:1.0–1.1。

副作用是真的,因為程式碼與資料故意重複 token:

  • 識別字合理地重複:counter.count 裡的 count。
  • JSON 的鍵與右括號在陣列的每個物件中重複。
  • 懲罰 1.2+ 早在治好散文迴圈之前,就先弄壞程式碼與 JSON(掉的括號、「被改正」的引號)。

現代 instruct 模型很少需要超過 1.05。對程式碼與結構化輸出,1.0 是合理選擇。

frequency 與 presence 懲罰(API 風格)

OpenAI 相容 API 提供 frequency_penalty(隨重複增加)與 presence_penalty(對已見 token 的一次性懲罰),而 llama.cpp 用的是 repeat_penalty。意圖相同、數學不同。不是每個本機引擎都實作兩者——疊上去之前先確認你的引擎實作了什麼:引擎參數。

把取樣器疊進死角

temp 0.1+top_k 10+top_p 0.5+min_p 0.2+repeat_penalty 1.3 全疊在一起,可以把每個候選 token 都遮掉。症狀:NaN logprob 警告、空生成、「sampling returned zero candidates」中止。

那不是模型壞了——是空的候選集。一次放鬆一個旋鈕。完整檢傷:疑難排解。

可用的預設

任務 temp top_p min_p repeat_penalty
對話(一般) 0.7 0.90–0.95 0.05 1.0–1.05
程式碼生成 0.1–0.2 0.9 — 1.0
抽取/分類 0(貪婪) — — 1.0
創意寫作 0.9–1.0 0.95 0.05–0.1 1.05–1.1
翻譯 0.2–0.4 0.9 — 1.0

對話那列換成 llama.cpp 旗標:

llama-server -m model.gguf --temp 0.7 --top-p 0.95 --min-p 0.05 --repeat-penalty 1.05

一次只改一件事

把預設當起點,不是法律。如果你同時動溫度與 top_p 而輸出變好,你對哪個旋鈕有用一事一無所獲。

  1. 固定一組測試題:5–10 個會用到你在意能力的提示詞。
  2. 每個設定各存輸出;並排 diff。
  3. 每次執行只動一個旋鈕。
  4. 把贏家存成具名預設——每個引擎與 UI 都能存。

這些旋鈕如何對應引擎旗標與 API 欄位:引擎參數。

相關章節: 引擎參數 · 提示詞 · 結構化輸出 · 疑難排解