3. Токенні Вбудовування

Reading time: 5 minutes

Токенні Вбудовування

Після токенізації текстових даних наступним критичним кроком у підготовці даних для навчання великих мовних моделей (LLMs), таких як GPT, є створення токенних вбудовувань. Токенні вбудовування перетворюють дискретні токени (такі як слова або підслова) у безперервні числові вектори, які модель може обробляти та навчатися з них. Це пояснення розкриває токенні вбудовування, їх ініціалізацію, використання та роль позиційних вбудовувань у покращенні розуміння моделі послідовностей токенів.

tip

Мета цього третього етапу дуже проста: Призначити кожному з попередніх токенів у словнику вектор бажаних розмірностей для навчання моделі. Кожне слово в словнику буде точкою в просторі X вимірів.
Зверніть увагу, що спочатку позиція кожного слова в просторі просто ініціалізується "випадковим чином", і ці позиції є параметрами, що підлягають навчання (будуть покращені під час навчання).

Більше того, під час токенного вбудовування створюється ще один шар вбудовувань, який представляє (в цьому випадку) абсолютну позицію слова в навчальному реченні. Таким чином, слово в різних позиціях у реченні матиме різне представлення (значення).

Що таке Токенні Вбудовування?

Токенні Вбудовування — це числові представлення токенів у безперервному векторному просторі. Кожен токен у словнику асоціюється з унікальним вектором фіксованих розмірностей. Ці вектори захоплюють семантичну та синтаксичну інформацію про токени, що дозволяє моделі розуміти відносини та шаблони в даних.

  • Розмір Словника: Загальна кількість унікальних токенів (наприклад, слів, підслів) у словнику моделі.
  • Розміри Вбудовування: Кількість числових значень (вимірів) у векторі кожного токена. Вищі виміри можуть захоплювати більш тонку інформацію, але вимагають більше обчислювальних ресурсів.

Приклад:

  • Розмір Словника: 6 токенів [1, 2, 3, 4, 5, 6]
  • Розміри Вбудовування: 3 (x, y, z)

Ініціалізація Токенних Вбудовувань

На початку навчання токенні вбудовування зазвичай ініціалізуються з малими випадковими значеннями. Ці початкові значення коригуються (доладно налаштовуються) під час навчання, щоб краще представляти значення токенів на основі навчальних даних.

Приклад PyTorch:

python
import torch

# Set a random seed for reproducibility
torch.manual_seed(123)

# Create an embedding layer with 6 tokens and 3 dimensions
embedding_layer = torch.nn.Embedding(6, 3)

# Display the initial weights (embeddings)
print(embedding_layer.weight)

Вихід:

lua
luaCopy codeParameter containing:
tensor([[ 0.3374, -0.1778, -0.1690],
[ 0.9178,  1.5810,  1.3010],
[ 1.2753, -0.2010, -0.1606],
[-0.4015,  0.9666, -1.1481],
[-1.1589,  0.3255, -0.6315],
[-2.8400, -0.7849, -1.4096]], requires_grad=True)

Пояснення:

  • Кожен рядок відповідає токену в словнику.
  • Кожен стовпець представляє вимір у векторі вбудовування.
  • Наприклад, токен з індексом 3 має вектор вбудовування [-0.4015, 0.9666, -1.1481].

Доступ до вбудовування токена:

python
# Retrieve the embedding for the token at index 3
token_index = torch.tensor([3])
print(embedding_layer(token_index))

Вихід:

lua
tensor([[-0.4015,  0.9666, -1.1481]], grad_fn=<EmbeddingBackward0>)

Інтерпретація:

  • Токен з індексом 3 представлений вектором [-0.4015, 0.9666, -1.1481].
  • Ці значення є параметрами, що підлягають навчання, які модель буде коригувати під час навчання, щоб краще відобразити контекст і значення токена.

Як працюють токенні вбудування під час навчання

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

Приклад сценарію:

  • Розмір партії: 8 (кількість зразків, що обробляються одночасно)
  • Максимальна довжина послідовності: 4 (кількість токенів на зразок)
  • Розміри вбудування: 256

Структура даних:

  • Кожна партія представлена як 3D тензор з формою (batch_size, max_length, embedding_dim).
  • Для нашого прикладу форма буде (8, 4, 256).

Візуалізація:

