LLM Fine-Tuning Guide: LoRA, QLoRA, Unsloth, Axolotl
Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
Die meisten Fehlschläge beim Fine-Tuning sind Entscheidungsfehler. Ein Team trainiert, bevor es nachweist, dass Prompting, Retrieval oder Constrained Decoding das Problem nicht lösen können. Ein anderes evaluiert auf der Trainingsverteilung oder stellt nach dem Training fest, dass sich das Artefakt nur umständlich serven lässt.
Dieser Leitfaden behandelt Adaptation als Experiment mit einem operativen Exit. Er beginnt mit der Entscheidungsgrenze und folgt anschließend einem Pfad durch Daten, LoRA oder QLoRA, aufgabenspezifische Evaluation, Export und Serving.
Die kurze Entscheidungshilfe zur Intervention finden Sie unter Fine-Tuning vs RAG vs Prompting.
Sollten Sie überhaupt Fine-Tuning durchführen?
Bevor Sie GPU-Stunden investieren, entscheiden Sie, ob Fine-Tuning für das vorliegende Problem das richtige Tool ist.
Fine-Tuning vs RAG
Fine-Tuning kann verändern, wie ein Model Domänensprache verwendet. Als Update-Mechanismus für Fakten, die sich ändern oder zitiert werden müssen, ist es jedoch ungeeignet. Retrieval und Fine-Tuning lösen unterschiedliche Teile des Problems und gehören häufig in dasselbe System.
| Feature | Fine-Tuning | RAG (Retrieval-Augmented Generation) |
|---|---|---|
| Kernfunktion | Verändert interne Weights, um Skills, Stile oder Verhaltensweisen zu vermitteln | Stellt zur Inference-Zeit externen, aktuellen Kontext bereit |
| Am besten geeignet für | • Spezifische Konversationsstile • Komplexes Befolgen von Anweisungen • Domänenspezifisches Reasoning | • Sich schnell ändernde Daten (Nachrichten, Aktienkurse) • Reduzierung von Hallucinations (Grounding) • Zitieren von Quellen |
| Umgang mit Wissen | Verändert das statistische Verhalten in den Weights; ein exakter Abruf ist nicht garantiert | Ruft Datensätze oder Passagen ab, die aktualisiert und zitiert werden können |
| Update-Häufigkeit | Erfordert für Updates ein erneutes Training | Wird mit neuen Dokumenten sofort aktualisiert |
Fine-Tuning vs Prompt Engineering
Moderne LLMs reagieren gut auf klare Prompts und Beispiele. Testen Sie diese Optionen, bevor Sie in Fine-Tuning investieren.
| Aspekt | Fine-Tuning | Prompt Engineering |
|---|---|---|
| Einrichtungskosten | Hoch (Datenaufbereitung, GPU-Rechenleistung, Iteration) | Niedrig (iterative Verfeinerung des Prompts) |
| Flexibilität | Erfordert einen weiteren Trainings- und Release-Zyklus | Ändert sich mit dem Prompt |
| Format/Stil | Kann ein wiederkehrendes Verhalten wahrscheinlicher machen | Oft ausreichend für Stil und einfache Formate |
| Latenz | Kann wiederholte Anweisungen verkürzen | Hängt von der Prompt-Länge und dem Caching des Providers ab |
| Am besten geeignet für | Komplexe Verhaltensweisen, Distillation, Kostenoptimierung im großen Maßstab | Schnelle Iteration, sich ändernde Anforderungen |
[!TIP] Zuerst Prompting ausprobieren Beginne mit einem Prompt und repräsentativen Beispielen. Wenn lediglich die Ausgabesyntax unzuverlässig ist, füge Constrained Decoding hinzu, bevor du die Weights änderst.
Fine-Tuning vs. Constrained Decoding
Bibliotheken wie xgrammar und outlines beschränken die Generierung auf ein JSON-Schema, einen regulären Ausdruck oder eine Grammatik. Abhängig von der Constraint und dem Backend kompilieren sie einen Automaten oder eine Grammatik und maskieren ungültige nächste Tokens. Ein Weight-Update ist nicht erforderlich.
Damit ist garantiert, dass die Ausgabe zur unterstützten Ausgabesprache gehört. Diese Garantie sagt nichts darüber aus, ob die Werte korrekt, vollständig oder semantisch angemessen sind. Ein syntaktisch gültiger Function Call kann weiterhin die falsche Kunden-ID enthalten.
| Aspekt | Constrained Decoding | Fine-Tuning |
|---|---|---|
| Einrichtung | Sofort möglich – Schema definieren, deployen | Erfordert Datenaufbereitung, GPU-Rechenleistung, Iteration |
| Garantie | Gültige Syntax für die unterstützte Constraint | Erlerntes Verhalten; Schema-Konformität kann variieren |
| Flexibilität | Schema jederzeit ohne erneutes Training ändern | Nach dem Training unveränderlich |
| Latenz | Geringfügiger Overhead (das Model „kämpft“ möglicherweise gegen das Schema) | Niedriger (das Model gibt das Format auf natürliche Weise aus) |
| Am besten geeignet für | JSON, Auswahlmöglichkeiten, Grammatiken, Tool-Call-Syntax | Wiederkehrendes Aufgabenverhalten, das dem Base Model fehlt |
Eine praxisnahe Reihenfolge:
- Beginne mit Prompting und Few-Shot-Beispielen für die grundlegende Formatierung.
- Füge Constrained Decoding (
xgrammaroderoutlines) hinzu, wenn die Syntax inkonsistent ist. - Führe Fine-Tuning nur durch, wenn du Verhaltensänderungen benötigst, die ein Schema nicht erzwingen kann.
Kurzreferenz: Probleme den passenden Lösungen zuordnen
| Herausforderung | Erster zu testender Mechanismus | Warum? |
|---|---|---|
| Fehlendes Wissen | RAG | Models halluzinieren Fakten. Retrieval liefert verankerten, aktuellen Kontext |
| Falsches Format bzw. falscher Ton | Prompt Engineering | Moderne Models befolgen Stilvorgaben über Few-Shot-Beispiele gut |
| Ungültige Ausgabesyntax | Constrained Decoding | Erzwingt während der Generierung ein unterstütztes Schema oder eine Grammatik |
| Wiederholtes Fehlschlagen einer Aufgabe | Fine-Tuning (SFT) | Lernt aus kuratierten Input-/Output-Beispielen |
| Mismatch bei paarweisen Präferenzen | Preference Optimization | Verwendet gewählte und abgelehnte Beispiele, sobald das Aufgabenverhalten messbar ist |
| Latenz bzw. Kosten bei hoher Skalierung | Distillation (SFT) | Trainiert ein kleineres Student Model mit den Outputs eines größeren Teacher Models |
| Model-Größe reduzieren | Quantization | Kein Training – komprimiert Weights (FP16→INT4) für schnellere Inference |
Die wirtschaftliche Argumentation messbar machen
Fine-Tuning kann wiederkehrende Prompt-Tokens reduzieren oder ermöglichen, dass ein kleineres Model das Ziel erreicht. Keine dieser Einsparungen ist jedoch automatisch gegeben. Berechne den Break-even-Punkt anhand deines eigenen Traffics und deiner Preise:
[ \text{break-even requests} = \frac{\text{training + evaluation + deployment cost}} {\text{baseline cost/request} - \text{tuned cost/request}} ]
Wenn der Nenner klein oder negativ ist oder auf einer unbewiesenen Qualitätsannahme beruht, gibt es für das Projekt noch keinen wirtschaftlichen Case.
[!TIP] Das hybride Setup Eine verbreitete Architektur kombiniert ein auf die Aufgabe angepasstes kleineres Model mit Retrieval für veränderliche Fakten. Behandle das größere, per Prompt gesteuerte Model als Baseline und behalte das kleinere Model nur dann bei, wenn es dieselben aufgabenspezifischen Qualitäts- und Safety-Schwellenwerte erfüllt.
Arten von Fine-Tuning
Fine-Tuning kann im Wesentlichen drei Formen annehmen. Sie unterscheiden sich darin, welche Daten sie benötigen und was sie dem Model beibringen.
1. Continued Pretraining (Self-Supervised)
Du trainierst das Base Model mit weiterem Rohtext und verwendest dabei das jeweils nächste Token in jeder Sequenz als Trainingsziel. Das ist Self-Supervised Learning: Der Text liefert seine eigenen Ziele – genau wie beim ursprünglichen Pretraining.
Wann du es einsetzen solltest:
- Die Domäne enthält Vokabular, das das Base Model noch nie gesehen hat (medizinische oder juristische Texte, interne Codebasen).
- Du verfügst über große Mengen an Domänentext, aber über keine gelabelten (Input, Output)-Paare.
- Das Base Model hat Schwierigkeiten mit domänenspezifischer Terminologie.
Beispiel: Training mit Millionen klinischer Notizen, damit das Model medizinische Abkürzungen, Medikamentennamen und klinische Workflows erfasst.
2. Supervised Fine-Tuning (SFT)
SFT wird mit gelabelten (Input, Output)-Paaren trainiert. Du zeigst dem Model für jeden Input exakt den gewünschten Output.
Wann du es einsetzen solltest:
- Du hast eine konkrete Aufgabe mit einem sauberen Input-/Output-Format.
- Du verfügst über hochwertige gelabelte Daten, auch wenn es nur wenige sind.
- Du benötigst vorhersehbares Verhalten bei einer bekannten Input-Struktur.
Beispiel: Training mit Paaren aus (Beschreibung einer SQL-Abfrage, SQL-Code) für Text-to-SQL.
{
"input": "Get all users who signed up last month",
"output": "SELECT * FROM users WHERE signup_date >= DATE_SUB(NOW(), INTERVAL 1 MONTH)"
}
3. Instruction Tuning
Instruction Tuning ist ein Sonderfall von SFT, der darauf ausgelegt ist, Models dazu zu bringen, eine große Bandbreite an natürlichsprachlichen Instructions zu befolgen. Die Trainingsdaten bestehen aus (Instruction, Response)-Paaren für viele verschiedene Tasks.
Wann sollte man es einsetzen?
- Sie möchten einen General-Purpose Assistant wie ChatGPT oder Claude.
- Das Model muss unterschiedliche, offene Anfragen verarbeiten können.
- Sie bauen eine Chat-Schnittstelle.
Beispiel: Training mit Tausenden unterschiedlichen Instructions wie „Fasse diesen Artikel zusammen“, „Schreibe ein Gedicht über X“ oder „Erkläre Y in einfachen Worten“.
Vergleich
| Aspekt | Continued Pre-Training | SFT | Instruction Tuning |
|---|---|---|---|
| Daten | Rohtext | (Input, Output)-Paare | (Instruction, Response)-Paare |
| Labels | Keine (unsupervised) | Task-spezifisch | Unterschiedliche Tasks |
| Ziel | Domänenwissen | Spezifisches Task-Verhalten | Jede Instruction befolgen |
| Datenvolumen | Meist der größte Korpus | Durch Task-Abdeckung und Fehlervielfalt bestimmt | Meist breiter als task-spezifisches SFT |
[!NOTE] Was in der Praxis tatsächlich gemacht wird SFT und Instruction Tuning verwenden dasselbe Next-Token-Objective; der Unterschied liegt in der Breite und der Konstruktion des Datasets. Continued Pre-Training ist ein separates Experiment und sollte von Tests auf Domänengewinne und Regressionen bei allgemeinen Fähigkeiten gefolgt werden.
Die Fine-Tuning-Pipeline mit 7 Stufen
Fine-Tuning ist eine Pipeline, kein einzelner Befehl. Jede Stufe hat eigene Failure Modes; wenn eine Stufe übersprungen wird, zeigt sich das später meist in einem schlechten Model.
Jede Stufe baut auf der vorherigen auf:
- Datenvorbereitung — Definieren Sie die Evaluationseinheit, teilen Sie die Daten auf und bereinigen und formatieren Sie sie anschließend
- Model-Auswahl — Wählen Sie das passende Base Model und laden Sie die Weights
- Training-Setup — Konfigurieren Sie Hardware, Hyperparameter und die Optimierungsstrategie
- Fine-Tuning — Führen Sie SFT-, DPO- oder ORPO-Training aus
- Evaluation — Benchmarken Sie die Performance und validieren Sie die Qualität
- Deployment — Exportieren und serven Sie Ihr Model
- Monitoring — Verfolgen Sie die Performance, warten Sie das System und iterieren Sie
[!WARNING] Daten sind das Fundament Das Training reproduziert systematische Fehler in den Beispielen. Prüfen Sie Labels, Leakage, Abdeckung und Policy-Compliance, bevor Sie Zeit in Optimizer-Sweeps investieren.
Stufe 1: Datenvorbereitung
Viele Fine-Tuning-Projekte scheitern hier, nicht im Training. Moderne Datenvorbereitung umfasst mehr, als einen Regex über CSVs laufen zu lassen.
Die Daten-Pipeline mit 5 Stufen
Tools wie DataTrove und Distilabel können bei großen Datenmengen helfen. Lassen Sie die Fehler-Taxonomie und den Data Contract das Pipeline-Design bestimmen; die Wahl des Tools ergibt sich daraus.
1. Ingestion und Filterung
- Aktion: Verweigerungen („I cannot answer that“), beschädigtes UTF-8 und nicht relevante Sprachen verwerfen.
- Tools: Trafilatura zur Extraktion und die Language-Identification-Modelle von fastText zur Sprachidentifikation; die verteilten
lid.176-Modelle erkennen 176 Sprachen.
2. Richtlinie für sensible Daten
- Aktion: festlegen, was das Model lernen darf, und anschließend personenbezogene sowie vertrauliche Felder je nach Anforderung redigieren, tokenisieren oder ausschließen.
- Tools: Microsoft Presidio oder scrubadub.
- Warum: Ein Detector ist nur eine einzelne Kontrollmaßnahme; Anforderungen an Provenance, Einwilligung, Aufbewahrung, Zugriff und Löschung gelten weiterhin.
3. Deduplizierung (MinHash LSH)
- Aktion: Near-Duplicates verwerfen, damit das Model sie nicht memoriert.
- Tools: DataTrove eignet sich gut für die Verarbeitung im Terabyte-Maßstab.
4. Synthetische Augmentierung, falls erforderlich
- Aktion: ein leistungsfähigeres Teacher Model (GPT-4o, DeepSeek-V3) verwenden, um Rohdaten in saubere Instruction-Response-Paare umzuschreiben.
- Tools: Distilabel.
- Validierung: Teacher-Outputs stichprobenartig prüfen, sie anhand derselben Rubrik wie Human Labels bewerten und synthetische sowie von Menschen verfasste Slices bei der Evaluation getrennt halten.
5. Formatierung
- Aktion: in ein Standardformat (Alpaca oder ShareGPT) konvertieren.
Beispiele für Datenformate
Alpaca-Format (Instruction-Following):
{
"instruction": "Summarize the following text.",
"input": "The text to be summarized...",
"output": "This is the summary."
}
ShareGPT-/ChatML-Format (konversationell):
{
"conversations": [
{ "from": "user", "value": "Hello, who are you?" },
{ "from": "assistant", "value": "I am a helpful AI assistant." }
]
}
Was tatsächlich wichtig ist
- Abdeckung vor Volumen. Beispiele hinzufügen, die unterschiedliche Failure Modes abbilden, statt Wiederholungen des einfachen Mehrheitsfalls.
- Sauberkeit. Irrelevanten Text verwerfen, Whitespace normalisieren und die Formatierung konsistent halten.
- Balance. Wichtige seltene Fälle bewahren und die Performance pro Slice ausweisen.
- Trennung. Nach Quelle, User, Dokument oder Zeit splitten, wenn zufällige Row-Splits Near-Duplicates durchsickern lassen würden.
- Provenance. Für jede Dataset-Version Quelle, Lizenz oder Einwilligung, Transformationsverlauf und Löschpfad dokumentieren.
Stage 2: Model-Auswahl und Hardware
Die Auswahl des Base Models und das Verständnis des GPU-Minimums bestimmen, was tatsächlich trainiert werden kann.
Mit dem kleinsten Base Model beginnen, das die unverzichtbaren Baseline-Checks bereits besteht. Folgendes bestätigen:
- Lizenz und Bedingungen für die Weiterverteilung im vorgesehenen Produkt;
- Language-, Domain-, Tool-Use- und Safety-Verhalten vor der Anpassung;
- Kompatibilität von Tokenizer und Chat-Template mit dem Dataset;
- maximaler Context und erforderliches Truncation-Verhalten für reale Beispiele;
- Unterstützung sowohl im Training Framework als auch in der vorgesehenen Serving Engine.
Fine-Tuning ist ein Anpassungsschritt und keine Reparatur für ein ungeeignetes Base Model. Wenn das Model bei Fähigkeiten versagt, die das Dataset nicht abdeckt, vor weiteren Epochen ein anderes Base Model auswählen.
Den Run dimensionieren, nicht die Marketing-Klasse
Es gibt keine dauerhaft gültige Tabelle „Model-Größe → GPU“. Der maximale Speicherbedarf ändert sich abhängig von Weight Precision, Optimizer, Anzahl der trainierbaren Parameter, Sequenzlänge, Micro-Batch-Größe, Activation Checkpointing, Attention-Implementierung und Framework-Overhead. Mit einer Speicherschätzung beginnen und anschließend einen kurzen Smoke Test mit maximaler Sequenzlänge auf dem exakten Stack ausführen.
| Memory-Komponente | Full Fine-Tuning | LoRA | QLoRA |
|---|---|---|---|
| Basis-Weights | Trainingspräzision | Eingefroren, meist BF16/FP16 | Eingefroren, typischerweise 4-Bit-NF4 |
| Gradienten | Alle trainierbaren Weights | Adapter-Weights | Adapter-Weights |
| Optimizer-States | Alle trainierbaren Weights | Adapter-Weights | Adapter-Weights |
| Activations | Hängt bei jeder Methode von Batch- und Sequenzlänge ab | Dieselbe Abhängigkeit | Dieselbe Abhängigkeit |
Das ursprüngliche QLoRA-Paper konnte ein 65B-LLaMA-Model in seinem spezifischen Setup auf einer einzelnen 48-GB-GPU fitten. Dieses Ergebnis ist eine nützliche Obergrenze, aber keine Garantie dafür, dass jede aktuelle 70B-Architektur, Context Length, jeder Kernel oder jeder Trainer auf dasselbe Gerät passt.
Memory-Mathematik
Für ein Model mit Parametern benötigen die Weights allein ungefähr Bytes in BF16/FP16 beziehungsweise Bytes bei vier Bits – noch ohne Quantization-Metadaten und Runtime-Puffer. Full Adam-Style-Training fügt Gradienten, Optimizer-States und häufig höherpräzise Master-Weights hinzu. LoRA vermeidet den Großteil des Speichers für trainierbare States; QLoRA reduziert zusätzlich den Footprint der eingefrorenen Basis-Weights. Bei langen Sequenzlängen können Activations weiterhin den größten Anteil ausmachen.
Verwende diesen Workflow:
- Wähle die längste Sequenz und den größten Micro-Batch, die du unterstützen musst.
- Schätze Weights und trainierbare States und lasse Headroom für Activations und Kernel.
- Führe einen Forward-/Backward-Step bei maximaler Länge aus.
- Erfasse den Peak der allozierten und reservierten Memory.
- Skaliere erst danach Batch Size, Rank, Sequenzlänge oder GPU-Anzahl.
Stage 3: Trainingsmethoden (PEFT und LoRA)
Full Fine-Tuning vs. PEFT
Full Fine-Tuning (FFT) aktualisiert jedes Weight, daher skalieren Gradienten und Optimizer-State mit dem gesamten Model. Der Peak lässt sich nicht allein aus der Parameteranzahl ableiten, liegt aber deutlich über der Memory, die zum Laden der Weights für Inference erforderlich ist.
Parameter-efficient Fine-Tuning (PEFT) trainiert nur eine kleine Teilmenge der Parameter und friert den Rest ein. Die Mathematik wird dadurch deutlich überschaubarer.
LoRA: der Ausgangspunkt
LoRA (Low-Rank Adaptation) friert eine vortrainierte Matrix ein und stellt ihr gelerntes Update durch zwei kleinere Matrizen dar. Das ursprüngliche Paper begründet dies mit der Hypothese, dass nützliche Adaptation-Updates einen niedrigen intrinsischen Rank haben.
Für eine eingefrorene Matrix lernt LoRA:
Die angepasste Layer lautet:
Der Adapter hat trainierbare Parameter statt für diese Matrix. Bei einer quadratischen Matrix mit einer Breite von 4.096 und einem Rank von 16 entspricht das für diese Matrix einer Reduktion um den Faktor 128 – nicht um den Faktor 10.000 für ein beliebiges Model. Die 10.000×-Headline des LoRA-Papers bezog sich auf eine spezifische GPT-3-175B-Konfiguration, bei der ausgewählte Matrizen angepasst wurden.
PEFT-Methoden im Vergleich
| Methode | Was sich ändert | Wählen Sie diese Methode, wenn |
|---|---|---|
| LoRA | Eingefrorener Base plus trainierbare Low-Rank-Updates | das Base Model problemlos passt und Sie kleine Task-Artefakte möchten |
| QLoRA | LoRA mit einem in 4 Bit gespeicherten Frozen Base | der Speicherbedarf der Base Weights der begrenzende Faktor ist |
| DoRA | Trennt die Magnitude der Weights von einer per LoRA aktualisierten Richtung | eine gemessene LoRA-Baseline eine Qualitätslücke lässt, die zusätzliche Komplexität rechtfertigt |
| Full Fine-Tuning | Alle Model Weights | PEFT das Ziel verfehlt und der Qualitätsgewinn verteiltes Training sowie vollständige Checkpoints rechtfertigt |
Wann welche Methode wählen?
- LoRA: Starten Sie hier. Schnell, speichereffizient und gut unterstützt.
- QLoRA: wenn dasselbe LoRA-Experiment wegen der Frozen Base Weights nicht passt.
- DoRA: nachdem ein direkter LoRA-Vergleich einen nützlichen Gewinn zeigt.
- Full Fine-Tuning: erst dann, wenn PEFT ein evaluierter Bottleneck und keine bloße Annahme ist.
DoRA: Weight-Decomposed LoRA
DoRA (Weight-Decomposed Low-Rank Adaptation) trennt die Magnitude jedes Weight-Vektors von seiner Richtung. Das DoRA-Paper wendet ein LoRA-Update auf die Richtungskomponente an und lernt die Magnitude separat.
So funktioniert es:
Statt Weights als eine Einheit zu behandeln, zerlegt DoRA die vortrainierten Weights in zwei Komponenten:
- Magnitude — ein trainierbarer Wert pro Weight-Vektor.
- Richtung — ein normalisierter Vektor, der über Low-Rank-Matrizen aktualisiert wird.
In kompakter spaltenweiser Notation:
wobei:
m= Magnitude (trainierbar)- = die eingefrorene Richtungs-Matrix
- = das gelernte Low-Rank-Richtungs-Update
- = spaltenweise Normalisierung
Was diese zusätzliche Struktur bringt:
- Mehr Freiheitsgrade als Standard-LoRA, da sich die Magnitude unabhängig ändern kann.
- Bessere Ergebnisse als LoRA in mehreren vom Paper der Autoren berichteten Konfigurationen.
- Zusätzliche Parameter und Berechnung; der Gewinn sollte daher für Ihre Task und Ihren Serving-Pfad verifiziert werden.
Adapter-Merging für Multi-Task-Learning
Separate Adapter ermöglichen es einem Frozen Base, mehrere Tasks zu unterstützen. Sie können Requests an einen Adapter routen, mehrere Adapter aus einer Engine serven, sofern dies unterstützt wird, oder offline einen gemergten Kandidaten erstellen. Merging kann Interferenzen verursachen. Evaluieren Sie daher das gemergte Artefakt, statt anzunehmen, dass sich die Quell-Adapter problemlos kombinieren lassen.
Gängige Merging-Methoden:
- Concatenation — Adapter-Parameter kombinieren und den effektiven Rank erhöhen. Schnell und einfach.
- Linear Combination — gewichtete Summe der Adapter. Bietet steuerbare Parameter.
- SVD — Matrixzerlegung für das Merging. Flexibler, aber langsamer.
Beispiel: Ein Adapter für Summarization und ein weiterer für Translation werden zu einem einzelnen Multi-Task-Model gemergt.
Stage 4: Fine-Tuning und Preference Alignment
SFT lernt anhand von Demonstrationen. Preference Optimization lernt dagegen aus Vergleichen wie „Die ausgewählte Antwort A ist besser als die abgelehnte Antwort B“. Verwenden Sie sie nur, wenn eine paarweise Präferenz die passende Kennzeichnung für den Fehler ist; für faktische Korrektheit und Policy-Compliance sind häufig stärkere Evaluatoren als eine globale Präferenz erforderlich.
PPO-basiertes RLHF
Das ursprüngliche Verfahren war eine Pipeline mit drei Stages:
- SFT – die Aufgabe lernen.
- Reward Model – anhand menschlicher Präferenzen trainieren (ausgewählt vs. abgelehnt).
- PPO (Proximal Policy Optimization) – Reinforcement Learning zur Optimierung der Policy.
Die operativen Kosten entstehen durch die vielen beweglichen Teile:
- Aufwendig zu implementieren und zu warten.
- Teuer – Sie trainieren mehrere Models.
- On-Policy-Sampling und Reward Optimization erfordern sorgfältige Stabilitätsprüfungen und Checks auf Reward Hacking.
DPO
DPO (Direct Preference Optimization) verzichtet auf das explizite Reward Model und den RL Loop. Das DPO-Paper leitet eine reparametrisierte Objective für die Reward Maximization mit einer KL-Divergence-Constraint her, sodass die Optimierung anhand von Präferenzpaaren statt durch Reinforcement Learning erfolgen kann:
{
"prompt": "Explain quantum computing",
"chosen": "Quantum computing uses qubits...", # Preferred response
"rejected": "Well, it's complicated..." # Non-preferred response
}
Was sich operativ ändert:
- Einfacherer Codepfad (kein separates Reward Model, kein RL Loop).
- Eine Offline-Objective über Präferenzpaare statt On-Policy-Reinforcement-Learning.
- Eine Reference Policy oder äquivalente Reference Log Probabilities in der Standardformulierung.
DPO lässt sich leichter prototypisieren als eine vollständige PPO-Pipeline, ist aber kein automatisches Qualitätsupgrade. Die Ergebnisse hängen von der Starting Policy, der Qualität der Paare, den Loss-Einstellungen, Längeneffekten und dem Eval-Protokoll ab. Vergleichen Sie DPO mit einem SFT-Checkpoint auf denselben zurückgehaltenen Präferenz- und Task-Suites.
ORPO
ORPO (Odds-Ratio Preference Optimization) kombiniert den SFT Negative-Log-Likelihood-Loss mit einer Odds-Ratio-Penalty für abgelehnte Antworten. Es entfernt das separate Reference Model und kann Task Learning und Preference Optimization in einem Run kombinieren.
So funktioniert es: ORPO verwendet einen kombinierten Loss, der gleichzeitig zwei Dinge tut:
- Maximiert die Likelihood der ausgewählten Antwort (die Aufgabe lernen).
- Bestraft die abgelehnte Antwort mit einem Odds-Ratio-Term (Präferenzen lernen).
Wichtige Hyperparameter:
from trl import ORPOConfig
config = ORPOConfig(
learning_rate=8e-6, # Very low, as recommended by the ORPO paper
beta=0.1, # Controls strength of preference penalty
# ... other params
)
- Learning Rate: Das Paper verwendete in seinen Experimenten niedrige Werte. Stimmen Sie sie auf Ihr Model, Ihren Batch und Ihre Daten ab, statt einen einzelnen Wert als allgemeine Regel zu übernehmen.
- Beta: Steuert den Anteil des Preference-Terms relativ zum SFT-Term.
Der Trade-off:
- Eine Training-Stage statt zwei.
- Kein Reward Model.
- Kein Forward Pass des Reference Models.
- Ein gekoppelter Run: Wenn Task Learning oder Preference-Verhalten regressiert, gibt es keinen intermediären SFT-Checkpoint aus derselben Pipeline zur Untersuchung.
Treffen Sie die Wahl anhand des Daten- und Eval-Designs:
- Verwenden Sie DPO, wenn Sie bereits einen zufriedenstellenden SFT-Checkpoint haben und ein einfacheres Offline-Preference-Experiment durchführen möchten.
- Testen Sie ORPO, wenn eine Reference-free-Objective mit einer einzigen Stage zu Ihren Daten und operativen Constraints passt.
- Verwenden Sie PPO-basiertes RLHF, wenn Online-Sampling gegen einen explizit gelernten Reward Teil der Anforderungen ist und Sie Reward Exploitation überwachen können.
Keine dieser Methoden ist für alle Tasks standardmäßig die richtige Wahl. Behalten Sie eine SFT-only-Baseline bei und berichten Sie sowohl Task-Metriken als auch Preference-Metriken.
Fine-Tuning-Frameworks
Frameworks überschneiden sich und ändern sich schnell. Wähle anhand des Execution Path, den du unterstützen musst, pinne die Versionen und halte die Training-Konfiguration portabel genug, um sie außerhalb eines Notebooks reproduzieren zu können.
Unsloth — Geschwindigkeit und Memory-Effizienz
Unsloth integriert sich in Hugging Face trl und transformers und stellt für unterstützte Models optimierte Kernels, Checkpointing und Quantized-Fine-Tuning-Pfade bereit.
- Eigene Triton-GPU-Kernels für Attention, RoPE und Cross-Entropy, die den PyTorch-Overhead überspringen.
- Memory-effizientes Backpropagation, bei dem Activations während des Backward Passes neu berechnet werden, statt sie im Memory zu halten.
- Fused Operations, die mehrere Schritte (Layer Norm + Linear und ähnliche Operationen) zu einzelnen GPU-Aufrufen zusammenfassen.
- 4-Bit-Quantization, direkt in den QLoRA-Pfad integriert, mit optimierter Dequantization.
[!IMPORTANT] Die Import-Reihenfolge ist relevant Verwende die Import-Reihenfolge aus dem Unsloth-Beispiel für die von dir gepinnte Version. Unsloth wendet beim Import Patches an. Wenn du es vor
trlundtransformersimportierst, vermeidest du fehlende Optimizations oder versionsspezifische Fehler.
# Correct order
from unsloth import FastLanguageModel # Must be first!
from trl import SFTTrainer
from transformers import TrainingArguments
# Avoid this order with Unsloth's patched path
from trl import SFTTrainer
from unsloth import FastLanguageModel
Am besten geeignet für: Training auf einer einzelnen GPU, Prototyping, Colab-Notebooks und alle, die ihre GPU-Kosten im Blick behalten.
Veröffentlichte Geschwindigkeits- und Memory-Werte variieren je nach Model, Sequence Length, Batch, Precision und Hardware. Miss Tokens pro Sekunde und den Peak-Memory-Verbrauch in deinem eigenen Run, statt eine prominente Verhältniszahl als Framework-Eigenschaft zu behandeln.
Axolotl — Config-driven Training
# config.yaml - no code required
base_model: meta-llama/Meta-Llama-3-8B
adapter: qlora
lora_r: 32
lora_alpha: 16
datasets:
- path: data/my_data.jsonl
type: alpaca
sample_packing: true
Ausführen mit: accelerate launch -m axolotl.cli.train config.yaml
Am besten geeignet für: deklarative, reproduzierbare Runs und integrierte Launcher-Optionen für Distributed Training. Die Config kann geprüft, versioniert und in lokalen sowie verteilten Runs wiederverwendet werden.
Framework-Vergleich
| Tool | Geeignet, wenn | Vor der Festlegung prüfen |
|---|---|---|
| Unsloth | Du einen optimierten Pfad für unterstützte Models mit kurzen Beispielen möchtest | Model-, GPU-, Quantization- und Distributed-Support-Matrix |
| Axolotl | Du deklarative Configs und integrierte Recipes für Distributed Training möchtest | Exaktes Config-Schema und Launcher für den gepinnten Release |
| TRL | Du direkten Zugriff auf Hugging Face SFT- und Preference-Trainer möchtest | Dataset-Format, Chat-Template, Loss-Masking und PEFT-Integration |
| Torchtune | Du PyTorch-native Recipes und Components möchtest | Abdeckung durch Model-Recipes und Export-Kompatibilität |
Praxisdemo: Fine-Tuning mit Unsloth
Hier ist ein repräsentativer Trainingsausschnitt aus meinem Repository unsloth-finetune-demo. Die Demo führt Fine-Tuning von Nemotron-Nano für Function Calling durch. Vor diesem Ausschnitt lädt und formatiert die src/unsloth_demo/data.py der Demo das Dataset. Anschließend erstellt ihr Training Path die versionierten Objekte train_dataset und eval_dataset.
Quick Start
# Clone and setup
git clone https://github.com/slavadubrov/unsloth-finetune-demo.git
cd unsloth-finetune-demo
# Install with uv (recommended)
uv sync
# Run fine-tuning (quick test)
uv run finetune --max-samples 1000
Konfiguration
Die interessanten Teile befinden sich in config.py:
# Model & Dataset
MODEL_NAME = "nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1" # 4B params, 128K context
DATASET_NAME = "glaiveai/glaive-function-calling-v2" # 113K examples
# LoRA Configuration
LORA_R = 16 # Adapter capacity; tune against held-out results
LORA_ALPHA = 32 # Update scaling; alpha/r is the classic LoRA scale
MAX_SEQ_LENGTH = 4096
# Candidate modules for this Llama-family model
LORA_TARGET_MODULES = [
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
]
[!NOTE] Das Alpha-to-Rank-Verhältnis
alpha/rskaliert das klassische LoRA-Update.alpha = 2rist eine gängige Ausgangsheuristik in der Dokumentation einiger Tools, aber keine Stabilitätsgarantie. Variiere Rank, Alpha, Learning Rate und Target Modules erst, nachdem Daten und Baseline feststehen.
Kern-Trainingscode
from unsloth import FastLanguageModel
from trl import SFTConfig, SFTTrainer
# Load model with 4-bit quantization
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1",
max_seq_length=4096,
load_in_4bit=True,
)
# Add LoRA adapters
model = FastLanguageModel.get_peft_model(
model,
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
use_gradient_checkpointing="unsloth", # Lower activation memory; extra compute
)
# The preceding data step must create these versioned dataset objects.
# Each row has the chat messages and tool schemas expected by current TRL.
# Train with the current TRL configuration surface.
trainer = SFTTrainer(
model=model,
processing_class=tokenizer,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
args=SFTConfig(
output_dir="outputs/nemotron-function-calling",
max_length=4096,
packing=True,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
learning_rate=2e-4,
num_train_epochs=3,
bf16=True,
),
)
trainer.train()
Fine-Tuning mit Axolotl
[!NOTE] Demo folgt Ich arbeite an einer praxisnahen Axolotl-Demo. Bis dahin ist der Accelerate n-D Parallelism Guide von Hugging Face eine gute Referenz für Multi-GPU-Trainingsstrategien.
Für Config-first- und verteilte Setups macht Axolotl den Workflow reproduzierbar:
# axolotl_config.yaml
base_model: meta-llama/Meta-Llama-3-8B
model_type: LlamaForCausalLM
# QLoRA configuration
load_in_4bit: true
adapter: qlora
lora_r: 32
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules:
- q_proj
- k_proj
- v_proj
- o_proj
- gate_proj
- up_proj
- down_proj
# Dataset
datasets:
- path: data/training_data.jsonl
type: alpaca
# Training settings
sequence_len: 4096
sample_packing: true # Benchmark with your length distribution
micro_batch_size: 2
gradient_accumulation_steps: 4
learning_rate: 0.0002
num_epochs: 3
# Current Axolotl key; verify support on the pinned release
bf16: true
attn_implementation: flash_attention_2
Training ausführen:
axolotl train axolotl_config.yaml
Phase 5: Evaluation
Lege den Evaluationsvertrag vor dem ersten Run fest. Vergleiche mindestens das getunte Checkpoint mit der exakt unveränderten Base unter demselben Prompt, denselben Decoding-Einstellungen und derselben Tool-Umgebung. Berichte aggregierte Qualität erst, nachdem du die Failure Slices geprüft hast, die das Projekt verbessern sollte.
Verfolge vier Gruppen:
- Zielaufgabe: Exact Match, Execution Success, Human Rubric oder ein anderes Ergebnis, das an den Use Case gekoppelt ist.
- Regression: allgemeine Fähigkeiten und zuvor unterstützte Task Slices, die durch die Anpassung beeinträchtigt werden könnten.
- Safety und Policy: Refusals, Data Leakage, Prompt Injection oder domänenspezifische Einschränkungen.
- Betrieb: Latency, Throughput, Memory, Artifact-Größe und Kosten in der vorgesehenen Serving-Konfiguration.
Automatisierte Benchmarks
Verwende lm-evaluation-harness für relevante standardisierte Tasks, aber nicht als Ersatz für die Produkt-Evaluation:
lm_eval --model hf \
--model_args pretrained=./outputs/merged-model \
--tasks hellaswag,arc_easy,mmlu \
--batch_size 8
LLM-as-Judge
Bei subjektiver Qualität kann ein größeres Model beim Scoring unterstützen. Kalibriere es jedoch anhand von durch Menschen geprüften Beispielen und halte die Identität der Kandidaten verborgen:
judge_prompt = """
Rate this response from 1-5 on:
- Relevance
- Accuracy
- Formatting
Response: {model_output}
Expected: {ground_truth}
"""
Domänenspezifische Evaluation
Halte reale Beispiele nach Quelle, User, Dokument oder Zeitpunkt zurück, damit Near-Duplicates nicht über den Split hinweg leaken können. Validiere beim Function Calling die vollständige Trajektorie: Tool-Auswahl, Argumente, Execution Result, Recovery und finale Antwort. Berichte bei kleinen Samples Konfidenzintervalle oder gepaarte Win/Loss-Zählungen und prüfe jede Regression in einer kritischen Slice.
Phase 6: Deployment und Ausgabeformate
Wähle das Artifact anhand der Serving Engine und des Rollback-Plans aus, nicht nur anhand der Dateigröße:
1. LoRA-Adapter
uv run finetune # Saves ~100-500MB adapter
- Größe: proportional zu den Target Modules, dem Rank, den Layern und dem Dtype; oft deutlich kleiner als die Base.
- Am besten geeignet für: Entwicklung, versionierte Task-Adapter und Engines mit direkter LoRA-Unterstützung.
- Vorteil: Du kannst Adapter austauschen, ohne das Base Model erneut herunterzuladen.
2. Gemergtes Model
uv run finetune --merge # Creates a standalone full model
- Größe: ungefähr der vollständige Base-Checkpoint in der gewählten Ausgabepräzision.
- Am besten geeignet für: Engines oder Distributionswege, die den Adapter nicht separat unterstützen.
- Trade-off: größeres Artefakt und langsameres Rollout; dafür einfacheres Laden als einzelnes Model.
3. GGUF-Format
uv run finetune --gguf q4_k_m # Creates ~2-4GB quantized model
- Größe: abhängig vom Model; bei Q4-Varianten ungefähr vier Bit pro Weight plus Metadaten.
- Am besten geeignet für: CPU-Inference, Ollama, llama.cpp und Edge-Deployment.
- Optionen:
q4_k_m(kleiner),q5_k_m(höhere Weight-Treue),q8_0(größer und höhere Treue). Messe die Auswirkungen auf die Aufgabe nach der Konvertierung.
Stage 7: Serving und Monitoring
Mit vLLM
# Serve the base and expose a PEFT adapter as a model name. This parser and
# template pair is for a Llama 3.1-compatible function-calling adapter.
vllm serve nvidia/Llama-3.1-Nemotron-Nano-4B-v1.1 \
--enable-lora \
--lora-modules function-calling=./outputs/adapter \
--enable-auto-tool-choice \
--tool-call-parser llama3_json \
--chat-template examples/tool_chat_template_llama3.1_json.jinja \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 4096
Frage die OpenAI-kompatible API ab:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")
response = client.chat.completions.create(
model="function-calling",
messages=[{"role": "user", "content": "Book a flight to Tokyo"}],
tools=[
{
"type": "function",
"function": {
"name": "book_flight",
"description": "Book a flight to a city.",
"strict": True,
"parameters": {
"type": "object",
"properties": {
"destination": {"type": "string"},
},
"required": ["destination"],
"additionalProperties": False,
},
},
}
],
tool_choice="auto",
)
Der Tool-Calling-Leitfaden von vLLM erfordert die automatische Tool-Auswahl und einen auf das Model abgestimmten Parser. Verwende das kompatible Chat-Template des Models, wenn die Tokenizer-Konfiguration kein eigenes bereitstellt. Bei tool_choice="auto" erfordern eingeschränkte Argumente außerdem strict: true für mindestens eine Funktion (sowie die aktivierte Strict-Tool-Calling-Einstellung von vLLM, die standardmäßig aktiviert ist). Verwende ein mit Strict Tool Calling kompatibles parameters-Schema. Ohne diese Opt-in-Einstellung extrahiert vLLM Calls aus dem Rohtext; dadurch können die Argumente fehlerhaft sein oder das Schema verletzen.
Mit Ollama (lokal)
# Create Modelfile
echo 'FROM ./outputs/unsloth-nemotron-function-calling-gguf/model-q4_k_m.gguf' > Modelfile
# Import to Ollama
ollama create my-function-model -f Modelfile
# Run
ollama run my-function-model
Mit llama.cpp (CPU)
./llama-cli -m ./outputs/model-q4_k_m.gguf \
-p "What's the weather in Tokyo?" \
--ctx-size 4096
Das veröffentlichte Model überwachen
Der Lebenszyklus endet nicht bei einem gesunden Trainings-Loss. Erfasse Revision des Base-Models, Tokenizer und Chat-Template, Adapter-Hash, Dataset-Version, Trainingskonfiguration und Evaluationsbericht als eine gemeinsame Release-Einheit. Überwache in der Produktion Task-Erfolg, ungültige Outputs, Policy-Verstöße, Latenz und Input-Drift anhand derselben Slices wie offline. Halte das vorherige Artefakt ladbar und definiere vor dem Launch einen Rollback-Schwellenwert.
Zentrale Erkenntnisse
- Führe Fine-Tuning erst durch, wenn eine ungetunte Baseline und eine Fehler-Taxonomie zeigen, dass Weight Adaptation das Problem adressiert.
- Retrieval verwaltet sich ändernde Evidenz; Constrained Decoding verwaltet Syntax; keines von beiden wird durch SFT ersetzt.
- LoRA reduziert den trainierbaren State. QLoRA komprimiert zusätzlich die eingefrorenen Base-Weights. Ordne Speicherangaben zu QLoRA nicht LoRA zu.
- Datenabdeckung, Split-Integrität, Provenance und Loss Masking sind wichtiger, als eine gerade verbreitete Optimizer-Konfiguration zu kopieren.
- DPO, ORPO und PPO-basiertes RLHF sind unterschiedliche experimentelle Designs, keine Qualitätsleiter mit einem universell gültigen Default.
- Evaluiere Zielverhalten, Regressionen, Safety und Betrieb gegen dasselbe Base-Model.
- Wähle Adapter-, Merged- oder GGUF-Output anhand der Anforderungen an Serving und Rollback, bevor du trainierst.
Referenzen
Papers und Forschung
- LoRA: Low-Rank Adaptation of Large Language Models
- QLoRA: Efficient Finetuning of Quantized LLMs
- DoRA: Weight-Decomposed Low-Rank Adaptation
- DPO: Direct Preference Optimization
- ORPO: Odds Ratio Preference Optimization
- PPO: Proximal Policy Optimization Algorithms — OpenAI, 2017
Tools für die Datenverarbeitung
- DataTrove — Hugging-Face-Datenverarbeitung im großen Maßstab
- Distilabel — Generierung synthetischer Daten (Argilla)
- Trafilatura — Extraktion und Crawling von Webtexten
- fastText language identification — Verteilte
lid.176-Modelle für 176 Sprachen - Microsoft Presidio — Erkennung und Anonymisierung personenbezogener Daten
- scrubadub — Python-Bibliothek zum Entfernen personenbezogener Daten
Constrained Decoding
Training-Frameworks
- Unsloth — Optimiertes Fine-Tuning-Framework
- Axolotl — Konfigurationsgesteuertes Training und verteilte Launcher
- TRL — Hugging-Face-Bibliothek für SFT und Preference Training
- Torchtune — PyTorch-native Fine-Tuning-Bibliothek
Inference und Deployment
- vLLM LoRA adapters — Einen oder mehrere Adapter mit dem Basismodell bereitstellen
- vLLM tool calling — Auto-Tool-Auswahl, Parser, Chat-Template und Request-Schema an das Model anpassen
- Ollama — Lokaler LLM-Runner für Mac/Windows/Linux
- llama.cpp — CPU/GPU-Inference mit dem GGUF-Format
Evaluation
- lm-evaluation-harness — Standardisiertes LLM-Benchmarking von EleutherAI
Guides und Ressourcen
- Demo Repository — Praktisches Beispiel für Fine-Tuning
- LLM Fine-Tuning. Theoretical Intuition and Practical Implementation — Research-Notebook in NotebookLM
- Accelerate n-D Parallelism Guide — Strategien von Hugging Face für Multi-GPU-Training