Deep dive · 2025

Как работает
языковая модель
изнутри

Полное руководство: от основ NLP, предобработки текста и классических эмбеддингов до токенов, механизма внимания и файн-тюнинга LLM. Всё — простым языком, с математикой и схемами.

Шаг 1

Уровни абстракции текстовых данных

Прежде чем текст попадёт в модель, его можно рассматривать на разных уровнях детализации — от отдельных символов до целых документов. Выбор уровня влияет на то, какие закономерности модель способна уловить и насколько длинными получаются последовательности.

Иерархия уровней текста
Буквы / символы к, о, ш, к, а ... Слова кошка, сидела, на, плите N-граммы (кошка, сидела), (сидела, на) ... Предложения «Кошка сидела на горячей плите.» Документы статья, письмо, книга
01

Буквы / символы минимальная единица

Отдельные символы алфавита, цифры и пунктуация. Char-level модели работают напрямую с ними — это удобно для языков без чётких границ слов и устойчиво к опечаткам, но последовательности получаются намного длиннее.

02

Слова базовая единица смысла

Классическая единица для большинства NLP-задач. Проблема — словоформы: «бежал», «бежит», «бегущий» формально разные слова, хотя относятся к одной лемме, из-за чего словарь быстро разрастается.

03

N-граммы локальный контекст

Последовательности из n соседних единиц — символов или слов. Униграммы, биграммы, триграммы позволяют захватить порядок и локальные сочетания без построения полноценной языковой модели: например, биграмма («кошка», «сидела») из предложения выше.

04

Предложения единица синтаксиса

Уровень, на котором строится синтаксический разбор (parsing) и на котором обычно работают модели NER и извлечения отношений — сущности и связи ищутся в границах одного предложения.

05

Документы верхний уровень

Текст целиком — статья, письмо, обращение в поддержку. Здесь работают классификация документов, тематическое моделирование (topic modeling) и суммаризация, где важна общая тема, а не отдельное предложение.

Шаг 2

Предобработка текста

Прежде чем текст можно будет векторизовать и подать в модель, он проходит через последовательность стандартных этапов очистки и нормализации. Не каждая задача требует всех этапов, но важно понимать, что делает каждый из них.

01

Сегментация предложений

Разбиение сплошного текста на отдельные предложения. Наивный вариант — резать по «.», «!», «?», но это ломается на сокращениях («т.е.», «г.», «США») и десятичных дробях («3.14»). Поэтому используют обученные сегментаторы (например, Punkt) или языковые правила.

02

Нормализация

Приведение текста к единому виду: нижний регистр, унификация Unicode (NFC/NFKC), удаление или замена HTML-тегов, лишних пробелов, эмодзи и спецсимволов. Цель — уменьшить «случайную» вариативность, не несущую смысла для задачи.

03

Токенизация

Разбиение предложения на слова или токены — по пробелам и пунктуации (word-level) либо на суб-словные единицы. Это та же идея, что и BPE-токенизация современных LLM (раздел «Токены» ниже), только для классических NLP-пайплайнов чаще используется токенизация на уровне целых слов.

04

Удаление стоп-слов

Стоп-слова — частые малоинформативные слова: предлоги, союзы, частицы («и», «в», «на», «что»). Их удаление уменьшает размер словаря и шум для моделей вроде «мешка слов». Но осторожно: в задачах тональности отрицания («не», «нет») часто несут ключевой смысл, и их удаление может всё испортить.

05

Морфологический анализ: стемминг и лемматизация

Оба метода приводят словоформы к общему виду, но по-разному: стемминг грубо отсекает окончания по эвристическим правилам (алгоритмы Портера, Snowball), не заботясь о существовании результата как реального слова; лемматизация приводит слово к словарной форме (лемме) с помощью морфологического анализа и словаря (pymorphy2, MyStem для русского языка).

Исходное словоСтеммингЛемматизация
бежалбежабежать
бегущийбегбежать
лучшелучшхороший

А как же современные LLM? Модели с BPE/subword-токенизацией (раздел «Токены») обычно не требуют отдельного удаления стоп-слов, стемминга или лемматизации — сеть сама учится нужным обобщениям на больших данных. Эти этапы остаются важными для классических ML-пайплайнов, поиска по ключевым словам и там, где признаки нужно готовить вручную.

