0Pricing
AI Prompt Engineering · Lezione

Sampling con top-k

Limitare la scelta ai k token più probabili e analizzarne l’effetto sulla varietà dell’output

Sampling con top-k è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 3 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-k?

Il campionamento top-k limita il modello al campionamento dai k token più probabili a ogni passaggio. A tutti i token al di fuori dei top-k viene assegnata probabilità zero e non possono essere selezionati.

k=1 corrisponde alla decodifica greedy (solo il token più probabile). k=50 è un intervallo creativo tipico. k=vocabulary_size equivale al campionamento senza restrizioni.

Algoritmo top-k

L'algoritmo è più semplice di quello di top-p:

  1. Calcolare le probabilità della softmax sull'intero vocabolario
  2. Ordinare i token in ordine decrescente di probabilità
  3. Mantenere solo i k token principali e impostare tutti gli altri a 0
  4. Rinormalizzare le probabilità dei top-k affinché la loro somma sia 1
  5. Campionare dalla distribuzione rinormalizzata
import numpy as np

def softmax(logits, temperature=1.0):
    scaled = logits / temperature
    e = np.exp(scaled - np.max(scaled))
    return e / e.sum()

def top_k_sample(logits, k=50, temperature=1.0):
    probs = softmax(logits, temperature)

    # Find top-k indices
    top_k_indices = np.argsort(probs)[::-1][:k]
    top_k_probs = probs[top_k_indices]

    # Renormalize
    top_k_probs = top_k_probs / top_k_probs.sum()

    # Sample
    chosen = np.random.choice(top_k_indices, p=top_k_probs)
    return chosen

# With a 10-token vocabulary:
logits = np.random.randn(10)
print('Chosen token:', top_k_sample(logits, k=3))

k=1: decodifica greedy

Quando k=1, l'insieme dei candidati contiene solo il token più probabile. Il campionamento da un insieme di dimensione 1 è deterministico: il modello sceglie sempre quel token. È identico alla decodifica greedy (temperature=0).

logits = np.array([3.0, 2.0, 1.0, 0.5, -1.0])

# k=1: greedy
top_1 = top_k_sample(logits, k=1)
print(f'k=1 always picks: {np.argmax(logits)}')  # index 0, the highest logit
print(f'top_k_sample result: {top_1}')  # always 0

# Multiple runs
for _ in range(5):
    print(top_k_sample(logits, k=1), end=' ')
# Output: 0 0 0 0 0 — perfectly deterministic

Intervallo creativo tipico: k=50

k=50 è un valore predefinito comune per la generazione di testo creativo. Consente di esplorare 50 token a ogni passaggio, impedendo al contempo al modello di selezionare token per i quali ha un livello di sicurezza molto basso.

Con un vocabolario di 50.000 token, k=50 significa che il modello considera solo lo 0,1% dei token con probabilità più alta a ogni passaggio. Si tratta di una restrizione significativa: la maggior parte del vocabolario viene esclusa.

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

# Note: OpenAI API does not expose top_k directly in chat completions.
# Top-k is primarily a parameter in Hugging Face Transformers and Anthropic's API.

# Hugging Face example:
from transformers import pipeline
generator = pipeline('text-generation', model='gpt2')
output = generator(
    'Once upon a time',
    max_new_tokens=100,
    do_sample=True,
    top_k=50,
    temperature=1.0
)
print(output[0]['generated_text'])

Top-k nell'API Claude di Anthropic

L'API Claude di Anthropic espone top_k come parametro diretto. Ciò semplifica la sperimentazione dell'effetto del troncamento fisso del vocabolario sugli output di Claude.

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

# top_k limits the number of tokens considered
message = claude.messages.create(
    model='claude-opus-4-5',
    max_tokens=256,
    temperature=1.0,
    top_k=50,  # sample from top 50 most probable tokens
    messages=[{
        'role': 'user',
        'content': 'Write a short poem about debugging code.'
    }]
)
print(message.content[0].text)

Il problema di k fisso

