Ця стаття пояснює все, що потрібно знати про великі мовні моделі (Large Language Models), простими та зрозумілими словами.
Ми всі чули про ChatGPT і DeepSeek, які є великими мовними моделями (LLM). Ці великі мовні моделі працюють на основі технології, що називається transformers або трансформерні нейронні мережі.
Що робить їх такими особливими? Вони здатні розуміти контекст між словами в реченні та передбачати наступне або очікуване слово у вихідному реченні. Саме тому ChatGPT та інші LLM генерують слова послідовно, адже ця складна нейронна мережа крок за кроком генерує або прогнозує наступне слово на основі вхідного речення.
Наприклад, якщо я введу речення «Thank you», очевидно, що LLM має відповісти «You are welcome». Тому вона використовує алгоритми, щоб передбачити перше слово — «You», потім наступне — «are», і нарешті «welcome».
Зараз я покажу вам детально, як вони працюють, тож готуйтеся — ми починаємо нашу подорож!
Логіка, яку використовує трансформер для передбачення наступного слова в реченні.
Модель трансформера складається з двох основних частин: енкодера (encoder) та декодера (decoder). Енкодер обробляє та кодує вхідне речення, тоді як декодер обробляє та декодує вихідне речення.
Отримані результати використовуються для передбачення очікуваного або наступного слова, яке стане вихідним реченням, переданим у декодер.
Під час навчання ми надаємо як вхідне речення, так і вихідне речення, щоб навчити модель трансформера, як правильно відповідати у вихідному реченні, коли подається певне вхідне речення.
Наприклад, якщо б я хотів навчити вас говорити японською, я дав би вам список речень англійською разом із їхнім відповідним перекладом японською. Тоді наступного разу ви могли б відповісти вже без перекладів. У цьому сценарії англійські речення подаються в енкодер, а вихідні або очікувані японські речення — у декодер.
Ми будемо перекладати речення «Thank you» на «Arigato» — японською. Уявіть, що ви ведете розмову з людиною, яка говорить мовою, яку ви не повністю розумієте. Вашому мозку потрібно трохи часу, щоб автоматично перетворити кожне іноземне слово, у вашу мову, перш ніж ви зможете повністю зрозуміти зміст. Саме так працюють трансформери. Але в цьому випадку ви — це трансформер, а людина — це користувач.
КРОКИ
Ось кроки, які проходить трансформер, щоб передбачити кожне слово в реченні.
Ця операція виконується як в ЕНКОДЕРІ, так і в ДЕКОДЕРІ. Ми розглянемо все це детально, тож приготуйтеся.
- Word embeddings. — Трансформер перетворює кожне слово в реченні на вектор дійсних чисел, щоб представити кожне слово.
- Positional encoding. — Це використовується для відстеження порядку слів у реченні, оскільки можна мати два речення з однаковими словами, але з різним значенням. Наприклад: «The bat ate the cat» і «The cat ate the bat».
- Self-Attention. — Щоб надати моделі трансформера більше контексту, механізм self-attention обчислює зв’язок між усіма словами в реченні. Для цього для кожного слова створюються три вектори: queries (запити), keys (ключі) та values (значення). Шляхом їхнього математичного зіставлення модель отримує фінальні оцінки уваги, які визначають, наскільки кожне слово важливе для розуміння інших
- Residual connections. — Попередні значення positional encoding додаються до фінальних значень self-attention для кожного слова, щоб отримати новий набір вихідних даних. Після додавання ці виходи нормалізуються.
- Feed-forward layer. — Нормалізовані виходи передаються через стандартну feed-forward нейронну мережу (нейронна мережа прямого поширення), яка створює feed-forward виходи, як я люблю їх називати.
- Residual connections (Залишкові зв’язки) — До цих feed-forward виходів додаються нові residual connections, але цього разу операція включає додавання між попередньо нормалізованими виходами та feed-forward виходами. Після додавання виходи знову нормалізуються, так само як і раніше.
Примітка: усі згадані операції застосовуються як до енкодера, так і до декодера. Однак декодер має більше шарів і включає більше кроків, порівняно з енкодером. Продовжуйте читати, щоб дізнатися, які саме.
Наступні кроки для декодера:
- Encoder-decoder attention — Наступний крок полягає в обчисленні зв’язку між кожним словом у вхідному реченні та кожним словом у вихідному реченні. Це називається encoder-decoder attention, а не self-attention, як раніше, і це допомагає надати трансформеру більше контексту та розуміння.
- Residual connections знову додаються. Але цього разу попередній фінальний вихід декодера після нормалізації додається до оцінок encoder-decoder attention і знову нормалізується, щоб отримати нові виходи (а не значення positional encoding).
- Feed forward layer — фінальні виходи передаються через стандартну feed-forward нейронну мережу, яка створює нові feed-forward виходи.
- Residual connections — додається ще один набір residual connections, який включає додавання між нормалізованими значеннями encoder-decoder attention і новими feed-forward виходами.
- На самому фінальному етапі використовується функція активації SoftMax, щоб перетворити остаточно нормалізовані виходи на ймовірності для слів у словнику вихідної мови. Слово з найвищою ймовірністю стає передбаченим словом і використовується разом із попередніми словами та вхідним реченням, щоб передбачити наступне слово у вихідному реченні.
ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
Residual connections додаються після кожного основного кроку (self-attention, encoder-decoder attention, feed-forward). Ця архітектура базується на статті «Attention Is All You Need», але в цьому прикладі буде лише одне residual connection після кожного кроку attention (self-attention, encoder-decoder attention) і один feed-forward шар після encoder-decoder attention.
ChatGPT використовує трансформер лише з декодером (decoder-only transformer), але цей матеріал описує, як працюють трансформери на основі статті «Attention Is All You Need», не повністю повторюючи її архітектуру.
THE ENCODER
Енкодер — це частина, куди подається вхідне речення. Наприклад, якщо ви скажете «Hello there» до LLM, ваше «Hello there» буде подано в енкодер моделі. Але оскільки ми навчаємо модель, нам потрібно надати їй очікувану відповідь, наприклад «Hi there, how can I help you?». Це відповідь, яку ми очікуємо від LLM, тому під час навчання вона подається в декодер, щоб навчити модель відповідати на «Hello there» фразою «Hi there, how can I help you?».
Вхідне речення оточується словами, які називаються стартовими та кінцевими токенами: <SOS> (Start of Sequence) і <EOS> (End of Sequence). Це повідомляє моделі трансформера, де починається речення і де воно закінчується.
Кожного разу, коли ви вводите речення в ChatGPT, ваше речення обгортається такими словами, які ми будемо називати «токенами».
Під час навчання та сама процедура застосовується і до вихідного речення в декодері. Воно також оточується токенами <SOS> і <EOS>, але в енкодері ми будемо працювати лише з токеном <EOS>.
КРОКИ ДЛЯ ЕНКОДЕРА.
1. Word Embeddings (Вкладання слів)
Спочатку енкодер обчислює word embeddings. Word embedding — це спосіб перетворення слів у числа, оскільки комп’ютери працюють із числами, а не з літерами. Ці числа використовуються для представлення кожного слова в реченні.
Для кожного слова можуть використовуватися 4 embedding-значення, 2 embedding-значення або навіть 512 embedding-значень, залежно від складності моделі трансформера. Ці числа представляють ідентичність слова в реченні. Наприклад: «Hi there». Слово «Hi» може мати 4 embedding-значення, наприклад [0.1, 3.2, -1.7, 2.1], а слово «there» може мати свої значення, наприклад [0.9, -3.2, 1.8, 0.4].
Ці числа представляють кожне слово в реченні, і їх може бути тисячі. Такі списки чисел називаються векторами, а їхній розмір визначається кількістю елементів (чисел) у них. Використовувати лише одне число для представлення слова не дуже добре, оскільки одне й те саме число може представляти різні слова.
Ми знайдемо 2 embedding-значення для слів «Thank», «you» і для токена «<EOS>». Хоча слово «to» є частиною речення, ми не будемо його кодувати, тому що в цьому випадку немає сенсу додавати його до речення.
Токен <EOS> означає кінець послідовності. Він повідомляє моделі, де закінчується речення. У цьому випадку ми не можемо використовувати крапку, оскільки в одному абзаці може бути кілька речень із кількома крапками.
Щоб знайти embedding-значення для кожного слова, кожному нейрону, що представляє слово, присвоюється значення. Оскільки ми намагаємося знайти embedding-значення для «Thank», ми ставимо 1 у нейрон, що представляє «Thank» (червоного кольору), а в усі інші слова ставимо 0. Після цього виконується обчислення.
Обчислення полягає в множенні кожного числового значення на вагу (weight) або лінію, з якою воно з’єднане.

