Что такое Perplexity (PPL)? Как интерпретировать значение 100 или 50? Почему низкий PPL не гарантирует хорошего текста?
Краткий тезис
Perplexity (PPL) — это метрика для оценки вероятностных языковых моделей, показывающая, насколько модель «удивлена» тестовыми данными. Математически PPL определяется через экспоненту перекрёстной энтропии (или через энтропию), а на практике интерпретируется как среднее количество равновероятных вариантов, из которых модель «выбирает» следующий токен. PPL = 100 означает, что модель в среднем «колеблется» между сотней альтернатив; PPL = 50 — между пятьюдесятью. Однако низкое значение PPL не гарантирует осмысленность или фактическую правильность текста — модель может давать уверенные, но пустые или повторяющиеся ответы (так называемые boring outputs), особенно при обучении на зашумленных или однородных данных.
2. Интерпретация PPL: среднее число вариантов на токен
PPL интуитивно понимается как «сколькими равновероятными вариантами можно заменить следующий токен». Если модель равномерно сомневается между K словами, энтропия равна log2(K), а PPL = 2^{log2(K)} = K. Таким образом:
- PPL = 1 → модель абсолютно уверена (всегда выбирает единственно возможный следующий токен).
- PPL = 50 → модель ведёт себя так, будто на каждом шаге у неё есть 50 равновероятных кандидатов.
- PPL = 100 → 100 равноправных альтернатив.
Важное замечание: на практике распределение модели не является равномерным по K вариантам; это эффективное среднее, усреднённое по всем токенам корпуса. Чем выше PPL, тем менее «предсказуем» текст с точки зрения модели. Для хорошо обученной языковой модели на естественном языке PPL обычно составляет от 20 до 100, в зависимости от размера модели и сложности домена.
Пример: если модель обучена на новостях и получает PPL=40, это значит, что при генерации новостного текста она «не удивляется» примерно так же, как если бы ей приходилось выбирать из 40 равновероятных слов на каждом шаге. Для технической документации PPL может быть ниже (например, 20) из-за более предсказуемых паттернов.
| PPL | Интерпретация | Пример контекста |
|---|---|---|
| 1 | Идеальное предсказание (вырожденный случай) | Тексты с однозначным шаблоном |
| 10 | Средняя неопределённость ≈ 10 слов | Простые фразы (e.g., "Hello") |
| 50 | Умеренная сложность; 50 равновероятных вариантов | Осмысленный текст на естественном языке |
| 100 | Высокая неопределённость; модель «блуждает» | Смешанный жанр, редкие слова |
| >200 | Очень низкая уверенность; почти случайный текст | Недоученная модель или чужеродный домен |
3. PPL = 100: что это значит практически?
Значение PPL = 100 указывает, что модель в среднем «выбирает» следующий токен из сотни примерно равновероятных альтернатив. Это можно интерпретировать в разных сценариях:
- Для генерации текста (авторегрессивные модели): при PPL = 100 качество сэмплированного текста обычно низкое — много грамматических ошибок, несвязные фразы, повторения. Если модель обучена на достаточно чистом корпусе, PPL=100 говорит либо о маленьком размере модели, либо о несовпадении домена (например, модель обучена на книгах, а тестируется на коде).
- Для N-граммных моделей: в классической N-граммной модели (например, 5-граммы) PPL=100 на новостном корпусе считается посредственным. Хорошая N-граммная модель достигает PPL ≈ 50–70 на английском.
- Сравнение моделей: если модель A имеет PPL=100, а модель B — PPL=50, то B в среднем увереннее в два раза (эквивалентно уменьшению числа вариантов вдвое). Однако это не всегда означает, что B генерирует более осмысленный текст.
Пример из практики: при тестировании GPT-2 (124M) на Wikitext-2 значение PPL составляло около 40. Модель размером 1.5B давала около 25. Значение 100 характерно для слабых моделей (например, односторонний LSTM с небольшим скрытым слоем).
# Вычисление PPL для bigram модели (игрушечный пример)
class BigramModel:
def __init__(self, corpus):
self.counts = defaultdict(lambda: defaultdict(int))
# ... обучение ...
def ppl(self, test_sequence):
log_prob = 0.0
n = len(test_sequence) - 1
for i in range(n):
ctx = test_sequence[i]
tok = test_sequence[i+1]
prob = self.counts[ctx][tok] / sum(self.counts[ctx].values())
log_prob += -np.log(prob + 1e-10)
return np.exp(log_prob / n)
4. Почему низкий PPL не гарантирует хорошего текста?
Низкое Perplexity свидетельствует о том, что модель присваивает высокие вероятности тестовым последовательностям. Однако это может происходить за счёт нежелательных свойств:
4.1. Выученные повторы и шаблоны
Модель может «выучить» тривиальные повторяющиеся фразы (например, «Итак, далее итак, далее»). Такие последовательности имеют высокую вероятностную оценку модели, но с точки зрения человека они бессмысленны. Причина — обучающие данные могли содержать множество повторяющихся паттернов, или модель переобучилась на короткие контексты.
4.2. Игнорирование глобальной семантики
PPL вычисляется локально, позлементно. Модель может давать высокие вероятности отдельным токенам, но при этом порождать логически противоречивый или фактически неверный текст. Например:
- Вопрос: «Какого цвета небо?» → Ответ: «Небо зелёное, потому что оно отражает траву.» Модель уверена в каждом слове (низкий PPL), но ответ ошибочен.
4.3. Безопасность и фактологичность
Низкое PPL не коррелирует с правдивостью. В тестах на фактическую точность (например, TruthfulQA) модели с лучшим PPL не всегда показывают лучшие результаты.
4.4. Скучные и безопасные ответы
Для избежания высоких потерь модель может выбирать «безопасные» продолжения: общие фразы, шаблоны, уход от специфики. Это приводит к низкому PPL, но порождает пресные, малоинформативные ответы — эффект «boring but confident».
Итог: PPL остаётся полезной метрикой для оценки качества обучения (чем ниже, тем лучше модель предсказывает выборку), но для оценки сгенерированного текста необходимы дополнительные метрики: BLEU, ROUGE, человеческая оценка, а также специальные метрики фактической корректности.
5. Пет-проект для закрепления
Задача: Реализовать простой калькулятор Perplexity для N-граммной модели на небольшом корпусе (например, русскоязычные новости) и проанализировать, как PPL меняется при добавлении повторов в тестовые данные.
Инструменты: Python, collections.Counter, numpy, любой текстовый корпус (например, news.2017.ru из Corpus).
Шаги:
- Загрузить корпус, разбить на токены (используя токенизатор по пробелам или морфологический анализатор).
- Обучить тригграмную модель с лапласовским сглаживанием (add-k).
- Вычислить PPL на тестовом наборе (без повторений).
- Искусственно добавить в тестовый набор повторяющиеся фразы (например, «кот кот кот» или целые предложения).
- Снова вычислить PPL; заметить, что PPL снизится (модель «рада» повторениям), но текст стал хуже.
- Сделать вывод: низкий PPL ≠ хороший текст.
Ожидаемый результат: Понять на практике, что PPL чувствителен к повторяющимся паттернам, и что он не отражает смысловую связность.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 923 | Perplexity (данный разбор) |
| 658 | Обзор метрик (BLEU, ROUGE, Perplexity и др.) |
Навигация
- Предыдущий: 922
- Следующий: 924
- Индекс: 00. Индекс разборов