Шаг 3

Векторизация текста: мешок слов и TF-IDF

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

Мешок слов (Bag-of-Words)

Документ представляется вектором длиной со словарь V, где на позиции каждого слова стоит число его вхождений. Порядок слов теряется полностью — отсюда и название «мешок».

Документкошкасиделанаплитегорячей
«Кошка сидела на плите»11110
«Кошка сидела на горячей плите»11111

Ограничения BoW: вектор не различает «кошка укусила собаку» и «собака укусила кошку», размерность равна размеру словаря (десятки-сотни тысяч), а частые слова (даже после удаления стоп-слов) доминируют над редкими, но более информативными.

TF-IDF: взвешиваем по информативности

TF-IDF (Term Frequency – Inverse Document Frequency) уменьшает вес слов, которые встречаются почти во всех документах, и увеличивает вес тех, что специфичны для конкретного документа.

// Term Frequency — частота слова t в документе d
TF(t, d) = count(t, d) / |d|

// Inverse Document Frequency — редкость слова во всём корпусе из N документов
IDF(t) = log( N / df(t) ) // df(t) — в скольких документах встречается t

// Итоговый вес слова в документе:
TF-IDF(t, d) = TF(t, d) · IDF(t)

Пример: слово «плите» встречается в обоих документах — его IDF низкий. Слово «горячей» встречается только в одном — его IDF выше, и TF-IDF «подсветит» его как более различающее эти два документа.

Где используется сегодня: TF-IDF остаётся сильным бейзлайном для классификации текстов и лежит в основе поисковых ранжирующих функций (BM25 — по сути «улучшенный» TF-IDF). Но векторы по-прежнему разреженные и не отражают смысловую близость слов — для этого нужны эмбеддинги.

Шаг 4

Нейросетевые эмбеддинги: Word2Vec, GloVe, FastText

В отличие от BoW и TF-IDF, нейросетевые эмбеддинги представляют слово плотным вектором небольшой размерности (обычно 100–300), в котором семантически близкие слова оказываются рядом в векторном пространстве.

Word2Vec: CBOW и Skip-Gram

Word2Vec обучает эмбеддинги на простой самоконтролируемой задаче — предсказании слова по контексту или наоборот — используя два возможных варианта архитектуры:

CBOW (Continuous Bag-of-Words)

Предсказывает целевое слово по контексту: по словам «кошка ___ на плите» модель должна угадать «сидела». Контекстные векторы усредняются, что делает CBOW быстрее и лучше подходит для частых слов.

Skip-Gram

Решает обратную задачу — предсказывает контекст по целевому слову: по слову «сидела» модель пытается угадать соседние «кошка», «на», «плите». Работает медленнее, но даёт более качественные векторы для редких слов.

// Skip-Gram: максимизируем вероятность контекстных слов при данном центральном
L = Σ_t Σ_{-c≤j≤c, j≠0} log P(w_{t+j} | w_t)

// P считается через softmax по всему словарю — дорого,
// поэтому на практике используют Negative Sampling:
P(w_O | w_I) ≈ σ(v'_{w_O}ᵀ v_{w_I}) · Π σ(-v'_{w_i}ᵀ v_{w_I}) // w_i — «шумовые» слова

GloVe: глобальная статистика совстречаемости

В отличие от Word2Vec, который смотрит только на локальное окно вокруг слова, GloVe (Global Vectors) строит матрицу совстречаемости слов по всему корпусу и обучает векторы так, чтобы их скалярное произведение приближало логарифм числа совместных встреч.

J = Σ_{i,j} f(X_ij) · (v_iᵀv_j + b_i + b_j − log X_ij)²
// X_ij — сколько раз слово j встретилось в контексте слова i по всему корпусу
// f(X_ij) — понижает вес слишком частых пар

FastText: субсловные n-граммы

FastText расширяет Skip-Gram идеей представлять слово как сумму векторов его символьных n-грамм. Слово «плита» раскладывается на части вроде «пли», «лит», «ита» (плюс спецсимволы границ слова), и вектор слова — их сумма.