Те, що ви бачите вище, — це типове представлення штучної нейронної мережі. У цьому випадку ця штучна нейронна мережа використовується для обчислення значень word embeddings для слова «Thank».
На діаграмі видно, що число [1] всередині першого нейрона, який представляє слово «Thank», з’єднане з вагою (лінією) зі значенням [1.2], яка, у свою чергу, з’єднана з першим вихідним нейроном або значенням word embedding. Те саме [1] також має ще одне з’єднання з вагою зі значенням [2.9], яка підключена до другого значення word embedding або нейрона. Воно позначене червоним кольором.
Примітка: квадрати — це нейрони, а лінії називаються вагами (weights). Число [1] множиться на вагу, з якою воно з’єднане [1.2], а всі інші [0], які також з’єднані з вагами, що ведуть до першого нейрона, множаться відповідним чином, як було пояснено.
Кінцеві результати цих множень додаються і пропускаються через функцію ідентичності (identity function), яка фактично повертає той самий результат, що й після множення. Отриманий результат стає першим значенням word embedding у вихідному нейроні — [1.2].
Друге значення word embedding обчислюється за тим самим принципом. Кожен нейрон, що містить [1] або [0] і представляє певне слово, множиться на відповідні ваги, після чого всі результати додаються, щоб отримати друге значення word embedding. Тепер у нас є значення word embedding для слова «Thank». Якщо вам цікаво щодо ваг — це випадкові числа, які будуть змінюватися під час навчання, коли модель навчається.
Щоб отримати значення word embedding для слова «you», повторюється той самий процес, але цього разу [0] ставиться в нейрон для «Thank» і всіх інших слів, а [1] ставиться в нейрон для «you».
Використовуються ті самі ваги, що й раніше, і в результаті обчислюються два значення word embedding для «you». Ці кроки повторюються і для останнього токена <EOS>, який позначає кінець послідовності або речення. Дивіться зображення нижче.


ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
Насправді реальний процес обчислення між вагами (weights) і нейронами — це множення матриць (matrix multiplication). Однак діаграми вище показують більш спрощене та зрозуміле пояснення всього процесу.
Щоб пояснити детальніше: нейрони, які представляють кожне слово і використовуються для обчислення word embeddings, перетворюються на рядки матриці. Наприклад, нейрони для обчислення embeddings слова «Thank» виглядатимуть у матриці так: [1, 0, 0, 0] Те саме для інших слів «you» і «<EOS>»: [0, 0, 1, 0] [0, 0, 0, 1] Саме так виглядають нейрони на основі діаграми, але насправді вони називаються one-hot vectors (one-hot вектори).
One-hot вектори:
[1, 0, 0, 0]
[0, 0, 1, 0]
[0, 0, 0, 1]
Щоб обчислити word embeddings, ваги (або лінії), які з’єднані з кожним вихідним нейроном word embedding, цього разу перетворюються на стовпці. Або ж ваги, підключені до вхідних нейронів, можуть бути представлені як рядки. Кожен one-hot вектор (рядок) у цьому випадку множиться на ваги, після чого результати додаються, щоб отримати одне значення word embedding.
Ваги (Weights):
[1.2, 2.9]
[0.7, -0.3]
[1.3, 0.8]
[0.3, 0.9]

