Handleiding voor LLM fine-tuning: LoRA, QLoRA, Unsloth, Axolotl

Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.

De meeste mislukkingen bij fine-tuning zijn beslissingsfouten. Een team gaat trainen voordat het heeft aangetoond dat prompting, retrieval of constrained decoding het probleem niet kan oplossen. Een ander team evalueert op de trainingsdistributie, of ontdekt pas na de training dat het artifact lastig te serven is.

Deze handleiding behandelt adaptation als een experiment met een operationele exit. We beginnen bij de beslissingsgrens en volgen daarna één pad door data, LoRA of QLoRA, task-specifieke evaluatie, export en serving.

Zie Fine-Tuning vs RAG vs Prompting voor de korte interventiebeslissing.

Moet je überhaupt fine-tunen?

Beslis voordat je GPU-uren besteedt of fine-tuning het juiste hulpmiddel is voor het probleem dat voor je ligt.

BeslissingsflowchartBeslissingsflowchart

Fine-tuning versus RAG

Fine-tuning kan veranderen hoe een model domeintaal gebruikt, maar is een slecht update-mechanisme voor feiten die veranderen of moeten worden geciteerd. Retrieval en fine-tuning lossen verschillende delen van het probleem op en horen vaak in hetzelfde systeem thuis.

KenmerkFine-TuningRAG (Retrieval-Augmented Generation)
KernfunctiePast interne weights aan om skills, stijlen of gedrag aan te lerenLevert externe, actuele context tijdens inference
Geschikt voor• Specifieke conversationele stijlen
• Complex instruction following
• Domeinspecifieke reasoning
• Snel veranderende data (nieuws, aandelenkoersen)
• Hallucinations verminderen (grounding)
• Bronnen citeren
Omgaan met kennisVerandert statistisch gedrag in de weights; exact recall is niet gegarandeerdHaalt records of passages op die kunnen worden bijgewerkt en geciteerd
UpdatefrequentieVoor updates is retraining vereistWordt onmiddellijk bijgewerkt met nieuwe documenten

Fine-tuning versus prompt engineering

Moderne LLMs reageren goed op duidelijke prompts en voorbeelden. Test die opties voordat je in fine-tuning investeert.

AspectFine-TuningPrompt Engineering
SetupkostenHoog (data-curatie, GPU-compute, iteratie)Laag (iteratieve promptverfijning)
FlexibiliteitVereist een nieuwe training- en releasecyclusVerandert met de prompt
Format/stijlKan herhaald gedrag waarschijnlijker makenVaak voldoende voor stijl en eenvoudige formats
LatencyKan herhaalde instructies verkortenHangt af van promptlengte en provider caching
Geschikt voorComplex gedrag, distillation, kosten op schaalSnelle iteratie, veranderende requirements

[!TIP] Probeer eerst prompting Begin met een prompt en representatieve voorbeelden. Als alleen de outputsyntax onbetrouwbaar is, voeg dan constrained decoding toe voordat je de weights wijzigt.

Fine-tuning versus constrained decoding

Libraries zoals xgrammar en outlines beperken generation tot een JSON Schema, regular expression of grammar. Afhankelijk van de constraint en backend compileren ze een automaton of grammar en maskeren ze ongeldige volgende tokens. Er is geen weight update nodig.

Dit garandeert dat de output tot de ondersteunde outputtaal behoort. De garantie zegt niets over de vraag of de waarden waar, volledig of semantisch geschikt zijn. Een syntactisch geldige function call kan nog steeds het verkeerde klant-ID bevatten.

AspectConstrained DecodingFine-Tuning
SetupDirect—definieer schema, deployVereist data-curatie, GPU-compute, iteratie
GarantieGeldige syntax voor de ondersteunde constraintLearned behavior; schema-compliance kan variëren
FlexibiliteitSchema op elk moment wijzigen zonder retrainingVast na de training
LatencyLichte overhead (het model kan het schema “tegenwerken”)Lager (het model produceert het format natuurlijk)
Geschikt voorJSON, keuzes, grammars, tool-call-syntaxHerhaald taskgedrag dat het base model mist