Il limite fondamentale di top-k è che k è fisso, indipendentemente dal livello di sicurezza del modello in quel passaggio.

Quando il modello è molto sicuro (un token ha una probabilità del 95%), k=50 include comunque 49 token in gran parte irrilevanti. Quando il modello è molto incerto (50 token hanno ciascuno una probabilità di circa il 2%), k=50 può invece essere appropriato.

Il problema è che k=50 può essere contemporaneamente troppo restrittivo e troppo permissivo, a seconda del contesto. Top-p risolve il problema con una dimensione dinamica del nucleo.

# Illustrating the fixed-k problem
logits_confident = np.array([5.0] + [0.1] * 9)  # model is very sure
logits_uncertain = np.array([1.0] * 10)           # model has no idea

probs_conf = softmax(logits_confident)
probs_unc = softmax(logits_uncertain)

print('Confident — top 3 tokens cover:', np.sort(probs_conf)[::-1][:3].sum().round(3))
# ~0.998 — k=50 is extremely wasteful, includes near-zero probability tokens

print('Uncertain — top 3 tokens cover:', np.sort(probs_unc)[::-1][:3].sum().round(3))
# ~0.30 — k=50 may actually be needed to cover a reasonable nucleus

Top-k nelle code della distribuzione

Top-k e top-p differiscono soprattutto nelle code della distribuzione:

  • Con top-k=50, il cinquantesimo token potrebbe avere una probabilità dello 0.001% (estremamente improbabile, ma comunque presente nell'insieme dei candidati)
  • Con top-p=0.9, ogni token al di fuori del nucleo del 90% viene escluso, inclusi i token che rientrerebbero nei top-k

Top-p gestisce il comportamento della coda in modo più fondato: esclude i token improbabili in base alla probabilità, non alla posizione nella graduatoria.

# Tail behavior comparison
import numpy as np

# Highly skewed distribution (one dominant token)
skewed_logits = np.array([4.0, 2.0, 1.5, 1.0, 0.5,
                           0.1, 0.0, -0.1, -0.5, -1.0])
probs = softmax(skewed_logits)

print('Probability of tokens 6-9 (tail):')
for i in range(6, 10):
    print(f'  Token {i}: {probs[i]:.4%}')
# These tokens are very unlikely but are included in top-k=10
# Top-p=0.9 would exclude them entirely

Combinare top-k e top-p

Alcune implementazioni applicano sia top-k sia top-p: prima limitano ai top-k, poi applicano il nucleus sampling di top-p all'interno di quell'insieme. Ciò fornisce un limite massimo rigido alla dimensione del vocabolario (top-k), applicando al contempo un filtro basato sulla probabilità (top-p).

def top_k_top_p_sample(logits, k=50, p=0.9, temperature=1.0):
    probs = softmax(logits, temperature)

    # First apply top-k
    top_k_indices = np.argsort(probs)[::-1][:k]
    top_k_probs = probs[top_k_indices]

    # Then apply top-p within top-k
    sorted_k = np.sort(top_k_probs)[::-1]
    cumulative = np.cumsum(sorted_k)
    nucleus_size = np.searchsorted(cumulative, p) + 1

    final_indices = top_k_indices[:nucleus_size]
    final_probs = top_k_probs[:nucleus_size]
    final_probs = final_probs / final_probs.sum()

    return np.random.choice(final_indices, p=final_probs)

Quando preferire top-k a top-p

Nonostante i vantaggi teorici di top-p, in alcuni scenari si preferisce top-k:

  • Attività con vocabolario vincolato: quando il modello deve produrre output appartenenti solo a un insieme fisso (ad esempio, una scelta multipla A/B/C/D), un top-k ridotto (4) impone direttamente questo vincolo
  • Riproducibilità: il comportamento di top-k è più facile da prevedere: «considerare sempre esattamente 50 token»
  • Implementazioni ottimizzate per l'hardware: alcuni motori di inferenza implementano top-k in modo più efficiente di top-p
# Constrained output with top-k=4
# For a multiple choice task (A, B, C, D)
# If A/B/C/D tokens have indices 32, 33, 34, 35
# top-k=4 with those as the top-4 logits forces selection from those 4 only

multiple_choice_prompt = (
    'Answer with only A, B, C, or D.\n'
    'What is the capital of France?\n'
    'A) Berlin\n'
    'B) Paris\n'
    'C) Rome\n'
    'D) Madrid\n'
    'Answer:'
)

# With temperature=0, top_k=1: always picks the highest logit token

Indicazioni pratiche per top-k

Quando utilizzare top-k e quali valori scegliere:

  • k=1: greedy / attività fattuali
  • k=5–20: attività creative mirate, con variazione minima
  • k=40–100: intervallo creativo standard nella maggior parte dei modelli linguistici
  • k=500+: esplorazione molto libera (raramente necessaria; utilizzi invece top-p)

Nella maggior parte delle moderne API per LLM, il parametro preferito è top-p. Utilizzi top-k quando ha bisogno di un limite rigido al vocabolario o quando l'API lo espone ma non offre top-p.

TOP_K_GUIDELINES = {
    'factual_qa': 1,           # greedy
    'code_generation': 10,     # near-greedy, correct syntax
    'summarization': 20,       # slightly varied but focused
    'chat': 50,                # natural variation
    'creative_writing': 100,   # wider vocabulary exploration
    'poetry': 200,             # unusual word choices encouraged
}

def call_with_top_k(task, prompt, model='claude-opus-4-5'):
    k = TOP_K_GUIDELINES.get(task, 50)
    claude = anthropic.Anthropic(api_key='sk-ant-...')
    return claude.messages.create(
        model=model,
        max_tokens=512,
        top_k=k,
        messages=[{'role': 'user', 'content': prompt}]
    )

Top-k e temperatura insieme

Top-k e temperatura vengono applicati in sequenza: prima la temperatura rimodella la distribuzione dei logit, poi top-k la tronca ai k token più probabili. L'uso combinato di entrambi è comune nelle pipeline di Hugging Face Transformers.

Combinazione tipica: temperature=0.9 (diversità moderata) + top_k=50 (limite rigido al vocabolario). In questo modo si evitano sia la piattezza causata dall'uso della sola temperatura elevata, sia il problema del campionamento dalla coda.

from transformers import pipeline

generator = pipeline('text-generation', model='gpt2')

# Combined top-k + temperature
output = generator(
    'The future of AI is',
    max_new_tokens=80,
    do_sample=True,
    top_k=50,
    temperature=0.9
)
print(output[0]['generated_text'])

# Compare: top-k=1 (greedy)
greedy_output = generator(
    'The future of AI is',
    max_new_tokens=80,
    do_sample=False  # greedy, equivalent to top_k=1
)
print(greedy_output[0]['generated_text'])

Verifica delle conoscenze

Nel campionamento top-k, quale comportamento mostra il modello quando si imposta k=1?

Riepilogo: campionamento top-k

Il campionamento top-k tronca il vocabolario ai k token più probabili prima del campionamento:

  • k=1: decodifica greedy — deterministica, seleziona sempre il token principale
  • k=50: intervallo creativo tipico — equilibrio tra diversità e coerenza
  • Limitazione principale: k è fisso indipendentemente dal livello di confidenza del modello — può essere eccessivamente permissivo o restrittivo
  • Rispetto a top-p: il nucleo dinamico di top-p si adatta al livello di confidenza; top-k no

Utilizzi top-k quando Le serve un limite rigido al vocabolario. Preferisca top-p per la maggior parte delle applicazioni in produzione. Nella prossima lezione: come scegliere i parametri per il Suo caso d'uso specifico.

Domande Frequenti

La lezione «Sampling con top-k» è gratuita?

Sì — il testo completo di «Sampling con top-k» è 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 «Sampling con top-k»?

Limitare la scelta ai k token più probabili e analizzarne l’effetto sulla varietà dell’output 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 3 di 4.

Quanto tempo richiede la lezione «Sampling con top-k»?

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