v(«плита») = Σ v(g) // g — n-граммы слова + сам вектор целого слова

Почему это важно для русского языка: благодаря субсловной структуре FastText умеет строить вектор даже для слова, не встречавшегося при обучении (out-of-vocabulary), и хорошо улавливает морфологию — родственные словоформы («плита», «плите», «плитой») получают близкие векторы за счёт общих n-грамм.

МетодИсточник сигналаOOV-словаМорфология
Word2Vecлокальное окно контекстанетне учитывает
GloVeглобальная матрица совстречаемостинетне учитывает
FastTextлокальное окно + символьные n-граммыдаучитывает
Шаг 5

Меры близости и оценка качества эмбеддингов

Получив векторы слов, нужно уметь сравнивать их между собой и проверять, насколько хорошо они отражают реальные языковые закономерности.

Меры близости векторов

// Косинусное сходство — самая частая мера для эмбеддингов
cos(u, v) = (u · v) / (‖u‖ · ‖v‖) // не зависит от длины векторов

// Евклидово расстояние — чувствительно к масштабу вектора
d(u, v) = √Σ(u_i − v_i)²

// Скалярное произведение — используется, когда важна и длина, и направление
score(u, v) = u · v

Почему обычно берут косинус: длина вектора слова часто зависит от его частотности в корпусе, а не от смысла, поэтому косинусное сходство (учитывающее только угол между векторами) надёжнее отражает семантическую близость.

Оценка качества эмбеддингов: intrinsic vs extrinsic

Intrinsic (внутренняя)

Проверяет сами векторы напрямую, без привязки к конкретной задаче: корреляция косинусного сходства пар слов с оценками людей (бенчмарки WordSim-353, SimLex-999), решение аналогий («король» − «мужчина» + «женщина» ≈ «королева»), качество кластеризации похожих слов.

Extrinsic (внешняя)

Проверяет, насколько эмбеддинги полезны как признаки в реальной downstream-задаче: подставляем векторы в классификатор тональности, NER или систему машинного перевода и смотрим на итоговую метрику (accuracy, F1, BLEU).

Компромисс: intrinsic-оценки быстрые и дешёвые, но плохая корреляция с бенчмарком не всегда означает, что эмбеддинги бесполезны на практике. Extrinsic-оценки достовернее отражают реальную пользу, но требуют полноценного обучения downstream-модели под каждый набор эмбеддингов.

Шаг 6

Что такое LLM?

Large Language Model (LLM) — это нейронная сеть с миллиардами параметров, обученная на огромных текстовых корпусах. Её единственная задача в процессе обучения — предсказывать следующий токен (слово/символ) по предыдущим. Из этой простой задачи вырастают все остальные способности: рассуждение, перевод, написание кода.

Ключевая идея: LLM — это функция P(следующий токен | контекст). Модель не «понимает» текст в человеческом смысле — она оценивает вероятность каждого возможного продолжения и выбирает наиболее вероятное (или семплирует из распределения).

📚

Данные

Триллионы токенов: веб-страницы, книги, код, научные статьи. GPT-4 обучен на ~13 трлн токенов.

⚙️

Параметры

Числа (веса) внутри сети. GPT-3 имеет 175 млрд параметров. Каждый участвует в вычислениях.

🎲

Вывод

Для каждого токена модель выдаёт вектор вероятностей (logits) по всему словарю (~50к токенов).

Аналогия: представьте, что вы читаете детектив и на каждом слове загораживаете следующее — и угадываете его. Чем больше книг вы прочли, тем лучше угадываете. LLM делает то же самое, но с математической точностью и на масштабе всего интернета.

Шаг 7

Токены: базовые единицы

LLM не работает с буквами или словами напрямую. Текст разбивается на токены — куски текста, которые могут быть словом, частью слова или символом. Словарь строится методом BPE (Byte Pair Encoding) или SentencePiece.

Пример токенизации фразы

Наведите на токен

Тран сфор мер пред ска зыва ет следу ющий токен
Trans former pred icts the next token

Эмбеддинг: токен → вектор