Een praktische volgorde:

  1. Begin met prompting en few-shot examples voor eenvoudige formatting.
  2. Voeg constrained decoding (xgrammar of outlines) toe wanneer de syntax inconsistent is.
  3. Fine-tune pas wanneer je gedragsveranderingen nodig hebt die een schema niet kan afdwingen.

Snelle referentie: problemen koppelen aan oplossingen

UitdagingEerste mechanisme om te testenWaarom?
Ontbrekende kennisRAGModels hallucinate facts. Retrieval levert grounded, actuele context
Verkeerd format of verkeerde toonPrompt EngineeringModerne models volgen stijlinstructies goed via few-shot examples
Ongeldige outputsyntaxConstrained decodingDwingt tijdens generation een ondersteund schema of grammar af
Herhaald falen op een taskFine-tuning (SFT)Leert van gecureerde input/output-examples
Mismatch in pairwise preferencesPreference optimizationGebruikt chosen/rejected-examples nadat het taskgedrag meetbaar is
Latency/kosten op schaalDistillation (SFT)Trained een kleiner student model op outputs van een groter teacher model
Model kleiner makenQuantizationGeen training—comprimeert weights (FP16→INT4) voor snellere inference

Maak de businesscase meetbaar

Fine-tuning kan terugkerende prompt-tokens verminderen of ervoor zorgen dat een kleiner model het doel haalt, maar geen van beide besparingen is automatisch. Bereken het break-evenpoint met je eigen traffic en pricing:

[ \text{break-even requests} = \frac{\text{training + evaluation + deployment cost}} {\text{baseline cost/request} - \text{tuned cost/request}} ]

Als de noemer klein of negatief is, of gebaseerd is op een onbewezen kwaliteitsaanname, heeft het project nog geen economische onderbouwing.

[!TIP] De hybride setup Een veelvoorkomende architectuur is een kleiner, task-adapted model plus retrieval voor veranderende feiten. Behandel het grotere model met prompts als baseline en behoud het kleinere model alleen als het aan dezelfde task-specifieke quality- en safety-thresholds voldoet.


Types fine-tuning

Fine-tuning kent drie hoofdvormen. Ze verschillen in het soort data dat ze nodig hebben en in wat ze het model leren.

Typen fine-tuningTypen fine-tuning

1. Continued pre-training (self-supervised)

Je traint het base model op meer raw text, waarbij de volgende token in elke sequence het training target vormt. Dat is self-supervised learning: de tekst levert zijn eigen targets, net als in de oorspronkelijke pretraining-run.

Wanneer gebruik je dit:

  • Het domein bevat vocabulary die het base model nooit heeft gezien (medisch, juridisch, interne codebases).
  • Je hebt grote hoeveelheden domain text, maar geen gelabelde (input, output)-paren.
  • Het base model heeft moeite met domeinspecifieke terminologie.

Voorbeeld: trainen op miljoenen klinische notities zodat het model medische afkortingen, medicijnnamen en klinische workflows oppikt.

2. Supervised fine-tuning (SFT)

SFT traint op gelabelde (input, output)-paren. Je laat het model voor elke input exact de gewenste output zien.

Wanneer gebruik je dit:

  • Je hebt een specifieke task met een schoon input/output-format.
  • Je beschikt over kwalitatieve gelabelde data, zelfs als de hoeveelheid klein is.
  • Je hebt voorspelbaar gedrag nodig voor een bekende inputvorm.

Voorbeeld: trainen op (beschrijving van SQL-query, SQL-code)-paren voor 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 is een speciaal geval van SFT dat is ontworpen om models uiteenlopende instructies in natuurlijke taal te laten volgen. De trainingsdata bestaat uit (instruction, response)-paren voor veel verschillende tasks.

Wanneer gebruik je dit:

  • Je wilt een general-purpose assistant bouwen (zoals ChatGPT of Claude).
  • Het model moet uiteenlopende, open-ended verzoeken kunnen verwerken.
  • Je bouwt een chatinterface.

Voorbeeld: trainen op duizenden diverse instructies zoals “Vat dit artikel samen”, “Schrijf een gedicht over X” en “Leg Y uit in eenvoudige bewoordingen.”

Vergelijking

