0Pricing
AI Prompt Engineering · Lezione

Nucleus sampling con top-p

Come top-p limita il sampling all’insieme di token più probabili

Nucleus sampling con top-p è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.

Che cos'è il campionamento top-p?

Il campionamento top-p (chiamato anche nucleus sampling) è una tecnica che limita il campionamento a un sottoinsieme dinamico del vocabolario. Invece di campionare da tutti i token, il modello considera solo l'insieme più piccolo di token la cui probabilità cumulativa è almeno pari a p.

Proposto nell'articolo 'The Curious Case of Neural Text Degeneration' (Holtzman et al., 2019), offre risultati migliori del semplice ridimensionamento della temperatura per la generazione di contenuti vari e coerenti.

Come funziona top-p, passo dopo passo

Algoritmo:

  1. Calcolare le probabilità della softmax sull'intero vocabolario
  2. Ordinare i token in base alla probabilità, dalla più alta alla più bassa
  3. Scorrere l'elenco ordinato, accumulando le probabilità, finché la somma cumulativa non raggiunge p
  4. Questo insieme di token costituisce il nucleo
  5. Campionare solo dal nucleo, rinormalizzando le probabilità affinché la loro somma sia 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)

Il nucleo dinamico

L'intuizione chiave di top-p è che la dimensione del nucleo è dinamica. Quando il modello è molto sicuro (un token domina con una probabilità di 0.95), il nucleo contiene un solo token. Quando il modello è incerto (molti token hanno probabilità simili), il nucleo si espande includendo più token.

In questo modo il metodo si adatta automaticamente al livello di sicurezza del modello: alta sicurezza → vocabolario ridotto → output mirato. Bassa sicurezza → vocabolario più ampio → maggiore esplorazione.

# 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%)

Top-p nell'API OpenAI

Imposti top_p nella chiamata API. L'intervallo valido è 0.0–1.0. Il valore predefinito è 1.0 (vocabolario completo, senza restrizioni del nucleo).

OpenAI consiglia di lasciare temperature a 1.0 se modifica top_p, e viceversa. Modificare entrambi contemporaneamente rende difficile prevedere il comportamento effettivo del campionamento.

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: campionamento senza restrizioni

Quando top_p=1.0, il nucleo include tutti i token, cioè l'intero vocabolario. Ciò equivale al puro campionamento con temperatura, senza restrizioni top-p. Ogni token, per quanto improbabile, ha una probabilità diversa da zero di essere selezionato.

Utilizzi p=1.0 quando desidera la massima diversità. Con p=1.0, solo la temperatura controlla la forma della distribuzione.

# 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
)

Compromesso: top-p e temperatura

Entrambi i parametri controllano la diversità dell'output, ma in modo diverso:

  • La temperatura modifica l'intera distribuzione — cambia la probabilità relativa di un token rispetto a tutti gli altri
  • Top-p tronca la distribuzione — un token viene semplicemente escluso se si trova al di fuori del nucleo, indipendentemente dalla sua probabilità relativa

Top-p previene il problema del «campionamento dalla coda»: con una temperatura elevata, token estremamente improbabili (testo senza senso, parole fuori contesto) vengono occasionalmente campionati. Top-p elimina completamente questi token dal processo di selezione.

# 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

Combinare temperatura e top-p

Quando si combinano entrambi i parametri, la temperatura viene applicata per prima (modificando la distribuzione), quindi top-p viene applicato alle probabilità risultanti (restringendole al nucleo).

Configurazioni comuni per la produzione:

  • Scrittura creativa: temp=1.0, top_p=0.95
  • Chat: temp=0.8, top_p=0.9
  • Codice: temp=0.2, top_p=1.0 (top-p non è restrittivo con una temperatura bassa)
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 e ripetizione

Valori bassi di top-p possono causare ripetizioni. Quando il nucleo è molto piccolo, ad esempio p=0.5, il modello campiona ripetutamente da un insieme minimo di token. L'output diventa ripetitivo e prevedibile, l'opposto dell'effetto creativo desiderato.

Consideri la ripetizione come un segnale che top-p è impostato su un valore troppo basso per l'attività. Un controllo utile: se il modello ripete ciclicamente le stesse frasi, aumenti top-p o la temperatura.

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 e top-k: un'anteprima

Top-p e top-k troncano entrambi il vocabolario prima del campionamento, ma in modo diverso:

  • Top-p: dimensione dinamica del nucleo — si espande quando il modello è incerto e si riduce quando è sicuro
  • Top-k: dimensione fissa del nucleo — considera sempre esattamente k token, indipendentemente dal livello di sicurezza

In genere si preferisce top-p perché si adatta al livello di sicurezza del modello. Top-k viene trattato in dettaglio nella prossima lezione.

# 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

Valori predefiniti e quando modificarli

Valori predefiniti dell'API: top_p = 1.0 (nessuna restrizione del nucleo). Quando è opportuno modificarlo?

  • Riduca top_p (0.7–0.9): quando gli output sembrano incoerenti o contengono parole prive di senso — è presente un eccessivo campionamento dalla coda
  • Lo lasci a 1.0: quando la temperatura è già bassa — con una temperatura bassa la distribuzione è già concentrata e top-p non è comunque restrittivo
  • Non lo riduca al di sotto di 0.5: ciò causa ripetizioni e perdita di diversità
# 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'
    }
}

Top-p in Anthropic Claude

Anche l'API Claude di Anthropic espone top_p come parametro. Il comportamento è identico: il modello costruisce un nucleo costituito dall'insieme più piccolo di token la cui probabilità cumulativa raggiunge la soglia p, quindi campiona da quel nucleo.

Lo combini con la temperatura per un controllo preciso: utilizzi la temperatura per modificare la forma della distribuzione e top_p per limitare i token che possono essere selezionati da quella distribuzione.

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)

Verifica delle conoscenze

Qual è il principale vantaggio del campionamento top-p (nucleus) rispetto al campionamento top-k?

Riepilogo: campionamento nucleus con top-p

Il campionamento top-p costruisce un nucleo dinamico, cioè l'insieme più piccolo di token che copre almeno p della probabilità totale:

  • p=1.0: vocabolario completo, nessuna restrizione
  • p=0.9: il 90% superiore della massa di probabilità — impostazione creativa tipica
  • p=0.5: molto mirato — rischio di ripetizioni

Il nucleo si espande quando il modello è incerto e si restringe quando è sicuro. Ciò impedisce il campionamento dalla coda (testo senza senso generato da token improbabili), preservando al contempo la diversità. Prossima lezione: campionamento top-k e differenze rispetto a top-p.

Domande Frequenti

La lezione «Nucleus sampling con top-p» è gratuita?

Sì — il testo completo di «Nucleus sampling con top-p» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.

Cosa imparerò in «Nucleus sampling con top-p»?

Come top-p limita il sampling all’insieme di token più probabili Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Prompt Engineering?

Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Nucleus sampling con top-p»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?

Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Che cos’è la temperatura negli LLM?
  2. Nucleus sampling con top-p
  3. Sampling con top-k
  4. Scelta dei parametri per il proprio caso d’uso
← Torna a AI Prompt Engineering