Каждый токен преобразуется в числовой вектор — эмбеддинг — размерностью d_model (например, 4096 у Llama-3). Схожие по смыслу слова имеют близкие векторы в пространстве.

// Embedding lookup: токен → вектор
token_id = 8432 // "кот" в словаре
embedding = E[token_id] // строка матрицы E ∈ ℝ^(V × d_model)
// Результат: вектор [0.23, -0.41, 0.88, ..., 0.12] ∈ ℝ^4096

// Позиционное кодирование (добавляется к эмбеддингу):
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
// Позиция 0 → один вектор, позиция 1 → другой, чтобы модель знала порядок

Зачем позиционное кодирование? Трансформер обрабатывает все токены параллельно и сам по себе «не знает» порядка. Позиционный вектор добавляется к эмбеддингу, чтобы слово «кот съел мышь» и «мышь съела кот» различались для модели.

Шаг 8

Архитектура трансформера

Трансформер — это стек из N идентичных слоёв (у GPT-4 их ~96). Каждый слой принимает матрицу токен-векторов и выдаёт обновлённую матрицу того же размера. Информация течёт снизу вверх.

Архитектура Decoder-Only трансформера (GPT-style)
Входные токены + Positional Encoding DECODER LAYER 1 Multi-Head Attention Feed-Forward Network (FFN) DECODER LAYER N (×96) Multi-Head Attention Feed-Forward Network (FFN) Layer Norm + Linear Head → вектор logits ∈ ℝ^vocab_size Softmax P(токен) = softmax(logits) + LayerNorm + Residual · · ·

Что внутри каждого слоя?

01

Multi-Head Self-Attention Ключевой механизм

Каждый токен «смотрит» на все остальные токены в контексте и определяет, насколько каждый из них важен для понимания текущего токена. Механизм подробно описан в следующем разделе.

02

Add & LayerNorm Стабильность

Residual connection: к выходу внимания прибавляется входной вектор. Это позволяет градиентам свободно течь при обратном распространении и предотвращает «исчезновение» информации в глубоких сетях.

x = LayerNorm(x + Attention(x))
03

Feed-Forward Network (FFN) Хранилище знаний

Два линейных преобразования с нелинейностью между ними. Применяется независимо к каждой позиции. FFN увеличивает размерность внутри (обычно в 4×: 4096→16384→4096), «усиливая» представление.

FFN(x) = max(0, xW₁ + b₁) · W₂ + b₂
// или GeLU/SwiGLU в современных моделях
04

Снова Add & LayerNorm

После FFN — ещё один residual + LayerNorm. Каждый из N слоёв уточняет представление всех токенов. Нижние слои улавливают синтаксис, верхние — семантику.

Шаг 9

Механизм внимания (Attention)

Самый важный механизм в трансформере. Позволяет каждому токену «видеть» все остальные и взвешенно агрегировать их информацию. Основан на операции Q·K^T.

Scaled Dot-Product Attention
Вход X ∈ ℝ^(n×d) W_Q W_K W_V Q K V Q · Kᵀ MatMul ÷ √d_k Softmax × V Weighted sum Output ∈ ℝ^(n×d)

Математика внимания — по шагам

// Шаг 1: Создаём Q, K, V из входа X
Q = X · W_Q // Запрос (что ищем)
K = X · W_K // Ключ (что предлагаем)
V = X · W_V // Значение (что возвращаем)

// Шаг 2: Вычисляем веса внимания
scores = Q · Kᵀ / √d_k // Скалярное произведение + масштабирование
weights = softmax(scores) // Нормировка → сумма = 1

// Шаг 3: Взвешенная сумма значений
Attention(Q, K, V) = weights · V

// Полная формула из статьи "Attention is All You Need" (2017):
Attention(Q,K,V) = softmax(QKᵀ / √d_k) · V

Аналогия: Q — это поисковый запрос в Google. K — ключевые слова страниц. V — содержимое страниц. Attention находит релевантные «страницы» (K близкие к Q) и возвращает взвешенную смесь их содержимого (V).

Интерактивная демонстрация

Нажмите на слово — увидите, как меняются веса внимания:

Кошка
сидела
на
горячей
плите

Веса внимания от выбранного слова:

Multi-Head Attention

Одной головы внимания недостаточно — разные аспекты требуют разных «взглядов». Multi-Head Attention запускает H параллельных голов, каждая со своими W_Q, W_K, W_V, и конкатенирует результаты:

head_i = Attention(QW_i^Q, KW_i^K, VW_i^V)
MultiHead(Q,K,V) = Concat(head_1,...,head_h) · W^O

// Пример: GPT-3 — 96 слоёв × 96 голов = 9216 голов внимания
// Каждая голова "специализируется": синтаксис, кореференция, семантика...
Шаг 10

Как обучается LLM

Обучение — это итерационный процесс минимизации функции потерь (loss). Модель делает предсказание, сравнивает с реальным ответом, вычисляет ошибку и корректирует веса через обратное распространение ошибки.

Цикл обучения
Батч токенов из датасета Forward Pass предсказание Loss cross-entropy Backward Pass градиенты Update AdamW следующий батч

Функция потерь: Cross-Entropy

// Модель предсказывает вероятности для каждого следующего токена:
ŷ = softmax(logits) // предсказание модели
y = one_hot(real_token) // реальный следующий токен

// Cross-Entropy Loss (хотим минимизировать):
L = -Σ y_i · log(ŷ_i) // сумма по всему словарю

// Если модель уверенно предсказала правильный токен: L → 0
// Если ошиблась: L → ∞

Обратное распространение (Backprop)

После вычисления Loss, правило цепочки (Chain Rule) позволяет вычислить, насколько каждый вес повлиял на ошибку.

// Градиент показывает направление роста Loss
∂L/∂W = ∂L/∂ŷ · ∂ŷ/∂z · ∂z/∂W // Chain Rule

// AdamW обновление весов:
m_t = β₁ · m_{t-1} + (1-β₁) · ∇L // momentum
v_t = β₂ · v_{t-1} + (1-β₂) · ∇L² // адаптивный LR
W_t = W_{t-1} - lr · m_t / (√v_t + ε) - λ·W // weight decay

Масштаб: Llama-3 70B обучался на ~15 трлн токенов. При batch size 4М токенов это ~3.75М шагов. На каждом шаге — backward pass через 80 слоёв. Суммарно: сотни тысяч GPU-часов H100.

Шаг 11

Пример от начала до конца

Проследим, как LLM обрабатывает запрос «Напиши функцию sum на Python» и генерирует ответ, задействуя все рассмотренные механизмы.

1

Токенизация входа

Напиши функцию sum на Python

6 токенов → 6 эмбеддингов ∈ ℝ^4096 + позиционные векторы

2

Прямой проход через 80 слоёв

Каждый слой применяет Multi-Head Attention (96 голов) и FFN. Слой 1: обрабатывает синтаксис («напиши» → императив → код-задача). Слои 20–40: семантические связи («sum» + «Python» → известная функция). Слои 60–80: стратегия ответа (структура кода, docstring, пример).

3

Attention в действии: токен «sum»

Голова внимания #47 слоя 38 обнаруживает: «sum» сильно аттендирует на «Python» (веса: 0.73) и «функцию» (0.18). Другие головы видят контекст «напиши» → нужен код, не определение.

// Упрощённые веса attention от токена "sum":
Напиши → 0.04 (не важен)
функцию → 0.18 (нужна функция)
sum → 0.05 (self)
на → 0.00
Python → 0.73 (ключевое!)
4

Генерация: авторегрессия токен за токеном

Модель генерирует ответ пошагово, добавляя по одному токену за раз:

# Генерированный ответ (каждая строка = отдельный шаг):
def sum_list(numbers):
    """Суммирует список чисел."""
    return sum(numbers)

# Пример использования:
print(sum_list([1, 2, 3])) # → 6

На каждом шаге: softmax(logits) → семплирование → новый токен → он добавляется к контексту

5

Остановка: EOS-токен

Генерация продолжается, пока не сгенерируется специальный токен <|end_of_text|> или не достигнет max_tokens. Итоговая вероятность последовательности — произведение вероятностей каждого токена.