AspectContinued Pre-trainingSFTInstruction Tuning
DataRaw text(input, output)-paren(instruction, response)-paren
LabelsGeen (unsupervised)Task-specifiekDiverse tasks
DoelDomeinkennisSpecifiek taskgedragElke instructie volgen
DatavolumeMeestal het grootste corpusBepaald door task coverage en error diversityMeestal breder dan task-specifieke SFT

[!NOTE] Wat mensen daadwerkelijk doen SFT en instruction tuning gebruiken hetzelfde next-token-objective; het onderscheid zit in de breedte en samenstelling van de dataset. Continued pre-training is een apart experiment en moet worden gevolgd door tests voor zowel domeinwinst als regressie van general capabilities.


De fine-tuning-pipeline in 7 stages

Fine-tuning is een pipeline, geen enkel commando. Elke stage kent eigen failure modes, en een overgeslagen stage wordt meestal later zichtbaar als een slecht model.

Pipeline in 7 stagesPipeline in 7 stages

Elke stage bouwt voort op de vorige:

  1. Data preparation — Definieer de evaluatie-eenheid, split de data en clean en formatteer deze
  2. Model selection — Kies het juiste base model en laad de weights
  3. Training setup — Configureer hardware, hyperparameters en optimization strategy
  4. Fine-tuning — Voer SFT-, DPO- of ORPO-training uit
  5. Evaluation — Benchmark performance en valideer quality
  6. Deployment — Exporteer en serve je model
  7. Monitoring — Volg performance, onderhoud het model en itereer

[!WARNING] Data is de basis Training reproduceert systematische fouten in de voorbeelden. Inspecteer labels, leakage, coverage en policy compliance voordat je tijd besteedt aan optimizer sweeps.


Stage 1: Data preparation

Veel fine-tuning-projecten mislukken hier, niet tijdens de training. Moderne data prep is meer dan een regex over CSVs uitvoeren.

Data-pipelineData-pipeline

De data-pipeline in 5 stages

Tools zoals DataTrove en Distilabel kunnen op schaal helpen. Laat de failure taxonomy en het data contract het pipelineontwerp sturen; de toolkeuze volgt daaruit.

1. Ingestion en filtering

  • Actie: verwijder refusals (“Ik kan dat niet beantwoorden”), corrupte UTF-8 en niet-doeltalen.
  • Tools: Trafilatura voor extractie en fastText’s language-identification models voor language ID; de distributed lid.176 models herkennen 176 talen.

2. Beleid voor gevoelige data

  • Actie: bepaal wat het model mag leren en redact, tokenize of sluit persoonlijke en vertrouwelijke velden uit waar nodig.
  • Tools: Microsoft Presidio of scrubadub.
  • Waarom: een detector is slechts één control; vereisten voor provenance, consent, retention, access en deletion blijven van toepassing.

3. Deduplicatie (MinHash LSH)

  • Actie: verwijder near-duplicates zodat het model ze niet memoriseert.
  • Tools: DataTrove verwerkt terabyte-scale data goed.

4. Synthetic augmentation, indien nodig

  • Actie: gebruik een sterker teacher model (GPT-4o, DeepSeek-V3) om raw data om te schrijven naar schone instruction-response-paren.
  • Tools: Distilabel.
  • Validatie: sample teacher outputs, controleer ze met dezelfde rubric als human labels en houd synthetic en human-written slices gescheiden in de evaluatie.

5. Formatting

  • Actie: converteer naar een standaardformat (Alpaca of ShareGPT).

Voorbeelden van dataformats

Alpaca-format (instruction-following):

{
    "instruction": "Summarize the following text.",
    "input": "The text to be summarized...",
    "output": "This is the summary."
}

ShareGPT/ChatML-format (conversationeel):

{
    "conversations": [
        { "from": "user", "value": "Hello, who are you?" },
        { "from": "assistant", "value": "I am a helpful AI assistant." }
    ]
}

Wat daadwerkelijk telt

  • Coverage vóór volume. Voeg voorbeelden toe die verschillende failure modes vertegenwoordigen, niet herhalingen van de eenvoudige meerderheidscase.
  • Cleanliness. Verwijder irrelevante tekst, normaliseer whitespace en houd formatting consistent.
  • Balance. Behoud belangrijke zeldzame cases en rapporteer performance per slice.
  • Separation. Split op source, user, document of time wanneer random row splits near-duplicates zouden laten lekken.
  • Provenance. Leg voor elke datasetversie de source, license of permission, transformation history en deletion path vast.

