Анатомія GPT-2: від тексту й токенів до результату
Модель GPT — це дві речі одночасно, які важко утримати в голові разом. З боку він відповідає на запитання, пише код і веде розмову — виглядає так, ніби він розуміє. Зсередини це кілька сотень матриць і цикл, який за певного тексту створює одне число на кожне слово у своєму словнику та вибирає одне. Розрив між цими двома описами — це місце, де живе більша частина містики, і він закривається, коли ви простежуєте, що насправді відбувається з підказкою, крок за кроком, до кінця.
У цій статті простежується одна конкретна модель: GPT-2, аналог BERT лише для декодера. Якщо БЕРТ є гілкою кодера архітектурний розкол — двонаправленою, навченою шляхом заповнення замаскованими словами — GPT-2 є гілкою декодера: причинною, навченою передбачати наступний токен і нічого більше. Ми вибрали GPT-2 саме тому, що він досить малий, щоб його можна було вмістити в одній голові (початковий випуск мав параметри від 124M до 1,5B), повністю публічний і модель, яку насправді анімують найкращі інтерактивні візуалізатори. Усюди, де етап має власну механіку, варту розділу, ми переходимо до глибокого занурення, а не повторюємо її тут — найбільше до демонтаж трансформаторного блоку, який відкриває ту коробку, яку ця стаття називає «блоками».
Єдина найкорисніша річ, яку потрібно виправити, перш ніж будь-яка частина матиме сенс, це те, для чого призначена машина.
Єдине завдання: передбачити наступний жетон
Видаляйте інтерфейс чату, системну підказку, виклики інструментів, і те, що залишається, це функція з одним завданням: за наявності послідовності токенів створити розподіл ймовірностей за тим, який жетон буде наступним. Це весь перехід вперед. «Кот сів на» заходить; виходить розподіл, який надає високу ймовірність mat, нижчу ймовірність floor і rug і майже жодну ймовірність purple. Зразок одного маркера з цього розповсюдження, додайте його та запустіть функцію знову. Генерація — це цикл — прогнозування наступного токена знову і знову.
Це єдине місце, де GPT і BERT справді розходяться. BERT дивиться на все речення одночасно і передбачає замасковані слова з обох сторін; GPT-2 читає строго зліва направо і передбачає наступне слово з усього перед ним. Той самий блок трансформатора внизу — різниця полягає виключно в масці уваги та тренувальній меті, що є саме тим, що виділяє стаття про кодувальник/декодер.
Усе інше служить для того, щоб зробити цей єдиний розподіл хорошим. Попереднє навчання — це модель навчання прогнозуванню наступного токена за мільярдами лексем тексту. Архітектура — те, що люди мають на увазі, коли кажуть «трансформатор» — це лише специфічна форма функції, яка, як виявилося, добре прогнозує наступні токени в масштабі.
Оформлення цього як розподілу не є метафорою; це буквально те, що випромінює модель, і саме тому втрата, яка її тренує, є перехресною ентропією/від’ємною логарифмічною ймовірністю за категоріальним розподілом. Чотири розподілу будівельних блоків, які з’являються скрізь у глибокому навчанні — і чому «передбачити розподіл, а потім мінімізувати NLL» — це рецепт класифікації, генерації та майже всього іншого — є предметом окрема стаття; відмінок із надлишковим словниковим запасом — це той, у якому живе GPT.
Чому GPT-2 має значення: масштаб — це багатозадачний учень
Внесок BERT став новою метою навчання. Внесок GPT-2 був протилежним твердженням — що вам взагалі не потрібна нова мета. Назва його статті чітко говорить про це: Мовні моделі — це багатозадачні особи, які навчаються без контролю. Візьміть єдину нудну мету вище — передбачте наступний маркер — і запустіть її в достатньому масштабі на досить різноманітному тексті, і модель почне виконувати завдання, яким її ніхто не навчав. Запропонуйте йому «перекласти французькою: кіт →», і він видасть chat; підкажіть його статтею, за якою слід “TL; DR:”, і це підсумовує. Ніхто не додав голову перекладу чи набір підсумкових даних. Завдання були приховані у передбаченні наступного токена, тому що навчальний текст уже містив переклади, резюме та запитання й відповіді, і для того, щоб передбачити їх добре, потрібно виконати завдання.
Це шарнір, на якому працює вся сучасна епоха LLM. BERT сказав “тренуватися інакше”; GPT-2 сказав «просто збільште», а друга ідея — це та, що масштабується. Усе звідси — передача вперед, тренування, висновок — служить цій одній ставці.
Таким чином, вся машина, зверху вниз, полягає в тому, щоб перетворити текст у форму, яку функція може використовувати, запустити функцію, прочитати розповсюдження з кінця, вибрати маркер. Ось цей трубопровід кінець в кінець.
Прохід вперед, етап за етапом
Шість ступенів, одна з яких петля. Форми мають таке ж значення, як і назви — більшість інтуїції для GPT полягає в тому, «яку форму мають дані в кожній точці та що змінилося». Клацніть етапи нижче; тоді ми ходимо кожен.
The prompt arrives as a Unicode string. The model never sees characters directly; the next stage turns them into integers.
A learned subword vocabulary splits the string into tokens and maps each to an integer id. Common words are one token; rare words split into pieces.
Deep dive: Tokenization: BPE, WordPiece, SentencePiece →Each token id indexes a row of a learned embedding table, turning 5 integers into 5 vectors of width d = 768. A learned positional embedding (one per slot) is added on top, so the vectors carry meaning and position — but no context yet.
Deep dive: Word embeddings & word2vec →The stack of N identical blocks (12 in GPT-2 small). Each block lets every token attend to itself and every EARLIER token (Q/K/V, multi-head, causal mask) and then transforms each position with a feed-forward network, wrapped in residuals + norm. Shape in = shape out; what changes is the content.
Deep dive: Inside a transformer block →The final vector of the last position is projected against the vocabulary to produce one raw score (a logit) for every possible next token. softmax turns these into a probability distribution.
Deep dive: The four distributions (softmax & NLL) →Pick one token from the distribution — greedily, or with temperature / top-k / nucleus sampling for variety. Append it to the input and run the whole pipeline again for the next token.
Sampling loops back to the start: the chosen token is appended and the full pass runs again, one token at a time. The KV cache is what stops this from re-reading the whole prompt on every step. Dimensions are illustrative (d = 768, N = 12, vocab = 50257 — GPT-2 small).
Токенізація: текст → цілі числа
Модель не може використовувати символи та цілі слова. Він використовує токени — підсловні одиниці з фіксованого словника, вивченого один раз перед навчанням за таким алгоритмом, як BPE. Словник GPT-2 становить 50 257 записів BPE рівня байтів. Часті слова (the, cat) є окремою лексемою; більш рідкісні слова, розбиті на частини (tokenization → token + ization); і оскільки він працює на рівні байтів, будь-який рядок — емодзі, код, сміття — завжди має запасний варіант. Результатом є список цілих ідентифікаторів — [976, 9059, 7731, 402, 290] для нашого запиту з п’яти слів.
Чому саме підслова, а не слова чи символи, це справжнє проектне рішення з реальними наслідками для розміру словника, довжини послідовності та того, як модель обробляє друкарські помилки та код. Цей компроміс і алгоритми, які домінують, є глибоке занурення в токенізацію. Для конвеєра єдине, що потрібно перенести: вхід тексту, вихід короткого списку цілих чисел.
Вбудовування: цілі → вектори (плюс позиція)
Ціле число не має значення — 9059 не є «більш котячим», ніж 976. Таблиця вбудовування це виправляє. Це вивчена матриця пошуку форми (vocab, d); кожен ідентифікатор маркера вибирає один рядок, вектор ширини d (768 у GPT-2 small, до 1600 у GPT-2 XL). П’ять ідентифікаторів токенів стають матрицею (5, 768).
У цих векторах «значення стає геометрією» — лексеми, що використовуються в подібних контекстах, закінчуються подібними векторами, тому напрямок і відстань у цьому просторі кодують відносини. Це та сама ідея, яку прославив word2vec, а стаття про вбудовування слів будує інтуїцію з нуля.
GPT-2 робить тут ще одну важливу річ: він додає вивчене позиційне вбудовування. Увага, наступний етап, не має внутрішнього поняття порядку — без сторонньої допомоги «собака кусає людину» і «людина кусає собаку» виглядали б однаково. GPT-2 вирішує це найпростішим способом: друга вивчена таблиця з одним вектором на позицію (слот 0, слот 1, …, до ліміту контексту в 1024 маркери), додана безпосередньо до вбудовування маркера. Отже, кожен вхідний вектор кодує, що є маркером і де він знаходиться. (Це фактична схема GPT-2 — вивчені абсолютні позиції. Пізніші моделі замінили її обертальними вбудовуваннями, RoPE, що є однією з характеристик демонтаж блоку і сучасного LLM.) Одне застереження вирішується на наступному етапі: вбудовування все ще контекстно-вільне — на цьому етапі bank має той самий вектор на «берегу річки». і “банківський рахунок”. Зробити вектор залежним від контексту — це вся робота трансформатора.
Блоки-трансформери: вектори → багатші вектори
Це двигун, і це єдине поле, яке ця стаття навмисно не відкриває повністю — стаття «Всередині трансформаторного блоку» робить саме це, виводячи кожен механізм із проблеми, яку він вирішує. Ось огляд решти конвеєра.
Блок трансформатора приймає матрицю (5, 768) і повертає матрицю (5, 768) — така ж форма, багатший вміст. Вектор кожного токена виходить контекстуалізованим: bank тепер вказує в різних напрямках залежно від того, поруч знаходиться river або account. Блок робить це за допомогою двох підрівнів, кожен з яких загорнутий у залишкове з’єднання та нормалізацію:
- Замаскована самоувага — це те, де позиції спілкуються одна з одною. Кожен токен формує запит, ключ і значення (проекції Q/K/V); запит кожного токена порівнюється з ключами, щоб вирішити, скільки читати з кожного, а результатом є зважена суміш значень. Multi-head запускає декілька з них паралельно (12 головок у GPT-2 small), щоб різні головки могли відстежувати різні зв’язки. Деталлю, що визначає декодер, є причинна маска: маркер може звертати увагу на себе та кожен попередній маркер, але ніколи на пізніший. Саме це робить передбачення наступного токена чесним — модель не може підглянути відповідь — і це єдиний біт архітектури, який відокремлює GPT від BERT.
- Мережа прямого зв’язку – це місце, де кожна позиція думає сама за себе: невеликий двошаровий MLP, що застосовується незалежно до кожного вектора маркера, без змішування між позиціями. Тут живе більшість параметрів моделі.
Потім цей блок складається N разів — 12 у GPT-2 small, 48 у GPT-2 XL — кожен шар ще трохи покращує представлення. Складання ідентичних блоків — це весь трюк: глибина — це те, що перетворює «вектори, які знають своїх сусідів», на «вектори, які зробили щось на зразок міркування».
Причиною уваги є дорога частина, чому вона квадратично масштабується з довжиною послідовності, і чому вікна контексту виходять там, де вони є — все це, а також математика зворотного зв’язку для підрахунку параметрів (≈ 12·N·d²) і пам’яті, опрацьовується в демонтаж блоку і стаття про оптимізацію висновків.
Логіти та вибірка: вектори → маркер
Після останнього блоку ми маємо контекстуалізований вектор для кожної позиції. Для передбачення наступного токена має значення лише остання позиція — його вектор (768,) є підсумком моделі про «все, що наразі, і те, що має відбутися далі». Цей вектор проектується на словниковий запас, щоб отримати одну необроблену оцінку — logit — на кожен запис словника: вектор оцінок (50257,). GPT-2 робить це за допомогою зв’язування ваги: вихідна проекція повторно використовує вхідну таблицю вбудовування, транспоновану, замість вивчення окремої матриці. Та сама таблиця (50257, 768), яка перетворює ідентифікатори на вектори у нижній частині, перетворює вектори назад у бали за маркер у верхній частині — менше параметрів і акуратна симетрія. softmax перетворює ці бали на розподіл ймовірностей, до якого ми будуємо.
Потім вибірка вибирає один жетон. Найпростіший вибір є жадібним — щоразу брати маркер із найвищою ймовірністю, але це створює плоский, повторюваний текст. На практиці ви спочатку змінюєте розподіл:
Logits are frozen; you are reshaping the distribution that the sampler draws from.Temperature < 1 sharpens it toward the top token (at the limit, greedy decoding);> 1 flattens it toward random. top-k keeps only the k highest tokens;top-p (nucleus) keeps the smallest set whose probability sums past p. Cut tokens (hatched) get zero mass and the rest renormalize. Values are illustrative.
Температура ділить логіти перед softmax: нижче 1 вона різкіша до верхнього маркера, вище 1 вона вирівнюється до рівномірного. Top-k зберігає лише k найімовірніших токенів; top-p (ядро) зберігає найменший набір токенів, маса ймовірності яких перевищує поріг. Усі три компроміс між когерентністю та різноманітністю, і всі три працюють на тих самих заморожених логітах — вони змінюють, які токени дозволено малювати семплеру, а не те, що вважає модель. Вибраний токен додається до вхідних даних, і весь проход запускається знову для наступного.
Це повний пас вперед. Залишається два питання: як вагові коефіцієнти моделі дають хороший розподіл (навчання) і як цикл генерації робиться досить дешевим для обслуговування (висновок).
Підрахунок параметрів
Книга блоків нараховує приблизно 12d² параметрів великої матриці на звичайний блок. Для GPT-2 small, d = 768 і 12 блоків дають приблизно 84,9 мільйона. Вбудовані токени (50,257 × 768) додають приблизно 38,6 мільйона, а вивчені позиції (1,024 × 768) додають приблизно 0,79 мільйона. Зі зміщеннями та параметрами нормалізації загальна сума становить близько 124 мільйонів. Прив’язка ваги означає, що зчитування словникового запасу не потребує іншої незалежної матриці розміру вбудованого маркера.
На FFN припадає дві третини ваг великої матриці всередині кожного блоку, але вбудовування залишаються значною частиною цієї невеликої моделі. Ваги змішування уваги є обчисленими активаціями та не входять до підрахунку параметрів.
Як навчився: навчання
Наведений вище перехід вперед фіксується після встановлення ваги. Тренування - це те, як ваги туди потрапили. Для GPT-2 існує фактично одна фаза: попередня підготовка. Моделі було показано великий корпус веб-тексту (WebText OpenAI, ~40 ГБ, зібраний із вихідних посилань Reddit) і попросили в кожній позиції передбачити наступний маркер; його прогноз порівнюється з фактичним наступним маркером із втратою перехресної ентропії, і помилка відсувається назад через кожен шар, щоб підштовхнути кожну вагу. Цей зворотний перехід є зворотним розповсюдженням — правило ланцюга, яке механічно застосовується до всього графа обчислень — і причина, чому воно взагалі працює, полягає в тому, що кожна операція в мережі є диференційованою, що є навмисне обмеження щодо того, що дозволено містити архітектурі. Те, як градієнт фактично протікає крізь складені блоки (і чому залишкові зв’язки так важливі для підтримки його життя на глибині) описано в як течуть градієнти.
Градієнти вказують вам, у якому напрямку рухатися для кожної ваги; оптимізатор вирішує, наскільки далеко. Plain SGD, momentum і Adam — це різні стратегії для перетворення галасливого потоку градієнтів на стабільні кроки, і вибір має великий вплив на те, чи тренується модель взагалі — стаття оптимізаторів проходить через них.
Продуктом попереднього навчання є модель із широкими можливостями, але без манер: GPT-2 є провісником наступного токена, а не помічником. Задайте необробленій моделі запитання, і вона з радістю продовжить із трьома запитаннями, тому що саме це робив текст, який вона побачила. GPT-2 є саме цією необробленою базовою моделлю — у цьому й полягає суть її навчального прикладу. Крок, який перетворює таку базову модель на щось, що відповідає, а не продовжує — після навчання: контрольоване точне налаштування пар інструкція–відповідь, потім налаштування параметрів (RLHF та його нащадки) — з’явився після GPT-2, у рядку InstructGPT/ChatGPT. Здібності випливають із попередньої підготовки; поведінка виліплюється пізніше. Кордон цієї пізньої фази, включаючи дистиляцію за політикою, є предметом на політику дистиляції ст.
Як це працює: висновок
Навчена модель - це купа ваг і цикл генерації з секції прямого проходу. Ефективне виконання цього циклу є окремою інженерною проблемою, і дві ідеї мають більшу вагу навіть для такої маленької моделі, як GPT-2.
Кеш-пам’ять KV – це те, що робить генерацію авторегресії доступною. Згадайте, що генерація додає один маркер і повторює проход. Наївно, це означає повторне обчислення уваги до всього підказки на кожному окремому кроці — квадратичне марнотратство. Але ключі та значення для минулих маркерів не змінюються, коли додається новий маркер, тому вони обчислюються один раз і кешуються. Кожен новий крок обчислює Q/K/V лише для нового токена та перевіряє збережений кеш. Ціною є пам’ять: кеш зростає разом із довжиною контексту. Чому це вузьке місце для висновків і схеми, які його зменшують (увага згрупованого запиту та друзі — сучасні доповнення GPT-2 передували), це глибокі занурення KV-кешування і GQA.
Квантування атакує відбиток пам’яті ваг. Зберігання вагових коефіцієнтів у INT8 або INT4 замість FP16 приблизно вдвічі або вчетверть зменшує обсяг пам’яті та прискорює пов’язані з пам’яттю частини логічного висновку за помірної та часто незначної вартості точності. Чому працює низька точність, що насправді ламається, коли ви натискаєте надто далеко, і як точність взаємодіє з висновком кількох GPU, описано в точність і багатографічний процесор. Повний набір інструментів для обслуговування — безперервне пакетування, увагу на сторінку, спекулятивне декодування — це стаття про оптимізацію висновків.
Форму, яку варто запам’ятати: ваги масштабуються з кількістю параметрів, кеш KV масштабується з довжиною контексту, а обчислення масштабується з обома — та сама арифметика, яку трансформаторно-блоковий ст отримує від розмірів блоку.
Вся машина в одному вигляді
GPT-2 не є одним незбагненним об’єктом. Це ланцюжок перетворень, кожне з яких робить невелику річ, яку можна назвати:
- Токенізація перетворює текст на короткий список цілих чисел зі словника BPE на рівні 50 257 байтів.
- Вбудовування перетворюють кожне ціле число на вивчений вектор і додають вивчений позиційний вектор для його слота.
- Блоки-трансформери — складені N разів — контекстуалізують ці вектори, кожен токен звертається до самого себе та кожного попереднього токена (каузальна маска), а потім трансформується позиційно. Це двигун; демонтаж блоку відкриває його повністю.
- Logits і softmax перетворюють останній вектор на розподіл імовірностей для всього словника, повторно використовуючи таблицю вбудовування (зв’язування ваги).
- Вибірка вибирає один маркер, який додається та повертається назад у цикл генерації.
- Тренування (попереднє навчання здібностям) — це те, як вагові коефіцієнти зробили цей розподіл хорошим; машина виводу (KV-кеш, квантування, пакетування) — це те, як цикл робиться дешевим у обслуговуванні.
Ніщо в цьому списку не є магією, і ніщо в ньому не виходить за межі виконання кроків за кроком. Найкращий спосіб закріпити це — спостерігати за рухом перетворень: 3D візуалізатор LLM Брендана Байкрофта шар за шаром анімує справжній GPT (включно з GPT-2) із розкладкою кожної форми тензора, а інтерактивний “Анатомія LLM” Роя ван Рейна дозволяє натискати повзунки на температуру та вибірку та спостерігати за реакцією розподілу.
GPT-2 — це оригінальний конкретний декодер. З тих пір майже кожна модель є варіацією цього конвеєра з декількома оновленнями — RoPE замість вивчених позицій, RMSNorm, SwiGLU, увага згрупованого запиту, суміш експертів — прикріплені до тієї самої історії введення тексту, розповсюдження, додавання маркерів. Що змінилося, чому та наскільки це насправді важливо – це тема продовження сучасного LLMs. Звідси ви можете або відкрити механізм — стаття «Всередині трансформаторного блоку» привертає увагу, мультиголовка, FFN, позиційні кодування та залишкова + норма з нуля — або повернутися до гілка кодера, щоб побачити, як інша половина поділу використовує той самий механізм.