2. POSITIONAL ENCODING
Ви можете мати два речення з точно тими самими словами, але з різним значенням. Наприклад: “The bat ate the cat.” і “The cat ate the bat.”
Обидва речення використовують ті самі слова, але мають різні значення.
Позиційне кодування (Positional Encoding) використовується для того, щоб відстежувати порядок слів і допомогти трансформеру розуміти різні значення в реченнях із тими самими словами. Позиційне кодування обчислюється шляхом додавання набору точок із хвиль синуса (sine) і косинуса (cosine) до кожного значення word embedding, яке представляє кожне слово.
Дивіться діаграму нижче. Жовті квадрати містять точки синуса і косинуса з хвиль, які додаються до значень word embedding, щоб отримати остаточні значення positional encoding.

3. SELF ATTENTION
Трансформери є особливими. Щоб зрозуміти контекст, вони намагаються знайти схожість між кожним словом у реченні, використовуючи техніку, яка називається self-attention.
Саме тут із речення витягується справжній зміст. Self-attention — це техніка, яка використовується для знаходження зв’язків між словами в реченні, щоб надати трансформеру контекст. Наприклад, у реченні:
“The Pirate bombarded the ship, and it sank to the bottom of the ocean”
слова “ship” і “it” тісно пов’язані в цьому реченні, як ми можемо бачити. Тому self-attention оцінки (scores) для ship і it повинні бути обчислені, щоб трансформер у майбутніх реченнях або прогнозах розумів, що “ship” і “it” тісно пов’язані.
Те саме робиться для кожного слова в реченні. Self-attention оцінки між кожним словом, включно із самим собою, обчислюються за допомогою різних математичних операцій. Але перед тим як знайти self-attention оцінки, потрібно знайти попередні значення, відомі як dot-products (скалярні добутки) або similarity scores (оцінки схожості). Це справжні оцінки зв’язку між словами в реченні, які показують, наскільки сильно кожне слово пов’язане з кожним іншим словом у реченні.
Процедура:
i. Щоб знайти скалярний добуток або similarity scores між кожним словом (включно із самим собою), кожному слову потрібно призначити QUERY, KEY і VALUE. Це нові числа, які представляють кожне слово, подібно до word embeddings, і вони обчислюються шляхом множення попередніх значень positional encoding на ваги (weights).
Наприклад, якщо ми хочемо знайти similarity scores між “Thank” і всіма іншими словами в реченні, включаючи саме слово “Thank”, нам потрібно: згенерувати QUERY значення для “Thank”, згенерувати KEY значення для кожного слова, включаючи “Thank”, потім помножити QUERY значення для “Thank” на його KEY значення, а також на KEY значення кожного іншого слова, і додати результати кожного разу, щоб отримати similarity scores.
ПРИМІТКА: У наступній процедурі ми будемо обчислювати self-attention оцінки тільки для слова “Thank”, спочатку знаходячи similarity scores між “Thank” і “you”, не враховуючи токен <EOS>.

На діаграмі (4.47 і 2.28) — це значення QUERY для “Thank”, а (9.54 і 8.22) — це значення KEY також для “Thank”. VALUES для “Thank” дорівнюють (2.1 і 6.3).
Значення KEY для “you” — (5.64 і 5.72), а VALUES для “you” — (2.36 і 4.8).
Щоб знайти показник подібності (similarity score) між “Thank” і самим собою та між “Thank” і “you”, потрібно помножити значення QUERY слова “Thank” на значення KEY слова “Thank” і скласти результати. Таким чином отримуємо показник подібності між “Thank” і самим собою — 61.3. Дивіться діаграму нижче.
Після цього множимо QUERY слова “Thank” на KEY слова “you”, щоб отримати показник подібності між “Thank” і “you” — 38.2. Дивіться діаграму нижче.
Натисніть Enter або клікніть, щоб переглянути зображення у повному розмірі.