Stage 2: Model selection en hardware

De keuze van het base model en inzicht in de GPU-floor bepalen wat je daadwerkelijk kunt trainen.

Begin met het kleinste base model dat de niet-onderhandelbare baseline checks al doorstaat. Controleer:

  • license- en redistribution terms voor het beoogde product;
  • language-, domain-, tool-use- en safety behavior vóór adaptation;
  • compatibiliteit van tokenizer en chat template met de dataset;
  • de maximale context en het truncation behavior dat echte voorbeelden vereisen;
  • support in zowel het training framework als de beoogde serving engine.

Fine-tuning is een adaptation-stap, geen reparatie voor een ongeschikt base model. Als het model capabilities mist die de dataset niet afdekt, kies dan een ander base model voordat je meer epochs uitvoert.

Size de run, niet de marketingtier

Er bestaat geen blijvende tabel van “model size → GPU”. Peak memory verandert door weight precision, optimizer, trainable parameter count, sequence length, micro-batch size, activation checkpointing, attention implementation en framework overhead. Begin met een memory estimate en voer daarna een korte smoke test op maximum length uit met exact dezelfde stack.

MemorycomponentFull fine-tuningLoRAQLoRA
Base weightsTraining precisionFrozen, meestal BF16/FP16Frozen, meestal 4-bit NF4
GradientsAlle trainable weightsAdapter weightsAdapter weights
Optimizer statesAlle trainable weightsAdapter weightsAdapter weights
ActivationsHangt bij elke methode af van batch en sequence lengthDezelfde afhankelijkheidDezelfde afhankelijkheid

Het oorspronkelijke QLoRA-paper paste een 65B LLaMA model op één GPU van 48 GB in de specifieke setup van het paper. Dat resultaat is een bruikbare bovengrens, geen garantie dat elke huidige 70B-architectuur, contextlengte, kernel of trainer op hetzelfde device past.

Memory math

Voor een model met PP parameters vereisen alleen de weights ongeveer 2P2P bytes in BF16/FP16 of 0.5P0.5P bytes bij four-bit, vóór quantization metadata en runtime buffers. Full Adam-style training voegt gradients, optimizer states en vaak higher-precision master weights toe. LoRA vermijdt het grootste deel van de trainable-state memory; QLoRA verkleint daarnaast de footprint van de frozen base weights. Activations kunnen bij lange sequence lengths nog steeds domineren.

Gebruik deze workflow:

  1. Kies de langste sequence en micro-batch die je moet ondersteunen.
  2. Schat weights en trainable state, en houd headroom over voor activations en kernels.
  3. Voer één forward/backward step uit op maximum length.
  4. Noteer peak allocated en reserved memory.
  5. Schaal pas daarna batch size, rank, sequence length of het aantal GPUs op.

Stage 3: Training methods (PEFT en LoRA)

Full fine-tuning versus PEFT

Full fine-tuning (FFT) update elke weight, waardoor gradients en optimizer state met het volledige model meegroeien. De peak kan niet alleen uit het aantal parameters worden afgeleid, maar ligt veel hoger dan de memory die nodig is om de weights voor inference te laden.

Parameter-efficient fine-tuning (PEFT) traint slechts een kleine subset van de parameters en freezet de rest. De wiskunde wordt een stuk vriendelijker.

LoRA: het startpunt

LoRA (Low-Rank Adaptation) freezet een pre-trained matrix en representeert de geleerde update met twee kleinere matrices. Het oorspronkelijke paper motiveert dit met de hypothese dat nuttige adaptation-updates een lage intrinsic rank hebben.

LoRA-architectuurLoRA-architectuur

Voor een frozen matrix W0Rdout×dinW_0 \in \mathbb{R}^{d_{out} \times d_{in}} leert LoRA:

  • ARr×dinA \in \mathbb{R}^{r \times d_{in}}
  • BRdout×rB \in \mathbb{R}^{d_{out} \times r}

De adapted layer is:

W=W0+αrBAW' = W_0 + \frac{\alpha}{r}BA