Шаг 12

Файн-тюнинг: тонкая настройка модели

Предобученная LLM — мощный «фундамент», но она обучена предсказывать текст, а не следовать инструкциям или быть полезным ассистентом. Fine-tuning адаптирует модель под конкретную задачу.

Pre-training

Следующий токен на триллионах токенов. Учит язык, факты, рассуждения. Base model

GPT, Llama base, Mistral base

SFT

Supervised Fine-Tuning: пары (запрос, идеальный ответ). Учит формат диалога. Instruct

ChatGPT, Claude Instant

RLHF

Reinforcement Learning from Human Feedback. Модель награды + PPO. Aligned

InstructGPT, Claude, Gemini

LoRA

Low-Rank Adaptation: дообучение маленьких матриц-адаптеров. Дёшево и эффективно. PEFT

Alpaca, Vicuna, домен

SFT в деталях

// SFT датасет: пары instruction → response
dataset = [
  { "user": "Объясни что такое LLM",
    "assistant": "LLM — это большая языковая модель..." },
  ...
]

// Обучаем только на ответах ассистента (маска на токены пользователя)
loss = CrossEntropy(model_output, target_tokens[assistant_mask])

LoRA: умный файн-тюнинг без полного обновления весов

Вместо обновления огромной матрицы W ∈ ℝ^(d×d) добавляем две маленькие матрицы, произведение которых аппроксимирует изменение:

// Полный файн-тюнинг: обновляем W (d×d, миллиарды параметров)
W_new = W + ΔW // ΔW ∈ ℝ^(d×d) — дорого!

// LoRA: аппроксимируем ΔW через два маленьких множителя
ΔW ≈ A · B // A ∈ ℝ^(d×r), B ∈ ℝ^(r×d), r << d (r=8 типично)
// Экономия: 2·d·r вместо d² параметров
// При d=4096, r=8: 65536 вместо 16 777 216 → в 256 раз меньше!

output = x · (W + A·B) // во время инференса объединяем

Что происходит при файн-тюнинге

Что меняется

Модель обучается более детерминированно отвечать в нужном стиле/формате. Нижние слои (синтаксис) почти не меняются, верхние (стратегия ответа) — сильно.

Catastrophic forgetting

Агрессивный файн-тюнинг на узких данных может «затереть» общие знания. Решение: низкий learning rate, LoRA, данные в т.ч. general-purpose.

RLHF: человеческие предпочтения

Люди ранжируют пары ответов → Reward Model обучается предсказывать качество → PPO оптимизирует LLM по сигналу от Reward Model.

DPO (Direct Preference Optimization)

Современная альтернатива RLHF: обучение прямо на парах (хороший/плохой ответ) без отдельной Reward Model. Проще и стабильнее.

Итог: современные LLM-ассистенты (Claude, GPT-4, Gemini) = Base model (pre-training) + SFT (instruction following) + RLHF или DPO (alignment). Каждый этап добавляет новые способности, сохраняя фундаментальные знания предыдущего.

Итог

Вся картина целиком

Полный пайплайн: от обучения до ответа
Pre-train 13T tokens SFT inst. data RLHF/DPO alignment Tokenize BPE Transformer N layers Generate sampling OFFLINE RUNTIME
Концепция Роль Ключевая формула
ЭмбеддингТокен → числовой векторE[token_id] ∈ ℝ^d
Positional EncodingДобавляет информацию о позицииsin/cos(pos/10000^(2i/d))
AttentionКонтекстное взвешиваниеsoftmax(QKᵀ/√d)·V
Multi-HeadПараллельные «взгляды»Concat(head₁,...,headₕ)·Wᴼ
FFNНелинейное преобразованиеmax(0, xW₁)·W₂
ResidualСтабильность глубоких сетейx = LayerNorm(x + sublayer(x))
TF-IDFКлассическая векторизация текстаTF(t,d) · log(N/df(t))
Word2VecНейросетевой эмбеддинг словаP(context | word)
Softmax + LossВероятности + обучение-Σ y·log(softmax(logits))
LoRAДешёвый файн-тюнингΔW ≈ A·B, r ≪ d