Языковая модель как предсказатель следующего токена

Этот урок объясняет главную идею: всё, что делает ChatGPT или Claude, вырастает из одной задачи — угадать следующий кусочек текста.

Языковая модель (language model) — это функция, которая по уже написанному тексту оценивает вероятность каждого возможного следующего токена.

Одна задача, из которой растёт всё

Кажется, что чат-бот «понимает вопрос», «рассуждает» и «отвечает». Но под капотом происходит нечто куда более скромное и механическое: модель снова и снова отвечает на один и тот же вопрос — «какой токен идёт дальше?». Возьмите фразу «Москва — столица», и модель оценит, что после неё вероятнее всего стоит «России», а не «банана». Затем она добавляет этот токен к тексту и спрашивает себя то же самое заново. Так, шаг за шагом, рождается целый ответ.

Это называется авторегрессией: каждый новый токен предсказывается на основе всех предыдущих, включая только что сгенерированные. Магии диалога нет — есть очень хорошо настроенный угадыватель продолжений.

Почему «токен», а не «слово»

Дальше в курсе мы посвятим токенизации целый раздел, но запомните сразу: модель работает не со словами и не с буквами, а с токенами — кусочками текста (часто это части слов). Слово «предсказание» может разбиться на «пред», «сказ», «ание». Для модели текст — это последовательность номеров токенов из заранее построенного словаря.

Что значит «вероятность следующего токена»

На каждом шаге модель выдаёт не один ответ, а целое распределение вероятностей по всему словарю (это десятки тысяч токенов). Грубую интуицию можно получить даже без нейросети — на простой статистике. Посчитаем, какое слово чаще шло следом за данным в маленьком тексте.

from collections import defaultdict, Counter

corpus = (
    "я люблю котов я люблю собак я люблю писать код "
    "ты любишь котов ты любишь чай"
).split()

# Биграммная модель: для каждого слова считаем, какое слово шло следом.
bigram = defaultdict(Counter)
for a, b in zip(corpus, corpus[1:]):
    bigram[a][b] += 1

def predict(word):
    if word not in bigram:
        return None, []
    options = bigram[word]
    total = sum(options.values())
    ranked = [(w, c / total) for w, c in options.most_common()]
    return ranked[0][0], ranked

for w in ("я", "люблю", "ты"):
    best, ranked = predict(w)
    dist = ", ".join(f"{x}={p:.2f}" for x, p in ranked)
    print(f"после '{w}' -> вероятнее всего '{best}'  ({dist})")

Вывод:

после 'я' -> вероятнее всего 'люблю'  (люблю=1.00)
после 'люблю' -> вероятнее всего 'котов'  (котов=0.33, собак=0.33, писать=0.33)
после 'ты' -> вероятнее всего 'любишь'  (любишь=1.00)

Видно главное: ответ — это не «то самое правильное слово», а ранжированный список кандидатов с вероятностями. После «люблю» в нашем тексте три равновероятных продолжения. Большая модель делает то же самое, только опираясь не на пару фраз, а на закономерности из триллионов слов.

Откуда берётся «понимание»

Чтобы хорошо предсказывать следующий токен в произвольном тексте, модели приходится неявно выучить очень многое: грамматику, факты о мире, логические связи, стиль, даже умение продолжать рассуждение. Предсказание следующего токена — это лишь цель обучения. А чтобы её достичь на гигантском разнообразии текстов, модель вынуждена построить внутри себя богатое представление языка и мира. Отсюда и возникает то, что мы воспринимаем как «понимание».

Итог

  • Языковая модель оценивает вероятность каждого следующего токена по предыдущему тексту.
  • Текст генерируется авторегрессивно: токен за токеном, каждый раз заново.
  • На выходе — распределение вероятностей по словарю, а не единственный ответ.
  • «Понимание» — побочный продукт того, что хорошо предсказывать текст без него невозможно.
Проверьте себя
1. Какую задачу решает языковая модель на каждом шаге генерации?
AПредсказывает вероятности следующего токена по предыдущему тексту
BПереводит текст с одного языка на другой
CИщет точный ответ в базе данных
DСжимает текст в короткое резюме
2. Что означает, что генерация авторегрессивна?
AМодель генерирует весь ответ сразу одним вызовом
BКаждый новый токен предсказывается с учётом всех предыдущих, включая уже сгенерированные
CМодель использует регрессию вместо классификации
DТекст пишется с конца к началу
3. Почему модель работает с токенами, а не со словами?
AТак требует процессор
BСлова занимают слишком много памяти
CТокены — это куски текста (часто части слов), удобные как единицы из фиксированного словаря
DТокены — это всегда отдельные буквы