Warum Fine-Tuning?
Große Sprachmodelle bringen bereits viel Wissen und gelernte Muster mit. Beim Fine-Tuning trainiert man ein solches vortrainiertes Modell mit einem kleineren, domänenspezifischen Datensatz weiter. Das Modell behält sein Vorwissen und wird bei der gewünschten Aufgabe besser.
Man nutzt so vorhandenes Wissen (Transfer Learning), passt das Modell an Fachbegriffe, Kontexte und Aufgaben einer Domäne an und kommt mit deutlich weniger Daten und Rechenleistung aus als bei einem Training von Grund auf.
Trotzdem bleibt klassisches Fine-Tuning teuer, weil dabei alle Gewichte angepasst werden. LoRA verspricht, mit einem Bruchteil an trainierbaren Parametern auszukommen. Das wollte ich in einem eigenen Experiment ausprobieren.
Wo das Wissen eines Sprachmodells steckt
Ein Sprachmodell ist ein neuronales Netz. Was es „weiß“, steckt nicht in einer Datenbank, sondern in seinen gelernten Parametern, den Gewichten seiner Schichten.
Text zerlegt das Modell zunächst in Tokens und übersetzt jedes Token in einen Zahlenvektor, ein Embedding. Dieser Vektor trägt die allgemeine Bedeutung eines Wortes. Was ein Wort im konkreten Satz bedeutet, ergibt sich erst durch den Attention-Mechanismus: Im Satz „Der Kuchen schmeckt“ wird aus der allgemeinen Bedeutung von „Kuchen“ eine kontextuelle.
Dafür berechnet das Modell aus jedem Embedding drei Vektoren über die Gewichtsmatrizen Wq, Wk und Wv:
Aus Queries und Keys entsteht eine Matrix mit Attention-Scores. Sie wird durch √dk (die Wurzel der Vektorlänge) geteilt und dann mit der Softmax-Funktion, die Werte in Anteile mit der Summe 1 umrechnet, in Attention-Gewichte umgerechnet. Die Teilung verhindert, dass die Scores bei langen Vektoren zu groß werden und Softmax fast nur noch einen Wert bevorzugt. Diese Gewichte legen fest, wie viel Information aus den Value-Vektoren der anderen Wörter übernommen wird.
Mehrere solcher Attention-Heads laufen parallel und werden über eine lineare Schicht zusammengeführt, danach folgt ein Feedforward-Netz. An den Gewichtsmatrizen dieser Schichten setzt Fine-Tuning an, und diese Matrizen sind riesig.
Der Trick von LoRA
LoRA (Low-Rank Adaptation) lässt die Originalgewichte W0 unverändert. Stattdessen wird jede anzupassende Matrix um das Produkt zweier kleiner Matrizen B und A ergänzt, deren Rang r deutlich kleiner ist als die Dimension der Originalmatrix: h = W0x + BAx, gewichtet mit dem Faktor α/r. Trainiert werden nur B und A.
- Neutraler Start. B beginnt mit Nullen, A mit Zufallswerten. Das Produkt BA ist anfangs null, das Modell verhält sich zu Beginn also exakt wie das Original.
- Steuerbare Wirkung. Der Faktor α/r gewichtet, wie stark die Anpassung einfließt. r bestimmt die Größe der LoRA-Matrizen, α die Gewichtung.
- Verschmelzen nach dem Training. B und A lassen sich in die Originalgewichte einrechnen: Wmerged = W0 + BA (skaliert mit α/r). Die Dimensionen bleiben erhalten, zur Laufzeit entsteht kein Zusatzaufwand.
- Einfacher Aufgabenwechsel. Ein Adapter ist klein. Für verschiedene Aufgaben kann man verschiedene Adapter auf dasselbe Basismodell setzen und zwischen ihnen wechseln.
Wird r groß genug gewählt, nähert sich LoRA einem vollständigen Fine-Tuning an. Offen ist also, wie klein man bleiben kann, ohne Qualität zu verlieren.
Mein Experiment: Fragestellung und Versuchsaufbau
Welche LoRA-Einstellung beeinflusst die Qualität am stärksten: die Größe der Zusatzmatrizen, ihre Gewichtung oder die Stelle im Modell, an der sie ansetzen?
Als Basis diente das kompakte Chat-Modell Qwen1.5-0.5B-Chat der Größenklasse „0.5B“ (rund 0,6 Milliarden Parameter inklusive Embeddings). Die Aufgabe habe ich bewusst so gewählt, dass der Erfolg sofort sichtbar ist: Mit einem Datensatz aus 100 Frage-Antwort-Paaren sollte das Modell lernen, wie ein Pirat zu antworten, „Arrr“, „aye“ und Rum inklusive.
- Tasktyp
- Textgenerierung
- Lernrate
- 0,0001
- Dropout
- 0,05
- Bias
- unverändert
- Epochen
- max. 200
- Early Stopping
- nach 3 Epochen
- r
- 110
- α
- 1632
- Zielmodule
- alle linearenq + kq + v
2 × 2 × 3 = 12 Läufe
Bei den angepassten Modellteilen stehen q, k und v für die Query-, Key- und Value-Matrizen. Trainiert habe ich auf Grafikkarten (GPUs) in den Cloud-Rechenumgebungen Kaggle bzw. Google Colab, mit den Bibliotheken Hugging Face Transformers, PEFT (Parameter-Efficient Fine-Tuning, also sparsames Nachtrainieren) und TRL (Transformer Reinforcement Learning, Trainingswerkzeuge für Sprachmodelle). Alle zwölf Läufe zusammen dauerten rund 16 Minuten. Für jeden Lauf habe ich Training Loss und Validation Loss aufgezeichnet, also den Fehlerwert auf den Trainingsdaten bzw. auf zurückgehaltenen Prüfdaten (niedriger ist besser), dazu die Perplexity auf den Validierungsdaten. Die Verläufe habe ich mit der Diagramm-Bibliothek Plotly visualisiert.
Ergebnisse
Die Perplexity misst, wie „überrascht“ das Modell von den Validierungsbeispielen ist. Sie ist die Exponentialfunktion des Validation Loss (e2,587 ≈ 13,29). Je niedriger, desto besser passt das Modell zu den Beispielen. Gruppiert nach Zielmodulen trennen sich die Varianten deutlich:
Bei der Auswertung bin ich schrittweise vorgegangen:
- Query + Key fällt raus. Alle vier Läufe, die nur Query und Key angepasst haben, landen bei einer Perplexity von 25,8 bis 27,6 und einem Validation Loss über 3,25, unabhängig von r und α. Das ergibt Sinn, denn Query und Key steuern nur, worauf das Modell achtet. Was es weitergibt, steckt im Value.
- Alle linearen Schichten vor Query + Value. Beide Varianten liegen zwischen 13,3 und 15,2. Die Läufe auf allen linearen Schichten erreichen aber die niedrigsten Validation-Loss-Werte und laufen gleichzeitig am schnellsten.
- Innerhalb von „alle linearen“ entscheidet die Laufzeit. Bei nahezu gleicher Qualität war r = 1 mit α = 32 mit gut 35 Sekunden der schnellste Lauf.
| Zielmodule | r | α | Training Loss | Validation Loss | Perplexity | Dauer (Sek.) | Durchsatz |
|---|---|---|---|---|---|---|---|
| alle linearen | 1 | 16 | 1,375 | 2,587 | 13,29 | 53,3 | 315,1 |
| alle linearen | 1 | 32 | 1,552 | 2,587 | 13,29 | 35,3 | 475,7 |
| alle linearen | 10 | 16 | 1,399 | 2,596 | 13,41 | 54,7 | 306,9 |
| alle linearen | 10 | 32 | 1,103 | 2,716 | 15,12 | 45,4 | 370,2 |
| q + v | 1 | 16 | 2,079 | 2,636 | 13,96 | 95,5 | 176,0 |
| q + v | 1 | 32 | 1,913 | 2,722 | 15,21 | 72,7 | 231,1 |
| q + v | 10 | 16 | 1,988 | 2,633 | 13,91 | 88,8 | 189,1 |
| q + v | 10 | 32 | 1,972 | 2,644 | 14,07 | 65,7 | 255,5 |
| q + k | 1 | 16 | 3,027 | 3,319 | 27,62 | 116,5 | 144,2 |
| q + k | 1 | 32 | 2,844 | 3,268 | 26,26 | 99,6 | 168,7 |
| q + k | 10 | 16 | 2,851 | 3,254 | 25,89 | 123,7 | 135,8 |
| q + k | 10 | 32 | 2,761 | 3,252 | 25,85 | 93,0 | 180,6 |
Alle Läufe mit Dropout 0,05 und Lernrate 0,0001. Werte gerundet, Dauer pro Lauf inklusive Early Stopping. Der Validation Loss stammt aus einem Lauf je Konfiguration und ist der Wert am Ende des Trainings. Während des Trainings lag er kurzzeitig etwas niedriger, bei rund 2,5 (siehe Lernkurve unten). Der Durchsatz ist eine abgeleitete Größe: verarbeitete Trainingsbeispiele pro Zeit, im Kern der Kehrwert der Laufzeit. Er zeigt also dasselbe wie die Dauer, nur umgerechnet.
Was ist die Hauptstadt von Frankreich?
Paris, harrr, aye, der Piraten des Rums!
Der Stil sitzt, die Grammatik leidet ein wenig.Overfitting & Early Stopping
Die Trainingskurven zeigen mehr als die Endwerte. In allen Läufen sinkt der Training Loss stetig. Der Validation Loss fällt zunächst mit, flacht dann ab und steigt gegen Ende wieder leicht an. Ab diesem Punkt lernt das Modell die Trainingsbeispiele auswendig, statt zu verallgemeinern.
Besonders deutlich wird das beim Lauf mit r = 10 und α = 32 auf allen linearen Schichten: Er erreicht mit 1,10 den niedrigsten Training Loss aller Läufe, aber nur einen Validation Loss von 2,72 und eine Perplexity von 15,1. Mehr Kapazität hat hier vor allem beim Auswendiglernen geholfen.
Dagegen hilft Early Stopping: Verbessert sich der Validation Loss drei Epochen lang nicht, bricht das Training ab. Deshalb liefen die Experimente trotz eines Limits von 200 Epochen nur zwischen 35 Sekunden und gut zwei Minuten.
Grenzen des Experiments
- Kleines Setup: Ein Modell der 0.5B-Klasse und 100 Trainingsbeispiele. Die konkreten Werte lassen sich nicht eins zu eins auf andere Modelle übertragen; bei größeren Modellen und Datensätzen können sich die Verhältnisse verschieben.
- Stil statt Fachwissen: Die Aufgabe war eine Stilanpassung. Ob die Erkenntnisse für Fachaufgaben gleich ausfallen, habe ich nicht getestet.
- Metriken sind nicht alles: Loss und Perplexity zeigen, wie gut das Modell zu den Beispielen passt. Sie ersetzen keine inhaltliche Prüfung der Antworten, wie die Beispielantwort zeigt.
- Ein Lauf pro Konfiguration: Kleine Unterschiede, etwa zwischen 13,29 und 13,41, können im Bereich zufälliger Schwankungen liegen und sollten nicht überinterpretiert werden.
Übertragbar ist vor allem das Vorgehen: Stellschrauben systematisch variieren und messen, statt Standardwerte blind zu übernehmen.
Learnings
Was das für Dein Unternehmen heißt
Fine-Tuning lohnt sich, wenn die Aufgabe dazu passt. Aus dem Experiment leite ich diese Empfehlungen ab:
- Fine-Tuning für Stil, Tonalität und Format. Soll ein Modell immer in Deiner Sprache, Deinem Format oder für eine klar umrissene Aufgabe antworten, ist LoRA ein ressourcenschonender Weg.
- RAG für Wissen. Soll das Modell aktuelle Inhalte aus Deinen Dokumenten nutzen, ist meist ein RAG-System der bessere Einstieg (Retrieval-Augmented Generation: Das Sprachmodell bekommt vor der Antwort passende Textstellen aus Deinen Dokumenten). Mehr dazu in meinem Artikel über Chunking und RAG; wie ich so etwas baue, zeigt die Fallstudie RT-Vector.
- Klein anfangen, sauber messen. Ein kompaktes Modell, ein kleiner Datensatz und ein fairer Vergleich mehrerer Varianten zeigen schnell, ob sich der Aufwand lohnt.
- Adapter statt Modellkopien. Mehrere kleine Adapter auf einem Basismodell sparen Speicher und machen es einfach, verschiedene Aufgaben getrennt zu pflegen.
Wie ich KI in bestehende Abläufe einbaue, beschreibe ich auf der Seite KI-Lösungen.
Tech-Stack
- Qwen1.5-0.5B-Chat
- Python
- PyTorch
- Hugging Face Transformers
- PEFT
- TRL
- Plotly
- Loss & Perplexity
- Kaggle
- Google Colab
- GPU