ОБЧИСЛЕННЯ:
– (4.47 × 9.54) + (2.28 × 8.22) = 61.3 — (оцінка схожості similarity score між «Thank» і самим собою).
– (4.47 × 5.64) + (2.28 × 5.72) = 38.2 — (оцінка схожості similarity score між «Thank» і «you»).
ii. Отримані значення пропускаються через функцію SoftMax.
Функція SoftMax — це математична операція, яка перетворює ці значення так, щоб їх сума дорівнювала 1. Тут: 0 відповідає 0% уваги (attention) 1 відповідає 100% уваги
Якщо: оцінка схожості між «Thank» і самим собою = 61.3, оцінка схожості між «Thank» і «you» = 38.2, то після застосування SoftMax: 61.3 перетвориться на більше значення, наприклад 0.62, 38.2 перетвориться на менше значення, наприклад 0.38. Ці значення 0.62 і 0.38 стають SoftMax-ймовірностями (відсотками). Це означає, що слово «Thank» більше пов’язане із самим собою, ніж зі словом «you».
Примітка: Значення SoftMax — це пропорційні ймовірності. На практиці вони часто мають значення, близькі до 1 або 0, наприклад 0.56 і 0.44.

Нарешті, вихід SoftMax для схожості між «Thank» і самим собою дорівнює 1, а 0 — для виходу SoftMax для схожості між «Thank» і «you».
iii. Далі 1 і 0 множаться на VALUES, які обчислюються шляхом множення нових ваг на раніше отримані значення positional encoding, так само як ми робили з word embeddings. Перші згенеровані VALUES, що належать «Thank», повинні використовуватися для множення тільки на оцінку схожості або відсоток SoftMax для «Thank». Ці VALUES множаться на 1. Обидва згенеровані VALUES множаться на 1, щоб отримати нові значення, які будуть використані для отримання остаточних self-attention оцінок.
2.1 і 6.3 — це раніше згенеровані VALUES для «Thank», які були отримані шляхом множення попередніх значень positional encoding на ваги і додавання результатів.
(2.1 × 1) = 2.1 — назвемо це x0
(6.3 × 1) = 6.3 — назвемо це x1
Примітка: поєднання цих двох значень створює один вектор з кількома вимірами.
Дивіться зображення вище.
iv. Та сама операція виконується для оцінки схожості між «Thank» і «you».
Слово «you» генерує нові VALUES, множачи свої positional encoding значення на ваги, щоб отримати два нових VALUES (2.36 і 4.8), які позначені світло-зеленим кольором. Обидва значення множаться на 0, який є відсотком SoftMax для схожості між «Thank» і «you».
(2.36 × 0) = 0 — назвемо це y0
(4.8 × 0) = 0 — назвемо це y1
Нарешті, щоб отримати self-attention оцінки для «Thank», ми додаємо відповідні перемножені значення: (x0 + y0) (x1 + y1) Отримані результати стають остаточними self-attention оцінками для «Thank», тобто (2.1 і 6.3).
Дивіться зображення нижче для прикладу матриці (MATRIX).

v. Та сама операція виконується між «you» і «<EOS>». QUERIES створюються як для «you», так і для «<EOS>», після чого вони множаться на KEYS кожного слова в реченні, включаючи самих себе («Thank», «you» і «<EOS>»).
ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
У цьому прикладі є лише 1 шар self-attention, тобто лише один набір QUERIES, KEYS і VALUES для кожного слова. Однак у більшості LLM, таких як ChatGPT, може бути приблизно 8 шарів self-attention, кожен зі своїм набором QUERIES, KEYS і VALUES.
4. RESIDUAL CONNECTIONS
Після того як self-attention оцінки обчислені, вони додаються до раніше обчислених значень positional encoding, щоб покращити продуктивність і допомогти трансформеру краще розуміти та запам’ятовувати позиції слів.
ПРИМІТКА: Residual connections додаються після таких етапів, як self-attention і feed-forward шари.
МАТРИЧНА ДЕМОНСТРАЦІЯ SELF-ATTENTION
Матрична демонстрація показує, як насправді виглядають обчислення всередині трансформера. Діаграми вище без матриць показують лише більш спрощену та зрозумілу версію всього процесу.
a. QUERIES, KEYS і VALUES для кожного слова в кожному рядку обчислюються шляхом множення кожного рядка на набір ваг-стовпців і додавання результатів, так само як і раніше. Застосовується множення рядка на стовпець (Row by Column multiplication).

ПРИКЛАД ОБЧИСЛЕННЯ:
(1.2 × 3.4) + (3.9 × 0.1) = 4.47 — (перше значення QUERY для «Thank»)
(1.2 × 0.6) + (3.9 × 0.4) = 2.28 — (друге значення QUERY для «Thank»)
Процес повторюється для кожного слова і так далі.
b. QUERIES повинні множитися на транспоновану (Transposed) версію KEYS, щоб отримати dot product similarities. Що означає Transpose? Множення рядка на стовпець не працюватиме, якщо у QUERIES є лише 2 стовпці, а у KEYS — 3 рядки. У такому випадку останній рядок буде пропущений.
Множення матриць вимагає, щоб кількість стовпців у першій матриці дорівнювала кількості рядків у другій. Тому матрицю KEYS потрібно транспонувати (transpose) або повернути горизонтально, щоб KEYS для кожного слова більше не були в рядках, а були перетворені на три стовпці з двома рядками, де кількість рядків збігається з кількістю стовпців у матриці QUERY.

