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

Die Artikelserie zeigt die internen Mechanismen groĂźer Sprachmodelle von der Texteingabe bis zur Textgenerierung.

In Pocket speichern vorlesen Druckansicht
KI-generiertes Auto mit offener motorhaube und Datenstrukturen

Blick unter die Motorhaube

(Bild: generated by DALL-E)

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

Ein Large Language Modell (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden EinfĂĽhrung von LLMs im ersten und den Hardwareanforderungen und vorabtrainierten Modellen im zweiten Teil geht es diesmal um unterschiedliche Architekturtypen.

Der Pragmatische Architekt – 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!

Ein häufiges Missverständnis der Transformer-Architektur besteht darin, dass LLMs notwendig alle Teile dieser Architektur enthalten müssen. Das ist nicht der Fall. Stattdessen lassen sich in der Praxis die folgenden Architekturtypen unterscheiden:

Sequence-to-Sequence-Modelle (Seq-to-Seq) sind darauf ausgelegt, eine Eingabesequenz wie einen Satz auf eine Ausgabesequenz wie eine Ăśbersetzung oder Antwort abzubilden. Sie implementieren die Transformer-Architektur und bestehen infolgedessen aus:

  • Encoder: wandelt die Eingabe in eine dichte Darstellung (Kontextvektor) um
  • Decoder: erzeugt die Ausgabesequenz schrittweise (Token fĂĽr Token) unter Verwendung des Kontextvektors

Seq-to-Seq-Modelle werden häufig für Aufgaben wie maschinelle Übersetzung, Textzusammenfassung und Textgenerierung eingesetzt. Beispiele sind das ursprüngliche Transformer-Modell von Google und T5 (Text-to-Text Transfer Transformer).

Decoder-Only-Modelle: Modelle wie GPT (Generative Pre-trained Transformer) verwenden eine reine Decoder-Architektur. Sie sind darauf trainiert, das nächste Token in einer Sequenz vorherzusagen, was sie besonders effektiv für Textgenerierung und -vervollständigung macht. Diese Modelle glänzen bei offenen Aufgaben, besitzen jedoch kein bidirektionales Kontextverständnis.

Encoder-Only-Modelle: BERT (Bidirectional Encoder Representations from Transformers) ist ein Beispiel fĂĽr ein reines Encoder-Modell. Es verarbeitet Eingabetext bidirektional und erfasst Kontext sowohl aus vorangehenden als auch nachfolgenden Token. BERT eignet sich ideal fĂĽr Aufgaben wie Sentimentanalyse, Named-Entity Recognition und Frage-Antwort-Systeme, kann aber keinen Text direkt generieren.

Wer Sentimentanalyse nicht kennt: Hier soll das Modell die Grundstimmung wie positiv oder negativ eines Satzes analysieren. Zum Beispiel enthält "Ich finde diesen Artikel gut." eine positive Aussage.

Hybride Architekturen: Einige Modelle wie T5 kombinieren Encoder-Decoder-Architekturen für einen einheitlichen Ansatz. T5 behandelt jede NLP-Aufgabe als ein Text-zu-Text-Problem, bei dem sowohl Eingabe als auch Ausgabe Textsequenzen sind. Diese Flexibilität macht es für vielfältige Aufgaben wie Übersetzung, Zusammenfassung und Klassifizierung geeignet.

Um LLMs zu trainieren, braucht es zunächst Daten und davon eine ganze Menge mit ausreichender Qualität. Das Training erfolgt in drei Schritten.

  • Vorbereitung der Daten, wobei Daten aus verschiedenen Quellen stammen, etwa BĂĽcher, Webseiten, Code, Wissenschaftstexte (z. B. The Pile, Common Crawl). Wichtig ist auch die Quantität der Daten. Moderne LLMs werden auf >1 Milliarde Gewichte trainiert.
  • Trainingsziel: Das Ziel des LLM ist die Next Token Prediction, also wie sich das nächste Wort vorhersagen lässt. DafĂĽr gibt es autoregressives Training: Das Modell lernt, das nächste Token x_{t+1} aus dem gegebenen Kontext ( x_1, ..., x_t ) vorherzusagen.
  • Verlustfunktion: Aus der Kreuzentropie zwischen vorhergesagter und tatsächlicher Token-Verteilung ergibt sich der Vorhersagefehler.

Das Training optimiert die gewählten Gewichte, bis die Verlustfunktion nur noch verschwindend kleine Vorhersagefehler (die Minima der Verlustfunktion) zurückmeldet.

Zur Optimierung gibt es unterschiedliche Stellgrößen und Verfahren:

  • AdamW-Optimierer: verfolgt einen adaptiven Lernratenansatz. Das heiĂźt, die Größe einzelner Lernschritte variiert, um möglichst schnell das Training durchzufĂĽhren und dabei gleichzeitig fĂĽr möglichst kleine Fehler der Vorhersagen zu sorgen.
  • Batch-Größen können bis zu Millionen von Token pro Batch sein.
  • Hardware: Das Training dauert auf TPU/GPU-Clustern ĂĽber Wochen/Monate und kostet von Millionen bis mehreren hundert Millionen Euro. Allein die dafĂĽr notwendige Hardwareinfrastruktur ist immens, ganz zu schweigen von deren Kosten.

Um das Training zu verbessern, hat es sich darüber hinaus als empfehlenswert herausgestellt, mit Dropouts zu arbeiten. Dropouts definieren für eine neuronale Schicht bzw. für ein neuronales Netzwerk, dass ein gewisser Prozentsatz zufällig ausgewählter Neuronen in einer Trainingsiteration inaktiv bleiben soll. Dadurch erhöht sich erfahrungsgemäß die Robustheit des Verfahrens.

In großen Sprachmodellen (LLMs) wie GPT, BERT oder T5 ist eine Residual Connection (manchmal auch Skip Connection) ein zentrales Element der Transformer-Architektur. Sie stabilisiert das Training und ermöglicht es dem Modell, effektiv über Dutzende oder Hunderte von Schichten hinweg zu lernen. Ohne Residual Connections wären moderne LLMs kaum effektiv trainierbar, insbesondere in großem Maßstab. Sie sind grundlegend für das "Deep" in Deep Learning bei Sprachmodellen!

Wie Residual Connections funktionieren:

  • Struktur der Transformer-Schicht: Jede Transformer-Schicht (z. B. Self-Attention- oder Feed-Forward-Sublayer) enthält eine Residual Connection. Die Eingabe der Schicht wird direkt zu ihrem Ausgang addiert: Ausgabe = LayerNorm(x) + Sublayer(x). Hier steht `Sublayer` fĂĽr die Self-Attention oder das Feed-Forward-Neuronale-Netz (FFN), und `LayerNorm` bezeichnet die Layer-Normalisierung.
  • Zweck von Residual Connections: Eine Residual Connection reduziert verschwindende Gradienten. Durch den "Kurzschluss" (Shortcut) fĂĽr Gradienten beim RĂĽckwärtsdurchlauf (Back Propagation) verhindern Residual Connections, dass Gradienten in tiefen Netzwerken während des Trainings auf nahezu Null schrumpfen. Dadurch können wegen numerischer Fehler Situationen auftreten, aus denen beim Training suboptimale Ergebnisse resultieren. Eine Residual Connection ermöglicht des Weiteren tiefe Architekturen. LLMs haben oft Dutzende bis Hunderte von Schichten. Residual Connections machen das Training solch tiefer Modelle praktikabel, indem das Netzwerk kleine Anpassungen (Residuen) zur Eingabe lernt, anstatt komplette Transformationen. Nicht zuletzt merkt sich eine Residual Connection Informationen. Das ist entscheidend fĂĽr Sprachaufgaben, bei denen rohe Eingaben (z. B. Wort-Embeddings) ĂĽber viele Schichten hinweg relevant bleiben mĂĽssen.

Residual Connections sind somit aus folgenden GrĂĽnden in LLMs wichtig:

  • Stabilität beim Training: LLMs werden mit Milliarden von Parametern trainiert. Residual Connections sorgen fĂĽr effiziente Gradientenausbreitung und verhindern instabiles Training.
  • Abhängigkeiten mit langer Reichweite: Sprachaufgaben erfordern das Verständnis von Beziehungen zwischen weit entfernten Token (z. B. in einem Absatz). Residual Connections helfen, Token-Informationen ĂĽber Schichten hinweg zu bewahren.
  • Synergie mit Layer-Normalisierung: Die Kombination aus Residual Connections und Layer-Normalisierung glättet die Optimierung und beschleunigt die Konvergenz.

Wichtige LLMs mit Residual Connections beinhalten unter anderem:

  • GPT-3/4: Jede Transformer-Decoder-Schicht nutzt Residual Connections.
  • BERT: Encoder-Schichten verwenden Residual Connections fĂĽr bidirektionalen Kontext.
  • T5: Kombiniert Encoder-Decoder-Architektur mit Residual Links in beiden Komponenten.

Der Einsatz trainierter LLMs geschieht ĂĽber Chatbots der Hersteller, ĂĽber APIs oder fĂĽr lokal verfĂĽgbare Modelle ĂĽber Werkzeuge wie Ollama und llama.cpp.

In der sogenannten autoregressiven Decodierung erzeugt das Modell Schritt fĂĽr Schritt neue Token:

  • Das LLM zerlegt die Eingabe des Benutzers in Token.
  • Das LLM sagt das nächste Token voraus.
  • Das LLM fĂĽgt das neue Token zur Eingabe fĂĽr den nächsten Schritt hinzu.

Die genutzten Sampling-Strategien (= Tokenauswahlstrategien) umfassen dabei verschiedene Optionen:

  • Greedy Decoding wählt das Token mit der höchsten Wahrscheinlichkeit aus (oft repetitiv).
  • Beam Search verfolgt parallel mehrere Kandidatensequenzen.
  • Top-k / Top-p Sampling trifft eine stochastische Auswahl aus den k wahrscheinlichsten Token oder Token mit kumulativer Wahrscheinlichkeit p.

Der vom Nutzer beeinflussbare Parameter Temperatur kontrolliert die Zufälligkeit (hohe Temperatur kreativ, niedrige konservativ) der gewählten Token.

Zu beachten sind dabei Skalierungsgesetze und Modellgrößen wie:

  • Chinchilla-Optimalität: Die Leistung korreliert natĂĽrlich mit Modellgröße N, Datenmenge D und Rechenkapazität C.
  • Effizienz: Größere Modelle benötigen exponentiell mehr Daten und Verarbeitungszeit.

Normalsterbliche Nutzer von LLMs können natürlich mangels ausreichender finanzieller Mittel und Hardware keine eigenen LLMs trainieren, zumindest nicht große Frontier-Modelle wie die von OpenAI, Claude, Cohere, Meta, Google und Microsoft. Allerdings ist es möglich, die Gewichte eines Open-Source- oder Open-Weight-Modells finezutunen. Open-Weights-Modelle liefern zwar die Gewichte mit, aber im Gegensatz zu Open-Source-Modellen nicht die zum Training verwendeten Daten oder Workflows. In beiden Fällen ist es aber möglich, die meisten Gewichte des trainierten Modells einzufrieren, um danach mit eigenen Trainingsdaten die nicht eingefrorenen Gewichte zu trainieren. Das nennt man Transfer-Learning. Dazu gibt es verschiedene Werkzeuge für macOS (z. B. MLX), Linux und Windows (z. B. Unsloth). Vorteil dieses eher leichtgewichtigen Ansatzes ist der geringere Hardwarebedarf und Zeitaufwand, um LLMs mit neuen domänenspezifischen Daten anzureichern. Das ist bei kleineren Modellen auch für den "Heimgebrauch" machbar.

Durch Retrieval Augmented Generation lassen sich Inhalte von Embedding-Datenbanken und ein LLM kombiniert fĂĽr Abfragen (Prompts) nutzen.

(Bild: Wikipedia)

Da Modelle immer nur die aktuellen Daten zum Zeitpunkt ihres Trainings beinhalten und meistens eine sehr breite Zahl von Domänen antrainiert bekommen, gibt es mehrere Möglichkeiten, nachträglich tagesaktuelle Daten oder domänenspezifische Daten auf Umwegen ins Modell "einzuschleusen":

RAG (Retrieval Augmented Generation): Die Benutzerin nutzt ein passendes LLM-Modell. Zusätzlich verwendet sie eine Vektordatenbank. In dieser speichert sie Embeddings. Die Generierung der Embeddings erfolgt mit Hilfe vorliegender Dokumente, die die Anwendung zunächst in Teile (Chunks) zerlegt, die Teile anschließend in Embeddings (Vektoren) umwandelt und dann in der Vektordatenbank speichert. Falls eine Benutzeranfrage eintrifft, sucht die Anwendung zunächst in der Datenbank nach zum Eingabe-Prompt ähnlichen Embeddings (z. B. mittels Cosinus-Ähnlichkeitssuche), übergibt diese mit einem dafür geeigneten Prompt an das LLM und liefert dessen Ausgabe nach optionaler Nachbearbeitung an den User zurück. Dafür ist freilich notwendig, dass RAG und LLM das gleiche Embedding-Modell verwenden. Natürlich kann ein RAG-System alternativ auch mit ElasticSearch nach passenden Informationen suchen. Letzteren Ansatz können Entwickler zusammen mit Websuchen dafür nutzen, um eine LLM-unterstützte Websuche zu implementieren. Der Dienst Perplexity ist hierfür ein interessantes Beispiel.

Knowledge Graphs: Modernere Ansätze nutzen eine Graph-Datenbank (z. B. Neo4j) aus Wissensgraphen (Knowledge Graphs), um Information strukturiert zu speichern. Bei RAG-Systemen handelt es sich hingegen bei den gespeicherten Embeddings in der Regel um unstrukturierte Daten. Strukturierte Daten führen erfahrungsgemäß zu weniger Halluzinationen und sind leichter zu analysieren. In der Zukunft könnten Wissensgraphen daher an Bedeutung gewinnen.

Sie möchten ein LLM-Modell, das nicht in den Arbeitsspeicher ihrer GPU oder CPU passt, dennoch nutzen? Normalerweise speichern die Schichten eines LLM Gewichte und Bias-Vektoren in Form von 32-Bit-Gleitkommazahlen. Diese Präzision ist aber nicht immer notwendig. Quantisierung in Large-Language-Modellen bezeichnet den Prozess, bei dem die Präzision der Modellparameter reduziert wird, um die Modellgröße und den Rechenaufwand zu verringern. Dies geschieht durch die Umwandlung von hochpräzisen Datenformaten (z. B. 32-Bit-Gleitkommazahlen) in weniger präzise Formate (z. B. 8-Bit-Ganzzahlen). Dadurch können LLMs auf Hardware mit begrenzten Ressourcen ausgeführt werden, was zu schnelleren Inferenzen und geringerem Speicherverbrauch führt. Allerdings kann die Quantisierung die Genauigkeit der Modelle beeinträchtigen. In vielen Fällen ist der Genauigkeitsverlust durch Quantisierung verschmerzbar.

Wenn sie beispielsweise in Hugging Face nach Modellen suchen, dürften Sie auf seltsame Dateinamen für Modelle stoßen, etwa auf <modelname>….Q4_K_M. Endungen von LLM-Namen wie Q4_K_M enthalten wichtige Informationen über die Quantisierung und Optimierung des Modells. Hier ist eine detaillierte Erklärung:

  • Q4: Dies zeigt an, dass das Modell auf eine 4-Bit-Präzision quantisiert wurde. Quantisierung reduziert die Präzision der Modellgewichte von der typischen 32-Bit-Gleitkommadarstellung auf eine niedrigere Präzision, wie 4 Bit, um Speicherplatz zu sparen und die Inferenzgeschwindigkeit zu verbessern.
  • K: Dies bezieht sich auf die spezifische Quantisierungsmethode, die fĂĽr bestimmte Teile des Modells verwendet wird, zum Beispiel die Aufmerksamkeitsmechanismen. Es beinhaltet oft die Optimierung des Kernels (K) fĂĽr bessere Leistung.
  • M: Dieser Suffix zeigt typischerweise an, dass die Quantisierungsmethode selektiv angewendet wird, oft auf bestimmte Schichten wie Einbettungen oder Aufmerksamkeitsmechanismen, während andere in der höheren Präzision bleiben. Dieser Ansatz balanciert Leistung und Speicherbedarf.

Zusammenfassend bedeutet Q4_K_M, dass das Modell auf 4-Bit-Präzision quantisiert ist, wobei optimierte Kernelmethoden selektiv Anwendung finden, um die Leistung zu erhalten, während sich der Speicherbedarf reduziert.

Hier ein Überblick über gängige Kürzel der möglichen Quantisierungsstufen:

  • Q2 (2 Bit)
  • Q4 (4 Bit)
  • Q8 (8 Bit)
  • Q16 (16 Bit)
  • Q32 (32 Bit, typischerweise nicht quantisiert)
  • K: Dies könnte sich auf eine spezifische Kernel- oder Optimierungsmethode beziehen. Mögliche Variationen könnten unterschiedliche Kerneloptimierungen oder Techniken umfassen, aber spezifische Werte sind nicht standardisiert.
  • FĂĽr die verwendete Präzision gibt es drei Möglichkeiten: M (Gemischte Präzision): Nur eine Teilmenge der Schichten erfährt eine Quantisierung, F (Volle Präzision): Das Modell verwendet die volle Präzision sowie S (Selektive Quantisierung): Quantisierung findet nur fĂĽr eine selektive Teilmenge der Schichten statt.

Mögliche Kombinationen könnten also sein:

  • Q2_K_M
  • Q4_K_F
  • Q8_K_S
  • Q16_K_M

Diese Kombinationen spiegeln somit unterschiedliche Quantisierungsstufen und Optimierungsstrategien wider. Die genauen Namenskonventionen können jedoch je nach spezifischer Implementierung oder Modellarchitektur variieren.

HinzufĂĽgungen wie _0 oder _1 bezeichnen Versionen von Quantisierungsschemata, beispielsweise unterschiedliche Algorithmen oder Techniken.

Im Umfeld von LLMs sind Modelle fast immer als GGUF/GGML-Dateien gespeichert. Auch Apple MLX unterstützt hauptsächlich das GGUF (GPT-Generated Unified Format) für Modelldateien, hat jedoch kürzlich eine begrenzte Unterstützung für Quantisierungsausgaben erhalten, was darauf hindeuten könnte, dass es indirekt mit anderen Formaten kompatibel ist. Es gibt jedoch keine explizite Erwähnung, dass MLX Formate außer GGUF für seine Kernoperationen nutzt.

Gängige Formate, die LLM-Anbieter im maschinellen Lernen und bei großen Sprachmodellen verwenden:

  • GGUF/GGML: Optimiert fĂĽr effiziente Inferenz und weit verbreitet im Apple-Ă–kosystem.
  • ONNX (Open Neural Network Exchange): Ein Format zum Austausch von Modellen zwischen verschiedenen Frameworks.
  • TensorFlow SavedModel: Verwendet fĂĽr TensorFlow-Modelle.
  • PyTorch-Modelldateien: z. B. .pt- oder .pth-Dateien.
  • Hugging-Face-Transformers-Modelle: Oft in einem spezifischen Format gespeichert, das fĂĽr die Hugging-Face-Bibliothek optimiert ist.

Tensordateien .pt und .pth:

Diese Formate erleichtern den Austausch und die Bereitstellung von Modellen auf verschiedenen Plattformen und Frameworks. In PyTorch sind .pt und .pth Dateierweiterungen, die Entwickler häufig zum Speichern von Modellen verwenden. Es gibt keinen funktionalen Unterschied zwischen ihnen; beide lassen sich nutzen, um PyTorch-Modelle oder Tensoren mithilfe des Python-pickle-Moduls über torch.save() zu speichern. Die Wahl zwischen .pt und .pth ist weitgehend eine Frage der Konvention. Allerdings wird .pt gegenüber .pth empfohlen, da .pth mit Python-Pfadkonfigurationsdateien in Konflikt geraten kann.

Beide Erweiterungen funktionieren austauschbar mit den torch.save()- und torch.load()-Funktionen. Aber was genau ist in diesen Dateien eigentlich gespeichert?

Sie speichern typischerweise serialisierte Daten, oft Modellgewichte oder andere Python-Objekte, konkret:

  • Modellgewichte: Diese Dateien enthalten die erlernten Parameter (Gewichte und Bias/Verzerrungen) eines neuronalen Netzwerkmodells nach dem Training. Dies ermöglicht das Speichern und spätere Laden des Modells fĂĽr Inferenz oder weiteres Training.
  • Andere Datenstrukturen: Neben Modellgewichten können .pt- oder .pth-Dateien andere Python-Objekte wie Dictionaries, Listen oder benutzerdefinierte Datenstrukturen speichern.
  • Zustandsdictionaries: Die Dateien enthalten oft ein Zustandsdictionary (state_dict), das die Modellparameter enthält.

Lightning-Checkpoints, die ebenfalls die Erweiterungen .pt oder .pth verwenden könnten, speichern umfassendere Informationen, darunter Modellzustand, Optimiererzustände, Lernrateplanungszustände, Callback-Zustände, Hyperparameter.

In einer .pt-Datei sind die Einträge nicht in einem menschenlesbaren Format gespeichert. Stattdessen verwendet PyTorch das Python-pickle-Modul, um Tensoren und andere Python-Objekte in ein binäres Format zu serialisieren.

Falls Sie sich über Kennzeichnungen wie "INSTRUCT" in den Modellnamen wundern, hier ein paar Erläuterungen dazu:

In LLM-Dateinamen gibt es verschiedene Namen, die auf spezifische Techniken oder Anwendungen hinweisen. Einige Beispiele sind:

  • INSTRUCT: Diese Modelle sind darauf trainiert, Anweisungen zu befolgen und kleine Programme auszufĂĽhren, was sie besonders nĂĽtzlich fĂĽr komplexe Aufgaben macht.
  • BASE: bezeichnet oft das grundlegende Modell ohne spezifische Feinabstimmung
  • FINE-TUNED: Modelle, die fĂĽr spezifische Aufgaben oder Stile weiterentwickelt wurden
  • CHAT: Modelle, die fĂĽr den Einsatz in Chatbots optimiert sind
  • QA (Question Answering): Modelle, die darauf spezialisiert sind, Fragen zu beantworten

Der letzte Teil dieser Blogserie wird Reasoning-Modelle vorstellen und einen Blick in die Zukunft der LLMs wagen.

(rme)