De adapter heeft r(din+dout)r(d_{in}+d_{out}) trainable parameters in plaats van dindoutd_{in}d_{out} voor die matrix. Voor een square matrix van 4.096 breed met rank 16 betekent dat een reductie van 128× voor de matrix, niet 10.000× voor een willekeurig model. De claim van 10.000× in het LoRA-paper betrof een specifieke GPT-3 175B-configuratie die geselecteerde matrices adapteerde.

PEFT-methoden vergeleken

MethodeWat verandertKies dit wanneer
LoRAFrozen base plus trainable updates met lage rankHet base model comfortabel past en je kleine task-artifacts wilt
QLoRALoRA met de frozen base opgeslagen in 4-bit-formaatMemory voor base weights de beperkende factor is
DoRAScheidt weight magnitude van een door LoRA geüpdatete richtingEen gemeten LoRA-baseline een quality gap laat dat extra complexiteit rechtvaardigt
Full fine-tuningAlle model weightsPEFT het doel mist en de quality gain distributed training en volledige checkpoints rechtvaardigt

Wanneer kies je welke methode?

  • LoRA: begin hier. Snel, memory-efficient en goed ondersteund.
  • QLoRA: wanneer hetzelfde LoRA-experiment niet past vanwege de frozen base weights.
  • DoRA: nadat een apples-to-apples LoRA-vergelijking een nuttige gain laat zien.
  • Full fine-tuning: pas nadat PEFT een geëvalueerde bottleneck is gebleken, niet slechts een aanname.

DoRA: weight-decomposed LoRA

DoRA (Weight-Decomposed Low-Rank Adaptation) scheidt de magnitude van elke weight vector van de richting ervan. Het DoRA-paper past een LoRA-update toe op de directionele component en leert de magnitude afzonderlijk.

DoRA-architectuurDoRA-architectuur

Zo werkt het:

In plaats van weights als één geheel te behandelen, splitst DoRA pre-trained weights op in twee componenten:

  1. Magnitude — één trainable value per weight vector.
  2. Direction — een genormaliseerde vector die via low-rank matrices wordt geüpdatet.

In compacte column-wise notatie:

W=mV+BAV+BAcW' = m \frac{V + BA}{\lVert V + BA \rVert_c}

waarbij:

  • m = magnitude (trainable)
  • VV = de frozen directionele matrix
  • BABA = de geleerde low-rank directionele update
  • c\lVert \cdot \rVert_c = column-wise normalization

Wat je voor die extra structuur krijgt:

  • Meer degrees of freedom dan bij standaard LoRA, omdat magnitude onafhankelijk kan veranderen.
  • Betere resultaten dan LoRA in verschillende configuraties die door het paper van de auteurs worden gerapporteerd.
  • Extra parameters en computation, dus de gain moet op jouw task en serving path worden geverifieerd.

Adapter merging voor multi-task learning

Met afzonderlijke adapters kan één frozen base meerdere tasks ondersteunen. Je kunt requests naar een adapter routen, meerdere adapters vanuit één engine serven wanneer dat wordt ondersteund, of offline een merged candidate maken. Merging kan interference veroorzaken; evalueer daarom het merged artifact in plaats van aan te nemen dat de source adapters probleemloos composeren.

Veelgebruikte merging-methoden:

  1. Concatenation — combineer adapterparameters en verhoog de effectieve rank. Snel en eenvoudig.
  2. Linear combination — gewogen som van adapters. Geeft je instelbare parameters.
  3. SVD — matrix decomposition voor merging. Flexibeler, maar trager.

Voorbeeld: één adapter voor summarization en een andere voor translation, samengevoegd tot één multi-task model.


Stage 4: Fine-tuning en preference alignment

SFT leert van demonstrations. Preference optimization leert daarentegen van vergelijkingen, zoals “chosen response A is beter dan rejected response B”. Gebruik dit alleen wanneer pairwise preference het juiste label voor de fout is; factual correctness en policy compliance vereisen vaak sterkere evaluators dan één algemene preference-score.

Alignment-methodenAlignment-methoden

PPO-based RLHF

Het oorspronkelijke recept was een pipeline in drie stages:

  1. SFT — leer de task.
  2. Reward model — train op human preferences (chosen versus rejected).
  3. PPO (Proximal Policy Optimization) — reinforcement learning om de policy te optimaliseren.