c. Згідно з формулою з оригінальної роботи «Attention is all you need», кожне число в матриці схожості скалярний добуток потрібно поділити на квадратний корінь із розмірності матриці KEYS (Dk або dk). Тобто на кількість KEYS, що представляють кожне слово, яка в цьому випадку дорівнює 2. Це робиться для того, щоб отримати масштабовані (scaled) оцінки схожості скалярного добутку між словами. Після цього scaled dot product similarities пропускаються через функцію SoftMax для кожного рядка, щоб отримати SoftMax-відсотки. Функція стискає значення в рядку так, щоб їх сума дорівнювала 1. Приклад: SoftMax (13.5, 8.6, 5.6) = [0.99, 0.0073, 0.00037] — остаточні SoftMax-відсотки для останнього рядка. Дивіться зображення нижче для прикладу цього процесу.
ФОРМУЛА НИЖЧЕ.

- QK — Це показує множення між QUERIES і транспонованими (Transpose) KEYS.
- √(dk) — Це означає ділення результатів множення QUERIES і KEYS на квадратний корінь із розмірності KEYS, тобто на кількість KEYS, що представляють кожне слово в цій матриці, щоб отримати scaled dot product similarities.
- SoftMax — Це означає обчислення відсотків SoftMax між результатами scaled dot product similarities.
- V — Це означає остаточне множення відсотків SoftMax на раніше згенеровані VALUES, щоб отримати self-attention scores.
- Ця формула виконує точно той самий процес, який був описаний раніше під час обчислення значень self-attention.

e. Потім відсотки SoftMax для кожного слова множаться на раніше згенеровані VALUES, щоб отримати остаточні self-attention оцінки для кожного слова, як показано на зображенні нижче.

f. Остаточні self-attention оцінки для кожного слова додаються до попередніх значень positional encoding, щоб отримати кінцеві виходи енкодера (encoder outputs) для кожного слова. Це називається «Residual Connections». Дивіться зображення нижче.

Спрощена діаграма, що пояснює весь процес енкодера до цього моменту.

- Червоний — представляє вхідний токен для слова «Thank».
- Блакитний — представляє вхідний токен для слова «you».
- Зелений — представляє вхідний токен для «<EOS>».
- Жовтий — це синусоїдальні та косинусоїдальні хвилі, які додаються до значень word embedding поруч із ними, щоб отримати значення positional encoding над знаками «=».
- Рожевий — це місце, де обчислюються scaled dot product similarity scores разом із відсотками SoftMax, щоб отримати остаточні self-attention оцінки для кожного слова.
- Чорний — представляє кінцеві значення або оцінки self-attention для кожного слова, які потім додаються до значень positional encoding за допомогою методу, що називається residual connections, щоб отримати значення над чорними заповненими квадратами.
- Остаточні значення над чорними заповненими квадратами — це результати residual connections, які є кінцевими виходами енкодера (encoder outputs).
ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
Ваги, які використовуються для обчислення QUERIES, KEYS і VALUES для кожного слова, ті самі, що показані в матричних діаграмах. Саме тому на діаграмі вище для кожного слова є три секції.
ДЕКОДЕР
Декодер містить вихідне або очікуване речення, яке містить слова, що потрібно передбачити, щоб згенерувати змістовну відповідь або речення. Декодер проходить ті самі кроки, що й енкодер, щоб декодувати кожне слово у вихідному реченні, але він має кілька важливих відмінностей, про які ми поговоримо трохи пізніше.
Під час навчання (training) вхідними даними декодера є очікувані вихідні значення або слова, які трансформер повинен передбачати по порядку.
Навіть якщо під час навчання ми подаємо «Arigato» і «<SOS>» у декодер, трансформер все одно повинен навчитися передбачати ці слова самостійно під час реального використання (inference), тому що під час inference ці слова не подаються в декодер. Єдине слово, яке подається в декодер під час inference, — це токен «<SOS>» (Start of Sequence), який визначає початок речення. Коли ви використовуєте LLM, так само як і в енкодері, токен «<SOS>» таємно подається в декодер, щоб запустити процес передбачення послідовності.
КРОКИ
- Word Embeddings. Перетворення кожного слова у два числа. Дивіться діаграму нижче.

2. Positional Encoding — відстеження порядку слів у реченні, тому що можуть бути речення з точно тими самими словами, але з різним значенням.

3. Генерація QUERIES, KEYS і VALUES для знаходження зв’язків або схожості (dot product similarities) між словами у вихідному реченні, яке подається як вхід до декодера.

4. QUERIES множаться на транспоновані (Transpose) KEYS, щоб отримати немасштабовані dot product similarities. Навіть якщо цього разу QUERIES і KEYS мають однакову матрицю 2×2, KEYS все одно потрібно транспонувати.

ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
Декодер трохи відрізняється від енкодера. По-перше, коли модель передбачає наступні слова, їй потрібно знати, де починається речення. Тому, так само як токен <EOS> використовувався для позначення кінця речення в енкодері, цього разу використовується токен <SOS>, щоб позначити початок речення в декодері.
<SOS> означає Start Of Sequence (початок послідовності).
Токен <SOS> завжди подається в декодер моделі, як під час навчання (training), так і під час передбачення (prediction). Коли ви користуєтесь різними LLM, навіть якщо ви не вводите <SOS> у текстове поле, цей токен таємно додається в декодер, щоб запустити процес передбачення, тоді як ваше вхідне речення подається в енкодер.
Токен <SOS> повідомляє моделі, де починається речення.
5. Після цього немасштабовані dot product similarities масштабуються, ділячи кожне число на розмірність матриці KEYS, що фактично є кількістю KEYS для кожного слова.
У цьому випадку — два для кожного слова.

