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

Этот урок объясняет главную идею: всё, что делает 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Токены — это всегда отдельные буквы
Поддержать проект