De operationele kosten komen door de moving parts:

  • Complex om te implementeren en te onderhouden.
  • Duur — je traint meerdere models.
  • On-policy sampling en reward optimization vereisen zorgvuldige stability- en reward-hacking-checks.

DPO

DPO (Direct Preference Optimization) verwijdert het expliciete reward model en de RL-loop. Het DPO-paper leidt een geparameteriseerd objective af voor reward maximization met een KL-divergence-constraint, zodat optimization kan plaatsvinden op basis van preference pairs in plaats van reinforcement learning:

{
    "prompt": "Explain quantum computing",
    "chosen": "Quantum computing uses qubits...",   # Preferred response
    "rejected": "Well, it's complicated..."        # Non-preferred response
}

Wat er operationeel verandert:

  • Eenvoudiger code path (geen afzonderlijk reward model en geen RL-loop).
  • Een offline objective over preference pairs in plaats van on-policy reinforcement learning.
  • Een reference policy of equivalente reference log probabilities in de standaardformulering.

DPO is eenvoudiger te prototypen dan een volledige PPO-pipeline, maar is geen automatische quality upgrade. Resultaten hangen af van de starting policy, pair quality, loss settings, length effects en het evaluation protocol. Vergelijk DPO met een SFT-checkpoint op dezelfde held-out preference- en task-suites.

ORPO

ORPO (Odds-Ratio Preference Optimization) combineert de SFT negative-log-likelihood loss met een odds-ratio penalty op rejected responses. Het verwijdert het afzonderlijke reference model en kan task learning en preference optimization in één run combineren.

Zo werkt het: ORPO gebruikt een gecombineerde loss die twee dingen tegelijk doet:

  1. Maximaliseert de likelihood van de chosen response (task learning).
  2. Penaliseert de rejected response met een odds-ratio-term (preference learning).

Relevante hyperparameters:

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: het paper gebruikte lage rates in zijn experimenten; tune deze voor jouw model, batch en data in plaats van één waarde als regel over te nemen.
  • Beta: bepaalt het gewicht van de preference term ten opzichte van de SFT term.

De trade-off:

  • Eén trainingstage in plaats van twee.
  • Geen reward model.
  • Geen forward pass van een reference model.
  • Een gekoppelde run: als task learning of preference behavior regressie vertoont, is er in dezelfde pipeline geen intermediate SFT-checkpoint om te inspecteren.

Kies op basis van het data- en evaluation design:

  • Gebruik DPO wanneer je al een satisfactory SFT-checkpoint hebt en een eenvoudiger offline preference-experiment wilt uitvoeren.
  • Test ORPO wanneer een reference-free objective in één stage past bij je data en operationele constraints.
  • Gebruik PPO-based RLHF wanneer online sampling tegen een expliciet learned reward onderdeel van de requirement is en je reward exploitation kunt monitoren.

Geen van deze methoden is een default voor alle tasks. Houd een SFT-only baseline aan en rapporteer zowel task metrics als preference metrics.


Fine-tuning frameworks

Frameworks overlappen en veranderen snel. Kies op basis van de execution path die je moet ondersteunen, pin versions en houd de training configuration voldoende portable om buiten een notebook te kunnen reproduceren.

Unsloth — snelheid en memory efficiency

Unsloth integreert met Hugging Face trl en transformers en levert optimized kernels, checkpointing en quantized fine-tuning paths voor ondersteunde models.

  • Custom Triton GPU kernels voor attention, RoPE en cross-entropy die PyTorch-overhead overslaan.
  • Memory-efficient backprop die activations tijdens de backward pass recompute in plaats van ze in memory te houden.
  • Fused operations die meerdere stappen samenvoegen (layer norm + linear en vergelijkbare operaties) tot afzonderlijke GPU-calls.
  • 4-bit quantization rechtstreeks geïntegreerd in de QLoRA-path, met optimized dequantization.

[!IMPORTANT] Importvolgorde is belangrijk Volg de importvolgorde in het Unsloth-voorbeeld voor de versie die je pint. Unsloth past tijdens import patches toe; importeer het daarom vóór trl en transformers om ontbrekende optimizations of version-specific errors te voorkomen.

# 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

Geschikt voor: single-GPU training, prototyping, Colab-notebooks en iedereen die op de GPU-rekening let.