ДУЖЕ ВАЖЛИВА ДЕТАЛЬ:
На зображенні вище ми бачимо, що були обчислені показники подібності між <SOS> і самим собою, а також між <SOS> і “Arigato”. Вони дорівнюють -29.9 і 25.1 відповідно. Одна важлива особливість декодера полягає в тому, що ми не хочемо використовувати показник подібності між токеном <SOS> і “Arigato”. Тому під час навчання ми використовуємо так звану маску уваги (Attention Mask), щоб ігнорувати показник подібності між <SOS> і “Arigato”, який на схемі виділений чорним.
Чому ми це робимо?
Оскільки ми навчаємо модель, ми не хочемо, щоб вона бачила, яке слово буде наступним після токена <SOS> або після будь-якого слова перед наступним словом у вихідному реченні. Ми хочемо, щоб модель самостійно передбачила наступне слово — “Arigato”, не знаючи наперед, що саме це слово буде наступним.
Це схоже на те, якби ви побачили шлях до кінця лабіринту ще до того, як почали рухатися. Ідея полягає в тому, щоб дістатися до кінця лабіринту без знання маршруту, покладаючись лише на власні рішення. Але якщо вам дозволять підглянути шлях до кінця, це фактично буде шахрайством, оскільки ви не використовуєте власне мислення — так само, як у грі про проходження лабіринту.
Тому ми залишаємо всі інші показники подібності в матриці, але додаємо −∞ (мінус нескінченність) до показника подібності між <SOS> і “Arigato”, перетворюючи 25.1 на −∞. Іншими словами, під час навчання ми додаємо −∞ до всіх показників подібності, що відповідають майбутнім словам, і залишаємо значення для попередніх слів. Це не дозволяє декодеру бачити майбутні токени під час навчання. Інакше це було б шахрайством.
6. Після цього, як і раніше, ми обчислюємо значення SoftMax для кожного рядка і множимо їх на VALUES, щоб отримати показники self-attention декодера для <SOS> і “Arigato”, які на схемі показані чорним кольором.


Діаграма, що описує загальний процес

- Фіолетовий колір представляє вхідний токен <SOS>.
- Червоний колір представляє вхідний токен “Arigato”.
- Жовтий колір показує точки синуса і косинуса, які додаються до значень word embedding поруч із ними, щоб отримати значення позиційного кодування (positional encoding), позначені чорним.
- Рожевий колір представляє QUERIES, KEYS і VALUES, які використовуються для обчислення подібності через скалярний добуток (dot product) і показників self-attention.
- Чорний колір представляє фінальні значення self-attention, які потім додаються до позиційного кодування, щоб отримати кінцеві виходи для кожного слова, показані червоним і фіолетовим.
ENCODER-DECODER ATTENTION
Self-attention — не єдина особливість трансформера. Після того як self-attention обчислюється між кожним словом у вхідному або вихідному реченні як в енкодері, так і в декодері, потрібно виконати ще один механізм, який називається encoder-decoder attention.
Чому? Це допомагає визначити зв’язок між словами у вхідному реченні та словами у вихідному реченні. Раніше ми обчислювали лише self-attention між словами всередині вхідного речення і окремо між словами вихідного речення. Тепер нам потрібно знайти зв’язки між усім вхідним і вихідним реченнями разом.
Єдина відмінність полягає в тому, що encoder-decoder attention застосовується лише до вихідного речення, яке подається в декодер — у нашому випадку це <SOS> і “Arigato”. Тому навіть якщо ми обчислюємо encoder-decoder attention, ці значення лише покращують розуміння декодером контексту, оскільки реальне передбачення наступного слова відбувається саме в декодері. Це буде пояснено пізніше.
Тепер ми знайдемо encoder-decoder attention значення для <SOS> і “Arigato”, тобто визначимо, як ці слова пов’язані з кожним словом у вхідному реченні, яке подається в декодер. Якби у вихідному реченні декодера було 10 слів (крім <SOS> і “Arigato”), та сама операція виконувалася б для кожного з них. Але в цьому прикладі ми маємо лише 2 слова.
КРОКИ
1. Як і раніше, ми генеруємо QUERIES, KEYS і VALUES, але цього разу: QUERIES генеруються лише з виходу декодера KEYS і VALUES генеруються з виходу енкодера.Це робиться шляхом множення кожного вихідного значення для кожного слова на набір випадкових чисел, які називаються вагами (weights), щоб отримати QUERIES, KEYS і VALUES для encoder-decoder attention.

2. Значення QUERIES з декодера множаться на транспоновану матрицю KEYS з енкодера, так само як і раніше, щоб отримати немасштабовані значення подібності через скалярний добуток (unscaled dot product similarities). Після цього ці значення діляться на квадратний корінь із розмірності матриці KEY (Dk або dk) — тобто на кількість значень KEY, що представляють кожне слово. У результаті отримуємо масштабовані значення подібності (scaled dot product similarities).

3. Значення SoftMax для масштабованих значень dot product similarities обчислюються для кожного рядка окремо. Після цього нові SoftMax-відсотки множаться на значення VALUES з виходів енкодера, щоб отримати фінальні значення encoder-decoder attention для обох слів у декодері — <SOS> і “Arigato”. Результати:<SOS> = [13.87, 0.72] “Arigato” = [16.2, 0.78]