css
cssCopy codeBatch
┌─────────────┐
│ Sample 1    │
│ ┌─────┐     │
│ │Token│ → [x₁₁, x₁₂, ..., x₁₂₅₆]
│ │ 1   │     │
│ │...  │     │
│ │Token│     │
│ │ 4   │     │
│ └─────┘     │
│ Sample 2    │
│ ┌─────┐     │
│ │Token│ → [x₂₁, x₂₂, ..., x₂₂₅₆]
│ │ 1   │     │
│ │...  │     │
│ │Token│     │
│ │ 4   │     │
│ └─────┘     │
│ ...         │
│ Sample 8    │
│ ┌─────┐     │
│ │Token│ → [x₈₁, x₈₂, ..., x₈₂₅₆]
│ │ 1   │     │
│ │...  │     │
│ │Token│     │
│ │ 4   │     │
│ └─────┘     │
└─────────────┘

Пояснення:

  • Кожен токен у послідовності представлений 256-вимірним вектором.
  • Модель обробляє ці вектори для вивчення мовних патернів і генерації прогнозів.

Позиційні вектори: Додавання контексту до токенів

Хоча токенові вектори захоплюють значення окремих токенів, вони не закодовані за замовчуванням у позиції токенів у послідовності. Розуміння порядку токенів є критично важливим для розуміння мови. Тут на допомогу приходять позиційні вектори.

Чому потрібні позиційні вектори:

  • Порядок токенів має значення: У реченнях значення часто залежить від порядку слів. Наприклад, "Кіт сидів на килимку" проти "Килимок сидів на коті."
  • Обмеження векторів: Без позиційної інформації модель розглядає токени як "мішок слів", ігноруючи їх послідовність.

Типи позиційних векторів:

  1. Абсолютні позиційні вектори:
  • Призначають унікальний вектор позиції для кожної позиції в послідовності.
  • Приклад: Перший токен у будь-якій послідовності має той самий позиційний вектор, другий токен має інший і так далі.
  • Використовується: Моделями GPT від OpenAI.
  1. Відносні позиційні вектори:
  • Кодують відносну відстань між токенами, а не їх абсолютні позиції.
  • Приклад: Вказують, наскільки далеко один токен від іншого, незалежно від їх абсолютних позицій у послідовності.
  • Використовується: Моделями, такими як Transformer-XL та деякими варіантами BERT.

Як інтегруються позиційні вектори:

  • Ті ж розміри: Позиційні вектори мають таку ж розмірність, як і токенові вектори.
  • Додавання: Вони додаються до токенових векторів, поєднуючи ідентичність токена з позиційною інформацією без збільшення загальної розмірності.

Приклад додавання позиційних векторів:

Припустимо, вектор токену є [0.5, -0.2, 0.1], а його позиційний вектор є [0.1, 0.3, -0.1]. Об'єднаний вектор, що використовується моделлю, буде:

css
Combined Embedding = Token Embedding + Positional Embedding
= [0.5 + 0.1, -0.2 + 0.3, 0.1 + (-0.1)]
= [0.6, 0.1, 0.0]

Переваги позиційних векторів:

  • Контекстуальна обізнаність: Модель може розрізняти токени на основі їхніх позицій.
  • Розуміння послідовності: Дозволяє моделі розуміти граматику, синтаксис та значення, що залежать від контексту.

Приклад коду

Наступний приклад коду з https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb:

python
# Use previous code...

# Create dimensional emdeddings
"""
BPE uses a vocabulary of 50257 words
Let's supose we want to use 256 dimensions (instead of the millions used by LLMs)
"""

vocab_size = 50257
output_dim = 256
token_embedding_layer = torch.nn.Embedding(vocab_size, output_dim)

## Generate the dataloader like before
max_length = 4
dataloader = create_dataloader_v1(
raw_text, batch_size=8, max_length=max_length,
stride=max_length, shuffle=False
)
data_iter = iter(dataloader)
inputs, targets = next(data_iter)

# Apply embeddings
token_embeddings = token_embedding_layer(inputs)
print(token_embeddings.shape)
torch.Size([8, 4, 256]) # 8 x 4 x 256

# Generate absolute embeddings
context_length = max_length
pos_embedding_layer = torch.nn.Embedding(context_length, output_dim)

pos_embeddings = pos_embedding_layer(torch.arange(max_length))

input_embeddings = token_embeddings + pos_embeddings
print(input_embeddings.shape) # torch.Size([8, 4, 256])

Посилання