中文翻译暂不可用,显示俄语原文。

Что такое repetition penalty и как он работает?

Краткий тезис

Repetition penalty (штраф за повторение) — это механизм, применяемый на этапе декодирования (decoding) в LLM, который снижает вероятность повторного выбора уже сгенерированных токенов. Он работает путём деления логита (logit) каждого ранее появившегося токена на коэффициент больше 1 (например, 1.2) на каждом шаге генерации. Это предотвращает зацикливание (например, «I love you love you love you») и улучшает разнообразие текста, особенно в длинных генерациях.


1. Термин: Логит и декодирование

Логит (logit) — это сырой выход последнего слоя нейросети перед softmax. Он не нормирован и может быть любым вещественным числом. Чем больше логит, тем выше вероятность токена после softmax.

Декодирование — процесс пошагового выбора следующего токена из распределения вероятностей, полученного из логитов. Основные стратегии: жадный поиск (greedy), семплинг (sampling) с temperature, top-k, top-p и repetition penalty.

Repetition penalty модифицирует логиты до применения softmax, тем самым влияя на итоговое распределение.


2. Формула и механизм работы

На каждом шаге генерации для каждого токена t в словаре вычисляется скорректированный логит:

logit[t] = logit[t] / penalty[t]

где penalty[t] — коэффициент штрафа для токена t. Обычно:

  • Если токен уже встречался в сгенерированной последовательности, то penalty[t] = repetition_penalty (значение > 1, например 1.2).
  • Если токен не встречался, то penalty[t] = 1.0 (без изменений).

Пример (упрощённо):

Пусть словарь: {a: 2.0, b: 1.5, c: 0.5}, уже сгенерирован токен a. Зададим repetition_penalty = 2.0.

  • Для a: logit = 2.0 / 2.0 = 1.0
  • Для b: logit = 1.5 / 1.0 = 1.5
  • Для c: logit = 0.5 / 1.0 = 0.5

После softmax вероятность a снизится, а b станет наиболее вероятным.

Важно: Штраф применяется на каждом шаге к всем ранее сгенерированным токенам. Чем чаще токен встречался, тем сильнее его логит делится (если штраф накапливается — см. вариант frequency penalty).


3. Отличие от frequency penalty и presence penalty

Repetition penalty — один из трёх популярных штрафов. Они различаются способом учёта повторений:

ПараметрДействиеТипичное значение
Repetition penaltyДелит логит каждого ранее встреченного токена на константу >11.0–2.0
Frequency penaltyВычитает из логита каждого токена величину, пропорциональную его частоте в сгенерированном тексте0.0–2.0
Presence penaltyВычитает константу из логита токена, если он уже появлялся (независимо от числа повторений)0.0–2.0

Пример (логит = 2.0, токен встречался 3 раза, penalty = 1.5):

  • Repetition: 2.0 / 1.5 ≈ 1.33
  • Frequency: 2.0 - 1.5 * 3 = 2.0 - 4.5 = -2.5 (сильное наказание)
  • Presence: 2.0 - 1.5 = 0.5

Когда какой использовать:

  • Repetition penalty — универсальный, хорошо предотвращает зацикливание.
  • Frequency penalty — жёстче наказывает частые токены, полезен для длинных текстов.
  • Presence penalty — поощряет появление новых токенов, но не штрафует за многократные повторы.

4. Влияние на качество генерации

Repetition penalty — это компромисс между разнообразием (diversity) и связностью (coherence).

  • Слишком низкий (1.0) — модель может зацикливаться, повторять одни и те же фразы.
  • Слишком высокий (>2.0) — модель начинает избегать любых повторений, даже естественных (например, «the» в английском), что приводит к неестественному, «рваному» тексту.
  • Оптимальный диапазон — 1.05–1.3 для большинства моделей (GPT, LLaMA).

Эксперимент (на примере генерации продолжения фразы «The cat sat on the»):

Repetition penaltyПродолжение
1.0 (без штрафа)«the mat the mat the mat» (зацикливание)
1.2«mat and looked around» (хорошо)
2.0«mat, then jumped, then ran, then hid» (неестественные перескоки)

5. Реализация в коде (Hugging Face Transformers)

В библиотеке transformers repetition penalty реализован в классе LogitsProcessor. Пример:

from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

model_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)