4. Остаточні значення encoder-decoder attention, отримані після множення SoftMax-відсотків на VALUES, додаються до попередніх виходів декодера за допомогою residual connections (залишкових з’єднань). Цього разу використовується додавання по рядках (row-by-row addition), у результаті чого отримуємо: для токена <SOS> → [2.57, 5.49] для “Arigato” → [9.5, 0.38]

Діаграма, що описує весь процес від енкодера до декодера та до механізму encoder-decoder attention.

На діаграмі вище 2.57 і 5.49 — це фінальні вихідні значення після residual connections між encoder-decoder attention значеннями для <SOS> та попередніми виходами декодера для <SOS>, які позначені чорним кольором.
9.5 і 0.38 — це фінальні вихідні значення після residual connections між encoder-decoder attention значеннями для “Arigato” та попередніми виходами декодера для “Arigato”, які також позначені чорним кольором.
ФІНАЛЬНИЙ ЕТАП, ДЕ ВІДБУВАЄТЬСЯ СПРАВЖНЄ ПЕРЕДБАЧЕННЯ. ЦЕ СПРАВЖНЄ ЗАВЕРШЕННЯ РОБОТИ ДЕКОДЕРА.
Після того як encoder-decoder attention значення були обчислені і додані residual connections, нам потрібно передбачити наступне вихідне слово, яким у цьому прикладі є “Arigato”. Процедура полягає в тому, щоб передати нові фінальні виходи для кожного слова з декодера через звичайну feed-forward нейронну мережу, де кількість вихідних нейронів відповідає кількості слів у всьому словнику (vocabulary). У цьому прикладі показано лише 4 вихідні нейрони, що відповідають 4 словам.
Насправді кількість вихідних нейронів повинна дорівнювати розміру словника всього датасету, але в цьому прикладі їх лише 4.
Цей процес подібний до того, як знаходяться значення word embeddings, але з кількома відмінностями: до кожного вихідного нейрона додаються bias (зміщення) one-hot кодування не використовується Bias — це випадкові числа, які змінюються під час навчання моделі.
Процедура
- Фінальні виходи для кожного слова після residual connections передаються через звичайний feed-forward шар (нейронну мережу).
- До результатів у кожному вихідному нейроні додаються bias. Bias — це випадкові числа, подібні до ваг (weights), які змінюються в процесі навчання моделі.
- Отримані результати пропускаються через функцію SoftMax, щоб визначити найбільшу ймовірність вихідного слова, яким у цьому прикладі буде “Arigato”.
Дивіться діаграму нижче.

Після того, як було передбачено «Arigato», модель трансформатора повинна знати, коли припинити робити передбачення. Як я вже згадував раніше, ми не можемо використовувати крапки, оскільки абзаци вхідних і вихідних даних для LLM можуть містити крапки, тому замість них використовується токен <EOS>.
Щоб модель припинила робити прогнози, вона повинна передбачити <EOS> як останнє слово після «Arigato», щоб модель знала, коли припинити генерувати майбутні слова або маркери.

ОСТАТОЧНА СХЕМА, ЯКА ПОЯСНЮЄ, ЯК ДЕКОДЕР ВРЕШТІ-РЕШТ ПРОГНОЗУЄ КОЖНЕ СЛОВО У ВИХІДНОМУ РЕЧЕННІ.

