生成AIのAPIを触っていると、temperature の隣に top_p や top_k というパラメータが並んでいます。
どちらも「次の1語の候補をどこまで残すか」を決めるつまみですが、絞り方の考え方がまるで違うのです。
今回は架空の確率分布を手元で計算しながら、2つの違いを整理しました。
AIは毎回「次の1語」を確率で選んでいる
言語モデルは文章を書くとき、語彙のすべてに対して「次に来る確率」を計算します。
たとえば「明日の天気は」に続く候補が、こんな分布になったとしましょう。
晴れ 0.40
曇り 0.25
雨 0.15
雪 0.08
暑い 0.05
寒い 0.03
バナナ 0.02
量子 0.01
### 0.008
ぬ 0.002
確率の低い側に、明らかにおかしい候補が混ざっているのが見えます。
確率どおりに毎回くじを引くと、100回に2回くらいは「バナナ」が出てしまうわけです。
この裾野を切り落とすのが top_k と top_p の役割でした。
では確率が一番高い語だけ選べばいいのでは
ここで多くの人が最初に思うのが、「毎回いちばん確率の高い語を選べば安全では」という発想。
ところが、それをやると文章は同じ言い回しをぐるぐる繰り返し始めます。
この現象を指摘したのが、top_p を提案した The Curious Case of Neural Text Degeneration(2019年)という論文でした。
確率を最大化する選び方は、人間が実際に書く文章の「ゆらぎ」を再現できません。
かといって全候補からくじを引けば「バナナ」を踏む。
この両極の間に線を引くのが、top_k と top_p の仕事です。
top_k は上位k個だけ残す
Hugging Face のドキュメントでは、top_k は「確率の高い語彙トークンを上位いくつ残すか」と定義されています。
つまり数を決め打ちする方式。
上の分布で top_k=3 にすると、残った3語の確率を合計1に割り直したうえでくじを引きます。
top_k=3
晴れ 0.5000
曇り 0.3125
雨 0.1875
top_k=5
晴れ 0.4301
曇り 0.2688
雨 0.1613
雪 0.0860
暑い 0.0538
「バナナ」も「ぬ」も、候補の時点で消えました。
top_p は確率の合計がpに届くまで残す
一方の top_p は、確率の高い順に足していって、合計が p を超えたところで打ち切る方式です。
個数ではなく確率の総量で線を引くのが違いになります。
top_p=0.80 -> 晴れ / 曇り / 雨 の3語
top_p=0.95 -> 晴れ / 曇り / 雨 / 雪 / 暑い / 寒い の6語
同じ分布でも、しきい値を 0.8 から 0.95 に動かすだけで候補数が倍になりました。
決定的な違いは、分布の形に合わせるかどうか
ここが両者のいちばん大きな差です。
次の2つの分布に、同じ top_p=0.9 と top_k=3 を当ててみました。
尖った分布 A:0.90 B:0.05 C:0.02 D:0.01 E:0.01 F:0.01
top_p=0.90 -> 残る候補 1 個 (A)
top_k=3 -> 残る候補 3 個 (A,B,C)
なだらかな分布 A:0.22 B:0.20 C:0.18 D:0.16 E:0.14 F:0.10
top_p=0.90 -> 残る候補 5 個 (A,B,C,D,E)
top_k=3 -> 残る候補 3 個 (A,B,C)
top_k は分布がどんな形でも機械的に3個。
対して top_p は、モデルが自信を持っている場面では1個まで絞り、迷っている場面では5個まで広げました。
確信度に応じて候補数が伸び縮みするのが top_p の長所なのです。
逆に言えば、top_k は「必ずk個の選択肢を残す」と保証したいときに向いています。
temperature とは役割が違う
よく並べて語られる temperature ですが、やっていることは別物でした。
- temperature … 確率分布そのものの尖り具合を変える(候補は減らさない)
- top_k / top_p … 候補リストから下位を切り捨てる(分布の形は変えない)
温度を上げて分布をなだらかにすれば、top_p が残す候補は自然と増えます。
つまり3つのつまみは独立ではなく、互いの効き方に影響し合う関係。
だからこそ、いきなり全部を動かすと何が効いたのか分からなくなります。
temperature そのものについては、別の記事で詳しく扱いました。
設定するときの考え方
Hugging Face の GenerationConfig では top_k と top_p の両方を指定でき、値を書かなければモデル側の generation_config.json にある既定値が使われます。
つまり「指定しない」も立派な選択で、モデル配布者が調整した値がそのまま効くわけです。
触るときは、まずどちらか片方だけを動かして出力の変化を見るのが分かりやすいでしょう。
パラメータ名と意味は Transformers の公式リファレンス に一覧があります。
最後に
top_k は個数で、top_p は確率の総量で候補を絞る。
この一行を押さえておけば、API のドキュメントを読むときに迷いません。
なお本記事の数値は、実際のモデル出力ではなく説明用の分布を手元で計算したものです。
トークンそのものの考え方は、こちらの記事で扱っています。
以上です。










コメントを残す