Как устроена LLM · How LLMs work · урок 1 · 13 мин

Токены, embeddings и transformer на одной картинке

Tokens, embeddings and the transformer

ТемыLLM изнутри

Зачем

После урока ты объяснишь путь от текста до следующего слова модели: tokenizer, embeddings, блоки transformer, logits. Это первый вопрос любого технического интервью на AI-роль («walk me through what happens inside an LLM»), и на этом фундаменте стоят остальные уроки модуля: память, обучение, inference.

Модель делает одно: предсказывает следующий token

Большая языковая модель, LLM (large language model), умеет одну вещь: по тексту предсказывать продолжение. Точнее, на каждом шаге она выдаёт распределение вероятностей по всему словарю: «следующим скорее всего будет вот этот кусочек слова с вероятностью 31 %, вот этот — 12 %…». Программа вокруг модели выбирает один вариант, дописывает его к тексту и снова спрашивает модель. Такой цикл называется autoregressive generation (авторегрессионная генерация: каждый новый кусочек зависит от всех предыдущих).

Из этого следуют три вещи, которые понадобятся во всём курсе. Ответ случаен: тот же вопрос может дать разные ответы. Модель знает только то, что выучила при обучении, и то, что лежит перед ней в context (всё, что модель видит за один вызов). И модель пишет гладко и тогда, когда ошибается: гладкость не доказывает правильность.

Tokenizer: текст превращается в номера

Модель не видит букв. Сначала tokenizer (программа нарезки текста) режет текст на tokens — кусочки слов — и заменяет каждый номером из словаря. В английском один token в среднем около ¾ слова.

Самый распространённый способ нарезки — BPE (byte-pair encoding, слияние частых пар). Его обучают заранее на большом корпусе: начинают с отдельных символов, а в byte-level BPE — с 256 возможных байтов, поэтому любой текст можно записать без «неизвестных» символов. Затем алгоритм раз за разом находит самую частую соседнюю пару и сливает её в новый token, пока словарь не дорастёт до заданного размера. У Qwen3-8B словарь — 151 936 tokens (файл config.json модели).

Отсюда практическое следствие. Если tokenizer учился в основном на английском, русское, казахское или арабское слово распадается на больше кусков. Исследование 2023 года нашло, что один и тот же переведённый текст в разных языках даёт число tokens с разницей до 15 раз. Это прямо бьёт по цене (API считает tokens), по задержке и по тому, сколько текста влезает в context. Инженерное решение: до выбора модели посчитать, сколько tokens дают твои реальные тексты, а не верить средней цифре для английского. И помнить, что модель, не видящая букв, плохо считает буквы в слове и путается в длинных числах.

Embeddings: номер превращается в вектор

Номер token сам по себе ничего не значит. Первый слой модели — embedding matrix (таблица векторов): одна строка на каждый token словаря. У Qwen3-8B это таблица 151 936 × 4096: каждый token становится вектором из 4096 чисел, а сама таблица занимает 622 млн параметров. Во время обучения векторы похожих по смыслу tokens сближаются.

Не путай это с embedding model из урока про RAG: там отдельная модель выдаёт один вектор на целый кусок документа для поиска. Здесь вектор у каждого token, и он живёт внутри LLM.

Ещё модели нужен порядок слов. Attention (ниже) сам по себе не знает, где какой token стоит. Авторы transformer прибавляли к векторам positional encoding (код позиции) из синусов и косинусов. Современные модели вроде Qwen и Llama используют RoPE (rotary position embedding): векторы поворачиваются на угол, зависящий от позиции, и модель видит относительное расстояние между tokens.

Блок transformer: attention, потом MLP

Transformer описан в статье «Attention Is All You Need» (2017): архитектура «based solely on attention», без рекуррентных сетей. Исходная модель переводила тексты и имела encoder и decoder по 6 слоёв, ширину 512 и 8 attention heads; обучение заняло 3,5 дня на восьми GPU. Современные LLM — decoder-only (только декодер): стопка одинаковых блоков. У Qwen3-8B их 36.

Каждый блок делает два шага.

Self-attention (внимание к другим tokens). Каждый token строит три вектора: query (что я ищу), key (что я содержу) и value (что я отдам). Его query сравнивается с keys всех предыдущих tokens, softmax (функция, которая превращает оценки в вероятности с суммой 1) делает из сравнений доли, и token забирает взвешенную смесь их values: Attention(Q, K, V) = softmax(QKᵀ / √d_k) · V. Деление на √d_k не даёт числам разрастись, иначе softmax становится почти ступенькой и обучение глохнет. Causal mask (причинная маска) запрещает смотреть на будущие tokens: модель учится предсказывать продолжение, не подглядывая. Attention heads (головы внимания) работают параллельно, и каждая может ловить свою связь: например, одна следит за подлежащим, другая — за тем, к чему относится местоимение.

MLP (multilayer perceptron, он же feed-forward слой) обрабатывает каждый token отдельно: расширяет вектор, пропускает через нелинейность и сжимает обратно. Здесь лежит большая часть параметров.

