Что такое языковая модель
Языковая модель как распределение над текстами, цепное правило и авторегрессия, n-граммы и их пределы, и как из «предсказателя следующего токена» вырастают ChatGPT и DeepSeek.
Зачем это нужно
Заголовок раздела «Зачем это нужно»ChatGPT, DeepSeek, Qwen и Kimi устроены по-разному, но внутри у всех крутится один и тот же цикл. Модель получает текст, выдаёт вероятности следующего токена, из них выбирается один токен, он дописывается в конец текста, и всё повторяется. Ответ на вопрос, код, рассуждение DeepSeek-R1 длиной в тысячи токенов — всё это собирается по одному кусочку.
Штука, которая выдаёт эти вероятности, называется языковая модельязыковая модельEN language model (LM)Распределение вероятностей над последовательностями токенов. На практике — функция «контекст → вероятности следующего токена».. Это центральное понятие всей ступени: дальше мы построим языковую модель на подсчётах (урок 2), научимся генерировать из неё текст (урок 3), а к концу ступени соберём GPT с нуля. Сегодня — фундамент: что именно модель предсказывает, почему достаточно предсказывать только следующий токен, и как из такого «автодополнения» получается ассистент.
Языковая модель — это распределение над текстами
Заголовок раздела «Языковая модель — это распределение над текстами»Пусть текст — это последовательность токеновтокенEN tokenВ разговорной речи и статьях китайцы чаще всего пишут просто «token». из словаря размера . Как текст режется на токены, разберём в модуле 4.2; пока считайте токеном слово или букву.
Языковая модель назначает каждой последовательности вероятность . Хорошая модель даёт высокую вероятность осмысленным текстам и низкую — бессмыслице:
| Текст | Хорошая модель скажет |
|---|---|
| «кот спит на диване» | довольно вероятно |
| «диване на спит кот» | маловероятно: порядок слов странный |
| «кот спит на квазаре» | маловероятно: грамматика в порядке, смысл — нет |
| «он пошёл в магазин за хлебам» | менее вероятно, чем «за хлебом» |
Такие оценки нужны не только чат-ботам. Распознавание речи выбирает из акустически похожих вариантов самый правдоподобный, проверка орфографии предлагает исправление, машинный перевод выбирает естественный порядок слов. Десятилетиями языковые модели работали именно «оценщиками», а не генераторами.
Сразу видна проблема: возможных текстов астрономически много. Даже при словаре в слов предложений из 10 слов . Таблицу «текст → вероятность» не построить, нужен способ разложить задачу на части.
Цепное правило: текст по одному токену
Заголовок раздела «Цепное правило: текст по одному токену»Из теории вероятностей (модуль 1.3) мы знаем, что . Применяя это правило снова и снова, получаем цепное правило вероятностицепное правило вероятностиEN chain rule of probabilityP(x₁, …, x_T) = ∏ P(x_t | x₁, …, x_{t−1}). Точное тождество, а не приближение.:
Здесь — все токены до позиции (контекст). У первого токена контекст пуст, поэтому первый множитель — просто : насколько вероятно, что текст начинается с этого токена. Пример с выдуманными, но правдоподобными числами:
Обратите внимание на третий множитель: после «мама мыла» слово «раму» очень вероятно, потому что фраза знакома каждому, кто учился читать по русскому букварю. Модель, которая это «знает», даст фразе высокую вероятность.
На практике перемножать маленькие числа неудобно, поэтому берут логарифмы и складывают: . В среднем на токен это , а перплексияперплексияEN perplexity (модуль 1.3): модель в среднем «колеблется» между ~19 вариантами. Средний на токен — это та же перекрёстная энтропияперекрёстная энтропияEN cross-entropy из модуля 1.3.
Главный вывод: цепное правило — точное тождество, а не приближение. Чтобы задать вероятность любого текста, достаточно уметь для любого контекста выдавать распределение следующего токена. Поэтому вся задача языкового моделирования сводится к предсказание следующего токенапредсказание следующего токенаEN next-token predictionГлавная задача языковой модели — по началу текста оценить вероятности следующего токена. Ответ чат-бота собирается из таких шагов по одному токену.: это обычная классификация на классов, где классы — токены словаря, а признаки — весь предыдущий текст. Логиты, softmax и cross-entropy вы уже умеете считать.
Авторегрессия: генерация по одному токену
Заголовок раздела «Авторегрессия: генерация по одному токену»Если модель умеет выдавать , генерировать текст просто:
flowchart LR A["Контекст: «Мама мыла»"] --> B["Языковая модель"] B --> C["P(следующий токен)<br/>раму 0.3, посуду 0.2, …"] C --> D["Выбрать токен<br/>(урок 3)"] D --> E["Дописать «раму»<br/>в контекст"] E -->|"повторять до конца текста"| B
Такая модель называется авторегрессионнойавторегрессионная модель (авторегрессия)EN autoregressive modelГенерирует последовательность по одному элементу, подавая каждый сгенерированный токен обратно на вход. Так работают GPT, Qwen, DeepSeek.: «регрессия на саму себя», каждый следующий элемент предсказывается по предыдущим собственным выходам. Термин пришёл из анализа временных рядов, где AR-модели предсказывают значение по прошлым значениям того же ряда. GPT, Llama, Qwen, DeepSeek — все авторегрессионные.
Как такую модель учат
Заголовок раздела «Как такую модель учат»Генерация последовательная, а обучение — нет. Из одного текста получается столько обучающих примеров, сколько
в нём токенов. Возьмём «мама мыла раму .» и служебный токен начала <s>:
| Вход (контекст) | Правильный ответ |
|---|---|
<s> | мама |
<s> мама | мыла |
<s> мама мыла | раму |
<s> мама мыла раму | . |
Входы и ответы — один и тот же текст, сдвинутый на одну позицию. Модель видит настоящий префикс, а не свои предсказания; такой режим называется teacher forcingteacher forcing (обучение на верном префиксе)EN teacher forcingПри обучении модель на каждом шаге видит настоящий текст, а не свои предсказания. Поэтому все позиции можно обучать параллельно.. Благодаря ему все позиции считаются за один проход: трансформер с причинной маскойпричинная (каузальная) маскаEN causal maskЗапрещает токену смотреть на будущие позиции — оценки выше диагонали заменяются на −∞ до softmax. Нужна, чтобы GPT-подобная модель училась предсказывать следующий токен на всех позициях сразу. (модуль 4.4) не даёт позиции подсмотреть будущие токены, и мы получаем предсказаний сразу. Loss — средняя cross-entropy по всем позициям.
Масштаб впечатляет: DeepSeek-V3 обучали на 14.8 трлн токенов — это 14.8 трлн задачек «угадай следующий токен».
N-граммы: первая рабочая языковая модель
Заголовок раздела «N-граммы: первая рабочая языковая модель»Контекст растёт с длиной текста, и запомнить распределение для каждого возможного контекста нельзя. Классическое решение — марковское допущениемарковское допущениеEN Markov assumptionСледующий токен зависит только от n−1 предыдущих. На нём построены n-граммные модели.: будем считать, что следующий токен зависит только от предыдущих.
Последовательность из соседних токенов называется n-граммаn-граммаEN n-gramПоследовательность из n подряд идущих токенов. В d2l-zh — буквально «одноэлементная», «двухэлементная» и «трёхэлементная грамматика» (unigram, bigram, trigram).. При получаем биграммнуюбиграммаEN bigramПара соседних токенов. Биграммная модель оценивает P(x_t | x_{t−1}) — таблица V × V. модель , при — триграммную. Обучение сводится к подсчёту — это и есть метод максимального правдоподобия из модуля 1.3:
Если «мама» встретилась в корпусе 4 раза, а «мама мыла» — 2 раза, то . С 1980-х до начала 2010-х n-граммные модели работали внутри систем распознавания речи и статистического машинного перевода, а к концу этой эпохи их обучали на корпусах из сотен миллиардов и даже триллионов слов. Но у них три фундаментальные проблемы.
Проблема 1: разреженность
Заголовок раздела «Проблема 1: разреженность»При словаре возможных биграмм , а триграмм . Даже корпус в триллион слов покрывает ничтожную долю, причём частоты распределены по закону Ципфазакон ЦипфаEN Zipf's lawЧастота слова примерно обратно пропорциональна его месту в частотном списке, поэтому немногие частые слова покрывают большую часть любого текста.: несколько n-грамм встречаются постоянно, а огромный «хвост» — один-два раза или никогда. Это разреженность данныхразреженность данныхEN data sparsityБольшинство возможных n-грамм ни разу не встречается в корпусе, и подсчёт даёт им вероятность 0..
Невиданная n-грамма получает вероятность ноль, а с ней и весь текст. Если в корпусе не было «мыла машину», модель объявит фразу «мама мыла машину» невозможной, хотя в ней нет ничего странного. Лечат это сглаживанием — подробно в следующем уроке.
Проблема 2: короткий контекст
Заголовок раздела «Проблема 2: короткий контекст»Чтобы выбрать окончание, иногда нужно заглянуть далеко назад:
«Девушка, с которой я познакомился вчера на остановке у старого кинотеатра, оказалась …»
Род глагола «оказалась» определяется словом, от которого его отделяют 10 слов. Триграммная модель, выбирая следующее слово, видит только два предыдущих — «старого кинотеатра» — и не может знать, нужно «оказался» или «оказалась». Увеличить нельзя: число возможных n-грамм и разреженность растут экспоненциально.
Проблема 3: нет обобщения
Заголовок раздела «Проблема 3: нет обобщения»Пусть в корпусе есть «кот ест рыбу», но нет «кошка ест рыбу». Для n-граммной модели «кот» и «кошка» — два несвязанных символа, и знание про кота никак не переносится на кошку. Человек же понимает, что слова похожи.
Нейросетевые модели решают эту проблему через эмбеддингиэмбеддинг, векторное представлениеEN embedding: похожие слова получают похожие векторы, и знание переносится само (модуль 4.3). Первая такая модель — «A Neural Probabilistic Language Model» Йошуа Бенджио и соавторов (2003): эмбеддинги нескольких предыдущих слов подавались в многослойную сеть.
| n-граммная модель | нейросетевая модель | |
|---|---|---|
| Обучение | подсчёт частот | градиентный спуск |
| Контекст | токенов, обычно 2–4 | от сотен тысяч до миллиона токенов у современных LLM |
| Невиданные сочетания | вероятность 0 без сглаживания | разумная оценка за счёт похожих слов |
| Память | таблица растёт как | число параметров почти не зависит от длины контекста |
Короткая история: от Маркова до DeepSeek
Заголовок раздела «Короткая история: от Маркова до DeepSeek»| Год | Событие |
|---|---|
| 1913 | Марков считает переходы букв в «Евгении Онегине» |
| 1948 | Шеннон генерирует текст из n-граммных приближений английского |
| 1980–2000-е | n-граммные модели — стандарт в распознавании речи и машинном переводе |
| 2003 | Нейросетевая языковая модель Бенджио: эмбеддинги + MLP |
| 2010 | Рекуррентные языковые модели (RNN LM, Томаш Миколов) |
| 2013 | word2vec — эмбеддинги слов как отдельный продукт |
| 2017 | Трансформер — внимание вместо рекуррентности |
| 2018–2020 | GPT, GPT-2 (1.5 млрд параметров), GPT-3 (175 млрд) |
| 2022 | ChatGPT — языковая модель, дообученная быть ассистентом |
| 2024–2025 | Открытые китайские DeepSeek-V3, DeepSeek-R1, Qwen3 конкурируют с лучшими закрытыми моделями |
Обратите внимание: за сто с лишним лет задача не изменилась. Менялись только способ оценить и количество данных.
От предсказателя следующего токена к ChatGPT и DeepSeek
Заголовок раздела «От предсказателя следующего токена к ChatGPT и DeepSeek»Как из «автодополнения» получается ассистент, который отвечает на вопросы и пишет код? В три этапа.
flowchart LR A["Претрейн<br/>триллионы токенов<br/>текстов из интернета"] --> B["Базовая модель<br/>продолжает любой текст"] B --> C["SFT<br/>диалоги в chat-шаблоне"] C --> D["RL / предпочтения<br/>RLHF, GRPO"] D --> E["Ассистент<br/>ChatGPT, DeepSeek, Qwen"]
1. Претрейн. Модель учат предсказывать следующий токен на огромном корпусе. Получается базовая модельбазовая модельEN base model: она продолжает любой документ так, как он мог бы продолжиться в интернете. Спросите её «Как сварить борщ?» — она может ответить рецептом, а может выдать ещё пять вопросов, как на странице форума. Она не «отвечает», она продолжает.
2. SFT. Модель дообучают на диалогах (обучение с учителем на инструкцияхобучение с учителем на инструкциях (SFT)EN supervised fine-tuning (SFT)). Диалог записывается одним текстом по chat-шаблонуchat-шаблонEN chat templateПравило (обычно Jinja в tokenizer_config.json), которое превращает список сообщений с ролями в одну строку со спецтокенами. со спецтокенамиспециальный токен (спецтокен)EN special tokenУправляющий токен, а не кусок текста — начало/конец текста (BOS/EOS), заполнитель для батча (PAD), разметка ролей в чате (например, <|im_start|> у Qwen).. У Qwen это ChatML:
<|im_start|>userКак сварить борщ?<|im_end|><|im_start|>assistantМодель продолжает этот текст после assistant — и это снова предсказание следующего токена. Просто теперь самое
вероятное продолжение такого документа — полезный ответ ассистента, а в конце — <|im_end|>.
3. RL и предпочтения. Дальше модель учат на оценках: какой ответ люди предпочли (обучение с подкреплением на основе отзывов людейобучение с подкреплением на основе отзывов людей (RLHF)EN reinforcement learning from human feedback (RLHF), InstructGPT, 2022) или прошло ли решение проверку (GRPO в DeepSeek-R1). Правильного «следующего токена» здесь нет, есть награда за весь ответ. Но обучается всё та же функция : RL лишь сдвигает вероятности в сторону хороших продолжений. Подробно — на ступени 6.
Практика
Заголовок раздела «Практика»Код ниже — биграммная модель на словах из восьми предложений, без библиотек. Он показывает цепное правило,
проблему нулей и авторегрессионную генерацию. Запустите его локально (python lm_intro.py).
import mathimport randomfrom collections import Counter
corpus = """мама мыла раму . папа мыл машину . мама мыла посуду .папа читал газету . мама читала книгу . кот спал на окне .кот ловил мышь . мама кормила кота .""".split()tokens = ["."] + corpus # «.» — граница предложения и начало текста
prev_counts = Counter(tokens[:-1]) # сколько раз слово стояло «перед» чем-тоbigrams = Counter(zip(tokens, tokens[1:])) # счётчик пар соседних слов: {(«мама», «мыла»): 2, …}
def p(word, prev): """Оценка максимального правдоподобия: count(prev, word) / count(prev).""" return bigrams[(prev, word)] / prev_counts[prev]
def sentence_prob(sentence): prob, prev = 1.0, "." # предложение начинается после границы «.» for w in sentence.split(): prob *= p(w, prev) # цепное правило + марковское допущение prev = w return prob
print(f"P(мыла | мама) = {p('мыла', 'мама'):.2f}")for s in ["мама мыла раму .", "раму мыла мама .", "мама мыла машину ."]: pr = sentence_prob(s) nll = -math.log(pr) if pr > 0 else float("inf") print(f"P(«{s}») = {pr:.3f} −ln P = {nll:.2f}")
# Авторегрессия: каждое сгенерированное слово становится контекстом для следующегоrng = random.Random(7) # свой генератор с seed=7 → одинаковый результат при каждом запускеprev, out = ".", [] # начинаем с границы предложенияfor _ in range(12): # 12 шагов = 12 слов cands = [w for (a, w) in bigrams if a == prev] # все слова, которые хоть раз шли после prev weights = [bigrams[(prev, w)] for w in cands] # их счётчики: чем чаще, тем вероятнее prev = rng.choices(cands, weights=weights)[0] # случайный выбор с весами; [0] — choices возвращает список out.append(prev) # выбранное слово становится новым контекстомprint(" ".join(out))Ожидаемый вывод:
P(мыла | мама) = 0.50P(«мама мыла раму .») = 0.125 −ln P = 2.08P(«раму мыла мама .») = 0.000 −ln P = infP(«мама мыла машину .») = 0.000 −ln P = infмама мыла посуду . папа мыл машину . мама мыла раму .Разберите результат:
- : из 8 начал предложений 4 — «мама», после «мама» в половине случаев «мыла», после «мыла» в половине случаев «раму», после «раму» всегда точка.
- Перестановка слов даёт ноль — это правильно.
- «мама мыла машину» тоже получает ноль, хотя фраза нормальная. Это разреженность в чистом виде.
- Генерация выдаёт только предложения, собранные из уже виденных пар слов. Модель с крошечным корпусом не может придумать ничего нового.
Попробуйте сами.
- Добавьте в корпус «папа мыл раму .» и пересчитайте вероятности. Какие выросли, какие упали?
- Сделайте триграммную версию: ключом счётчика станет пара предыдущих слов. Что случится с нулями?
- Посчитайте среднее на токен для всего корпуса и perplexity .
Проверь себя
Заголовок раздела «Проверь себя»- Языковая модель задаёт вероятность текста. По цепному правилу , поэтому достаточно уметь предсказывать следующий токен — это классификация на классов.
- Генерация авторегрессионная: выбранный токен дописывается в контекст. Обучение параллельное: текст из токенов даёт примеров (teacher forcing), loss — средняя cross-entropy.
- N-граммы оценивают вероятности подсчётом при марковском допущении. Их пределы — нули, короткий контекст и отсутствие обобщения. Нейросети с эмбеддингами снимают все три ограничения.
- ChatGPT и DeepSeek — те же языковые модели: претрейн даёт базовую модель, SFT учит продолжать диалоги, RL сдвигает вероятности к хорошим ответам.
Дальше: строим первую настоящую модель — биграммную модель на русских именах: подсчёт, сэмплирование, оценка через NLL и та же модель в виде нейросети — Биграммная модель на русских именах.