Per Anhalter durch die KI-Galaxie – LLM-Crashkurs Teil 2

Die Artikelserie zu den internen Mechanismen großer Sprachmodelle behandelt diesmal die benötigte Hardware und pretrained Models.

vorlesen Druckansicht 3 Kommentare lesen
Under the Motor Hood of an LLM

Blick unter die Motorhaube

(Bild: Erstellt mit DALL-E)

Lesezeit: 6 Min.
Von
  • Dr. Michael Stal
Inhaltsverzeichnis

Ein Large Language Model (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden Übersicht zu LLMs im ersten Teil geht es dieses Mal um die Hardware-Anforderungen und unterschiedliche vorab trainierte Modelle.

Der Pragmatische Architekt – Michael Stal
Michael Stal

Prof. Dr. Michael Stal arbeitet seit 1991 bei Siemens Technology. Seine Forschungsschwerpunkte umfassen Softwarearchitekturen für große komplexe Systeme (Verteilte Systeme, Cloud Computing, IIoT), Eingebettte Systeme und Künstliche Intelligenz. Er berät Geschäftsbereiche in Softwarearchitekturfragen und ist für die Architekturausbildung der Senior-Software-Architekten bei Siemens verantwortlich.

Fasten your seat belts!

Per Anhalter durch die KI-Galaxie

Am Rande eine Bemerkung zu Hardware-Anforderungen: In der Beschreibung ist zu erkennen, dass im LLM sowohl für das Training als auch für die Ausführung (Inferenz) komplexe mathematische Berechnungen mit Vektoren vorkommen. Auf diese sind GPU-Kerne und neuronale Prozessoren spezialisiert. Daher benötigen LLM-Entwicklerinnen und -Nutzer leistungsvolle TPUs oder GPUs mit möglichst viel RAM. Mit normalen CPUs und wenig Arbeitsspeicher kommt man nicht weit, außer für sehr kleine Modelle. In den Speicher der GPU müssen unter anderem der Kontext und die errechneten Gewichte des LLM passen. Letztere können bis zu mehreren Hundert Gigabyte umfassen, während der Kontext von einigen Kilobytes bis zu vielen Megabytes reicht. Das Modell Deepseek R1 weist 671 Milliarden Gewichte/Tensoren und damit einen Speicherbedarf von rund 500 Gigabyte auf; OpenAI-Modelle sollen teilweise über ein Terabyte benötigen. Dafür wären etwa mehrere GPU-Beschleuniger vom Typ Nvidia H100 notwendig. Folgerichtig können Entwickler nur beschränkt Modelle auf ihren lokalen Systemen trainieren und laufen lassen, etwa bei guter Hardware-Ausstattung Modelle mit bis zu 70 Milliarden Parametern.

Vorab trainierte Modelle sind LLMs, die ihre Schöpfer auf großen Datensätzen trainiert und für spezifische Aufgaben feingetunt haben. Diese Modelle dienen als Ausgangspunkt für andere Aufgaben, um dem Modell zu ermöglichen, die während des Trainings gelernten Muster und Beziehungen zu nutzen. Beliebte vorab trainierte Modelltypen sind:

  • BERT (Bidirectional Encoder Representations from Transformers): ein vorab trainiertes Modell, das einen mehrschichtigen bidirektionalen Transformer-Encoder verwendet, um kontextualisierte Darstellungen von Wörtern im Eingabetext zu generieren.
  • RoBERTa (Robustly Optimized BERT Pretraining Approach): ein vorab trainiertes Modell, das eine modifizierte Version der BERT-Architektur und ein anderes Trainingsziel verwendet.
  • XLNet (Extreme Language Modeling): ein vorab trainiertes Modell, das eine Kombination von Autoencoding- und autoregressiven Techniken nutzt, um kontextualisierte Darstellungen von Wörtern im Eingabetext zu generieren.

Kontextfenster beziehen sich auf die Menge an Eingabetext, die das Modell zu einem bestimmten Zeitpunkt betrachten kann. Das haben wir schon im ersten Teil der Serie betrachtet, soll aber hier nochmals Erwähnung finden. Das Kontextfenster kann fest oder dynamisch sein, je nach Modellarchitektur. Ein größeres Kontextfenster ermöglicht es dem Modell, mehr Kontext zu erfassen, erhöht aber auch den Rechenaufwand. Moderne LLMs haben Kontextlängen von ein paar tausend bis zu ein paar Millionen Tokens.

Masken helfen, das Modell daran zu hindern, auf bestimmte Teile des Eingabetextes zu achten. Es gibt verschiedene Arten von Masken, darunter:

  • Padding-Masken dienen dazu, um das Modell daran zu hindern, auf Padding-Token zu achten, die zum Eingabetext hinzugefügt werden, um ihm eine feste Länge zu geben. Zu diesen Token gehört zum Beispiel das EoS-Token (End of Sequence).
  • Achtungsmasken verhindern im Modell, bestimmte Teile des Eingabetextes zu sehen, etwa zukünftige Token in einer Sequenz.
  • Kausale Masken sind nützlich, um das Modell daran zu hindern, auf zukünftige Token in einer Sequenz zu achten, und um dadurch zu ermöglichen, Text Token-weise zu generieren.

Sobald man eine Abfrage (Prompt) in ein LLM eingibt, durchläuft die Abfrage die folgenden Schritte:

  • Tokenisierung: Die Implementierung zerlegt die Nutzeranfrage (Prompt) in eine Folge von Token, wie Wörter oder Subwörter.
  • Embedding-Erstellung: Jedes Token wandelt sich in eine numerische Darstellung, indem die Implementierung es durch eine Embedding-Schicht leitet.
  • Positionelle Codierung: Die Embeddings des Prompts verknüpft das Modell mit positionellen Codierungen, um die Reihenfolge der Token zu erhalten.

Danach führt das LLM die folgenden Schritte aus:

  • Self-Attention: Das Embedding des Prompts durchläuft eine Self-Attention-Schicht, um eine kontextualisierte Darstellung zu generieren.
  • Cross-Attention: Die kontextualisierte Darstellung durchläuft eine Cross-Attention-Schicht, um externe Informationen zu berücksichtigen, beispielsweise den Eingabetext oder andere Modelle.
  • Feed-Forward-Layer: Das LLM leitet die Ausgabe der Cross-Attention-Schicht danach durch mehrere Feed-Forward-Layer, um die Darstellung in eine höhere Ebene zu transformieren. Zweck: Der Layer fügt Nichtlinearität und Kapazität hinzu, um komplexe Muster zu lernen.
  • Kontextfenster: Die endgültige Ausgabe erzeugt das LLM durch Anwendung eines Kontextfensters. Es arbeitet auf der erwähnten höheren Ebene der Darstellung. Das erlaubt dem Modell, sich auf einen bestimmten Teil der Abfrage zu konzentrieren.
  • Maskierung: Letztlich erfolgt die Maskierung der endgültigen Ausgabe, um das Modell daran zu hindern, auf bestimmte Teile der Abfrage zu achten, wie auf Padding-Token.

Der nachfolgende Code demonstriert die Schritt-für-Schritt-Verarbeitung einer Abfrage, einschließlich Tokenisierung, Embedding-Erstellung, positioneller Codierung, Self-Attention, Cross-Attention, Feed-Forward-Layer, Kontextfenster und Maskierung.


import torch
from transformers import AutoModelForMaskedLM, AutoTokenizer

# Laden Sie das vorab trainierte Modell und den Tokenizer
modell = AutoModelForMaskedLM.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# Definieren Sie eine Abfrage
abfrage = "Erläutere die Geschichte des Heise-Verlags."

# Tokenisieren Sie die Abfrage
eingabe = tokenizer(abfrage, return_tensors="pt")

# Erstellen Sie die Embeddings
embedded_abfrage = modell.embeddings(eingabe["input_ids"])

# Fügen Sie die positionale Kodierung hinzu
positionale_kodierung = modell.positional_encodings(embedded_abfrage)
embedded_abfrage = embedded_abfrage + positionale_kodierung

# Wenden Sie die Self-Attention an
kontextualisierte_darstellung = modell.self_attention(embedded_abfrage)

# Wenden Sie die Cross-Attention an
hoeher_ebene_darstellung = modell.cross_attention(kontextualisierte_darstellung)

# Wenden Sie die Feed-Forward-Layer an
transformierte_darstellung = modell.feed_forward_layers(hoeher_ebene_darstellung)

# Wenden Sie das Kontextfenster an
endgueltige_ausgabe = modell.context_window(transformierte_darstellung)

# Maskieren Sie die Ausgabe
antwort = modell.masking(endgueltige_ausgabe)

print(antwort)

Die folgenden Dateien erstellt oder modifiziert das Modell während der Ausführung:

  • modell.pth: die trainierte Modell-Datei
  • tokenizer.json: die Tokenizer-Konfigurationsdatei
  • abfrage.txt: die Eingabe-Abfrage-Datei
  • antwort.txt: die Ausgabe-Antwort-Datei

Hinweis: Dies ist ein stark vereinfachtes Beispiel. Reale Anwendungen mit LLMs sind in der Praxis viel komplexer und vielschichtiger.

In meinem nächsten Blogbeitrag gehe ich auf unterschiedliche Architekturtypen von LLMs ein. (rme)