Посчитаем на Qwen3-8B по размерам из её файлов. Attention одного блока: матрицы q и o по 4096 × 4096, k и v по 1024 × 4096 — вместе 41,9 млн параметров. MLP: три матрицы 12 288 × 4096 — 151 млн. Блок ≈ 193 млн, 36 блоков ≈ 6,95 млрд. Плюс таблица embeddings (0,62 млрд) и выходной слой такого же размера (0,62 млрд) — итого 8,19 млрд. Карточка модели пишет «8.2B», из них «6.95B» без embeddings. Сошлось, и видно главное: около 78 % параметров блока — MLP.

Выход: logits, вероятности, выбор

После последнего блока вектор последнего token умножается на выходной слой lm_head (4096 → 151 936) и превращается в logits — по одному числу-оценке на каждый token словаря. Softmax превращает их в вероятности. Какой token взять — самый вероятный или случайный по распределению — решает decoding strategy (стратегия выбора), и это урок a1-4.

Одна цена, которую стоит знать уже сейчас: наивный attention сравнивает каждый token с каждым, то есть растёт квадратично с длиной. Документация Hugging Face приводит пример: при 40 головах и 16 000 tokens одни матрицы сравнений заняли бы 19 ГБ. Поэтому существуют FlashAttention (алгоритм, который считает attention по частям и не хранит всю матрицу сравнений) и KV cache из урока a1-4.

Схема

Термины · Key terms

token
кусочек слова, единица длины текста для модели
tokenizer
программа, которая режет текст на tokens и даёт им номера
BPE (byte-pair encoding)
нарезка, которая сливает самые частые соседние пары в новые tokens
embedding
вектор чисел, которым модель представляет token
self-attention
шаг, где каждый token берёт информацию у предыдущих по весам сходства
query / key / value
векторы «что ищу», «что содержу», «что отдам» внутри attention
causal mask
запрет смотреть на будущие tokens
MLP / feed-forward
слой, который обрабатывает каждый token отдельно; в нём большинство параметров
logits
сырые оценки модели для каждого token словаря до softmax
decoder-only
архитектура из одних блоков декодера; так устроены современные LLM
RoPE
кодирование позиции поворотом векторов query и key

Сделай сам

Посчитай число параметров Qwen3-8B сам, 10 строк Python без пакетов. Данные из config.json: vocab_size 151936, hidden_size 4096, intermediate_size 12288, num_hidden_layers 36, num_attention_heads 32, num_key_value_heads 8, head_dim 128, tie_word_embeddings false. Посчитай размеры q, k, v, o и трёх матриц MLP, умножь на число слоёв, добавь embeddings и lm_head. Нормы (векторы длиной 4096 и 128) можно не считать. Результат сравни с 8,19 млрд и запиши, какой процент дают MLP.

Обсуди с тьютором: покажи свой расчёт и спроси, почему k и v в четыре раза меньше q (подсказка: num_key_value_heads) и что изменилось бы при tie_word_embeddings: true.

Проверь себя · ответ под вопросом

1Почему один и тот же абзац на казахском стоит в API дороже, чем на английском?
Tokenizer обучен в основном на английском тексте, поэтому казахские слова режутся на больше кусков. API считает tokens, а не слова, так что тот же смысл даёт больше tokens: дороже, дольше и меньше помещается в context. Исследование 2023 года нашло разницу до 15 раз между языками.
2Чем embedding token внутри LLM отличается от embedding в RAG?
Внутри LLM у каждого token своя строка в таблице embeddings, это первый слой модели. В RAG отдельная embedding model выдаёт один вектор на целый кусок документа, чтобы искать похожие куски. Это разные модели и разные задачи.
3Где в блоке transformer лежит большая часть параметров и как это проверить?
В MLP. У Qwen3-8B attention одного блока — 41,9 млн параметров, MLP — 151 млн, то есть около 78 % блока. Проверяется по размерам матриц в config.json или по заголовку файла safetensors.

Interview questions · US / UK

1Walk me through what happens inside a decoder-only LLM from the moment it receives a prompt until it emits the first token.
Strong answer: tokenizer turns text into ids; embedding lookup plus positional information (RoPE); a stack of identical blocks, each causal self-attention then MLP with residuals and norms; final hidden state of the last position goes through the LM head to logits over the vocabulary; softmax plus a decoding strategy picks the token, then the loop repeats with a KV cache.
2Why does the same content cost more tokens in Arabic or Kazakh than in English, and what would you do about it on a product?
Strong answer: BPE vocabularies are learned mostly on English, so other scripts fragment into more tokens; research shows gaps up to 15x; this hits cost, latency and how much fits in context; measure tokens per word on your own corpus; choose a model with a better tokenizer or budget per language.
3Explain self-attention to a product manager, then give the formula and say why it is scaled.
Strong answer: each token asks a question (query), every earlier token advertises what it holds (key) and offers content (value), and the token takes a weighted mix; softmax(QKᵀ/√d_k)V; scaling keeps dot products from saturating softmax and killing gradients; causal mask hides the future; multi-head attention looks at several relations at once; naive cost is quadratic in sequence length.

Ключевые фразы · Say it aloud

Материалы