3. Token Embeddings

Token-Embeddings

Nach der Tokenisierung von Textdaten ist der nächste kritische Schritt bei der Vorbereitung von Daten für das Training großer Sprachmodelle (LLMs) wie GPT die Erstellung von Token-Embeddings. Token-Embeddings transformieren diskrete Tokens (wie Wörter oder Subwörter) in kontinuierliche numerische Vektoren, die das Modell verarbeiten und aus denen es lernen kann. Diese Erklärung zerlegt Token-Embeddings, deren Initialisierung, Verwendung und die Rolle von Positions-Embeddings zur Verbesserung des Modells beim Verständnis von Token-Sequenzen.

Das Ziel dieser dritten Phase ist sehr einfach: Weisen Sie jedem der vorherigen Tokens im Vokabular einen Vektor der gewünschten Dimensionen zu, um das Modell zu trainieren. Jedes Wort im Vokabular wird einen Punkt in einem Raum von X Dimensionen haben. Beachten Sie, dass die Position jedes Wortes im Raum zunächst "zufällig" initialisiert wird und diese Positionen trainierbare Parameter sind (während des Trainings verbessert werden).

Darüber hinaus wird während des Token-Embeddings eine weitere Schicht von Embeddings erstellt, die (in diesem Fall) die absolute Position des Wortes im Trainingssatz darstellt. Auf diese Weise hat ein Wort an verschiedenen Positionen im Satz eine unterschiedliche Darstellung (Bedeutung).

Was sind Token-Embeddings?

Token-Embeddings sind numerische Darstellungen von Tokens in einem kontinuierlichen Vektorraums. Jedes Token im Vokabular ist mit einem einzigartigen Vektor fester Dimensionen verbunden. Diese Vektoren erfassen semantische und syntaktische Informationen über die Tokens, sodass das Modell Beziehungen und Muster in den Daten verstehen kann.

  • Vokabulargröße: Die Gesamtzahl der einzigartigen Tokens (z. B. Wörter, Subwörter) im Vokabular des Modells.

  • Embedding-Dimensionen: Die Anzahl der numerischen Werte (Dimensionen) im Vektor jedes Tokens. Höhere Dimensionen können nuanciertere Informationen erfassen, erfordern jedoch mehr Rechenressourcen.

Beispiel:

  • Vokabulargröße: 6 Tokens [1, 2, 3, 4, 5, 6]

  • Embedding-Dimensionen: 3 (x, y, z)

Initialisierung von Token-Embeddings

Zu Beginn des Trainings werden Token-Embeddings typischerweise mit kleinen zufälligen Werten initialisiert. Diese Anfangswerte werden während des Trainings angepasst (feinabgestimmt), um die Bedeutungen der Tokens besser basierend auf den Trainingsdaten darzustellen.

PyTorch-Beispiel:

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)

Ausgabe:

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)

Erklärung:

  • Jede Zeile entspricht einem Token im Vokabular.

  • Jede Spalte repräsentiert eine Dimension im Einbettungsvektor.

  • Zum Beispiel hat das Token an Index 3 einen Einbettungsvektor [-0.4015, 0.9666, -1.1481].

Zugriff auf die Einbettung eines Tokens:

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

Ausgabe:

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

Interpretation:

  • Der Token am Index 3 wird durch den Vektor [-0.4015, 0.9666, -1.1481] dargestellt.

  • Diese Werte sind trainierbare Parameter, die das Modell während des Trainings anpassen wird, um den Kontext und die Bedeutung des Tokens besser darzustellen.

Wie Token-Embeddings während des Trainings funktionieren

Während des Trainings wird jeder Token in den Eingabedaten in seinen entsprechenden Embedding-Vektor umgewandelt. Diese Vektoren werden dann in verschiedenen Berechnungen innerhalb des Modells verwendet, wie z.B. Aufmerksamkeitsmechanismen und neuronalen Netzwerk-Schichten.

Beispiel-Szenario:

  • Batch-Größe: 8 (Anzahl der gleichzeitig verarbeiteten Proben)

  • Maximale Sequenzlänge: 4 (Anzahl der Tokens pro Probe)

  • Embedding-Dimensionen: 256

Datenstruktur:

  • Jeder Batch wird als 3D-Tensor mit der Form (batch_size, max_length, embedding_dim) dargestellt.

  • Für unser Beispiel wäre die Form (8, 4, 256).

Visualisierung:

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   │     │
│ └─────┘     │
└─────────────┘

Erklärung:

  • Jedes Token in der Sequenz wird durch einen 256-dimensionalen Vektor dargestellt.

  • Das Modell verarbeitet diese Embeddings, um Sprachmuster zu lernen und Vorhersagen zu generieren.

Positions-Embeddings: Kontext zu Token-Embeddings hinzufügen

Während Token-Embeddings die Bedeutung einzelner Tokens erfassen, kodieren sie nicht von Natur aus die Position der Tokens innerhalb einer Sequenz. Das Verständnis der Reihenfolge der Tokens ist entscheidend für das Sprachverständnis. Hier kommen Positions-Embeddings ins Spiel.

Warum Positions-Embeddings benötigt werden:

  • Token-Reihenfolge ist wichtig: In Sätzen hängt die Bedeutung oft von der Reihenfolge der Wörter ab. Zum Beispiel: "Die Katze saß auf der Matte" vs. "Die Matte saß auf der Katze."

  • Einschränkung der Embeddings: Ohne Positionsinformationen behandelt das Modell Tokens als eine "Tüte voller Wörter" und ignoriert ihre Reihenfolge.

Arten von Positions-Embeddings:

  1. Absolute Positions-Embeddings:

  • Weisen jeder Position in der Sequenz einen einzigartigen Positionsvektor zu.

  • Beispiel: Das erste Token in jeder Sequenz hat dasselbe Positions-Embedding, das zweite Token hat ein anderes und so weiter.

  • Verwendet von: OpenAI’s GPT-Modelle.

  1. Relative Positions-Embeddings:

  • Kodieren den relativen Abstand zwischen Tokens anstelle ihrer absoluten Positionen.

  • Beispiel: Geben an, wie weit zwei Tokens voneinander entfernt sind, unabhängig von ihren absoluten Positionen in der Sequenz.

  • Verwendet von: Modellen wie Transformer-XL und einigen Varianten von BERT.

Wie Positions-Embeddings integriert werden:

  • Gleiche Dimensionen: Positions-Embeddings haben die gleiche Dimensionalität wie Token-Embeddings.

  • Addition: Sie werden zu Token-Embeddings addiert, wodurch die Identität des Tokens mit Positionsinformationen kombiniert wird, ohne die gesamte Dimensionalität zu erhöhen.

Beispiel für das Hinzufügen von Positions-Embeddings:

Angenommen, ein Token-Embedding-Vektor ist [0.5, -0.2, 0.1] und sein Positions-Embedding-Vektor ist [0.1, 0.3, -0.1]. Das kombinierte Embedding, das vom Modell verwendet wird, wäre:

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

Vorteile von Positional Embeddings:

  • Kontextuelles Bewusstsein: Das Modell kann zwischen Tokens basierend auf ihren Positionen unterscheiden.

  • Sequenzverständnis: Ermöglicht es dem Modell, Grammatik, Syntax und kontextabhängige Bedeutungen zu verstehen.

Codebeispiel

Folgend das Codebeispiel von https://github.com/rasbt/LLMs-from-scratch/blob/main/ch02/01_main-chapter-code/ch02.ipynb:

# 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])

Referenzen

Last updated