0Pricing
AI Prompt Engineering · Урок

Выборка 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:

  1. Вычислите вероятности softmax для всего словаря
  2. Отсортируйте токены по убыванию вероятности
  3. Оставьте только k наиболее вероятных токенов, а всем остальным присвойте значение 0
  4. Перенормируйте вероятности top-k так, чтобы их сумма была равна 1
  5. Выполните выборку из перенормированного распределения
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 nucleus

Top-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 — локальная установка не требуется.

Все уроки этого курса

  1. Что такое температура в LLM
  2. Выборка по ядру top-p
  3. Выборка top-k
  4. Выбор параметров для вашего сценария
← Назад к AI Prompt Engineering