- Перший шар з 1 і 0 представляє вхідні маркери для кожного слова. Вони називаються векторами з одноразовим кодуванням.
- Другий шар представляє значення вбудовування слів для кожного слова, які додаються до точок синусоїдальної та косинусоїдальної хвиль жовтим кольором, щоб отримати значення позиційного кодування.
- Третій шар представляє значення позиційного кодування.
- Четвертий шар представляє шар самоуваги, де обчислюються показники схожості та значення самоуваги.
- П’ятий шар представляє остаточні значення самоуваги після обчислення.
- Шостий шар представляє остаточні вихідні дані декодера, які є результатом додавання значень самоуваги та значень позиційного кодування, що називаються залишковими зв’язками.
- Сьомий шар представляє шар уваги кодера-декодера, де схожість або взаємозв’язки між кожним словом в кодері обчислюються відносно цього окремого слова в декодері.
- Восьмий шар представляє остаточні бали уваги кодера-декодера, які потім додаються до остаточних вихідних даних декодера як залишкові зв’язки, щоб отримати значення вище нього.
- Дев’ятий шар представляє кінцеві результати після залишкових зв’язків між кінцевими балами уваги кодера-декодера та раніше обчисленими результатами декодера.
- Десятий шар представляє початок кінцевої нейронної мережі прямого поширення, яка використовується для прогнозування наступного токена.
- Одинадцятий шар містить відсотки SoftMax десятого шару.
- Дванадцятий шар містить кінцеві прогнози або ймовірності SoftMax для кожного слова в словнику.
ЗАКЛЮЧНА ПРИМІТКА:
Під час навчання, якщо остаточне передбачуване вихідне слово з декодера після маркера було передбачене неправильно, всі ваги в усьому трансформері, включаючи кодер, декодер і шари самоуваги, будуть змінені для передбачення правильного слова («Arigato»).
ПІДСУМОК:
Під час навчання вхідне речення подається в кодер, а очікуване вихідне речення — в декодер. Наприклад, якщо я хочу навчити вас, як відповідати на речення «Привіт», я подам «Привіт» у ваш кодер, а очікувану відповідь «Привіт, чим можу допомогти?» — у ваш декодер. Ось для чого потрібні кодер і декодер. Зрештою, ви навчитеся згадувати кожне слово в очікуваній відповіді («Привіт, чим можу допомогти?»), коли я згадую «Привіт», тільки цього разу я не надаватиму вам очікувану відповідь.
ПІДСУМОК:
Кодер:
- Вхідне речення подається в кодер, і для кожного слова в реченні обчислюються значення вбудовування слів.
- Значення позиційного кодування обчислюються шляхом додавання точок на синусоїдальних і косинусоїдальних хвилях до вкладання слів, щоб відстежувати порядок слів у реченні, оскільки ви можете мати два речення з однаковими словами, але з різним значенням.
- Самоувага обчислюється для пошуку взаємозв’язку між кожним словом у вхідному реченні, щоб краще зрозуміти контекст. Це робиться шляхом генерації ЗАПИТІВ, КЛЮЧІВ і ЗНАЧЕНЬ, обчислення скалярних добутків ЗАПИТІВ і транспонованих КЛЮЧІВ, ділення скалярних добутків на квадратний корінь розмірів матриці КЛЮЧІВ, застосування функції SoftMax по рядках до масштабованих результатів і, нарешті, множення їх на ЗНАЧЕННЯ, щоб отримати остаточні оцінки самоуваги.
- Додаються залишкові зв’язки, що передбачає додавання раніше обчислених значень позиційного кодування до нових значень самоуваги, щоб запобігти забуванню значень. Ці остаточні значення стають вихідними даними кодера. Примітка: залишкові зв’язки додаються після шарів прямого поширення та уваги.
Декодер:
- Вхідне речення подається в кодер, і для кожного слова в реченні обчислюються значення вкладання слів.
- Значення позиційного кодування обчислюються шляхом додавання точок на синусоїдальних і косинусоїдальних хвилях до вбудовувань слів, щоб відстежувати порядок слів у реченні, оскільки можуть бути два речення з однаковими словами, але з різним значенням.
- Самоувага обчислюється для пошуку взаємозв’язку між кожним словом у вхідному реченні, щоб краще зрозуміти контекст. Це робиться шляхом генерації ЗАПИТІВ, КЛЮЧІВ і ЗНАЧЕНЬ, обчисленням скалярних добутків ЗАПИТІВ і транспонованих КЛЮЧІВ, діленням скалярних добутків на квадратний корінь розмірів матриці KEY, застосуванням маски уваги або маски попереднього перегляду, щоб запобігти декодеру заглядати вперед, щоб побачити наступні слова під час навчання, застосуванням функції SoftMax для отримання їх відсотків SoftMax по рядках і, нарешті, множенням їх на ЗНАЧЕНЬ для отримання остаточних балів самоуваги.
- Додаються залишкові зв’язки, що передбачає додавання раніше обчислених значень позиційного кодування до нових балів самоуваги. Ці остаточні значення стають результатами роботи декодера.
Кодер-декодер:
- Увага кодера-декодера здійснюється шляхом спочатку генерування КЛЮЧІВ і ЗНАЧЕНЬ з результату роботи кодера, а також ЗАПИТІВ з поточних результатів роботи декодера, а також виконання операцій скалярного добутку або обчислень для всіх значень. Це робиться для того, щоб знайти взаємозв’язок між усіма словами в кодері та кожним словом в декодері.
- Значення уваги кодера-декодера спочатку ділять на квадратний корінь розмірів матриці КЛЮЧІВ (кількість КЛЮЧІВ, що представляють кожне слово), а потім масштабують, передаючи всі значення по рядках у функцію SoftMax, щоб отримати їхні відсотки SoftMax.
- Ці відсотки SoftMax множаться на раніше згенеровані ЗНАЧЕННЯ з виходу кодера, а їхні результати додаються відповідно, щоб отримати остаточні бали уваги кодера-декодера.
- Додаються залишкові з’єднання, що передбачає додавання попередніх кінцевих виходів декодера до нових кінцевих балів уваги кодера-декодера, щоб отримати нові виходи для кожного слова.
- Ці нові вихідні дані для кожного слова проходять через стандартну нейронну мережу прямого поширення, а їхні результати проходять через функцію SoftMax, щоб отримати відсотки SoftMax для наступного вихідного слова, яке буде передбачено.
- Вихідне слово з найвищим відсотком SoftMax стає передбачуваним вихідним словом.
Молодець, моряк! Ти дійшов до кінця цієї статті. Тепер ти експерт з великих мовних моделей і трансформерів.
Вихідний код моєї магістерської роботи на GitHub:
DeepLearning-projects/Large Language Model.ipynb at main · Piraytekinz/DeepLearning-projects
[1] J. Anang, профіль у LinkedIn (2025),Joshua Anang | LinkedIn
[2] J. Anang, профіль у Twitter, Joshua Anang (@ChatDoc783) / X
[3] J. Anang, Поточний проект — додаток, який перетворює ваші зображення на дивовижні ефекти частинок, https://array-psi.vercel.app
Подяка StatQuest за подібні дизайни діаграм.
ОРИГІНАЛ СТАТТІ:The math and logic behind ChatGPT. This paper is all you need.
АВТОР СТАТІ:Joshua Anang
🚀Долучайтесь до нашої спільноти Telegram:
🚀Долучайтесь до нашої спільноти FaceBook:
🚀Долучайтесь до нашої спільноти Twiter X:
