Выборка top-k
Ограничение выбора k наиболее вероятными токенами и влияние этого параметра на разнообразие результатов.
«Выборка top-k» — бесплатный урок AI Prompt Engineering на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Prompt Engineering, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Prompt Engineering содержит 4 уроков всего.
Что такое выборка top-k?
Выборка top-k ограничивает модель выборкой из k наиболее вероятных токенов на каждом шаге. Всем токенам за пределами top-k присваивается нулевая вероятность, поэтому их нельзя выбрать.
k=1 — это жадное декодирование (только один наиболее вероятный токен). k=50 — типичный диапазон для творческих задач. k=размер словаря эквивалентно выборке без ограничений.
Алгоритм top-k
Алгоритм проще, чем у top-p:
- Вычислите вероятности softmax для всего словаря
- Отсортируйте токены по убыванию вероятности
- Оставьте только k наиболее вероятных токенов, а всем остальным присвойте значение 0
- Перенормируйте вероятности top-k так, чтобы их сумма была равна 1
- Выполните выборку из перенормированного распределения
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: жадное декодирование
При k=1 в набор кандидатов входит только один наиболее вероятный токен. Выборка из набора размера 1 является детерминированной — модель всегда выбирает этот токен. Это идентично жадному декодированию (температура=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Типичный диапазон для творческих задач: k=50
k=50 — распространённое значение по умолчанию для генерации творческого текста. Оно позволяет выбирать из 50 токенов на каждом шаге, не давая модели выбирать токены, в которых она почти не уверена.
При словаре из 50 000 токенов значение k=50 означает, что на каждом шаге модель рассматривает только верхние 0,1% токенов. Это серьёзное ограничение: большая часть словаря исключается.
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 в API Anthropic Claude
API Anthropic Claude предоставляет top_k как отдельный параметр. Это упрощает эксперименты с влиянием фиксированного обрезания словаря на результаты 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)Проблема фиксированного k
Главное ограничение top-k: k фиксировано независимо от уверенности модели на данном шаге.
Когда модель очень уверена (вероятность одного токена составляет 95%), k=50 всё равно включает 49 практически не относящихся к делу токенов. Когда модель очень не уверена (вероятность каждого из 50 токенов составляет около 2%), k=50 действительно может быть подходящим значением.
Проблема в том, что k=50 в зависимости от контекста может одновременно быть слишком ограничивающим и слишком свободным. Top-p решает эту проблему с помощью динамического размера ядра.
# 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 nucleusTop-k в хвостах распределения
Различие между top-k и top-p наиболее заметно в хвостах распределения:
- При top-k=50 вероятность 50-го токена может составлять 0,001% (он крайне маловероятен, но всё ещё входит в набор кандидатов)
- При top-p=0.9 исключается любой токен за пределами ядра, содержащего 90% вероятности, включая токены, которые вошли бы в top-k
Top-p более обоснованно обрабатывает хвост распределения: маловероятные токены исключаются на основе вероятности, а не позиции в рейтинге.
# 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Совместное использование top-k и top-p
Некоторые реализации применяют одновременно top-k и top-p: сначала ограничивают выборку top-k, а затем применяют выборку по ядру top-p внутри полученного набора. Это обеспечивает жёсткое ограничение размера словаря (top-k) и одновременно фильтрацию на основе вероятности (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)Когда top-k предпочтительнее top-p
Несмотря на теоретические преимущества top-p, в некоторых случаях предпочтителен top-k:
- Задачи с ограниченным словарём: когда модель должна выдавать результат только из фиксированного набора, например при выборе одного из вариантов A/B/C/D, небольшое значение top-k (4) напрямую обеспечивает это ограничение
- Воспроизводимость: поведение top-k проще анализировать — «всегда рассматриваются ровно 50 токенов»
- Реализации, оптимизированные для аппаратного обеспечения: некоторые механизмы выполнения вывода реализуют top-k эффективнее, чем 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Практические рекомендации по top-k
Когда использовать top-k и какие значения выбирать:
- k=1: жадный режим / фактические задачи
- k=5–20: сфокусированные творческие задачи, минимальная вариативность
- k=40–100: стандартный диапазон для творческих задач в большинстве языковых моделей
- k=500+: очень свободное исследование вариантов (требуется редко; вместо этого используйте top-p)
В большинстве современных API для LLM предпочтительным параметром является top-p. Используйте top-k, когда нужно жёстко ограничить словарь или когда API предоставляет top-k, но не 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}]
)Топ-k и температура вместе
Топ-k и температура применяются последовательно: сначала температура изменяет распределение логитов, затем топ-k усекает его до k наиболее вероятных токенов. Использование обоих параметров вместе распространено в конвейерах Hugging Face Transformers.
Обычно используют сочетание: температура = 0,9 (умеренное разнообразие) + k = 50 (жёсткое ограничение словаря). Это позволяет избежать как однообразия, свойственного одной лишь высокой температуре, так и проблемы выборки из хвоста распределения.
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'])Проверка знаний
Какое поведение демонстрирует модель при выборке топ-k, если задано k=1?
Повторение: выборка топ-k
При выборке топ-k словарь перед выборкой усекается до k наиболее вероятных токенов:
- k=1: жадное декодирование — детерминированный режим, всегда выбирается самый вероятный токен
- k=50: типичный диапазон для творческих задач — сбалансированные разнообразие и связность
- Ключевое ограничение: k фиксировано независимо от уверенности модели — ограничение может оказаться слишком мягким или слишком жёстким
- В сравнении с топ-p: динамическое ядро топ-p подстраивается под уверенность модели, а топ-k — нет
Используйте топ-k, когда требуется жёстко ограничить словарь. Для большинства производственных приложений предпочтительнее топ-p. На следующем уроке Вы узнаете, как выбирать параметры для конкретного варианта использования.
Часто задаваемые вопросы
Урок «Выборка top-k» бесплатный?
Да — полный текст урока «Выборка top-k» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Prompt Engineering, подпишись на CoddyKit PRO. Курс AI Prompt Engineering содержит 4 уроков всего.
Чему я научусь в уроке «Выборка top-k»?
Ограничение выбора k наиболее вероятными токенами и влияние этого параметра на разнообразие результатов. Ты практикуешь AI Prompt Engineering с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Prompt Engineering?
Предыдущий опыт не требуется. AI Prompt Engineering на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Выборка top-k»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Prompt Engineering?
Да. Каждый урок AI Prompt Engineering включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.