0Pricing
AI Prompt Engineering · レッスン

Top-p(Nucleus)サンプリング

top-pによって、最も確率の高いトークン集合にサンプリングを限定する方法を学びます。

「Top-p(Nucleus)サンプリング」はCoddyKit上の無料AI Prompt Engineeringレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Prompt Engineering学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Prompt Engineeringコースには全4レッスンが含まれています。

Top-pサンプリングとは

Top-pサンプリング(nucleus samplingとも呼ばれます)は、語彙から動的に選ばれた部分集合にサンプリングを制限する手法です。すべてのトークンからサンプリングするのではなく、累積確率が少なくともpになる最小のトークン集合だけをモデルが考慮します。

この手法は『The Curious Case of Neural Text Degeneration』(Holtzman et al., 2019)という論文で提案され、多様性と一貫性を両立した生成において、単純なtemperatureスケーリングを上回ります。

Top-pの仕組み:手順

アルゴリズム:

  1. 語彙全体に対するsoftmax確率を計算する
  2. 確率の高い順にトークンを並べ替える
  3. 並べ替えたリストを順にたどり、累積合計がpに達するまで確率を加算する
  4. このトークン集合がnucleusになる
  5. nucleusだけを対象にサンプリングする(確率の合計が1になるよう再正規化する)
import numpy as np

def top_p_sample(logits, p=0.9):
    probs = softmax(logits, temperature=1.0)

    # Sort by probability descending
    sorted_indices = np.argsort(probs)[::-1]
    sorted_probs = probs[sorted_indices]

    # Find nucleus: smallest set with cumulative prob >= p
    cumulative = np.cumsum(sorted_probs)
    nucleus_size = np.searchsorted(cumulative, p) + 1
    nucleus_indices = sorted_indices[:nucleus_size]
    nucleus_probs = sorted_probs[:nucleus_size]

    # Renormalize
    nucleus_probs = nucleus_probs / nucleus_probs.sum()

    # Sample
    chosen = np.random.choice(nucleus_indices, p=nucleus_probs)
    return chosen

token = top_p_sample(logits, p=0.9)

動的なNucleus

Top-pの重要なポイントは、nucleusの大きさが動的であることです。モデルの確信度が非常に高い場合(1つのトークンが0.95の確率で優勢な場合)、nucleusには1つのトークンだけが含まれます。モデルが不確かな場合(多くのトークンの確率が似ている場合)、nucleusはより多くのトークンを含むように拡大します。

これはモデルの確信度に自動的に適応します。確信度が高い → 語彙サイズが小さい → 集中的な出力。確信度が低い → 語彙サイズが大きい → より広い探索。

# High-confidence situation: model strongly prefers 'the'
high_confidence_logits = np.array([5.0, 1.0, 0.5, 0.1, -0.5])
hc_probs = softmax(high_confidence_logits)
print('High confidence probs:', np.round(hc_probs, 3))
# [0.974, 0.018, 0.011, 0.007, 0.004]
# Top-p=0.9 nucleus: just 1 token (cumulative after token 0 = 97.4% > 90%)

# Low-confidence situation: model unsure
low_confidence_logits = np.array([1.1, 1.0, 0.9, 0.8, 0.7])
lc_probs = softmax(low_confidence_logits)
print('Low confidence probs:', np.round(lc_probs, 3))
# [0.218, 0.208, 0.199, 0.190, 0.181]
# Top-p=0.9 nucleus: all 5 tokens (need all to reach 90%)

OpenAI APIでのTop-p

API呼び出しで top_p を設定します。有効範囲は0.0–1.0です。デフォルトは1.0(語彙全体を使用し、nucleusによる制限はなし)です。

OpenAIは、top_pを変更する場合はtemperatureを1.0のままにし、その逆も同様にすることを推奨しています。両方を同時に調整すると、実際のサンプリング動作を予測しにくくなります。

import openai
client = openai.OpenAI(api_key='sk-...')

# Nucleus sampling: top 90% of probability mass
resp = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'Tell me an interesting fact about the ocean.'}],
    temperature=1.0,   # leave temperature at default
    top_p=0.9          # sample from top 90% nucleus
)
print(resp.choices[0].message.content)

p=1.0:制限なしのサンプリング

