Як працюють Transformer: від обмежень RNN до уваги, агентів та вікон контексту
Покроковий огляд трансформера: чому RNN зупинилися у розвитку, як працюють токени та ембеддинги, увага, QKV, голови, позиції, структура блоків, масштабування та агенти.
Будь-хто, хто використовує лише інструменти ШІ, може обійтися без розуміння того, що працює під капотом. Але ті, хто хоче створювати, виправляти помилки чи розвивати ці системи, не можуть обійтися без цього розуміння. Кожна з поширених моделей великих мов ґрунтується на одній архітектурі, описаній у 2017 році у п’ятнадцятисторінковій статті під назвою «Attention Is All You Need». Мало які наукові праці останнього десятиліття настільки сильно вплинули на розвиток штучного інтелекту. Ідеї, що лежать в основі цієї архітектури, не є настільки складними, як здається, а математика стає зрозумілою, якщо її пояснювати у правильній послідовності. Після цього ті самі ідеї зустрічаються скрізь: у тому, як агенти планують свої дії, у причинах ефективності навчання в межах контексту, у тому, чому модель може переходити між темами під час розмови, та у причинах такої важливості довших вікон контексту.
Наведений нижче маршрут починається зі старого послідовного підходу та причин його зупинки, розглядає, як текст перетворюється на числа, потім — механізми уваги та повну структуру блоків, і закінчується тим, як цей підхід розвинувся у сучасні моделі мов та агенти.
Чому читання тексту по одному слову викликало труднощі
До появи трансформерів мову переважно обробляли рекурентні нейронні мережі, які зазвичай скорочують до RNN. Ідея проста: мережа проходить через послідовність слів по одному та передає далі прихований стан — кумулятивний огляд усього, що було побачено досі.
Оглядова картина: хтось читає роман, але може зберегти лише одну записку, і йому доводиться читати сторінку за сторінкою, ніколи не пропускаючи вперед чи не повертаючись назад. Після кожного речення записку переписують, додаючи те, що здається важливим, але записка залишається маленькою. До 300-ї сторінки майже нічого з першої сторінки не залишається. Також неможливо передати другові другий розділ для читання одночасно, оскільки спочатку потрібно завершити записки до першого розділу.
Цей суворий порядок спричиняє дві окремі проблеми масштабування.
Перша — це зникнення градієнта. Навчання коригує ваги за допомогою методу зворотного поширення помилки, який визначає, наскільки кожен параметр вплинув на помилку. У RNN, яка читає довгу послідовність, цей сигнал мусить пройти назад через кожен крок часу. До моменту, коли він досягає найраніших кроків, він часто зменшується майже до нуля, тож мережа фактично не може навчитися на тому, що зробили ті перші слова.
Другою проблемою є послідовний вузький місце. Результат на позиції n не можна обчислити до завершення роботи з позицією n-1, оскільки кожен крок використовує попередній прихований стан. Сучасні GPU розроблені для виконання великої кількості операцій одночасно, а RNN майже не дає їм можливостей для паралельної роботи. Документ довжиною 1 000 слів вимагає 1 000 послідовних кроків, причому апаратне забезпечення переважно залишається без роботи між ними.
На діаграмі нижче порівнюються два способи обробки токенів: з одного боку — по одному токену із поступовим зникненням прихованого стану, а з іншого — кожна пара токенів обробляється одночасно:
╔══════════════════════════════════════════════════════════════════════════════╗
║ RNN vs TRANSFORMER: HOW TOKENS ARE PROCESSED ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ RNN ── Sequential (slow, forgets early context) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ║
║ │ │ │ │ │ │ ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ RNN │──▶│ RNN │─▶│ RNN │▶│ RNN │▶│ RNN │▶│ RNN │ ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ h₁ ──▶ h₂ ──▶ h₃ ──▶ h₄ ──▶ h₅ ──▶ h₆ ║
║ ║
║ Step 1 Step 2 Step 3 Step 4 Step 5 Step 6 (must wait!) ║
║ ⚠ "The" signal is diluted through 5 hops by the time we reach "mat" ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────┐ ║
║ │ TRANSFORMER ── Parallel (fast, every token sees all others) │ ║
║ └─────────────────────────────────────────────────────────────────────┘ ║
║ ║
║ "The" "cat" "sat" "on" "the" "mat" ◀── ALL AT ONCE ║
║ │╲╲ │╲ ╲╲ │╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ │ ╲╲ │ ╲ ╲╲ │ ╲╲ ╲ │ ╲╲ │ ╲╲ │ ║
║ ├───╫──┼───╫───┼───╫───┼────╫──┼────╫───┤ ← every token ║
║ │ ╱╱ │ ╱ ╱╱ │ ╱╱ ╱ │ ╱╱ │ ╱╱ │ attends to ║
║ │╱╱ │╱ ╱╱ │╱╱ ╱ │ ╱╱ │ ╱╱ │ every token ║
║ ▼ ▼ ▼ ▼ ▼ ▼ ║
║ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ║
║ │ out │ │ out │ │ out │ │ out │ │ out │ │ out │ ← all computed ║
║ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │ │ 6 │ simultaneously ║
║ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ ║
║ ✓ "The" has DIRECT connection to "mat" — no information decay ║
║ ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ LEGEND: ──▶ sequential dependency ╲╱╱ all-pairs attention ║
║ h₁ hidden state ⚠ information bottleneck ║
╚══════════════════════════════════════════════════════════════════════════════╝
Гейти допомогли, але не змінили суті проблеми
Мережі довготривалої короткострокової пам’яті, запропоновані Хохрайтером та Шмідхубером у 1997 році, включили гейти та чіткий контроль над тим, що зберігати, що видаляти та що генерувати на кожному кроці. Вони добре працювали. Протягом 2010-х років вони використовувалися у більшості практичних застосувань у галузі обробки природної мови, включаючи ранні системи машинного перекладу, аналіз настроїв та генерацію тексту.
Вони залишалися послідовними. Дуже далекі залежності все ще були складними для обробки, а паралельне обладнання ще не могло використовуватися повною мірою. LSTMs зазнали невдачі не тому, що погано моделювали мову. Вони зазнали невдачі тому, що не могли масштабуватися: додавання обчислювальних ресурсів приносило все меншу користь, а для подолання цього обмеження потрібен був зовсім інший підхід до обробки даних.
Від тексту до чисел
Нейронні мережі працюють із числами, а мова складається зі слів, тому перед тим, як вони почнуть аналізувати текст, необхідно здійснити його перетворення. Це вимагає двох кроків: токенізації та вбудовування.
Токенізація
Під час токенізації рядок перетворюється на послідовність цілочисельних ідентифікаторів, взятих з фіксованого словника. Спочатку варто зрозуміти, що токени — це не слова. Сучасні токенайзери розділяють текст на частини, які є підсловами, зазвичай за допомогою методу Byte-Pair Encoding або WordPiece, і результат виглядає ось так:
"Hello world" → ["Hello", " world"] → [15496, 995]
"unbelievable" → ["un", "believ", "able"] → [256, 9391, 540]
"ChatGPT" → ["Chat", "G", "PT"] → [14126, 38, 2969]
"antidisestablishmentarianism" → ["ant", "idis", "est", "ablish", "ment", "ari", "an", "ism"]
Часто вживані слова отримують власний токен, тоді як рідкісні чи складні слова розбиваються на менші частини. Це забезпечує хороше покриття за допомогою словника помірного розміру, адже немає потреби створювати запис для кожного можливого слова. Розмір словників коливається від приблизно 30 000 у BERT та 50 257 у GPT-2 до понад 100 000 у сучасних моделях.
Зручне переведення для англійської мови: один токен дорівнює приблизно трьом чвертям слова, а одне слово — приблизно 1,3 токенів. Тож роман із 100 000 слів складається приблизно з 133 000 токенів, що має значення кожного разу, коли діють обмеження контекстного вікна.
Ембеддинги
Матриця вбудовування, яка має один рядок на кожен елемент словника та d_model стовпців, перетворює кожен ідентифікатор токена на щільний вектор. Щоб знайти токен, достатньо лише вибрати його рядок. Ідентифікатор токена 995, який позначає слово „world“, вказує на рядок 995 та повертає значення d_model – наприклад, 0.24, -0.83, 0.17 тощо аж до 0.91.
Ці рядки формуються під час навчання, і виникає корисна властивість: токени з схожими значеннями мають вектори, які є геометрично близькими.
Cosine similarity in embedding space:
similarity("cat", "lion") ≈ 0.89 ← very similar
similarity("cat", "moon") ≈ 0.12 ← not similar
similarity("king", "queen") ≈ 0.91 ← very similar
Одна застереження щодо відомого прикладу: король мінус чоловік плюс жінка дорівнює королеві. Ця арифметика походить від Word2Vec у 2013 році, а не від ембеддингів трансформерів. Трансформери засвоюють свої ембеддинги разом із усіма іншими параметрами, тому чиста векторна арифметика є менш надійною. Те, що залишається, — це принцип, згідно з яким слова з схожими значеннями знаходяться у сусідніх областях простору.
Однака ширина скрізь
Фіксована величина d_model присутня скрізь у трансформері: у ембеддингах, результатах обробки уваги, а також у вхідних та вихідних даних шарів з передаванням сигналу вперед. Це робиться навмисно. Кожен компонент читає та записує дані у векторний потік фіксованої ширини, який називається потоком залишків та проходить крізь кожен шар. Оскільки всі компоненти працюють із вектором однакового розміру та додають свої результати назад у нього, елементи чисто комбінуються між собою. Саме тому інформацію про позицію можна просто додати до ембеддингу токена: у обох є однакова форма, і сума потрапляє у потік безпосередньо.
Отже, вхідними даними для першого блоку є ембеддинг токенів разом із вектором позиції. Оскільки обидва елементи знаходяться у одному просторі, їхнє додавання не вимагає додаткових параметрів, а інформація про позицію вбудовується у ті самі вектори, які несуть сенс. Моделі у стилі BERT, які обробляють два речення разом, наприклад під час відповідей на запитання з запитанням та уривком тексту, додають ембеддинг сегмента, який вказує, до якого речення належить кожен токен — 0 для першого та 1 для другого. Моделі у стилі GPT його пропускають.
Увага: навчання того, куди дивитися
Близько 2014–2015 років дослідники, які працювали над машинним перекладом, помітили недолік навіть у системах LSTM. Модель скорочувала всю інформацію про вхідне речення до одного вектора фіксованого розміру перед тим, як почати генерувати результат, що створювало ще одну перешкоду. Очевидним питанням було те, чи може модель на кожному кроці генерації поглянути на весь вхідний текст. Відповіддю на це питання став механізм уваги, який змінив підхід до моделювання послідовностей.
Два повсякденні ситуації роблять цю ідею зрозумілою.
На шумній вечірці, де триває десять розмов, мозок не надає кожному звуку однакової ваги під час прослуховування розмови друга. Він посилює голос та напрямок розмови друга, знижуючи гучність інших звуків, але не вимикаючи їх повністю. Це посилення є континуальним, а не перемикачем «ввімкнено/вимкнено».
Коли людині дають класну фотографію та просять знайти вчителя, вона не сканує кожен піксель однаково. Пошук спрямовується безпосередньо на ознаки, які вказують на дорослу особу, такі як зріст порівняно з іншими та пропорції обличчя. Те, що шукають, визначає напрямок погляду.
Обчислювальна увага перетворює ці інтуїції на чотири кроки: мати щось для пошуку, тобто запит; мати набір кандидатів, які можуть бути релевантними; присвоїти кожному кандидату континуальний рейтинг релевантності; та поєднати інформацію, зважену за цими рейтингами.
Є хибне уявлення, яке варто прояснити заздалегідь: увага не означає, що модель зосереджується на одній речі та ігнорує все інше. Результат — це зважена середня величина, до якої вносить внесок кожен елемент, причому деякі з них вносять значно більший внесок, ніж інші. Це поступове розглядання, а не бінарна концентрація.
Оригінальна, додана форма
У своїй початковій формі увага була додатком до моделей RNN та LSTM. На кожному кроці декодування модель робила наступне:
- дивилася на всі приховані стани кодеру;
- обчислювала показник релевантності між поточним станом декодеру та кожним станом кодеру;
- перетворювала ці показники на ваги за допомогою функції softmax;
- брала суму вагованих значень станів кодеру як контекст уваги.
Функція softmax потребує короткого пояснення. Вона перетворює вектор довільних дійсних чисел у розподіл ймовірностей. Кожен показник перетворюється на e вище цього показника, поділене на суму експонент e вище кожного показника. Усі результати є додатніми та дорівнюють 1, а оскільки експонента посилює різницю між великими та малими показниками, елемент із найвищим балом отримує найбільшу частку ваги.
Це було значне покращення, адже тепер модель могла досягати будь-якої частини вхідних даних на кожному кроці. Потім автори статті „Attention Is All You Need“ поставили ще сміливіше запитання: а що, якщо видалити рекурентні механізми та зробити так, щоб увага не була додатковим елементом, а стала всією моделлю?
Самоувага та тріо запиту, ключа та значення
Центральною ідеєю статті 2017 року є самоувага. Замість того, щоб зосереджуватися від однієї послідовності до іншої, кожен токен у одній послідовності зосереджується на кожному іншому токені в тій самій послідовності. Саме так трансформери створюють контекст, а для його розуміння потрібні три вектори, які використовуються під час кожного обчислення уваги: запит, ключ та значення.
Мотор пошуку відео
Введення фрази «як зробити хліб з сирої дріжджів» на відеосайт не означає порівняння цього тексту з кожним кадром кожного відео. Кожне відео має метадани у вигляді позначок, які виконують роль ключів: назва, теги, ключові слова опису. Сайт порівнює запит із цими позначками, щоб отримати оцінки релевантності, а потім відображає відео з найвищими оцінками, щоб можна було отримати їхній фактичний контент.
Існує одна важлива особливість. Результатом є не одне відео, а змішання всіх відео одночасно з урахуванням їхньої ваги; кожне з них відтворюється з гучністю, пропорційною його релевантності. Найбільш релевантне відео домінує, а менш релевантні відео додають свій внесок у меншій мірі. Спосіб мапування є наступним:
| YouTube Concept | Attention Concept | Question it Answers |
|----------------|------------------|---------------------|
| Search query | **Query (Q)** | "What am I looking for?" |
| Video metadata/tags | **Key (K)** | "What do I contain?" |
| Actual video content | **Value (V)** | "What should I contribute?" |
Чому три окремі вектори
Чому б не порівнювати ембеддинги безпосередньо? Візьмемо речення "Кіт сидів на килимку, тому що він був втомлений." Щоб з’ясувати, на що посилається "він", слово має враховувати "кіта". Однак у первинному просторі ембеддингів займенник та іменник не є особливо схожими. Розділення на запити та ключі дозволяє моделі зрозуміти, що запит займенника має збігатися з ключами іменників, на які він може посилатися, навіть коли займенник та іменник зовсім не схожі у своїх базових ембеддингах. Навчені проекції створюють простір релевантності, який відрізняється від простору схожості первинних ембеддингів. Релевантність та схожість — це різні поняття, і конструкція QKV дозволяє моделі кодувати обидва.
Масштабована увага з дотичним добутком у чотири кроки
Перший крок — це проєкція. Ембеддинг кожного токена множиться на три навчені матриці, W_Q, W_K та W_V, що дає запит, ключ та значення для цього токена.
Другий крок вимірює сумісність. Питання полягає у тому, наскільки добре токен a відповідає токену b, а відповідь — це скалярний добуток запиту для a та ключа для b. Висока цінність означає, що токен a повинен уважно стежити за токеном b. Скалярні добутки зростають з розміром вектора та з розмірністю ключа d_k, а не лише з напрямком, тому наступний крок їх масштабує.
Третій крок — це масштабування та нормалізація. Коли d_k великий, необроблені скалярні добутки стають великими та змушують функцію softmax працювати в діапазонах, де градієнти мізерні. Ділення на квадратний корінь d_k перед застосуванням softmax запобігає цьому, що й дало назву методу — масштабована увага на основі скалярного добутку. Результатом є набір ваг alpha_ab.
Четвертий крок — агрегація. Результат для токена a — це сума, по кожному токену b, значень alpha_ab помножених на вектор значень для b.
Усі токени можна обробляти разом як матриці в одному компактному виразі: Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V. На діаграмі показано цей процес для трислівного виразу „the cat sat“:
╔══════════════════════════════════════════════════════════════════════════════╗
║ SCALED DOT-PRODUCT ATTENTION ── "the cat sat" ║
╚══════════════════════════════════════════════════════════════════════════════╝
STEP 1: Input embeddings - ALL tokens are stacked into one matrix X
┌─────────────────────────────────────────┐
│ "the"→x₁ "cat"→x₂ "sat"→x₃ │ X ∈ ℝⁿˣᵈ
└──────────────────┬──────────────────────┘
│ the SAME X feeds all three projections
STEP 2: Three separate linear projections (each applied to every token)
┌─────────────┴─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ W_Q │ │ W_K │ │ W_V │ ← learned weight matrices
└────┬────┘ └────┬────┘ └────┬────┘
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Q rows │ │ K rows │ │ V rows │
│ q₁ │ │ k₁ │ │ v₁ │
│ q₂ │ │ k₂ │ │ v₂ │
│ q₃ │ │ k₃ │ │ v₃ │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
STEP 3: score = QKᵀ, scale by 1/√dₖ, then softmax row-wise
│ │ │
└──────┬──────┘ │
▼ │
┌─────────────────────┐ │
│ softmax(QKᵀ / √dₖ) │ │
│ the cat sat │ │
│ the[.72 .20 .08] │ │ each row
│ cat[.12 .71 .17] │ │ sums to 1.0
│ sat[.09 .28 .63] │ │
└──────────┬──────────┘ │
│ │
STEP 4: multiply weights by Values V (weighted sum)
└──────────┬─────────┘
▼
┌─────────────────┐
│ output for "cat"│ 0.12·v₁ + 0.71·v₂ + 0.17·v₃
└────────┬────────┘ ← rich context-aware vector
│
OUTPUT: contextualized token representations
┌──────────┐ ┌──────────┐ ┌──────────┐
│"the" │ │"cat" │ │"sat" │
│knows it │ │knows it │ │knows │
│precedes │ │sat, and │ │who was │
│"cat" │ │where │ │sitting │
└──────────┘ └──────────┘ └──────────┘
Приклад з реального використання: банк слів
Візьмемо речення „Вона пішла до банку, щоб внести гроші“. Під час кодування слова „банк“ трансформатором механізм самоуваги дозволяє цьому слову одночасно аналізувати кожне інше слово. Великі ваги надаються словам „внести“ та „гроші“, що впливає на фінансове значення слова „банк“ у його представленні. Контекст усуває неоднозначність.
╔══════════════════════════════════════════════════════════════════════════════╗
║ SELF-ATTENTION RESOLVES AMBIGUITY: What does "bank" mean? ║
╚══════════════════════════════════════════════════════════════════════════════╝
Sentence: "I went to the bank to deposit money"
t₁ t₂ t₃ t₄ t₅ t₆ t₇ t₈
ATTENTION WEIGHTS for token "bank" (t₅) attending to all other tokens:
Token │ Weight │ Visualization
──────────┼────────┼───────────────────────────────────────────
"I" │ 0.03 │ ░
"went" │ 0.04 │ ░
"to" │ 0.02 │
"the" │ 0.03 │ ░
"bank" │ 0.08 │ ░░
"to" │ 0.05 │ ░
"deposit" │ 0.38 │ ████████████████████████░░░░░░░░ ← strong!
"money" │ 0.37 │ ████████████████████████░░░░░░░ ← strong!
FULL ATTENTION HEATMAP (rows = query token, columns = key token):
Higher weight → more ░/▒/▓/█
Q\K │ I went to the bank to deposit money
──────────┼──────────────────────────────────────────────
I │ ▓ ░ ░ ░ ░ ░ ░ ░
went │ ░ ▓ ░ ░ ░ ░ ░ ░
bank │ ░ ░ ░ ░ ▒ ░ █ █ ← "bank"→"deposit","money"
deposit │ ░ ░ ░ ░ █ ░ ▓ ▒ ← "deposit"→"bank"
money │ ░ ░ ░ ░ █ ░ ▒ ▓ ← "money"→"bank"
BEFORE attention: "bank" = ambiguous (river bank? financial bank?)
AFTER attention: "bank" ≈ 0.38·v(deposit) + 0.37·v(money) + ...
→ "bank" representation is now strongly financial ✓
The model learned this WITHOUT any explicit disambiguation rules.
Ваги на тій ілюстрації показані для наглядності та не є частиною реальної моделі. Фактичні патерни зазвичай є більш хаотичними, а дослідження того, як ваги уваги пов’язані з тим, про що „думає“ модель, все ще тривають. Практична користь відрізняється від тієї, що показана на малюнку: самоувага до всіх токенів — це множення матриць, одна операція на GPU. Те, що для RNN коштує n послідовних кроків, для трансформера коштує однієї паралельної операції, і саме тому трансформери ефективні у великих обсягах даних.
Кілька голів, кілька „об’єктивів“
Один механізм обробки обчислює один тип взаємозв’язку за раз, тож що відбувається, коли важливі кілька типів взаємозв’язків одночасно? Розгляньте речення «Музикант, який виступив на фестивалі, виграв нагороду». Щоб його зрозуміти, потрібно відстежувати кілька залежностей одночасно: зв’язок «виграв» з «музикантом» як підметом та дієсловом, зв’язок «музикант» з «виступив» через відносний речення, зв’язок «виступив» з «фестивалем» щодо місця та зв’язок «нагороду» з «виграв» як дієсловом та об’єктом.
Одна голова мусила б помістити все це в один набір ваг. Натомість багатоголова увага виконує функцію уваги h разів паралельно, кожного разу з власними навченими проекціями для запитів, ключів та значень. Результати h вихідних даних об’єднуються та проходять через ще одну навчену матрицю W_O, яка переводить їх назад у розмір моделі. Кожна голова працює у меншому підпросторі, де d_k дорівнює d_model поділеному на h, тож загальна вартість обробки для всіх голів приблизно дорівнює вартості однієї голови повної ширини.
Уявіть рукопис, надісланий до редакційного комітету. Редактор з граматики перевіряє синтаксис, редактор зі стилю слідкує за наративним потоком, перевіряючий факти шукає семантичну послідовність, а редактор зі структури контролює довгострокову організацію. Усі вони читають одночасно та незалежно, а їхні примітки об’єднуються в один огляд. Багатоголова увага працює аналогічним чином.
╔══════════════════════════════════════════════════════════════════════════════╗
║ MULTI-HEAD ATTENTION (3 heads shown) ║
╚══════════════════════════════════════════════════════════════════════════════╝
Input Embedding x ∈ ℝᵈ_model
┌────────────────────────────┐
│ [ x₁ x₂ x₃ ... xₙ ] │
└──────────┬─────────────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
╔══════════════╗ ╔══════════════╗ ╔══════════════╗
║ HEAD 1 ║ ║ HEAD 2 ║ ║ HEAD 3 ║
║ "Syntax" ║ ║ "Semantics" ║ ║ "Position" ║
║ ║ ║ ║ ║ ║
║ W_Q¹ W_K¹ ║ ║ W_Q² W_K² ║ ║ W_Q³ W_K³ ║
║ W_V¹ ║ ║ W_V² ║ ║ W_V³ ║
║ ║ ║ ║ ║ ║
║ ┌──────────┐ ║ ║ ┌──────────┐ ║ ║ ┌──────────┐ ║
║ │ Scaled │ ║ ║ │ Scaled │ ║ ║ │ Scaled │ ║
║ │ Dot- │ ║ ║ │ Dot- │ ║ ║ │ Dot- │ ║
║ │ Product │ ║ ║ │ Product │ ║ ║ │ Product │ ║
║ │Attention │ ║ ║ │Attention │ ║ ║ │Attention │ ║
║ └────┬─────┘ ║ ║ └────┬─────┘ ║ ║ └────┬─────┘ ║
║ │ ║ ║ │ ║ ║ │ ║
║ learns: ║ ║ learns: ║ ║ learns: ║
║ subject-verb ║ ║ word meaning ║ ║ nearby-word ║
║ agreement ║ ║ similarity ║ ║ relationships║
╚══════╤═══════╝ ╚══════╤═══════╝ ╚══════╤═══════╝
│ head₁ ∈ ℝⁿˣ⁽ᵈ/ʰ⁾ │ head₂ │ head₃
└───────────────────┼───────────────────┘
▼
┌──────────────────────────────┐
│ CONCATENATE all heads │
│ [head₁ ║ head₂ ║ head₃] │ ∈ ℝⁿˣᵈ_model
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Final linear projection W_O │ blends info from all heads
└──────────────┬───────────────┘
▼
┌──────────────────────────────┐
│ Multi-Head Attention Output │ ∈ ℝⁿˣᵈ_model (same shape as input)
└──────────────────────────────┘
Що насправді роблять голови
Аналізи навчених моделей виявили голови, які спеціалізуються. Деякі з них відстежують синтаксис, такий як узгодження підмета та дієслова та модифікатори, що приєднуються до іменників. Інші працюють на великих відстанях, пов’язуючи займенники з їхніми антецедентами. Є ще голови, які діють локально, звертаючи увагу на сусідні слова та патерни біграм. Деякі визначають відносну відстань між токенами, а інші виокремлюють тематичні ролі, тобто хто що зробив кому. Ніхто це не програмує. Під час навчання винагороджуються точні прогнози, і мережа розуміє, що розділення завдань між спеціалізованими головами є ефективним.
Обмеження цього підходу: ці категорії переважно походять з досліджень щодо інтерпретованості менших моделей. У великих моделях багато компонентів неможливо чітко прочитати, і експерименти показують, що такі моделі часто залишаються стабільними після видалення багатьох компонентів з мінімальними втратами. Архітектура дозволяє спеціалізацію, але не гарантує чіткого розділення, зрозумілого для людини.
Надання словам адреси
Самоувага пов’язує кожну пару токенів, але при цьому розглядає послідовність як множину без певного порядку. Оцінка між будь-якими токенами a та b залежить лише від їхнього змісту, а не від того, який з них йде першим чи наскільки вони розташовані один від одного. Мова сильно залежить від порядку. Фрази „Собака кусає чоловіка“ та „Чоловік кусає собаку“ містять однакові слова, але означають протилежне, а вираз „Не щасливий“ означає зовсім інше, ніж „Щасливий, але не“. Оскільки трансформер обробляє всі позиції паралельно, за замовчуванням він не кодує порядок, тому його потрібно явно вказувати. Саме це і є завданням позиційного кодування.
Уявіть собі додавання метаданих до кожної будівлі в місті. Кожній з них потрібна адреса, яка визначає її місцезнаходження, показує відносне положення (будівля 402 знаходиться поруч із 404) та працює без необхідності знати весь план міста заздалегідь. GPS-координати ефективно виконують цю функцію. Кодування положення — це його лінгвістична версія: математична координата, додана до представлення кожного слова.
Хвилі синуса та косинуса
Спочатку для цього використовувалися синусоїдальні функції — по одній частоті на кожну пару розмірностей вбудовування. Для положення pos та індексу розмірності k у вектор додаються синуси та косинуси значення pos, розділені на степінь 10000 та множені на k. Повільні, низькочастотні хвилі позначають крупне положення, а швидкі, високочастотні — дрібне; разом вони надають кожному положенню унікальний «відбиток».
╔══════════════════════════════════════════════════════════════════════════╗
║ SINUSOIDAL POSITIONAL ENCODING ║
╚══════════════════════════════════════════════════════════════════════════╝
GRID: exact values for a tiny d_model=8 - positions 0-4, dims 0-7
(frequency denominators are 1, 10, 100, 1000 for dim-pairs 0,1,2,3)
dim→ d=0 d=1 d=2 d=3 d=4 d=5 d=6 d=7
sin cos sin cos sin cos sin cos
pos↓ ──────────────────────────────────────────────────────
pos=0 │ 0.000 1.000 0.000 1.000 0.000 1.000 0.000 1.000 │
pos=1 │ 0.841 0.540 0.100 0.995 0.010 1.000 0.001 1.000 │
pos=2 │ 0.909 -0.416 0.199 0.980 0.020 1.000 0.002 1.000 │
pos=3 │ 0.141 -0.990 0.296 0.955 0.030 1.000 0.003 1.000 │
pos=4 │ -0.757 -0.654 0.389 0.921 0.040 0.999 0.004 1.000 │
↑ fast-changing ↑ medium-changing ↑ very slow
(high frequency) (mid frequency) (low freq)
unique per position gradual shift global structure
WAVE PATTERNS (each row = one dimension across positions):
dim 0 (sin): █ ▇ ▄ ▁ ▂ ▅ ▇ █ ▇ ▄ ▁ ← fast oscillation
dim 2 (sin): █ █ ▇ ▇ ▆ ▅ ▄ ▃ ▂ ▁ ▁ ← medium oscillation
dim 4 (sin): █ █ █ █ █ █ ▇ ▇ ▇ ▇ ▆ ← slow oscillation
dim 6 (sin): █ █ █ █ █ █ █ █ █ █ █ ← very slow oscillation
HOW IT'S USED: Added to the token embedding elementwise
┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│ Token Embedding│ │ Positional Enc. │ │ Final Input x_t │
│ "cat" │ │ position = 2 │ │ │
│ [0.2, 0.8, │ │ [0.9,-0.4, │ │ [1.1, 0.4, │
│ 0.1, 0.5, │ + │ 0.2, 1.0, │ = │ 0.3, 1.5, │
│ 0.9, 0.3] │ │ 0.0, 1.0] │ │ 0.9, 1.3] │
│ (meaning) │ │ (where in seq) │ │ (meaning+position)│
└─────────────────┘ └─────────────────┘ └──────────────────┘
WHY SINUSOIDS?
✓ Each position gets a unique encoding across all dimensions
✓ Distance between nearby positions is consistent and learnable
✓ Can represent any position mathematically (unlike learned embeddings)
✓ Model can attend to relative positions via linear combinations
Нижчі розміри швидко коливаються та фіксують детальну позицію, тоді як вищі розміри змінюються повільно та відображають глобальний порядок. Вектор просто додається до ембеддингу токена.
Фіксовані хвилі, навчені таблиці та обертання
Синусоїдальна схема має корисну математичну властивість: кодування в позиції pos+k є лінійною функцією від кодування в позиції pos. Тому відносні зсуви представлені послідовно, що полегшує засвоєння позиційних взаємозв’язків.
Позиційні імбеддинги, які є окремою таблицею з одним записом на кожну позицію, як це використовує BERT, є простішими, але не можуть екстраполювати дані за межі позицій, які бачилися під час навчання, тоді як синусоїди в принципі можуть представляти будь-яку позицію. Проте синусоїди також не повністю вирішують проблему узагальнення на довгі контексти. Моделі все ще мають труднощі з послідовностями, які значно довші за їхні дані навчання, оскільки самі шаблони уваги також мають узагальнюватися на невідомі відстані.
Моделі на кшталт Llama використовують Rotary Position Embeddings, або RoPE. Перш ніж обчислювати дотичні добутки, запити та ключі обертаються під кутом, пропорційним їхнім положенням. У добутку запиту з певного положення та ключа з іншого положення відносне обертання безпосередньо кодує зсув. Використання відносного положення як прямого вхідних даних для оцінки уваги, замість чогось непрямого, що вивчається через матриці проекції, допомагає ефективно працювати з довгими контекстами.
Повна архітектура
Тепер можна зібрати всі елементи. На діаграмі показано сучасну версію структури з використанням Pre-LayerNorm:
╔═══════════════════════════════════════════════════════════════════════════════════════╗
║ THE COMPLETE TRANSFORMER ARCHITECTURE (Pre-LayerNorm, modern) ║
╠═══════════════════════════════════════════╦═══════════════════════════════════════════╣
║ ENCODER (×N layers) ║ DECODER (×N layers) ║
╠═══════════════════════════════════════════╬═══════════════════════════════════════════╣
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ Linear → Softmax → P(next token) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ ⊕ Add (residual) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ ║ ┌───────────────────────────────────────┐ ║
║ ║ │ FFN( LayerNorm(x) ) │ ║
║ ║ └───────────────────────────────────────┘ ║
║ ║ ▲ ║
║ Encoder output → K, V (to decoder) ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ ⊕ Add (residual) │ ║
║ ┌───────────────────────────────────────┐ ║ └───────────────────────────────────────┘ ║
║ │ ⊕ Add (residual) │ ║ ▲ ║
║ └───────────────────────────────────────┘ ║ ┌───────────────────────────────────────┐ ║
║ ▲ ║ │ Cross-Attention │ ║
║ ┌───────────────────────────────────────┐ ║ │ Q ← decoder │ ║
║ │ FFN( LayerNorm(x) ) │ ║ │ K, V ← encoder output │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ ⊕ Add (residual) │ ║ │ ⊕ Add (residual) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Multi-Head Self-Attention │ ║ │ Masked Multi-Head Self-Attention │ ║
║ │ ( on LayerNorm(x), bidirectional ) │ ║ │ ( on LayerNorm(x), causal ) │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Input Embedding + Positional Enc. │ ║ │ Output Embedding + Positional Enc. │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
║ ▲ ║ ▲ ║
║ ┌───────────────────────────────────────┐ ║ ┌───────────────────────────────────────┐ ║
║ │ Source: "The cat sat on the mat" │ ║ │ Target (shifted): <BOS> "Le" "chat"… │ ║
║ └───────────────────────────────────────┘ ║ └───────────────────────────────────────┘ ║
╠═══════════════════════════════════════════╩═══════════════════════════════════════════╣
║ Data flows UPWARD (▲). Each sub-layer is a residual branch over a ║
║ LayerNorm-ed input: h = x + SubLayer( LayerNorm(x) ) ║
║ The encoder's output (K, V) flows into the decoder's Cross-Attention. ║
╚═══════════════════════════════════════════════════════════════════════════════════════╝
Трансформер складається з двох основних частин — енкодера та декодера. У оригінальній статті кожен з них мав 6 шарів, по 8 голів уваги та параметр d_model розміром 512.
Енкодер: розуміння в контексті
Енкодер читає послідовність вхідних даних та створює контекстуалізоване представлення кожного токена, фіксуючи не те, що означає слово окремо, а те, що воно означає в цьому конкретному реченні. Він використовує двонапрямкову самоувагу, тож кожен токен може брати до уваги всі інші токени з обох сторін. Саме так вирішується зазначена вище двозначність слова „bank“: модель бачить одночасно „deposit“ та „money“.
Шість шарів кодувача працюють по черзі, кожен з яких удосконалює представлення інформації. Ранні шари зосереджуються на синтаксисі, такому як порядок слів та частини мови. Середні шари обробляють більш складні граматичні структури. Пізніші шари фіксують високорівневий зміст, такий як типи ентитетів, структура подій та прагматика. Саме ця ієрархія є причиною такої ефективності методу перенесення знань: тонке налаштування переважно впливає на пізніші шари, тоді як загальні лінгвістичні закономірності ранніх шарів залишаються корисними для різних завдань.
Декодер: генерація з використанням пам’яті
Декодер генерує результати по одному токену за раз, авторегресивно. Кожен новий токен залежить від усього, що було вже генеровано, а також від усього закодованого вхідного даних. Він має три підшари.
Перший тип — це маскована самоувага, яку також називають причинно-наслідковою увагою. Декодер може дивитися лише на токени, які він вже створив, що забезпечується причинно-наслідковою маскою. Значення над діагоналлю перед функцією softmax ставляться дорівними мінус нескінченності, що робить майбутні токени невидимими. Таким чином процес навчання збігається з процесом інференсу, оскільки модель повинна прогнозувати кожен токен лише на основі попереднього контексту.
╔══════════════════════════════════════════════════════════════════════════╗
║ DECODER SELF-ATTENTION: Causal (Autoregressive) Masking ║
║ "Each token can only attend to itself and tokens before it" ║
╚══════════════════════════════════════════════════════════════════════════╝
Tokens: [The] [cat] [sat] [on] [mat]
t₁ t₂ t₃ t₄ t₅
ATTENTION SCORE MATRIX (row = query, col = key)
KEY → t₁ t₂ t₃ t₄ t₅
QUERY ↓ "The" "cat" "sat" "on" "mat"
──────────────────────────────────────
t₁ "The" │ ✓ ✗ ✗ ✗ ✗
t₂ "cat" │ ✓ ✓ ✗ ✗ ✗
t₃ "sat" │ ✓ ✓ ✓ ✗ ✗
t₄ "on" │ ✓ ✓ ✓ ✓ ✗
t₅ "mat" │ ✓ ✓ ✓ ✓ ✓
✓ = ALLOWED (score kept, participates in softmax)
✗ = MASKED (score → −∞, becomes 0 after softmax)
When generating t₃ "sat":
Raw scores: [ 2.1 3.4 1.8 -∞ -∞ ]
After softmax: [ 0.18 0.68 0.14 0 0 ]
↑
future tokens are invisible
WHY IS MASKING NECESSARY?
┌──────────────────────────────────────────────────────────┐
│ TRAINING: We feed the whole target sequence at once │
│ (teacher-forcing). Without masking, t₃ could "cheat" │
│ by looking at t₄ and t₅ - the answers it should │
│ be predicting. │
│ │
│ INFERENCE: We generate one token at a time anyway, │
│ so future tokens literally don't exist yet. Masking │
│ makes training match inference behavior exactly. │
└──────────────────────────────────────────────────────────┘
Другий елемент — це крос-увага, місток між кодером та декодером. Запити походять від декодера та відображають поточний стан генерації, тоді як ключі та значення походять від кодера та показують, що було сказано у вхідному тексті. Переклад відбувається саме так: коли декодер генерує французьке слово „chat“, він запитує представлення всього англійського речення в кодері, і крос-увага спрямовує велику вагу на слово „cat“.
Третій елемент — це мережа з передаванням сигналу вперед, яка виконує таку саму функцію, що й мережа в кодері, і про неї йтиметься нижче.
Три групи, побудовані з однакових елементів
Поєднання кодера та декодера — це лише один спосіб використання цих компонентів, а різні завдання вимагають різних комбінацій:
| Model | Architecture | Training Objective | Best For |
|-------|-------------|-------------------|----------|
| **BERT** | Encoder-only | Masked Language Modeling | Understanding: classification, NER, QA |
| **GPT** | Decoder-only | Next token prediction | Generation: writing, coding, conversation |
| **T5** | Encoder-Decoder | Text-to-text seq-to-seq | Transformation: translation, summarization |
╔══════════════════════════════════════════════════════════════════════════════════════╗
║ BERT vs GPT vs T5: Architecture Families ║
╠══════════════════╦═══════════════════════════╦═════════════════════════════════════╣
║ BERT ║ GPT ║ T5 ║
║ Encoder-Only ║ Decoder-Only ║ Encoder + Decoder ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ ATTENTION: ║ ATTENTION: ║ ATTENTION: ║
║ t₁ ● ● ● ● ║ t₁ ● ║ Encoder: ● ● ● ● (bidir) ║
║ t₂ ● ● ● ● ║ t₂ ● ● ║ ● ● ● ● ║
║ t₃ ● ● ● ● ║ t₃ ● ● ● ║ Decoder: causal + ║
║ t₄ ● ● ● ● ║ t₄ ● ● ● ● ║ cross-attn to encoder ║
║ (bidirectional) ║ (causal/left-only) ║ ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ BEST FOR: ║ BEST FOR: ║ BEST FOR: ║
║ ✓ Classification ║ ✓ Text generation ║ ✓ Translation ║
║ ✓ NER / tagging ║ ✓ Completion ║ ✓ Summarization ║
║ ✓ Sentence embeds ║ ✓ Chat / dialogue ║ ✓ Question answering ║
║ ✓ Reading comp. ║ ✓ Code generation ║ ✓ Any seq-to-seq task ║
╠══════════════════╬═══════════════════════════╬═════════════════════════════════════╣
║ EXAMPLES: ║ EXAMPLES: ║ EXAMPLES: ║
║ BERT, RoBERTa ║ GPT-4o, Claude 4, ║ T5, BART, ║
║ DeBERTa ║ Llama 4, Gemini 2.5 ║ mT5, FLAN-T5 ║
╚══════════════════╩═══════════════════════════╩═════════════════════════════════════╝
BERT читає в обох напрямках та підходить для завдань розуміння тексту. GPT генерує текст зліва направо за допомогою причинно-наслідкового маскування. T5 зберігає повну архітектуру для структурованої трансформації послідовностей. Вибір між ними залежить від підбору архітектури до конкретного завдання, а не від того, який з них кращий. Коротко кажучи, енкодер створює двонапрямкові контекстуальні представлення, декодер генерує текст авторегресивно з використанням причинно-наслідкового маскування та крос-уваги, а різні підмножини цієї структури налаштовуються для розуміння, генерації та трансформації.
Допоміжні елементи
Увага та шар передавання сигналу привертають найбільше уваги, але ще три елементи запобігають занепаду функцій глибоких трансформерів під час навчання: самі мережі передавання сигналу, нормалізація шарів та залишкові з’єднання.
Мережі передавання сигналу: час обробки на один токен
Після кожного шару уваги в кожному блоку йде мережа з прямим передаванням даних за позиціями. Вектор кожного токена проходить через ту саму двошарову MLP, яка застосовується окремо до кожної позиції: множення на W1, додавання зсуву, застосування нелінійної функції GeLU, потім множення на W2 та додавання ще одного зсуву. W1 переводить розмір від d_model до чотирьох разів d_model, а W2 — назад. У початкових розмірах це 512, яке збільшується до 2048 та зменшується до 512, що дає мережі можливість зберігати та перетворювати інформацію, яку сама увага не може зафіксувати.
Ключовою фразою є «за позиціями», оскільки цей шар обробляє кожен токен окремо. Увага є механізмом комунікації, коли токени спілкуються між собою, а мережа з прямим передаванням даних — механізмом обробки, де кожен токен обробляє інформацію, яку він зібрав.
Geva та його колеги (2021) виявили, що ці шари поводяться дещо схоже на пам’яті типу «ключ-значення», і можна ідентифікувати окремі нейрони, які активуються для певних семантичних концепцій. Коли модель мовлення «знає», що Париж — це столиця Франції, цей зв’язок переважно зберігається у вагах прямого передавання сигналу. Це пояснює дві речі: налаштування моделі може оновлювати фактичні знання, оскільки воно змінює саме ці ваги. А генерація з підсиленням через пошук працює тому, що факт поміщається у вікно контексту, куди увага може безпосередньо дістатися.
Резидуальні з’єднання
Градієнти, які рухаються назад через глибоку мережу, зменшуються протягом багатьох шарів. Резидуальне з’єднання, також відоме як пропускне з’єднання, ефективно вирішує цю проблему: вихідний сигнал підшару є результатом роботи цього підшару плюс його власний вхід. Таким чином шару потрібно опановувати лише зміну, тобто резидуал, а не всю функцію мапування. Це створює «шосе», по якому градієнти можуть рухатися прямо назад, обходячи будь-які шари, і саме тому сучасні трансформери можуть мати 96 або більше шарів без погіршення якості навчання.
Нормалізація шару: контроль масштабів
Нормалізація шару стандартизує вектор активації кожного токена до середнього значення нуль та дисперсії одиниця, а потім застосовує навчений масштаб gamma та зсув beta. Статистичні показники беруться з характеристик d_model одного токена: середнє значення — це проста середня з його елементів, а дисперсія — це середнє квадратичне відстань від цього середнього значення. Малий константний параметр epsilon, зазвичай 10 у мінус 5 степенях, додається всередину квадратного кореня, щоб уникнути ділення на нуль. На відміну від батч-нормалізації, обчислення виконується для кожного токена окремо, а не для всього батчу, що підходить для послідовностей різної довжини.
Сучасна структура блоку
У початковій роботі використовувався LayerNorm після додавання резидуалу, що називається Post-LN. Майже кожна сучасна модель — від GPT-2 та GPT-3 до Llama, а також практично всі моделі, навчені з приблизно 2020 року, — використовує Pre-LayerNorm та нормалізує дані перед кожним підшаром. Pre-LN забезпечує більш стабільне навчання та не вимагає попереднього налаштування швидкості навчання.
Кожен блок потім додає гілку уваги та гілку передавання даних до вже нормалізованих вхідних даних. Перший проміжний стан — це вхідні дані плюс ефект уваги, застосований до нормалізованих даних, а другий стан — цей проміжний результат плюс мережа передавання даних, застосована до її власної нормалізованої версії. Якщо переглянути код будь-якого сучасного трансформера, можна побачити, що LayerNorm розташований перед етапом уваги та перед етапом передавання даних. Повторивши цей блок N разів, де N може бути 6, 12, 24, 96 або більше залежно від розміру моделі, утворюється весь трансформер.
Механізм уваги — це геніальна ідея. Ці допоміжні елементи — це інженерні рішення, які забезпечують функціонування цієї ідеї. Шари з передачею сигналу без зворотного зв’язку здійснюють обчислення для кожного токена, що зберігає фактичні асоціації; резидуальні шляхи надають градієнтам маршрут крізь структуру моделі, а Pre-LN підтримує стабільність активацій. Разом вони роблять можливим використання десятків блоків.
Шлях речення
Один цілісний процес виглядає так: токенізація, вбудовування значень, додавання кодування позиції, кодування, декодування по одному токену за раз, а потім проєктування на словниковий запас. Наступна діаграма показує процес перекладу фрази „Hello world“:
╔══════════════════════════════════════════════════════════════════════════╗
║ END-TO-END DATA FLOW: "Hello world" → Translation ║
╚══════════════════════════════════════════════════════════════════════════╝
STAGE 1: Tokenization
┌─────────────────────────────────────────────────────────────────┐
│ Raw text: "Hello world" │
│ ↓ Tokenizer (BPE / WordPiece) │
│ Token IDs: [ 7592, 2088 ] ← integers into vocabulary │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 2: Embedding Lookup e_t = E[t] ∈ ℝ^512
┌─────────────────────────────────────────────────────────────────┐
│ 7592 → [0.21, -0.54, 0.88, ...] "Hello" │
│ 2088 → [0.67, 0.12,-0.34, ...] "world" │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 3: Add Positional Encoding x_t = e_t + PE(t)
┌─────────────────────────────────────────────────────────────────┐
│ embedding + PE = input vector carrying BOTH meaning AND order │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 4: Encoder Stack (× N layers)
┌─────────────────────────────────────────────────────────────────┐
│ ╔═══════════════════════════════════╗ │
│ ║ Each Encoder Layer: ║ × 6 │
│ ║ h₁ = x + Attn(LayerNorm(x)) ║ │
│ ║ h₂ = h₁ + FFN(LayerNorm(h₁)) ║ │
│ ╚═══════════════════════════════════╝ │
│ After 6 layers: rich contextual reps - "Hello" knows context │
└──────────────────────┬──────────────────────────────────────────┘
↓ (K, V flow into decoder cross-attention)
STAGE 5: Decoder Stack (generates tokens autoregressively)
┌─────────────────────────────────────────────────────────────────┐
│ Step 1: <BOS> → Decoder → predict "Hola" │
│ Step 2: <BOS> "Hola" → Decoder → predict "mundo" │
│ Step 3: <BOS> "Hola mundo" → Decoder → predict <EOS> │
│ │
│ Each step: ① Masked self-attention on generated tokens │
│ ② Cross-attention: Q←decoder, K,V←encoder │
│ ③ LayerNorm → FFN → residual │
└──────────────────────┬──────────────────────────────────────────┘
↓
STAGE 6: Output Projection & Softmax
┌─────────────────────────────────────────────────────────────────┐
│ hidden state → W_vocab → logits over 50k vocab items │
│ → softmax → probability distribution │
│ → sample or argmax → next token │
└──────────────────────┬──────────────────────────────────────────┘
↓
"Hola mundo" ✓
Як стаття про переклад перетворилася на мовну модель
Це описує повну архітектуру, але як проект машинного перекладу перетворився на системи, які пишуть есе та код та вирішують складні проблеми? Коротка відповідь — масштаб.
Наведена нижче часова шкала охоплює період від трансформерів 2017 року до сучасних передових моделей:
YEAR MODEL PARAMS KEY DEVELOPMENT
────────────────────────────────────────────────────────────────────────────────
2017 Transformer 65M "Attention Is All You Need" published
2018 GPT-1 117M First successful generative pre-training
2019 GPT-2 1.5B Improved fluency; staged release
2020 GPT-3 175B Few-shot in-context learning emerges
2022 ChatGPT 175B+ InstructGPT + RLHF = aligned conversational AI
2023 GPT-4 undisclosed Multimodal input + stronger reasoning
2024 GPT-4o undisclosed Natively multimodal, faster & cheaper (May)
2024 o1 undisclosed "Reasoning" model: thinks before answering (Sep)
2025 o3 / o4-mini undisclosed Stronger reasoning, tool use, long-horizon
2025 Claude 4 undisclosed Anthropic: Opus 4 / Sonnet 4 (May)
2025 Gemini 2.5 undisclosed Google: 1M-token context, multimodal
2025 Llama 4 undisclosed Meta: open weights, up to 10M-token context
2026 GPT-5 series undisclosed OpenAI flagship (GPT-5.4 / 5.5); 272K-1M ctx
2026 Gemini 3.x undisclosed Google: frontier reasoning; 1M context
2026 Claude 5 family undisclosed Anthropic: Opus 4.8, Sonnet 5, Fable 5
2026 Grok 4.x undisclosed xAI frontier line (Grok 4.5, Jul 2026)
(Every one is the same core transformer from 2017 — scaled and refined, not replaced)
Основна архітектура майже не змінилася від GPT-1 до сучасних передових моделей. Змінилися наступні аспекти:
- Масштаб, тобто більше параметрів, більше даних та більш потужні обчислення.
- Вирівнювання, де за допомогою посилення навчання на основі зворотного зв’язку від людей моделі стають корисними та безпечними.
- Налаштування за інструкціями, яке навчає моделі слідувати вказівкам, а не просто продовжувати текст.
- Навчання на міркування, яке застосовує масштабне посилення навчання до перевірюваних проблем. Це основа моделей для міркувань, таких як серія o від OpenAI та режими розширеного мислення, які зараз поширені в Claude, Gemini та інших моделях — вони витрачають додаткові ресурси на обміркування перед тим, як відповісти.
Здібності, які, здається, активуються
Під час розвитку моделей сталося щось несподіване. Певні здібності не покращувалися поступово, а раптово з’являлися при певних розмірах. Багатокрокові арифметичні операції майже відсутні були при кількості параметрів менше 10 мільярдів, але ставали надійними при близько 100 мільярдів. Мислення у форматі ланцюга думок практично відсутнє, якщо тільки модель не є достатньо великою та не отримує відповідних запитів. Генерація коду значно покращилась при розмірах, більших за GPT-3. Усе це не було запрограмовано — воно просто з’явилося.
Існують суперечки щодо того, наскільки реально великими є ці стрибки. У 2023 році Шеффер та його колеги опублікували аналіз під назвою „Чи є емергентні здібності великих мовних моделей ілюзією?“, який часто цитується; у ньому показано, що деякі здавалося б різкі зміни частково походять від самої метрики. Оцінювання завдань у форматі „усе або нічого“, як це робить точність повного збігу, може перетворити поступові покращення на щось, що виглядає як раптовий стрибок, тоді як неперервна метрика відображає справжній поступ. Практичний аспект залишається актуальним, оскільки великі моделі можуть робити те, що не під силу малим, але конкретні порогові значення слід розглядати лише як приблизну ілюстрацію, а не як жорсткі фізичні закони.
Метою навчання кожної моделі у стилі GPT є однакове просте завдання — прогнозувати наступний токен. Міркування, генерація коду, багатомовне розуміння та творче письмо ніколи не навчаються прямо. Вони виникають у міру того, як модель стає кращою у прогнозуванні наступних токенів, за умови наявності достатньої масштабності: великого, високоякісного та різноманітного корпусу текстів, а також моделі достатньої величини для зберігання необхідних закономірностей. Саме тому дослідники називають цю мету оманливо простою. Мета справді проста, але те, що модель мусить опанувати, щоб добре її виконувати, — ні.
Вікно контексту як робоча пам’ять
Для моделі робоча пам’ять — це вікно контексту: найбільша кількість токенів, які вона може обробити під час одного проходження даних. Її обсяг значно зріс. GPT-2 у 2019 році обробляв 1 024 токени, а GPT-3 у 2020 році — 2 048. GPT-4o у 2024 році досяг 128 000 токенів. До середини 2026 року цей показник ще більше зріс: серія GPT-5 від OpenAI пропонує 272 000 токенів як стандарт, а через API — близько мільйона; Claude від Anthropic та Gemini 3 від Google також забезпечують понад мільйон токенів, а Llama 4 Scout від Meta пропонує до 10 мільйонів токенів, що становить приблизно 15 000 сторінок. Ці цифри продовжують зростати з кожним поколінням.
Більше вікно контексту має значення, оскільки дозволяє аналізувати цілий файл коду, а не лише його фрагменти, підтримувати послідовність у розмові протягом багатьох етапів, створювати узагальнення цілих документів та здійснювати багатоетапне міркування, враховуючи багато проміжних результатів.
Є один недолік. Обчислення повної матриці уваги, яка пов’язує кожен токен із кожним іншим, потребує часу та пам’яті O(n²) під час навчання. Подвоєння довжини контексту призводить до подвоєння обох показників. Під час інференсу кешування даних KV зменшує обчислювальні витрати на кожен крок, але пам’ять все одно зростає лінійно з довжиною контексту. Ця квадратична перешкода під час навчання є активною темою досліджень. Розріджена увага, увага з ковзним вікном, яка використовується в Mistral та інших ефективних рішеннях, Flash Attention (точна увага з ефективним використанням пам’яті) та лінійні апроксимації — усе це спрямовано на зниження витрат.
Що стоїть на основі
Увага, QKV, кілька голів, позиційне кодування та структура енкодер-декодер є інфраструктурою, а причина їх вивчення полягає у тому, що все інше будується на їх основі.
Генеративний ШІ — це повторюване прогнозування наступного токена
Кожен генеративний додаток по суті — це та сама петля, яка виконується знову та знову:
Prompt: "Write a poem about autumn"
↓
Model predicts most likely next token: "The"
↓
Prompt + "The" → predicts: "leaves"
↓
Prompt + "The leaves" → predicts: "fall"
↓
... continues until <end-of-sequence> token predicted
Якщо дивитися на це так, загадковість кількох форм поведінки зникає:
- Галюцинація. Модель прогнозує ймовірні токени та не отримує фактів з бази даних. Якщо є правдоподібний, але неправильний токен, він може бути створений.
- Чому контекст має таке велике значення. На кожному кроці генерації враховується весь контекстний вікно, тож все, що вказано у запиті, впливає на обчислення ваг уваги та, відповідно, на результат.
Навчання в контексті: увага для пошуку інформації
Однією з найвражаючіших здібностей великих трансформерів є навчання в межах контексту — здатність адаптуватися до нового завдання на основі прикладів у запиті без будь-якої додаткової налаштування. Цей механізм відповідає тому, про що йшлося вище. Приклади з кількома екземплярами займають певні позиції в „вікні“. Коли модель обробляє тестовий екземпляр, запит цього токена порівнюється за допомогою скалярного добутку з ключами кожного попереднього токена, включаючи пари прикладів. Оскільки приклади мають спільну структурну модель із тестовим екземпляром, їхні ключі добре збігаються, а їхні значення отримують високі ваги. Увага буквально є механізмом пошуку, і саме тому структура запиту, через свій вплив на патерни уваги, змінює результат.
Агенти: трансформер як механізм міркувань
Агенти ШІ — це системи, які самостійно розбивають завдання на частини, використовують інструменти, ураховують зворотний зв’язок та досягають цілей у кількох етапах. У 2023 році вони були об’єктом досліджень. Тепер такі продукти, як Claude Code, GitHub Copilot, Cursor та Devin, щодня використовуються розробниками. Кожен серйозний агент має трансформер у своїй основі.
╔══════════════════════════════════════════════════════════════════════════════╗
║ THE CONTEXT WINDOW AS AGENT WORKING MEMORY ║
╚══════════════════════════════════════════════════════════════════════════════╝
TIME ──────────────────────────────────────────────────────────────────────▶
┌──────────────┬──────────────┬────────────────┬────────────┬──────────────┐
│ SYSTEM │ USER │ AGENT │ TOOL │ AGENT │
│ PROMPT │ MESSAGE │ THOUGHT │ RESULT │ RESPONSE │
│ │ │ (reasoning) │ │ │
│ "You are a │ "What is │ <think> │ {"temp": │ "The current │
│ weather │ the weather │ I need to │ 22, │ temperature │
│ assistant │ in Paris │ call the │ "unit": │ in Paris │
│ ..." │ today?" │ weather API │ "C", │ is 22°C and │
│ │ │ for Paris... │ "cond": │ cloudy." │
│ │ │ </think> │ "cloudy"} │ │
│ ~200 tokens │ ~15 tokens │ ~80 tokens │ ~40 tokens │ ~25 tokens │
└──────────────┴──────────────┴────────────────┴────────────┴──────────────┘
▲ ▲ ▲ ▲ ▲
└───────────────┴───────────────┴───────────────┴─────────────┘
│
At each generation step:
Full self-attention runs over the
ENTIRE context simultaneously.
Cost: O(n²) in total context length.
WHAT THIS MEANS FOR AGENTS:
✓ Tool results are just tokens - the model attends to them like any text
✓ Reasoning traces are visible - chain-of-thought shapes next generation
✓ Long task history - "memory" without any separate mechanism
⚠ Context fills up - very long loops need summarization/offload
⚠ O(n²) attention cost - longer context = quadratically more compute
KEY INSIGHT: There is no "working memory" separate from the context.
The context window IS the agent's entire cognitive state.
Для агента вікно є одним рівним, упорядкованим буфером токенів, і кожен крок генерації охоплює всю його область, що дозволяє зберігати все, що сталось, у межах встановленого ліміту. Вікно є робочою пам’яттю агента, увага — його механізмом міркування, а цикл наступного токена — його циклом дій. Для агентського ШІ не було потреби у новій архітектурі. Необхідним було лише усвідомлення того, що трансформер при достатньому розмірі вже може підтримувати агентність.
На практиці агенти, створені у 2026 році, рідко користуються лише самим вікном для обробки інформації. Щоб ефективно виконувати тривалі завдання, вони підключають зовнішню пам’ять: файли тимчасового зберігання, шар пошуку чи базу знань, яку агент постійно оновлює. Це не суперечить попередньому твердженню, адже зовнішня пам’ять впливає на модель лише шляхом її зчитування назад у вікно. Вона розширює буфер, не замінюючи його, і увага трансформера до цього контексту залишається єдиним місцем, де відбувається мислення.
Куди рухається дослідження
Ефективність трансформерів підкоряється передбачуваним законам залежності від кількості параметрів, даних для навчання та обчислювальних ресурсів, що дає дослідникам чіткий напрямок розвитку. Дослідження розвиваються у кількох напрямках:
- Ефективні архітектури, які зменшують квадратичні витрати, пов’язані з механізмом уваги, за допомогою технологій Flash Attention, sparse attention та linear attention.
Усе це ґрунтується на основі трансформерів, тому розуміння їх допомагає краще сприймати ці напрямки.
У таблиці нижче кожен компонент представлений у єдиному вигляді: проблема, яку він вирішує, принцип його роботи та основні характеристики:
| Component | Problem it Solves | Core Mechanism | Key Properties |
|-----------|------------------|----------------|----------------|
| **Tokenization** | Text is not natively numeric | Subword BPE/WordPiece splitting | Vocabulary ≈ 30k–100k; subwords handle rare terms |
| **Embeddings** | Discrete IDs have no geometry | $\mathbf{e}_t = E[t] \in \mathbb{R}^{d_{\text{model}}}$ | Semantic similarity → geometric proximity |
| **Positional Encoding** | Parallel attention loses token order | sin/cos at different frequencies (or RoPE) | Multi-scale; encodes absolute and relative position |
| **Self-Attention** | Long-range deps, sequential bottleneck | $\text{softmax}(QK^\top/\sqrt{d_k})V$ | $O(n^2)$ but parallel; dynamic contextual reps |
| **Query/Key/Value** | Separating "what I seek" from "what I offer" | Three separate learned linear projections | Relevance ≠ similarity; flexible dependency modeling |
| **Multi-Head Attention** | Single head captures only one relationship type | $h$ parallel heads, concatenated + $W^O$ | Simultaneously captures syntactic, semantic, positional |
| **Encoder** | Understanding input in full bidirectional context | Full self-attention, no masking | Bidirectional; rich contextualized representations |
| **Decoder** | Generating output autoregressively | Causal self-attention + cross-attention | Predicts one token at a time; teacher-forcing in training |
| **Cross-Attention** | Connecting generation to input understanding | Q from decoder, K/V from encoder | Enables encoder→decoder communication |
| **Feed-Forward Network** | Per-token computation + factual storage | $\text{GeLU}(\mathbf{x}W_1)\,W_2$ per token | Position-wise; stores factual associations in weights |
| **Residual Connections** | Vanishing gradients in deep networks | $\mathbf{h} = \text{SubLayer}(\mathbf{x}) + \mathbf{x}$ | Creates gradient highway; enables 100+ layer models |
| **Pre-LayerNorm** | Unstable activations in deep networks | Normalize before each sublayer | Stable training; standard in all modern transformers |
Що вже розглянуто та куди рухатися далі
Елементи поєднуються наступним чином. Паралельна увага працює краще, ніж поетапна обробка, і ефективніше фіксує віддалені залежності, саме тому трансформери витіснили послідовні моделі. Дані проходять від тексту до токенів, потім до ембеддингів, далі до позиційного кодування, до механізму уваги та до шарів з передаванням даних, після чого цей процес повторюється. Основною операцією є самоувага, при якій кожен токен звертає увагу на всі інші через навчені проекції Q, K та V, як у формулі Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V. Кілька голів дозволяють фіксувати різноманітні патерни, позиційне кодування відновлює порядок, а архітектура енкодер-декодер підтримує як розуміння, так і генерацію тексту. Шари з передаванням даних зберігають знання, резидуальні зв’язки забезпечують глибину обробки, а Pre-LayerNorm підтримує стабільність навчання. Прогнозування наступного токену в масштабі призводить до появи нових можливостей, вікно контексту слугує робочою пам’яттю агента, а сама архітектура...
Стаття з 2017 року стала основою для сучасних найсучасніших систем.
Щоб глибше зрозуміти тему, ефективним є поетапний підхід.
Перші два тижні: математика. Пройдіть серію відео Андрея Карпаті „Neural Networks: Zero to Hero“ на YouTube, особливо те, де створюється GPT з нуля. Потім напишіть простий шар самоуваги у NumPy. Концепції краще засвоюються, коли їх обчислюють вручну.
Три та чотири тижні: наукові статті. Прочитайте статтю „Attention Is All You Need“ (Vaswani та ін., 2017), яку тепер можна легко прочитати, а також статтю про BERT (Devlin та ін., 2018), статтю про GPT-3 „Language Models are Few-Shot Learners“ (Brown та ін., 2020) та „Scaling Laws for Neural Language Models“ (Kaplan та ін., 2020).
Другий місяць: практика з бібліотеками та API. Бібліотека Hugging Face transformers дозволяє використовувати ці моделі з Python майже без налаштувань. Налаштуйте BERT або невелику модель з відкритими вагами, таку як версія Llama чи Qwen, для завдань класифікації. Потім скористайтеся Python SDK від Anthropic чи OpenAI, щоб дістатися до сучасних передових моделей — чи то Claude Sonnet 5, чи одна з моделей GPT-5. Поєднання обох підходів поєднує теорію з практикою, адже однакові принципи трансформерів проявляються як у моделях з відкритими вагами, так і в передових API-моделях.
Третій місяць: глибоке вивчення однієї теми. Виберіть одну з фреймворків для агентів (LangChain, LlamaIndex) чи попрактикуйтеся з Claude Code чи Cursor, щоб спостерігати за поведінкою агентів у реальному інструменті для розробки, ефективні трансформери (Flash Attention, розріджена та лінійна увага) або налаштування LLM за допомогою LoRA та PEFT. Тут важливіша глибина, ніж ширина охоплення теми.
У розвитку: стежте за дослідженнями. Розділи cs.CL та cs.LG на arXiv, блог Hugging Face, сторінка досліджень Anthropic та форум AI Alignment Forum є хорошими джерелами інформації. Ця галузь розвивається швидко, але зазначені вище ресурси допомагають зрозуміти нові наукові праці.
Стаття про трансформери має близько п’ятнадцяти сторінок, а описана в ній архітектура настільки проста, що її можна реалізувати за один день. Те, що вона започаткувала, а також те, що продовжує розвиватися завдяки масштабуванню та удосконаленням, змінило уявлення людей про те, що можуть робити машини.