input_text = "Once upon a time"
inputs = tokenizer(input_text, return_tensors="pt")

# Генерация с repetition_penalty
output = model.generate(
    **inputs,
    max_new_tokens=50,
    repetition_penalty=1.2,       # основной параметр
    do_sample=True,               # включаем семплинг
    temperature=0.9,
    top_k=50,
    top_p=0.95
)

print(tokenizer.decode(output[0], skip_special_tokens=True))

Внутренняя работа (упрощённо):

class RepetitionPenaltyLogitsProcessor:
    def __init__(self, penalty: float):
        self.penalty = penalty

    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor) -> torch.FloatTensor:
        # input_ids: [batch, seq_len] — уже сгенерированные токены
        # scores: [batch, vocab_size] — логиты
        for batch_idx in range(scores.shape[0]):
            for token_id in input_ids[batch_idx]:
                if scores[batch_idx, token_id] < 0:
                    scores[batch_idx, token_id] *= self.penalty
                else:
                    scores[batch_idx, token_id] /= self.penalty
        return scores

Обратите внимание: для отрицательных логитов штраф применяется как умножение (чтобы не менять знак), для положительных — деление.


6. Взаимодействие с другими параметрами декодирования

Repetition penalty не работает изолированно. Его эффект зависит от:

  • Temperature: высокая температура (>1) сглаживает распределение, штраф становится менее заметен; низкая (<1) — наоборот, усиливает.
  • Top-k / Top-p: если семплинг ограничен небольшим набором токенов, штраф может быть неэффективен, если все кандидаты уже повторялись.
  • Beam search: при лучевом поиске repetition penalty применяется к каждому лучу отдельно, что может приводить к разным эффектам.

Рекомендация: настраивать repetition penalty в паре с temperature. Например, для креативных задач (поэзия) — penalty 1.1–1.2 + temperature 0.9–1.0; для фактологических (пересказ) — penalty 1.0–1.05 + temperature 0.7.


7. Ограничения и альтернативы

Ограничения:

  • Не различает синтаксические и лексические повторы. Например, в предложении «He said that he would come» повтор «he» естественен, но штраф всё равно снизит его вероятность.
  • Может ухудшить копирование (copying) из контекста в задачах RAG, где нужно дословно воспроизвести факт.
  • Не решает проблему глобальных повторяющихся паттернов (например, модель может начать каждое предложение с «However»).

Альтернативы:

  • No-repeat n-gram sizetransformers: no_repeat_ngram_size) — запрещает появление любой n-граммы, которая уже встречалась. Жёстче, но может ломать грамматику.
  • Diverse beam search — модификация beam search, поощряющая разнообразие между лучами.
  • Contrastive search (SimCTG) — метод, который одновременно максимизирует вероятность и минимизирует сходство с предыдущими токенами.

8. Пет-проект для закрепления

Задача: Создать скрипт, который сравнивает влияние repetition penalty на генерацию текста для заданной модели.

Инструменты: Python, Hugging Face Transformers, Matplotlib (для визуализации).

Шаги:

  1. Выберите модель (например, gpt2 или microsoft/DialoGPT-medium).
  2. Задайте фиксированный промпт (например, «Artificial intelligence is»).
  3. Сгенерируйте 5 вариантов текста с разными значениями repetition_penalty: 1.0, 1.1, 1.2, 1.5, 2.0. Остальные параметры зафиксируйте (temperature=0.9, top_k=50).
  4. Для каждого варианта посчитайте метрики разнообразия:
    • Distinct-1 (доля уникальных униграмм).
    • Distinct-2 (доля уникальных биграмм).
    • Количество повторяющихся n-грамм (например, триграмм).
  5. Постройте график зависимости метрик от repetition penalty.
  6. Выведите примеры текстов для каждого значения.

Ожидаемый результат: Вы увидите, что с ростом penalty увеличивается Distinct-1 и Distinct-2, но при слишком высоких значениях текст становится бессвязным. Оптимум — около 1.1–1.3.


9. Связь с другими вопросами

ВопросТема
678Что такое temperature и как он влияет на генерацию?
680Как работают top-k и top-p sampling?
681Что такое beam search и чем отличается от greedy decoding?
682Как настроить параметры генерации для RAG-системы?
683Что такое contrastive search и когда его применять?
684Как бороться с галлюцинациями в LLM?

10. Навигация


Навигация