Что такое 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 | Делит логит каждого ранее встреченного токена на константу >1 | 1.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 size (в transformers:
no_repeat_ngram_size) — запрещает появление любой n-граммы, которая уже встречалась. Жёстче, но может ломать грамматику. - Diverse beam search — модификация beam search, поощряющая разнообразие между лучами.
- Contrastive search (SimCTG) — метод, который одновременно максимизирует вероятность и минимизирует сходство с предыдущими токенами.
8. Пет-проект для закрепления
Задача: Создать скрипт, который сравнивает влияние repetition penalty на генерацию текста для заданной модели.
Инструменты: Python, Hugging Face Transformers, Matplotlib (для визуализации).
Шаги:
- Выберите модель (например,
gpt2илиmicrosoft/DialoGPT-medium). - Задайте фиксированный промпт (например, «Artificial intelligence is»).
- Сгенерируйте 5 вариантов текста с разными значениями
repetition_penalty: 1.0, 1.1, 1.2, 1.5, 2.0. Остальные параметры зафиксируйте (temperature=0.9,top_k=50). - Для каждого варианта посчитайте метрики разнообразия:
- Distinct-1 (доля уникальных униграмм).
- Distinct-2 (доля уникальных биграмм).
- Количество повторяющихся n-грамм (например, триграмм).
- Постройте график зависимости метрик от repetition penalty.
- Выведите примеры текстов для каждого значения.
Ожидаемый результат: Вы увидите, что с ростом 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. Навигация
- Предыдущий: 678
- Следующий: 680
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 678
- Следующий: 680
- Индекс: 00. Индекс разборов