Een volledige gids om AI-modellen nieuwe vaardigheden aan te leren: supervised fine-tuning (SFT), LoRA/QLoRA, RLHF, DPO, GRPO, modeldistillatie, model-merging en evaluatie. Van concept tot productie — met werkende code bij elke stap.
Pretraining geeft een model brede kennis van de wereld, maar slechts één vaardigheid: het volgende token voorspellen. Het model heeft Wikipedia, code, boeken en het web gezien — maar het weet niet hoe het behulpzaam moet zijn, instructies moet volgen of gevaarlijke verzoeken moet weigeren. Fine-tuning is het proces om deze gedragingen na de pretraining aan te leren.
De sector is geconvergeerd naar een standaard trainingsladder die alle grote frontier-modellen (GPT-4o, Claude Opus 4.6, Llama 4, Gemini 2.5) volgen. Elke fase bouwt voort op de vorige — je kunt SFT niet overslaan en meteen naar RLHF springen.
graph LR A[Raw Text Corpus] -->|Pretraining cross-entropy| B[Base Model] B -->|Supervised Fine-Tuning| C[Instruction-Following Model] C -->|RLHF / DPO / GRPO| D[Aligned Model] D -->|Evaluation & Red-teaming| E[Production Model]
Zelfgesuperviseerde voorspelling van het volgende token op enorme corpora. Codeert wereldkennis.
Supervised fine-tuning op instructie-antwoordparen. Leert het model behulpzaam te zijn.
RLHF, DPO of GRPO op menselijke voorkeursdata. Maakt uitvoer veilig en geprefereerd.
Geautomatiseerde benchmarks + red-teaming. Regressies opvangen vóór de uitrol.
SFT traint het model om assistent-tokens te voorspellen op basis van een gesprekscontext. Het cruciale detail is loss masking: het cross-entropieverlies wordt alleen berekend op assistent-tokens, niet op de systeemprompt of de gebruikersbeurten. Dit voorkomt dat het model de gebruikerskant van het gesprek „leert“.
Drie formaten domineren het SFT-landschap. ChatML is het meest breed toegepast vanwege de ondubbelzinnige speciale tokens.
<|im_start|>system You are a helpful AI assistant specialized in European AI regulation. <|im_end|> <|im_start|>user What are the key obligations under the EU AI Act for high-risk systems? <|im_end|> <|im_start|>assistant High-risk AI systems under the EU AI Act (in force August 2024) must comply with... <|im_end|>
| Parameter | Typische waarde | Opmerkingen |
|---|---|---|
| Learning rate | 2e-5 | Lager dan bij pretraining; cosinusafname |
| Epochs | 2–3 | Meer epochs → overfitting op kleine datasets |
| Batch size (effective) | 64–128 | Gebruik gradiëntaccumulatie bij weinig GPU-geheugen |
| Warmup ratio | 0.1 | 10% van de stappen voor LR-warmup |
| Max sequence length | 2048–8192 | Stem af op je inferentie-contextvenster |
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTConfig, SFTTrainer
from datasets import load_dataset
import torch
model_name = "meta-llama/Llama-4-Scout-17B-16E-Instruct" # 2026: Llama 4 Scout replaces Llama 3.1 8B
model = AutoModelForCausalLM.from_pretrained(
model_name, torch_dtype=torch.bfloat16, device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
dataset = load_dataset("HuggingFaceH4/ultrachat_200k", split="train_sft")
sft_config = SFTConfig(
output_dir="./sft-llama-4-scout",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=2e-5,
lr_scheduler_type="cosine",
warmup_ratio=0.1,
logging_steps=10,
save_strategy="epoch",
bf16=True,
)
trainer = SFTTrainer(
model=model,
args=sft_config,
train_dataset=dataset,
processing_class=tokenizer,
)
trainer.train()
trainer.save_model()Volledige fine-tuning wijzigt alle ~7 miljard parameters van een 7B-model. In bfloat16 is dat 14 GB alleen al voor parameteropslag, plus gradiënten en optimizer-states. LoRA (Low-Rank Adaptation, Hu et al. 2021) benut een belangrijke empirische observatie: gewichtswijzigingen tijdens fine-tuning zijn van lage rang.
In plaats van een volledige gewichtsupdate ΔW ∈ ℝ^(d×k) te leren, leert LoRA twee kleine matrices: A ∈ ℝ^(d×r) en B ∈ ℝ^(r×k) waarbij r ≪ min(d, k). Bij inferentie wordt de adapter teruggevouwen: W′ = W + αAB/r. Eenmaal samengevoegd is er nul inferentie-overhead.
from peft import LoraConfig, TaskType, get_peft_model
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
],
bias="none",
)
model = get_peft_model(base_model, config)
model.print_trainable_parameters()
# trainable params: 83,886,080 || all params: 8,030,261,248 || trainable%: 1.044
# After training, merge adapter back into the base weights
merged = model.merge_and_unload()
merged.save_pretrained("./my-lora-merged")| Methode | Trainbare parameters | GPU-RAM (8B) | Kwaliteit | Trainingssnelheid |
|---|---|---|---|---|
| Full Fine-Tuning | 7B (100%) | ~80 GB | Beste | Traagste |
| LoRA r=4 | ~21M (0.3%) | ~16 GB | Goed | Snel |
| LoRA r=16 | ~83M (1.0%) | ~18 GB | Zeer goed | Snel |
| LoRA r=64 | ~335M (4.1%) | ~24 GB | Nabij volledige FT | Gematigd |
Zelfs met LoRA vereist het in bfloat16 geladen basismodel 16 GB voor een 8B-model — buiten het budget van consumenten-GPU's. QLoRA (Dettmers et al. 2023) lost dit op door het bevroren basismodel te kwantiseren naar 4-bit NormalFloat (NF4) en de LoRA-adapters te trainen in bfloat16-precisie.
NormalFloat4 is informatietheoretisch optimaal voor normaal verdeelde gewichten van neurale netwerken. Minder fout dan int4 of fp4.
Optimizer-states worden automatisch naar het CPU-RAM gepaged wanneer het GPU-geheugen volloopt, wat OOM-crashes tijdens de training voorkomt.
Kwantiseert de kwantisatieconstanten zelf, wat ongeveer 0,5 bit per parameter extra bespaart.
| Model | FP16-VRAM | QLoRA-VRAM | Min. GPU |
|---|---|---|---|
| Llama 4 Scout (17B) | 34 GB | 10 GB | RTX 4090 24GB |
| Llama 4 Maverick (70B-class) | 140 GB | 40 GB | 2× A100 40GB |
| Llama 4 Behemoth (frontier) | 800+ GB | ~200 GB | 8× H100 80GB |
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-4-Maverick-17B-128E-Instruct", # 2026: Llama 4 Maverick replaces Llama 3.1 70B
quantization_config=bnb_config,
device_map="auto",
)
# Now apply LoRA to the 4-bit model — same LoraConfig + get_peft_model as beforeReinforcement Learning from Human Feedback (RLHF) was de doorbraak die GPT-3 in InstructGPT en uiteindelijk in GPT-4o veranderde. Het stemt het modelgedrag af op menselijke voorkeuren — niet alleen het volgen van instructies, maar uitvoer die werkelijk geprefereerd, veilig en behulpzaam is.
Het basismodel fine-tunen op een gecureerde set hoogwaardige instructie-volgende demonstraties. Dit creëert het startbeleid dat RLHF zal verbeteren.
Een classifier trainen op paarsgewijze menselijke voorkeuren: welke van twee completions (y_w, y_l) bij dezelfde prompt is beter? Verlies: log σ(r(x, y_w) − r(x, y_l)).
Proximal Policy Optimization gebruiken om de score van het reward-model te maximaliseren terwijl het dicht bij het SFT-beleid blijft (de KL-divergentiestraf voorkomt reward hacking).
graph LR A[Base Model] -->|SFT on demos| B[SFT Model] B -->|Sample completions| C[Completion Pairs] C -->|Human labelers rank| D[Preference Dataset] D -->|Train| E[Reward Model] B -->|Initialize policy| F[Policy Model] F -->|Rollout + PPO| G[RL Optimization] E -->|Score rollouts| G G -->|Converged| H[RLHF Model]
DPO (Direct Preference Optimization) (Rafailov et al. 2023) elimineert het reward-model volledig. Het toonde wiskundig aan dat het optimale RLHF-beleid rechtstreeks kan worden uitgedrukt als een functie van de voorkeursdata, waardoor een pijplijn van drie fasen wordt teruggebracht tot één fine-tuning-stap.
Het DPO-verlies optimaliseert het beleid rechtstreeks op voorkeursparen (prompt, chosen, rejected) met het SFT-model als bevroren referentie. Geen PPO, geen reward-model, geen aparte verzameling van RM-trainingsdata.
from trl import DPOConfig, DPOTrainer
from datasets import load_dataset
# Dataset needs: prompt, chosen, rejected columns
dataset = load_dataset("HuggingFaceH4/ultrafeedback_binarized", split="train_prefs")
dpo_config = DPOConfig(
output_dir="./dpo-output",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=5e-7, # much smaller than SFT lr
beta=0.1, # KL penalty coefficient
bf16=True,
)
trainer = DPOTrainer(
model=sft_model, # your SFT fine-tuned model
ref_model=sft_ref_model, # frozen reference
args=dpo_config,
train_dataset=dataset,
processing_class=tokenizer,
)
trainer.train()Group Relative Policy Optimization (GRPO) (gebruikt in DeepSeek-R1) elimineert het referentiemodel. Voor elke prompt sampelt het meerdere uitvoeren en gebruikt het de gemiddelde groepsbeloning als baseline voor de voordeelschatting. Dit is goedkoper dan PPO (geen value-model) en beter geschikt voor redeneertaken waarbij je de juistheid programmatisch kunt verifiëren.
| Methode | Rekenkracht | Stabiliteit | Datavereisten | Opmerkingen |
|---|---|---|---|---|
| RLHF (PPO) | Zeer hoog | Laag | Menselijke rangschikkingen | 4 modellen in geheugen; risico op reward hacking |
| DPO | Laag | Hoog | Voorkeursparen | Geen reward-model; eenvoudigere pijplijn |
| GRPO | Gemiddeld | Gemiddeld | Rollout-samples | Geen referentiemodel; goed voor redeneren |
| SimPO | Laag | Hoog | Voorkeursparen | Geen referentiemodel; gemiddelde log-prob-beloning |
Kennisdistillatie traint een klein „student“-model om een groot „teacher“-model na te bootsen. Het kerninzicht is dat de teacher zachte kansverdelingen over het vocabulaire (logits) levert in plaats van one-hot-labels. Deze zachte doelen coderen veel meer informatie — ze onthullen welke tokens semantisch lijken op het juiste antwoord, wat de student een rijker trainingssignaal geeft.
Het gecombineerde verlies: L = α × L_CE(harde labels) + (1 − α) × L_KL(student-logits ‖ teacher-logits). Temperatuurschaling T > 1 verzacht de verdeling van de teacher, verdeelt de kansmassa over meer tokens en maakt de zachte labels nog informatiever.
graph TB A["Large Teacher (70B)"] -->|"Generate on training data"| B[Soft Logits] C[Input Prompt] --> A C --> D["Small Student (7B)"] B -->|KL Loss| D E[Ground Truth] -->|CE Loss| D D -->|Both losses| F[Distilled Student]
De student bootst de uitvoer van de teacher na — genereer teacher-completions, train de student om ze te reproduceren. Gebruikt door DeepSeek-R1-Distill om redeneersporen over te dragen.
Tussenliggende representaties (hidden states, attention-patronen) afstemmen tussen de lagen van teacher en student. Draagt structurele kennis over, niet alleen oppervlakte-uitvoer.
Een klein conceptmodel stelt tokensequenties voor; het grote model verifieert ze parallel. Behaalt een 2- tot 4-voudige inferentieversnelling zonder kwaliteitsverlies.
De student genereert tokens; de teacher scoort ze. Vermijdt exposure bias (verschil in verdeling tussen training en test) dat gangbaar is bij offline distillatie.
Model-merging combineert meerdere gefinetunede checkpoints tot één enkel model zonder enige aanvullende training. Het is goedkoop, snel en verrassend effectief om gespecialiseerde vaardigheden — code, wiskunde, instructievolging — te combineren in één inzetbaar model. Gemergde modellen verschijnen vaak bovenaan het HuggingFace Open LLM Leaderboard.
Vloeiende interpolatie tussen twee modelcheckpoints in de gewichtsruimte. Behandelt gewichten als punten op een hypersfeer. Het best voor het mengen van twee nauw verwante modellen.
Bereken ΔW = W_FT − W_base voor elk gefinetuned model en tel de delta's vervolgens op. Hiermee kun je capaciteiten samenstellen of ongewenste gedragingen aftrekken.
Lost conflicten tussen modellen op: trim parameters met lage magnitude, kies het dominante teken voor elk gewicht en merge vervolgens. Verwerkt 3 of meer modellen netjes.
Laat fine-tuning-gewichtsdelta's willekeurig vallen (met kans p) en herschaalt de overlevenden om de norm te behouden. Vermindert interferentie tussen modellen.
# mergekit config.yaml
models:
- model: meta-llama/Llama-4-Scout-17B-16E
parameters:
weight: 0.4
- model: ./llama-4-scout-code-finetuned
parameters:
weight: 0.3
- model: ./llama-4-scout-math-finetuned
parameters:
weight: 0.3
merge_method: ties
base_model: meta-llama/Llama-4-Scout-17B-16E
parameters:
density: 0.7
normalize: truemergekit-yaml config.yaml ./merged-model --cuda
Datasetkwaliteit is veruit de belangrijkste factor voor het succes van fine-tuning — belangrijker dan de modelarchitectuur, de trainingsduur of de keuze van de optimizer. Een slecht gecureerde dataset garandeert slechte resultaten, ongeacht al het andere.
Door experts geschreven voorbeelden; hoogste signaal-ruisverhouding. Gebruikt voor kritieke gedragingen.
Synthetische generatie met frontier-modellen. Goed om domeindekking op schaal op gang te brengen.
Seed-instructies laten evolueren tot moeilijkere, diversere varianten. Gebruikt in WizardLM en OpenHermes.
Vereist agressieve kwaliteitsfiltering: deduplicatie, lengtefilter, perplexiteitsfilter, veiligheidsfilter.
{
"conversations": [
{"from": "system", "value": "You are an expert in EU AI regulation."},
{"from": "human", "value": "Explain the risk categories in the EU AI Act."},
{"from": "gpt", "value": "The EU AI Act categorizes AI systems into four risk levels..."}
]
}from openai import OpenAI # or use Mistral/Llama locally
client = OpenAI()
def generate_training_example(topic: str, difficulty: str) -> dict:
prompt = (
f"Generate a challenging {difficulty}-level question about {topic} "
"and a comprehensive expert answer."
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.8,
)
content = response.choices[0].message.content
# Parse and structure output (question/answer split)...
return {"instruction": topic, "response": content}De fine-tuning-lus is: trainen → evalueren op een holdout → faalmodi diagnosticeren → data verbeteren → opnieuw trainen. Goede evaluatie is wat trial-and-error omzet in systematische verbetering.
Multi-turn benchmark van 80 vragen over 8 categorieën (schrijven, wiskunde, coderen, enz.). GPT-4 scoort elk antwoord 1–10.
Winstpercentage van je model versus een referentiemodel (GPT-4o), beoordeeld door GPT-4o. Snelle geautomatiseerde evaluatie van de kwaliteit van instructievolging.
Nauwkeurigheid van instructievolging op verifieerbare beperkingen (bijv. 'antwoord in minder dan 100 woorden'). Strikte en losse scoringsvarianten.
Codegeneratiebenchmarks. Pass@k-metriek: fractie van problemen opgelost in k pogingen. Uitvoerbare testgevallen als ground truth.
import json
from openai import OpenAI
client = OpenAI()
def evaluate_response(question: str, answer: str, judge_model: str = "gpt-4o") -> dict:
prompt = f"""Rate the following AI assistant response on a scale of 1-10.
Question: {question}
Answer: {answer}
Evaluate: helpfulness (1-10), factuality (1-10), safety (1-10).
Return JSON: {{"helpfulness": N, "factuality": N, "safety": N, "rationale": "..."}}"""
response = client.chat.completions.create(
model=judge_model,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
)
return json.loads(response.choices[0].message.content)| Run | Basismodel | Methode | Dataset | MT-Bench | AlpacaEval Win% | Opmerkingen |
|---|---|---|---|---|---|---|
| v1 | Llama-4-Scout | SFT | UltraChat 200K | 7.4 | 70% | Baseline |
| v2 | Llama-4-Scout | SFT+DPO | + UltraFeedback | 8.0 | 76% | +DPO verbeterde de veiligheid |
| v3 | Llama-4-Scout | SFT+DPO (r=16) | + UltraFeedback | 8.1 | 77% | LoRA r=16 vs. volledige FT |
Fine-tuning is krachtig, maar niet altijd het juiste gereedschap. De beslissing hangt af van wat je probeert te veranderen: kennis, gedrag, format of voorkeuren. De verkeerde keuze kost weken aan engineering en rekenkracht.
| Scenario | Beste aanpak | Waarom |
|---|---|---|
| Antwoorden verankeren in bedrijfsdocumenten | RAG | Kennis kan veranderen; FT laat zich niet eenvoudig bijwerken |
| Een consistente toon/stijl willen | SFT | Toon is format, geen kennis |
| Gebruik van domeinspecifieke terminologie | SFT + weinig data | Standaardgedrag goedkoop wijzigen |
| Specifieke uitvoerformaten verwerken | SFT | Schemanaleving is een aangeleerde vaardigheid |
| Schadelijke uitvoer verminderen | DPO / RLHF | Voorkeur-alignment richt zich daar rechtstreeks op |
| Redeneervermogen nodig hebben | GRPO of distilleren uit R1 | Redeneerpatronen zijn trainbaar |
| Nieuwe feitenkennis toevoegen | RAG (geen FT) | FT memoriseert, kan geen bronnen citeren |
| API-kosten op schaal verlagen | Klein model fine-tunen | Kwaliteit van grote modellen evenaren op een smalle taak |
| Prototype / snel experiment | Eerst prompt-engineering | Geen trainingskosten; eerst het concept valideren |
Begin onderaan. Klim alleen wanneer het huidige niveau werkelijk ontoereikend is — elke trede voegt kosten, complexiteit en latentie toe.
Of je nu een domeinspecifieke assistent, op voorkeuren afgestemde modellen of gedistilleerde productie-uitrollen nodig hebt — ons team heeft ze gebouwd en uitgerold. Laten we het over jouw use case hebben.