Gepubliceerde snelheids- en memory-cijfers variëren per model, sequence length, batch, precision en hardware. Benchmark tokens per second en peak memory in je eigen run in plaats van een headline ratio als frameworkeigenschap te behandelen.

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

Uitvoeren met: accelerate launch -m axolotl.cli.train config.yaml

Geschikt voor: declaratieve, reproduceerbare runs en ingebouwde launcher-opties voor distributed training. De config kan worden gereviewd, versioned en hergebruikt voor lokale en distributed runs.

Frameworkvergelijking

ToolNuttig wanneerVerifieer vóór je committeert
UnslothJe een optimized path voor een ondersteund model wilt met beknopte voorbeeldenMatrix voor model, GPU, quantization en distributed support
AxolotlJe declarative configs en ingebouwde distributed recipes wiltExacte config schema en launcher voor de gepinde release
TRLJe direct toegang wilt tot Hugging Face SFT- en preference-trainersDatasetformat, chat template, loss masking en PEFT-integratie
TorchtuneJe PyTorch-native recipes en components wiltModel recipe coverage en export compatibility

Praktische demo: fine-tuning met Unsloth

Hier is een representatief trainingsfragment uit mijn repository unsloth-finetune-demo. De demo fine-tunet Nemotron-Nano voor function calling. Voor dit fragment laadt en formatteert de demo’s src/unsloth_demo/data.py de dataset; daarna maakt het training path de versioned train_dataset- en eval_dataset-objects aan.

Training-pipelineTraining-pipeline

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

Configuration

De interessante onderdelen staan 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] De alpha-to-rank-ratio alpha/r schaalt de klassieke LoRA-update. alpha = 2r is een gebruikelijke startheuristiek in documentatie van sommige tools, geen stabiliteitsgarantie. Sweep rank, alpha, learning rate en target modules pas nadat de data en baseline zijn vastgelegd.

Core training code

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 met Axolotl

[!NOTE] Demo komt eraan Ik werk aan een hands-on Axolotl-demo. Tot die tijd is de Accelerate n-D Parallelism Guide van Hugging Face een goede referentie voor multi-GPU-trainingstrategieën.

Voor config-first en distributed setups maakt Axolotl de workflow reproduceerbaar:

# 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 uitvoeren:

axolotl train axolotl_config.yaml

Stage 5: Evaluation

Bevries het evaluation contract vóór de eerste run. Vergelijk minimaal het tuned checkpoint met exact dezelfde untuned base, dezelfde prompt, decoding settings en tool environment. Rapporteer aggregate quality pas nadat je de failure slices hebt gecontroleerd die het project moest verbeteren.

Volg vier groepen:

  1. Target task: exact match, execution success, human rubric of een andere uitkomst die aan de use case is gekoppeld.
  2. Regression: general abilities en eerder ondersteunde task slices die door adaptation kunnen verslechteren.
  3. Safety en policy: refusals, data leakage, prompt injection of domeinspecifieke constraints.
  4. Operations: latency, throughput, memory, artifact size en kosten bij de beoogde serving configuration.

Geautomatiseerde benchmarks

Gebruik lm-evaluation-harness voor relevante gestandaardiseerde tasks, niet als vervanging voor de product evaluation:

lm_eval --model hf \
    --model_args pretrained=./outputs/merged-model \
    --tasks hellaswag,arc_easy,mmlu \
    --batch_size 8

LLM-as-judge

Voor subjectieve quality kan een groter model helpen met scoring, maar kalibreer dit tegen door mensen gereviewde voorbeelden en houd de identiteit van de candidate verborgen:

judge_prompt = """
Rate this response from 1-5 on:
- Relevance
- Accuracy
- Formatting

Response: {model_output}
Expected: {ground_truth}
"""

Domeinspecifieke evaluatie

Houd echte voorbeelden apart per source, user, document of time, zodat near-duplicates niet over de split kunnen lekken. Valideer bij function calling de volledige trajectory: tool selection, arguments, execution result, recovery en final response. Rapporteer confidence intervals of paired win/loss counts wanneer de sample klein is, en inspecteer elke regressie in een kritieke slice.


Stage 6: Deployment en outputformats

Kies het artifact op basis van serving engine en rollback plan, niet alleen op basis van file size:

OutputformatsOutputformats

1. LoRA-adapter

uv run finetune  # Saves ~100-500MB adapter
  • Grootte: evenredig aan targeted modules, rank, layers en dtype; vaak veel kleiner dan de base.
  • Geschikt voor: development, versioned task adapters en engines die LoRA rechtstreeks ondersteunen.
  • Bonus: je kunt adapters wisselen zonder het base model opnieuw te downloaden.

2. Merged model

uv run finetune --merge  # Creates a standalone full model
  • Grootte: ongeveer die van het volledige base checkpoint bij de gekozen output precision.
  • Geschikt voor: engines of distribution paths die de adapter niet afzonderlijk ondersteunen.
  • Trade-off: groter artifact en tragere rollout; eenvoudiger laden van één model.

3. GGUF-format

uv run finetune --gguf q4_k_m  # Creates ~2-4GB quantized model
  • Grootte: afhankelijk van het model; voor Q4-varianten ongeveer four-bit weights plus metadata.
  • Geschikt voor: CPU-inference, Ollama, llama.cpp en edge deployment.
  • Opties: q4_k_m (kleiner), q5_k_m (meer weight fidelity), q8_0 (groter en hogere fidelity). Meet na conversion de impact op de task.

Stage 7: Serving en monitoring

Met 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

Query via de OpenAI-compatible API:

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",
)

De tool-calling guide van vLLM vereist auto tool choice en een parser die bij het model past; gebruik de compatible chat template van het model wanneer de tokenizerconfiguratie er geen levert. Met tool_choice="auto" vereisen constrained arguments bovendien strict: true op ten minste één function (en moet vLLM’s strict-tool-calling-setting zijn ingeschakeld, wat de default is); gebruik een strict-compatible parameters schema. Zonder die opt-in extraheert vLLM calls uit raw text, waardoor de arguments malformed kunnen zijn of het schema kunnen schenden.

Met Ollama (lokaal)

# 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

Met llama.cpp (CPU)

./llama-cli -m ./outputs/model-q4_k_m.gguf \
    -p "What's the weather in Tokyo?" \
    --ctx-size 4096

Monitor het released model

De lifecycle stopt niet bij een gezonde training loss. Leg de base-model revision, tokenizer en chat template, adapter hash, datasetversie, trainingconfiguratie en evaluation report vast als één release-unit. Monitor in production task success, invalid outputs, policy failures, latency en input drift met dezelfde slices als offline. Houd het vorige artifact loadable en definieer vóór de launch een rollback threshold.


Belangrijkste conclusies

  1. Fine-tune pas nadat een untuned baseline en failure taxonomy laten zien dat weight adaptation het probleem adresseert.
  2. Retrieval beheert veranderende evidence; constrained decoding beheert syntax; geen van beide wordt door SFT vervangen.
  3. LoRA reduceert trainable state. QLoRA comprimeert daarnaast de frozen base weights. Schrijf QLoRA-memorycijfers niet toe aan LoRA.
  4. Data coverage, split integrity, provenance en loss masking zijn belangrijker dan het kopiëren van een modieuze optimizerconfiguratie.
  5. DPO, ORPO en PPO-based RLHF zijn verschillende experimental designs, geen quality ladder met één universele default.
  6. Evalueer target behavior, regressions, safety en operations tegen hetzelfde base model.
  7. Kies vóór de training tussen adapter-, merged- of GGUF-output op basis van serving- en rollbackrequirements.

Referenties

Papers en research

Tools voor dataverwerking

Constrained decoding

  • xgrammar — Constrained decoding met FSMs
  • outlines — Structured generation voor LLMs

Training frameworks

  • Unsloth — Optimized fine-tuning framework
  • Axolotl — Config-driven training en distributed launchers
  • TRL — Hugging Face SFT- en preference-training-library
  • Torchtune — PyTorch-native fine-tuning-library

Inference en deployment

  • vLLM LoRA adapters — Serve één of meer adapters met het base model
  • vLLM tool calling — Stem auto tool choice, parser, chat template en request schema af op het model
  • Ollama — Lokale LLM-runner voor Mac/Windows/Linux
  • llama.cpp — CPU/GPU-inference met GGUF-format

Evaluation

Guides en resources