top_p=1.0の場合、nucleusにはすべてのトークン、つまり語彙全体が含まれます。これはtop-pによる制限のない、純粋なtemperatureサンプリングと同等です。どれほど確率が低いトークンでも、選択される可能性はゼロではありません。

最大限の多様性が必要な場合は、p=1.0を使用してください。p=1.0では、分布の形状を制御するのはtemperatureだけです。

# p=1.0: all tokens in nucleus
resp_full = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
    temperature=1.0,
    top_p=1.0  # no nucleus restriction
)

# p=0.5: very focused nucleus
resp_focused = client.chat.completions.create(
    model='gpt-4o',
    messages=[{'role': 'user', 'content': 'Generate a creative story opening.'}],
    temperature=1.0,
    top_p=0.5  # only top 50% probability mass
)

トレードオフ:Top-pとTemperature

どちらのパラメーターも出力の多様性を制御しますが、その方法は異なります。

  • Temperatureは分布全体を形作る — トークンの、他のすべてのトークンに対する相対確率が変化する
  • Top-pは分布を切り詰める — トークンがnucleusの外側にある場合、相対確率に関係なく単純に除外される

Top-pは「tail sampling」の問題を防ぎます。高いtemperatureでは、極めて確率の低いトークン(意味不明な文字列や無関係な単語)が、ときどきサンプリングされます。Top-pを使うと、これらのトークンを候補から完全に除外できます。

# The tail problem with temperature alone
high_temp_logits = np.array([3.0, 2.0, 1.0, 0.0, -1.0, -5.0, -10.0])
probs_high_temp = softmax(high_temp_logits, temperature=2.0)
print('High temp probs:', np.round(probs_high_temp, 4))
# The last token (logit=-10) still has a small probability
# With many tokens in a real vocab, these rare tokens accumulate
# and occasionally get sampled, producing incoherent output

# Top-p=0.9 cuts these off entirely
# ensuring only tokens contributing to the top 90% are considered

TemperatureとTop-pの組み合わせ

両方のパラメーターを組み合わせる場合、まずtemperatureを適用して分布を形作り、その結果得られた確率にtop-pを適用してnucleusに切り詰めます。

本番環境でよく使われる設定:

  • クリエイティブ・ライティング:temp=1.0、top_p=0.95
  • チャット:temp=0.8、top_p=0.9
  • コード:temp=0.2、top_p=1.0(低いtemperatureではtop-pによる制限はかからない)
def combined_sample(logits, temperature=1.0, top_p=0.9):
    # Step 1: apply temperature
    probs = softmax(logits, temperature=temperature)

    # Step 2: apply top-p nucleus
    sorted_idx = np.argsort(probs)[::-1]
    sorted_probs = probs[sorted_idx]
    cumulative = np.cumsum(sorted_probs)
    nucleus_size = np.searchsorted(cumulative, top_p) + 1
    nucleus_idx = sorted_idx[:nucleus_size]
    nucleus_probs = probs[nucleus_idx]
    nucleus_probs = nucleus_probs / nucleus_probs.sum()

    return np.random.choice(nucleus_idx, p=nucleus_probs)

Top-pと反復

低いtop-p値は、反復を引き起こすことがあります。nucleusが非常に小さい場合(例:p=0.5)、モデルはごく小さなトークン集合から繰り返しサンプリングします。その結果、出力は反復的で予測しやすくなり、本来意図した創造性とは逆の効果になります。

タスクに対してtop-pが低すぎる兆候として、反復に注意してください。便利な診断方法は、モデルが同じフレーズを繰り返す場合にtop-pまたはtemperatureを上げることです。

def detect_repetition(text, window=20):
    words = text.split()
    if len(words) < window * 2:
        return False
    # Check if any window of words repeats within the text
    for i in range(len(words) - window):
        phrase = ' '.join(words[i:i + window])
        rest = ' '.join(words[i + window:])
        if phrase in rest:
            return True
    return False

response = call_llm(prompt)
if detect_repetition(response):
    print('Warning: repetition detected — consider increasing top_p or temperature')

Top-pとTop-k:概要

Top-pとtop-kは、どちらもサンプリング前に語彙を切り詰めますが、その方法は異なります。

  • Top-p: nucleusのサイズが動的 — モデルが不確かなときは拡大し、確信しているときは縮小する
  • Top-k: nucleusのサイズが固定 — 確信度に関係なく常に正確にk個のトークンを考慮する

Top-pはモデルの確信度に適応するため、一般的にはtop-kより好まれます。Top-kについては次のレッスンで詳しく説明します。

# Top-k equivalent for comparison
def top_k_sample(logits, k=50):
    probs = softmax(logits)
    # Keep only top-k tokens
    top_k_indices = np.argsort(probs)[::-1][:k]
    top_k_probs = probs[top_k_indices]
    top_k_probs = top_k_probs / top_k_probs.sum()
    return np.random.choice(top_k_indices, p=top_k_probs)

# Key difference: k is always 50, regardless of model confidence
# Top-p nucleus size varies from 1 to thousands depending on confidence

デフォルト値と変更するタイミング

APIのデフォルト値:top_p = 1.0(nucleusによる制限なし)。どのような場合に変更すべきでしょうか?

  • top_pを下げる(0.7–0.9): 出力の一貫性がない、または意味のない単語が含まれる場合 — tail samplingが多すぎる
  • 1.0のままにする: temperatureがすでに低い場合 — 低いtemperatureでは分布がすでに鋭くなっているため、top-pによる制限は実質的にかからない
  • 0.5未満には下げない: 反復と多様性の低下を引き起こす
# Guidance: what to adjust based on symptoms
TROUBLESHOOTING = {
    'output is incoherent or contains random words': {
        'fix': 'lower top_p to 0.9 or 0.85',
        'or': 'lower temperature'
    },
    'output is repetitive and looping': {
        'fix': 'increase top_p or temperature',
        'also': 'try adding frequency_penalty or presence_penalty'
    },
    'output is too predictable and boring': {
        'fix': 'increase temperature to 0.9-1.2',
        'keep': 'top_p at 0.95'
    },
    'output needs to be deterministic': {
        'fix': 'set temperature=0, top_p=1.0'
    }
}

Anthropic ClaudeでのTop-p

AnthropicのClaude APIでも、パラメーターとして top_p が公開されています。動作は同じです。モデルは、累積確率がしきい値pに達する最小のトークン集合からなるnucleusを構築し、そのnucleusからサンプリングします。

きめ細かな制御のためにtemperatureと組み合わせてください。temperatureで分布の形状を整え、top_pでその分布から選択できるトークンを制限します。

import anthropic
claude = anthropic.Anthropic(api_key='sk-ant-...')

# Creative writing with nucleus sampling
message = claude.messages.create(
    model='claude-opus-4-5',
    max_tokens=256,
    temperature=1.0,
    top_p=0.95,
    messages=[{
        'role': 'user',
        'content': 'Write a short poem about the ocean.'
    }]
)
print(message.content[0].text)

理解度チェック

Top-kサンプリングと比較した場合、top-p(nucleus)サンプリングの主な利点は何ですか?

復習:Top-p Nucleus Sampling

Top-pサンプリングは、確率全体の少なくともpをカバーする最小のトークン集合である、動的なnucleusを構築します。

  • p=1.0: 語彙全体、制限なし
  • p=0.9: 確率質量の上位90% — 典型的なクリエイティブ設定
  • p=0.5: 非常に集中的 — 反復のリスクがある

nucleusは、モデルが不確かなときに拡大し、確信しているときに縮小します。これにより、tail sampling(低確率トークンのサンプリング)を防ぎながら、多様性を維持できます。次のレッスンでは、top-kサンプリングとtop-pとの違いを扱います。

よくある質問

「Top-p(Nucleus)サンプリング」レッスンは無料ですか?

はい。「Top-p(Nucleus)サンプリング」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Prompt Engineeringコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Prompt Engineeringコースには全4レッスンが含まれています。

「Top-p(Nucleus)サンプリング」で何を学びますか?

top-pによって、最も確率の高いトークン集合にサンプリングを限定する方法を学びます。 ブラウザで直接実行するハンズオンコードでAI Prompt Engineeringを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Prompt Engineeringを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Prompt Engineeringは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Top-p(Nucleus)サンプリング」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Prompt Engineeringレッスンでコードを書いて実行できますか?

はい。すべてのAI Prompt Engineeringレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. LLMにおけるTemperatureとは
  2. Top-p(Nucleus)サンプリング
  3. Top-kサンプリング
  4. ユースケースに合わせたパラメータ選択
← AI Prompt Engineeringに戻る