LLM Engineering Guide: 45 concepten voor production systems

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

Een LLM-service kan zijn latency-SLO missen omdat decode wordt beperkt door memory bandwidth, omdat de KV-cache het batchbudget heeft opgebruikt, of omdat de queue beide problemen aan het zicht onttrekt. Een fine-tuning-run kan om een andere variant van dezelfde reden mislukken: de model state past niet meer op de hardware. De juiste oplossing volgt uit de bottleneck, niet uit de langste lijst met technieken.

Dit is een naslagwerk voor engineers die de basis van ML en systems al kennen en een productiesymptoom willen koppelen aan het relevante onderdeel van de stack. Het behandelt 45 concepten rond hardware, inference, training, deployment, applicaties en operations. Gebruik een onderdeel om het mechanisme, de praktische consequentie en de voorwaarde die het genoemde resultaat begrenst te identificeren; gebruik daarna de gekoppelde deep dive of je eigen benchmark om de beslissing te nemen.

Een opmerking over de scope

Dit is een naslagwerk, geen lineaire tutorial. Begin met het onderdeel dat aansluit op de beslissing die voor je ligt.

OnderdeelOnderwerpenSecties
I — Hardware foundationsRoofline model, GPU memory, hardware glossary1–3
II — Inference fundamentalsLatency, throughput, KV cache, attention, quantization4–9
III — Inference optimizationsCUDA kernels, FlashAttention, batching, PagedAttention, speculative decoding10–17
IV — Model architectureTransformer internals, decoder-only, MoE, tokenization, context windows18–22
V — Training and alignmentPretraining, LoRA, mixed precision, ZeRO, scaling laws, RLHF/DPO/GRPO, distillation23–32
VI — Scaling and deploymentParallelism, serving frameworks, GPU selection, routing33–36
VII — ApplicationsEmbeddings, RAG, agents, prompt engineering37–40
VIII — Production operationsRate limiting, failure modes, monitoring, cost, capacity planning41–45

Deze guide gebruiken als hub

Deze pagina is bewust breed opgezet. Gebruik haar als kaart en spring vervolgens naar de diepgaandere posts zodra de beslissing concreet wordt.

Als je beslist…Begin metLees daarna
Hoe je een model serveertInference fundamentals en deploymentLoRAX Serving Guide
Of je moet fine-tunenTraining en alignmentLLM Fine-Tuning Guide
Hoe retrieval in een app pastEmbeddings en RAGRAG Evaluation Metrics
Hoe agent-systemen werkenAgents en prompt engineeringAI Agent Reasoning Loops
Hoe je zoekresultaten rangschiktEmbeddings en rerankingSearch Ranking Stack

Begin bij de bottleneck, gebruik de kleinste stack die deze zichtbaar maakt, benchmark de echte workload en voeg alleen complexiteit toe als de cijfers dat rechtvaardigen.


Deel I — Hardwarefundamenten

Arithmetic intensity, de GPU memory hierarchy en de hardwaretermen in dit deel verklaren veel van de keuzes verderop in deze guide.

1. Memory-bound versus compute-bound en het roofline-model

Het uitgangspunt voor LLM-performance is arithmetic intensity: hoeveel nuttige berekeningen voert de GPU uit voor elke byte data die hij uit het geheugen laadt? Die verhouding bepaalt of een operatie compute-bound is (wachten op de processor) of memory-bound (wachten tot data is geladen).

Elke GPU heeft een drempel voor “critical intensity” waarbij de maximale compute-throughput gelijk is aan de memory bandwidth. Voor een NVIDIA H100 SXM met dense BF16- of FP16 Tensor Cores (989 TFLOPS; de 1.979-TFLOPS-specificatie gaat uit van structured sparsity):

989 TFLOPS3.35 TB/s295 FLOPs/byte\frac{989 \text{ TFLOPS}}{3.35 \text{ TB/s}} \approx 295 \text{ FLOPs/byte}

Roofline-grafiek waarin batch-one decode onder de compute-to-bandwidth-drempel van de H100 ligt en long of gebatchte prefill dichter bij het compute-bound gebied ligt.Roofline-grafiek waarin batch-one decode onder de compute-to-bandwidth-drempel van de H100 ligt en long of gebatchte prefill dichter bij het compute-bound gebied ligt.

Batch-one decode en long of voldoende gebatchte prefill bevinden zich doorgaans aan tegenovergestelde kanten van deze drempel:

  • Decode is memory-bound. Tokens één voor één genereren betekent dat de multi-gigabyte weight matrix uit het geheugen wordt geladen om die met één nieuwe token te vermenigvuldigen. In een vereenvoudigde dense 16-bit-analyse met batch-one heeft de operatie ongeveer 1 FLOP/byte, circa 295× onder de roofline-drempel van de H100. Dat verschil verklaart waarom decode in dit regime de maximale compute-throughput niet kan benaderen.
  • Long of voldoende gebatchte prefill is vaak compute-bound. Bij het verwerken van veel prompttokens worden weights hergebruikt in grote matrixmultiplicaties, waardoor de arithmetic intensity boven de roofline-drempel kan uitkomen. Korte prompts en kleine batches kunnen daarentegen worden beperkt door memory traffic of kernel-launch-overhead.

Verlaag dus voor snellere decode de druk op de memory bandwidth: verklein de weights met quantization, verminder de KV memory overhead met GQA en PagedAttention, en verhoog de intensity met batching. Voor lange of goed gebatchte prefills kunnen snellere matrixberekeningen en compute met lagere precisie helpen; profileer workloads met korte prefills afzonderlijk.

2. GPU memory hierarchy

Een GPU heeft vier memory layers, gerangschikt als een piramide: onderaan bevindt zich groot maar traag main memory (HBM), bovenaan kleine maar zeer snelle registers. Data door deze hiërarchie verplaatsen is een belangrijke performance constraint.

H100 memory hierarchy from per-thread registers and per-SM shared memory through shared L2 cache to HBM3.H100 memory hierarchy from per-thread registers and per-SM shared memory through shared L2 cache to HBM3.

Van snelst naar traagst op een H100:

  1. Registers zijn het snelste memory en zijn direct gekoppeld aan processing threads. Voor Hopper’s WGMMA kan matrix A uit registers of shared memory komen, terwijl matrix B uit shared memory komt.
  2. SRAM (shared memory) is snel on-chip working memory die lokaal is voor elke SM.
  3. L2 cache is een gedeelde layer van 50 MB. Deze kan data die over meerdere SMs wordt hergebruikt leveren zonder een nieuwe HBM-fetch.
  4. HBM3 is het main memory van 80 GB waarin model weights en de KV cache worden opgeslagen, met een bandwidth van ~3.35 TB/s.

FlashAttention en kernel fusion verminderen HBM-verkeer door intermediate work op de chip te houden of te combineren. PagedAttention richt zich op een ander probleem: het mapt logische KV-blocks naar niet-contigue physical GPU-memory-blocks, waardoor fragmentation afneemt en block sharing mogelijk wordt.

3. GPU hardware glossary

De onderstaande termen komen in de rest van deze guide regelmatig terug.

HBM (High Bandwidth Memory) stackt DRAM-dies die via through-silicon vias (TSVs) zijn verbonden naast de GPU-die. Generaties zijn onder andere HBM2e (A100, 2 TB/s), HBM3 (H100, 3.35 TB/s) en HBM3e (H200/B200, 4.8–8 TB/s). HBM-bandwidth is een directe constraint voor TPOT in memory-bound decode-regimes.

GDDR (Graphics DDR) is traditioneel graphics memory dat wordt gebruikt in consumer- en workstation-GPU’s zoals de RTX 4090 en L40S. Het heeft een lagere bandwidth dan HBM, maar kost minder per GB. GDDR6X op de RTX 4090 levert ongeveer 1 TB/s, tegenover de H100 met 3.35 TB/s HBM3-bandwidth.

Een SM (Streaming Multiprocessor) is het belangrijkste compute block in een NVIDIA-GPU. Elke SM bevat CUDA cores, Tensor Cores, shared memory en een warp scheduler. De H100 heeft 132 SMs; de A100 heeft er 108.

Tensor Cores zijn gespecialiseerde matrix-multiply-accumulate-units binnen elke SM. Ze versnellen de mixed-precision matmuls die het grootste deel van transformer-compute bepalen. H100 SXM Tensor Cores leveren 494.5 dense of 989 sparse TF32 TFLOPS; vermeld bij het vergelijken van dit cijfer altijd de precision en sparsity mode.

CUDA Cores zijn general-purpose floating-point- en integer-units. Ze verwerken element-wise operations, activation functions en ander non-matrix work terwijl Tensor Cores ondersteunde matrix operations uitvoeren.

Een warp is een groep van 32 threads die lockstep op een SM uitvoeren en daarmee NVIDIA’s kleinste scheduling unit vormen. Warp specialization wijst verschillende warps toe aan data movement en computation, zodat de taken kunnen overlappen.

NVLink is NVIDIA’s high-speed GPU-to-GPU-interconnect binnen een node. NVLink 4.0 op de H100 levert 900 GB/s bidirectionele bandbreedte; NVLink 5.0 op de B200 haalt 1,8 TB/s. Deze bandbreedte is belangrijk voor tensor parallelism, omdat GPU’s bij elke transformer layer partial results uitwisselen.

InfiniBand is een high-speed network fabric voor inter-node communicatie. InfiniBand-adapters uit de ConnectX-klasse vormen de inter-node fabric voor pipeline-parallel of distributed-trainingverkeer; de bandbreedte hangt af van de adapter- en poortconfiguratie.

RDMA (Remote Direct Memory Access) geeft een device toegang tot geheugen op een andere machine zonder het datapad via een van beide CPU’s te routeren. GPUDirect RDMA ondersteunt directe GPU-to-GPU-transfers tussen nodes, waaronder KV-cache-transfers bij disaggregated serving.

NVMe (Non-Volatile Memory Express) is de SSD-interface die wordt gebruikt voor het offloaden van de KV-cache en voor het offloaden van ZeRO-Infinity-parameters wanneer GPU- en CPU-geheugen ontoereikend zijn. De sequential bandwidth hangt af van de drive en de workload en blijft aanzienlijk lager dan de HBM-bandwidth.

TFLOPS en PFLOPS zijn respectievelijk biljoenen en biljarden floating-point operations per seconde. Eén TFLOPS staat gelijk aan 101210^{12} FLOPS. De H100 haalt 989 sparse TF32 tensor TFLOPS, terwijl FlashAttention-3 ongeveer 1,2 PFLOPS in FP8 rapporteert; deze waarden gebruiken verschillende formats en mogen niet worden vergeleken alsof het één metric is.


Deel II — Inference fundamentals

Inference zet een model om in een service die voor gebruikers beschikbaar is. De volgende concepten onderscheiden werk dat de eerste token vertraagt van werk dat elke volgende token vertraagt en maken de geheugenlimieten achter beide zichtbaar.

4. Latency: TTFT, TPOT en percentielen

Time to First Token (TTFT) is de end-to-end vertraging vanaf het indienen van een request tot de eerste outputtoken. Dit omvat queueing, tokenization, scheduling, prompt prefill, de eerste decode step en network delivery. Langere prompts vergroten doorgaans de prefill-component, maar elk van deze fasen kan dominant worden. Targets zijn productspecifiek; MLPerf Inference v5.0 hanteert voor het interactieve Llama 2 70B-scenario een P99 TTFT-limiet van \leq 450 ms.

Time Per Output Token (TPOT) is het gemiddelde interval tussen opeenvolgende tokens na de eerste token. Dit correspondeert met de decodefase. Decode met batch size één of lage intensity is doorgaans memory-bandwidth-bound, terwijl voldoende grote batches compute-bound kunnen worden:

TPOT=E2E LatencyTTFTOutput Tokens1\text{TPOT} = \frac{\text{E2E Latency} - \text{TTFT}}{\text{Output Tokens} - 1}

Deze definitie vereist ten minste twee outputtokens; TPOT is undefined voor een response van één token.

De gemiddelde stille leessnelheid van volwassenen in het Engels bedraagt ongeveer 238 woorden per minuut voor non-fictie (Brysbaert, 2019). Streamingtargets moeten nog steeds uit producttests komen; MLPerf hanteert voor het interactieve scenario een P99 TPOT-limiet van \leq 40 ms.

P50 versus P99 latency is belangrijk omdat de mediaan de staart verbergt. Een systeem met een goede P50 en een slechte P99 kan problemen hebben met batching, preemption, queueing of workload skew; traces zijn nodig om deze oorzaken van elkaar te onderscheiden.

5. Throughput: tokens per second en de latency trade-off

Throughput wordt gemeten in output tokens per seconde over gelijktijdige requests. Requests per seconde is op zichzelf een minder goede maatstaf, omdat een response van 10 tokens en een response van 1.000 tokens zeer verschillende kosten hebben. Gepubliceerde benchmarkresultaten variëren afhankelijk van model, precision, hardware, prompt- en outputlengte, concurrency en SLO. Vergelijk vLLM, SGLang en TensorRT-LLM met één harness, in plaats van hun headline-resultaten te combineren.

De trade-off: bij lage concurrency krijgt elke request een lage latency, maar wordt de GPU onderbenut. Een grotere batch size verhoogt de throughput vrijwel lineair totdat de compute-capaciteit verzadigd is; daarna loopt de latency sterk op. Goodput, de requests per seconde die aan je SLO-doelen voldoen, verbindt raw throughput met wat gebruikers daadwerkelijk ervaren.

6. KV cache: de bottleneck achter de meeste andere bottlenecks

Tijdens autoregressive generation attendt elke nieuwe token op alle voorgaande tokens. De KV cache slaat de Key- en Value-projections van elke token in elke layer op, zodat O(n2)O(n^2) niet opnieuw hoeft te worden berekend. Zonder deze cache zou het genereren van token nn vereisen dat het model opnieuw over alle n1n-1 voorgaande tokens wordt uitgevoerd.

De KV cache kan bij lange sequence lengths of hoge concurrency de dominante bron van variabele memory pressure worden, omdat deze lineair groeit met de sequence length, batch size en het aantal layers:

KVcache=2×L×hkv×dh×s×B×bytesKVcache = 2 \times L \times h_{kv} \times d_h \times s \times B \times \text{bytes}

waarbij:

  • LL = aantal layers
  • hkvh_{kv} = aantal KV heads
  • dhd_h = head dimension
  • ss = sequence length
  • BB = batch size
  • bytes\text{bytes} = aantal bytes per gecached element, bepaald door de precision van de KV cache

Concrete voorbeelden met FP16 en batch size 1: Llama 3.1 8B gebruikt bij 8.192 tokens ongeveer 1,0 GB KV cache; bij 128K tokens 16 GB. Llama 3.1 70B heeft bij 128K tokens ongeveer 40 GB nodig voor één sequence, de helft van het VRAM van een H100. Bij hoge concurrency of een lange context kan de KV cache meer geheugen innemen dan de model weights; het resultaat hangt af van de sequence length, active batch size, KV precision en het aantal KV heads. Naïeve implementaties verspillen 60–80% van het gealloceerde KV-geheugen aan fragmentatie. Dat is het probleem waarvoor PagedAttention is ontwikkeld.

De belangrijkste optimalisaties zijn GQA (minder KV heads), quantization van de KV cache (FP8/INT8), PagedAttention (block-based allocation met <4% verspilling) en offloading van de KV cache naar CPU of NVMe.

7. Prefill versus decode: twee fasen, twee bottlenecks

De prefillfase verwerkt de inputprompt parallel en vult de KV cache. Lange of voldoende gebatchte prefills worden vaak compute-bound, omdat ze grote matrixvermenigvuldigingen gebruiken; korte prefills kunnen beperkt blijven door memory traffic of kernel-launch-overhead. Prefill draagt bij aan de time to first token (TTFT), naast queueing, tokenization, scheduling, de eerste decode-stap en network delivery. De decodefase genereert één token per keer. Elke stap leest model weights en de KV cache uit HBM, waardoor decode met batch size één memory-bandwidth-bound is en de belangrijkste factor vormt voor de time per output token (TPOT).

Prefill verwerkt prompt tokens parallel voordat decode outputtokens sequentieel genereert; TTFT omvat prefill en TPOT omvat de daaropvolgende decode-stappen.Prefill verwerkt prompt tokens parallel voordat decode outputtokens sequentieel genereert; TTFT omvat prefill en TPOT omvat de daaropvolgende decode-stappen.

Chunked prefill splitst de prompt op in chunks met een vaste grootte, in plaats van de prompt in één keer te verwerken. Een scheduler kan deze chunks afwisselen met decode-werk, zodat één lange prompt niet een volledige iteratie monopoliseert. Sarathi-Serve rapporteert betere throughput-latency trade-offs in de geteste workloads, maar de winst hangt af van het model, de hardware, de request-length distribution, de chunkgrootte en de comparison baseline. Extra scheduling en kleinere kernels kunnen de TTFT van het nieuwe request verhogen.

Disaggregated serving plaatst prefill en decode op afzonderlijke GPU-pools, zodat elke pool zich op een andere bottleneck kan richten. Splitwise en DistServe beschrijven dit patroon. De pools dragen KV-cachedata over via een snelle interconnect, zoals RDMA, waardoor de communicatiekosten onderdeel worden van het ontwerp.

8. GQA en MQA: de KV-cache verkleinen

Vergelijking van MHA, MQA en GQA: één KV-head per query-head, één gedeelde KV-head en gegroepeerd delen van KV-heads.Vergelijking van MHA, MQA en GQA: één KV-head per query-head, één gedeelde KV-head en gegroepeerd delen van KV-heads.

Standard Multi-Head Attention (MHA) geeft elke query-head een eigen K- en V-head. Multi-Query Attention (MQA) deelt één KV-head over alle query-heads; dit is een extreme reductie. Grouped-Query Attention (GQA) is de praktische middenweg: groepen query-heads delen één KV-head.

Llama 3 70B gebruikt 64 query-heads, maar slechts 8 KV-heads: een 8x kleinere KV-cache dan bij dezelfde architectuur met één KV-head per query-head. Llama 3.1 405B gebruikt 128 query-heads en 8 KV-heads, wat volgens dezelfde berekening neerkomt op een 16x reductie (Meta, 2024). Ainslie et al. rapporteren dat de kwaliteit van GQA in hun geteste modellen dicht bij die van MHA ligt, terwijl de snelheid die van MQA benadert. Een kleinere KV-cache kan grotere batches ondersteunen, maar de daadwerkelijk gerealiseerde latency- en throughputwinst hangt nog steeds af van de kernel en de workload.

9. Quantization: bits inruilen voor snelheid en geheugen

Quantization verlaagt de precisie van modelgewichten en/of activations. De belangrijkste trade-offs:

FormatBitsWeight memory (7B model)Quality note
FP16/BF1616~14 GBBaseline for comparison
FP88~7 GBHardware-native on Hopper; evaluate model
INT88~7 GBCalibration and kernel dependent
INT44~3.5 GBLargest compression; evaluate carefully

AWQ (Activation-Aware Weight Quantization) identificeert belangrijke weight channels op basis van activation magnitudes en past per-channel scaling toe om deze te beschermen. De calibratievereisten hangen af van het model en de configuratie; in één OPT-6.7B INT3-g128-vergelijking gebruikte AWQ 16 calibration sequences, tegenover 192 voor GPTQ. Rapporteer in een reproduceerbare setup zowel het aantal sequences als de sequence length. GPTQ gebruikt approximate second-order information voor layer-wise quantization. bitsandbytes kan tijdens het laden van het model quantizen, zonder afzonderlijke preprocessing pass; het NF4-format vormt de basis voor QLoRA fine-tuning. FP8 halveert op Hopper-class hardware het weight memory-verbruik ten opzichte van FP16/BF16, maar kwaliteit en snelheid blijven afhankelijk van het model, de calibratie en de kernel.

De serving kernel kan net zo belangrijk zijn als het quantization-algoritme. Section 10 geeft een begrensd Marlin-resultaat en legt uit waarom de winst afhankelijk is van de serving configuration.


Part III — Inference-optimalisaties

De optimalisaties in dit deel lossen verschillende knelpunten op. FlashAttention vermindert het HBM-verkeer van attention; PagedAttention verbetert de KV-allocatie; continuous batching voorkomt dat voltooide sequences batchcapaciteit bezet houden.

10. CUDA-kernels en kernel fusion

Een CUDA-kernel is een functie voor de GPU die parallel over duizenden threads wordt uitgevoerd. Wanneer de CPU een kernel aanroept, verdeelt de GPU het werk over zijn SMs: elke SM voert meerdere warps van 32 threads uit en elke thread verwerkt een deel van de data. Elke operatie in LLM-inference, van matrix multiplication tot token sampling, resulteert uiteindelijk in een kernel launch. Eén forward pass door een 70B-model activeert honderden tot duizenden kernel launches, en het verschil tussen een naïeve kernel en een geoptimaliseerde kernel kan bepalen of je systeem zijn latency SLO haalt.

De belangrijkste kernelcategorieën in LLM-serving:

  • GEMM-kernels voor matrix multiplication, die zowel de prefill- als de decode-compute domineren.
  • Attention-kernels zoals FlashAttention, die berekeningen tilen zodat ze in SRAM blijven in plaats van naar HBM te worden weggeschreven.
  • Fused kernels die meerdere operaties (zoals add + layer norm of QKV projection) combineren in één launch, zodat tussentijdse HBM round-trips worden overgeslagen.
  • Sampling-kernels die logits via top-k-, top-p- of temperature sampling omzetten naar token IDs.

De kwaliteit van kernels kan bepalen of compressed weights een speedup opleveren. Het Marlin-paper rapporteert voor de geteste weight-only INT4 vLLM-configuraties tot 2.8x end-to-end speedup ten opzichte van zijn FP16-baseline. Dat resultaat is specifiek voor de modellen, GPU’s, batch sizes en serving setup van het paper en is daarom geen universele INT4-winst.

Triton verlaagt de drempel voor het schrijven van custom kernels door GPU-programmering via Python aan te bieden in plaats van raw CUDA C++. Daardoor komt kernel-level optimalisatie binnen bereik van ML-engineers en niet alleen van GPU-specialisten. De meeste optimalisaties verderop in dit deel (FlashAttention, fused kernels, PagedAttention) zijn betere kernels of slimmere manieren om kernel launches te orkestreren.

Kernel fusion combineert sequentiële operaties tot één GPU-kernel en slaat tussentijdse HBM-writes over. Veelvoorkomende fusions zijn QKV-projectie, attention plus softmax, add plus RMSNorm (FlashNorm) en SwiGLU-activatie (DeepFusionKernel). Triton maakt deze kernels toegankelijk via Python. De exacte winst in het aantal kernel launches en de utilization hangt af van de modelgraph, compiler, GPU en serving framework. Profile daarom de gedeployde stack in plaats van uit te gaan van één universeel percentage.

11. FlashAttention: attention tilen zodat deze in SRAM past

Standard attention materialiseert de volledige N×NN \times N attention-matrix in HBM. Dat kost O(N2)O(N^2) geheugen en genereert veel memory traffic. Het idee achter FlashAttention is om deze matrix helemaal niet te materialiseren. De Q-, K- en V-matrices worden opgedeeld in blocks die in SRAM passen. Binnen elke tile wordt gedeeltelijke attention berekend en worden de resultaten samengevoegd met een online softmax, waarbij de running max en som incrementeel over de blocks worden bijgehouden. Het geheugengebruik daalt van O(N2)O(N^2) naar O(N)O(N) en het aantal HBM-reads daalt met een orde van grootte.

Elke versie richt zich op de bottleneck van zijn GPU-generatie:

  • FlashAttention v1 (A100, 2022) liet zien dat het idee van tiling plus online softmax werkt. Het paper rapporteerde een speedup van 2–4x ten opzichte van standard attention, maar slechts 25–40% GPU-utilization, omdat de kernel scheduling veel SMs idle liet.
  • FlashAttention v2 (A100, 2023) herontwierp de parallelism door over de sequence-dimensie te sharden in plaats van over batch en heads. De implementatie bereikte 50–73% utilization op de A100 en was ongeveer 2x sneller dan v1.
  • FlashAttention v3 (H100 Hopper, 2024) voegde warp specialization toe, met afzonderlijke warps voor data movement en math, plus GEMM-softmax pipelining om memory loads en computation te overlappen. Het paper rapporteert tot 740 TFLOPS/s in FP16 (75% utilization) en bijna 1,2 PFLOPS/s in FP8 op de H100. NeurIPS 2024 spotlight.
  • FlashAttention v4 (B200 Blackwell, 2026) adresseert een nieuwe bottleneck: op Blackwell schaalt de tensor-core throughput zo snel dat non-matmul-operaties, zoals softmax-exponentials en rescaling, de limiter worden. FA4 emuleert de exponential in software met polynomial approximations op FMA-units, gebruikt conditional rescaling om overhead te beperken en slaat intermediates op in Blackwells dedicated tensor memory (TMEM) in plaats van registers. Het paper rapporteert ongeveer 1,6 PFLOPS op de B200 in BF16, 1,3x sneller dan cuDNN 9.13 en 2,7x sneller dan Triton in de tests.

12. FlashDecoding: de decode-bottleneck paralleliseren

Standard FlashAttention houdt de GPU bezet door het werk op te splitsen over batch size en query length. Tijdens decode genereert het model precies één token per keer (query length = 1). Als de batch size maal het aantal attention heads kleiner is dan het totale aantal SMs van de GPU (108 op een A100), blijft het grootste deel van de GPU idle terwijl enkele units de tokengeschiedenis sequentieel verwerken.

FlashDecoding lost dit op door een nieuwe dimensie voor parallelisatie toe te voegen: de KV-sequentielengte zelf. De KV-cache wordt in kleinere chunks opgesplitst en over alle anders inactieve GPU-processors verdeeld om de chunks parallel te evalueren. Vervolgens worden de partiële berekeningen samengevoegd met een log-sum-exp-reductie.

In Stanford’s CodeLlama-34B-benchmark met sequentielengtes van 512 tot 64K tokens behaalde FlashDecoding tot 8x end-to-end speedup ten opzichte van de geteste baselines en bleef de attention-latency tot 64K tokens vrijwel constant. Dit resultaat is gebonden aan die hardware en benchmark en vormt geen algemene garantie voor decode-performance.

13. Continuous batching versus static batching

Static batching wacht tot elke sequentie in een batch is voltooid voordat de volgende batch wordt gestart. Korte sequenties verspillen daardoor GPU-cycli terwijl ze inactief wachten nadat ze het einde van de sequentie hebben bereikt. Continuous batching (geïntroduceerd in het Orca-paper, OSDI 2022) werkt op iteration-level granularity: bij elke decode-stap worden voltooide sequenties verwijderd en nieuwe toegevoegd.

In Anyscale’s OPT-13B-benchmark behaalde geoptimaliseerde static batching 4x de naive baseline, continuous batching 8x en vLLM met continuous batching plus PagedAttention 23x (Anyscale, 2023). Continuous batching verhoogt ook de druk op KV allocation. Daarom wordt het vaak gecombineerd met paged memory management.

14. PagedAttention: virtual memory voor KV-cache

vLLM’s PagedAttention past het OS-concept van virtual memory toe op KV-cachemanagement. De KV-cache wordt opgesplitst in blocks met een vaste grootte (doorgaans 16 tokens). Blocks worden tijdens het genereren van tokens on demand gealloceerd, en logische (sequentiële) posities worden via block tables aan fysieke (verspreid opgeslagen) geheugenlocaties gekoppeld. Meerdere requests met een gedeelde prefix (zoals system prompts of beam search) kunnen naar dezelfde fysieke blocks verwijzen.

Eerdere systemen verspilden 60–80% van het KV-cachegeheugen aan fragmentation en pre-allocation. PagedAttention verlaagt dit tot <4%, waardoor de throughput bij dezelfde latency met 2–4x kan stijgen en tot 24x hoger kan liggen dan bij HuggingFace Transformers (vLLM Blog, 2023).

15. Speculative decoding: meerdere tokens per forward pass

Flow van speculative decoding waarin een draft model tokens voorstelt, het target model deze parallel scoort en rejection sampling een prefix accepteert of een correctie genereert.Flow van speculative decoding waarin een draft model tokens voorstelt, het target model deze parallel scoort en rejection sampling een prefix accepteert of een correctie genereert.

Bij speculative decoding genereert een klein draft model KK kandidaat-tokens. Vervolgens scoort het grote target model alle KK posities in één forward pass. De decoder accepteert draft-tokens van links naar rechts met probabilities die uit de target- en draft-distributies zijn afgeleid. Na de eerste rejection samplet het model een correctie uit de residual target-distributie en worden de resterende draft-tokens verworpen. Deze aangepaste rejection-samplingstap behoudt de outputdistributie van het target model binnen de numerieke precisie van de hardware; exact overeenkomende tokens op zichzelf doen dat niet.

De winst is het meest aannemelijk bij kleine serving batches en korte draft-lengtes, wanneer het scoren van de draft vooral wordt gedomineerd door weight-, KV-cache- of communication traffic, en niet door de extra token compute. De oorspronkelijke paper over speculative sampling rapporteerde een decoding speedup van 2–2,5x voor de geteste 70B Chinchilla-configuratie; EAGLE-3 rapporteerde in zijn tests tot 6,5x. Varianten zijn onder andere Medusa (extra prediction heads, zonder afzonderlijk model), prompt lookup decoding (n-gram matching tegen de input, zonder een afzonderlijke forward pass van een draft model) en EAGLE (extrapolatie op feature-niveau).

Bij hoge batch sizes kunnen extra draft- en verification-work de winst tenietdoen. Speculative decoding is het veelbelovendst wanneer de serving batch klein genoeg is en de draft acceptance hoog is; benchmark de volledige serving loop in plaats van alleen de verification kernel.

16. Prefix caching en hergebruik van de KV-cache

In plaats van de KV-cache weg te gooien wanneer een request is voltooid, houdt prefix caching deze beschikbaar voor hergebruik bij nieuwe requests met dezelfde prefix-tokens. Dit voorkomt redundante prefill voor system prompts, few-shot examples, RAG-context en de conversatiegeschiedenis van multi-turn gesprekken.

Automatic Prefix Caching van vLLM hasht KV-blocks en gebruikt een globale hash table voor lookup. RadixAttention van SGLang onderhoudt een radix tree van gecachte KV-tensors met token-level granulariteit. Beide zijn afhankelijk van herhaalde, token-identieke prefixes. Rapporteer daarom de hit rate naast latency of throughput.

17. Streaming in de praktijk

Streaming stuurt tokens naar de client terwijl ze worden gegenereerd, in plaats van te wachten op de volledige response. Veel serving frameworks bieden dit aan via Server-Sent Events: de client opent een langdurige HTTP-verbinding en de server pusht elke token of token batch als een data:-event. TTFT bepaalt wanneer de gebruiker voor het eerst output ziet; TPOT helpt bepalen hoe vloeiend dat aanvoelt. Stel het doel vast via producttests en het gekozen interaction model.

Aan de clientzijde dwingt streaming keuzes over buffering af. Token-voor-token renderen kan visuele jitter veroorzaken, vooral bij markdown of codeblokken die multi-token context nodig hebben om correct te worden geformatteerd. Veelgebruikte patronen zijn word-level buffering (tokens verzamelen tot een whitespace boundary), line-level buffering (wachten op een newline voordat er wordt gerenderd) en adaptive buffering (proza direct renderen en codeblokken bufferen). In de OpenAI Chat Completions API voegt stream_options: {"include_usage": true} een laatste usage chunk toe vóór het data: [DONE]-message. OpenAI-compatible servers kunnen hiervan afwijken; controleer daarom de geselecteerde implementatie.

Chunked prefill is een manier om te voorkomen dat lange prefills de token delivery voor gelijktijdige gebruikers blokkeren. Decode-priority scheduling kan in-flight requests beschermen, terwijl disaggregated serving prefill en decode op afzonderlijke GPU-pools isoleert.


Deel IV — Modelarchitectuur

Architectuur bepaalt de memory footprint, het attention-gedrag en de training dynamics waar de secties over serving en training omheen werken.

18. Essentiële onderdelen van de Transformer-architectuur

Een moderne decoder-only transformer (GPT, Llama) bestaat uit een stack van identieke lagen, die elk twee subblokken bevatten: attention en feed-forward. Elk subblok is voorzien van een residual connection en normalization. De belangrijkste componenten:

Multi-Head Attention laat elk token informatie wegen uit de tokens die volgens het attention mask zichtbaar zijn. De input wordt geprojecteerd naar drie matrices: Queries (waar ben ik naar op zoek?), Keys (wat bevat ik?) en Values (welke informatie draag ik?). Vervolgens worden de attention-scores berekend als:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

Het QKTQK^T dotproduct meet de overeenkomst tussen elk paar tokens. Delen door dk\sqrt{d_k} voorkomt dat de dotproducten te groot worden (waardoor softmax in gebieden met verdwijnende gradients terecht zou komen). Softmax zet de scores om in probabilities, en vermenigvuldiging met VV levert een gewogen combinatie van value vectors op. Door dit parallel over meerdere heads uit te voeren, kan het model tegelijkertijd op verschillende relaties letten (één head voor syntax, een andere voor coreference, enzovoort).

Het Feed-Forward Network (FFN) transformeert elke tokenrepresentatie onafhankelijk nadat attention informatie over tokens heeft gemengd. Moderne LLM’s gebruiken vaak SwiGLU in plaats van de oorspronkelijke ReLU-FFN met twee matrices:

SwiGLU(x)=(Swish(xWgate)xWup)Wdown\text{SwiGLU}(x) = \left(\text{Swish}(xW_{gate}) \odot xW_{up}\right)W_{down}

SwiGLU heeft drie weight matrices, tegenover twee voor een ReLU-FFN, en gebruikt de smooth Swish-activatiefunctie. Llama, Mistral en Qwen gebruiken deze variant; Gemma gebruikt een approximate GeGLU. De bekende two-thirds rule geldt voor een conventioneel full-MHA-blok met dff4dd_{ff} \approx 4d: de twee FFN-matrices dragen ongeveer 8d28d^2 parameters bij, tegenover ongeveer 4d24d^2 voor attention. Dit is geen algemene schatting voor SwiGLU/GQA-architecturen. In Llama 3 8B maken d=4,096d=4{,}096, dff=14,336d_{ff}=14{,}336 en acht key/value-heads de FFN 3d×dff1763d \times d_{ff} \approx 176M parameters per layer, tegenover ongeveer 42M attention-projection-parameters: ongeveer 81% van die projection-weights, vóór embeddings en normalization.

Residual connections tellen de output van elk subblok op bij de input: Output=Input+Sublayer(Input)\text{Output} = \text{Input} + \text{Sublayer}(\text{Input}). Het skip path verbetert de propagatie van signalen en gradients door diepe stacks.

RMSNorm komt veel voor in moderne LLM-families. LayerNorm centreert opnieuw door het gemiddelde af te trekken en schaalt vervolgens met de standaarddeviatie. RMSNorm slaat het aftrekken van het gemiddelde over en schaalt alleen opnieuw; het bijbehorende paper rapporteert 7–64% speedup voor de geteste modellen, zonder performanceverlies in die experimenten. Ook pre-norm-plaatsing, waarbij vóór attention of de FFN wordt genormaliseerd, is gebruikelijk omdat dit de gradient stability verbetert.

Parameter count estimation voor een decoder-only model:

TotalV×d+12×L×d2\text{Total} \approx V \times d + 12 \times L \times d^2

waarbij VV de vocabulary size is, dd de hidden dimension en LL het aantal layers. De term V×dV \times d is de input-embeddingmatrix; de term 12×d212 \times d^2 benadert de attention- en FFN-weights in elke layer. Voor Llama 3 8B (V=128,256V=128{,}256, d=4,096d=4{,}096, L=32L=32) komt de schatting uit op ongeveer 0.53B+6.44B=6.97B0.53B + 6.44B = 6.97B parameters. Het gepubliceerde totaal van 8.03B ligt hoger omdat de benadering architectuurdetails weglaat, zoals de exacte FFN-width en de afzonderlijke output projection.

19. Decoder-only-modellen voor general-purpose generatie

De oorspronkelijke Transformer (2017) had zowel een encoder als een decoder. Sindsdien is het veld opgesplitst in drie architectuurfamilies, waarvan er één de standaard werd voor generative AI.

Encoder-only-modellen (BERT, RoBERTa) gebruiken bidirectional attention: elke token attendt in beide richtingen op elke andere token. Dat levert rijke representaties op voor understanding-taken (classificatie, NER, semantic similarity), maar ze kunnen niet autoregressief tekst genereren. Encoder-only-modellen worden nog steeds veel gebruikt als backbone voor embedding-modellen, rerankers en lightweight classifiers (bijvoorbeeld de op BERT gebaseerde routers in RouteLLM).

Encoder-decoder-modellen (T5, BART, de oorspronkelijke Transformer) scheiden understanding van generation. De encoder verwerkt de volledige input met bidirectional attention, waarna de decoder output autoregressief genereert en via cross-attention de representaties van de encoder gebruikt. Dit bood een natuurlijk voordeel voor sequence-to-sequence-taken zoals vertaling, waarbij input en output verschillende sequences zijn. Google’s T5 liet zien dat elke NLP-taak als text-to-text kon worden geformuleerd, en encoder-decoder-modellen vormen nog steeds de basis van gespecialiseerde systemen (Whisper voor speech recognition, FLAN-T5 voor instruction following).

Decoder-only-modellen (GPT, Llama, Mistral, Gemini) gebruiken causal (unidirectional) attention: elke token attendt alleen op eerdere tokens. Ze worden veel gebruikt voor general-purpose text generation, omdat één causal language-model objective kan schalen over ongepaarde tekst, terwijl inference instructies, few-shot-demonstraties en de query behandelt als tokens in één prefix. Het herhaalde decoder block vermijdt bovendien een aparte encoder stack en een cross-attention-pad. Encoder-decoder-modellen blijven nuttig wanneer een taak baat heeft bij het afzonderlijk encoden van de input en generation op basis van die representatie, waaronder vertaling en speech recognition.

20. Mixture of experts

MoE vervangt de dense FFN in elke transformerlaag door meerdere kleinere expert-FFN’s plus een lightweight gating router. De router berekent per expert een score (doorgaans een softmax over geleerde linear projections) en selecteert per token de top-kk experts. Alleen de geactiveerde experts voeren berekeningen uit, zodat een model een enorme totale capaciteit kan hebben terwijl de kosten per token laag blijven. Dit is sparse conditional computation: het totale aantal parameters bepaalt wat het model kan representeren, en de actieve parameters bepalen wat het kost om het uit te voeren.

ModelTotal ParamsActive ParamsExperts (Routed + Shared)Top-kk
Mixtral 8x7B47B~13B8 + 02
DeepSeek-V3671B37B256 + 18

De shared expert in DeepSeek-V3 wordt voor elke token geactiveerd. Deze levert een baseline-representatie waarop de routed experts zich verder kunnen specialiseren.

Training van MoE-modellen kent drie terugkerende problemen: load imbalance, expert collapse en communicatie-overhead voor expert parallelism. Traditionele MoE-modellen voegen een auxiliary loss toe om imbalanced routing te bestraffen, maar die loss kan concurreren met de hoofddoelstelling. DeepSeek-V3 gebruikt voornamelijk een batch-wise strategie zonder auxiliary loss: bias-termen buiten backpropagation verlagen de score van overbelaste experts en verhogen de score van onderbenutte experts. Daarnaast wordt een uiterst kleine, complementaire sequence-wise balance loss toegepast om extreme imbalance binnen een sequence te voorkomen. De paper rapporteert in de beschreven setup een betere routing balance zonder de trade-off van de belangrijkste auxiliary loss.

21. Tokenization: BPE, SentencePiece en tiktoken

LLM’s zien geen tekst. Ze zien sequences van gehele token-ID’s. Een tokenizer splitst ruwe tekst op in tokens (subword pieces) en koppelt elk token aan een ID. De keuze van de tokenizer beïnvloedt de modelkwaliteit, inferentiesnelheid en meertalige fairness.

Byte Pair Encoding (BPE) is het meest gebruikte algoritme. Het voegt iteratief de meest voorkomende aangrenzende paren in de training corpus samen. Een vereenvoudigd voorbeeld:

  1. Begin met een vocabulary op character-niveau: [l, o, w, e, r, _]
  2. Het meest voorkomende paar is (l, o) → voeg samen tot lo → vocabulary: [l, o, w, e, r, _, lo]
  3. Het volgende meest voorkomende paar is (lo, w) → voeg samen tot low → de vocabulary krijgt low erbij
  4. Ga door totdat de vocabulary de gewenste omvang bereikt (bijvoorbeeld 128K tokens)

Veelvoorkomende woorden zoals “the” worden één token, terwijl zeldzame woorden zoals “defenestration” worden opgesplitst in subword pieces zoals ["def", "en", "est", "ration"]. De trade-off is die tussen vocabulary-grootte en sequence-lengte.

Drie tokenizer-implementaties dekken het grootste deel van production use-cases:

  • SentencePiece wordt rechtstreeks op ruwe Unicode-tekst getraind, zonder language-specific pre-tokenizer. Het behoudt whitespace met het -meta-symbool en kan optioneel terugvallen op UTF-8 byte-tokens. Het ondersteunt zowel BPE- als unigram-modellen en wordt gebruikt door Llama 1/2, T5 en Mistral.
  • tiktoken is de op Rust gebaseerde tokenizer van OpenAI, die byte-level BPE gebruikt. In de gepubliceerde GPT-2-benchmark draaide deze 3–6x sneller dan de geteste configuratie van GPT2TokenizerFast. Llama 3 stapte over van SentencePiece naar het algoritme van tiktoken.
  • Hugging Face Tokenizers is een veelgebruikte, op Rust gebaseerde library die BPE, WordPiece en Unigram ondersteunt.

Fertility meet hoeveel tokens een tokenizer produceert per woord of andere gekozen teksteenheid. Dit varieert afhankelijk van de exacte tokenizer, taal, script, normalisatie, het domein en de sample. Meet dit op representatief verkeer in plaats van het af te leiden uit één tokenizer of taal.

22. Context windows en positional encodings

Het context window is het maximale aantal tokens dat een model in één forward pass kan verwerken. Dit is sterk toegenomen:

ModelContext windowJaar
Llama 12,0482023
Llama 3.1128K2024
GPT-4.11,047,5762025
Gemini 2.5 Pro1,048,5762025

Unmasked self-attention is permutation-equivariant: als je de inputtokens herschikt, worden de outputs op dezelfde manier herschikt. Het causale mask van een decoder beperkt elke token al tot zijn prefix, waardoor het omkeren van een zin niet tot identieke hidden states leidt. Positional encodings voegen expliciete informatie toe over positie en relatieve afstand binnen die zichtbare prefix.

Drie veelgebruikte benaderingen zijn:

  • RoPE (Rotary Position Embeddings) roteert query- en key-vectoren met positieafhankelijke hoeken, zodat hun dotproduct afhangt van de relatieve positie. De tokeninhoud bepaalt nog steeds de attention score; RoPE voegt positie-informatie toe zonder learned absolute-position embeddings. Het wordt gebruikt door open model families zoals Llama, Mistral en Qwen.

  • ALiBi (Attention with Linear Biases) wijzigt embeddings niet, maar voegt rechtstreeks een penalty toe aan attention scores: hoe verder twee tokens van elkaar verwijderd zijn, hoe groter de negatieve bias. Het heeft geen learned positional parameters. In het oorspronkelijke paper presteerde een 1.3B-model dat was getraind met sequences van 1.024 tokens bij 2.048 tokens vergelijkbaar met een model met sinusoidal positions dat op 2.048 tokens was getraind. Het gedrag buiten de modellen en lengtes die in het paper zijn getest, is modelafhankelijk.

  • YaRN (Yet another RoPE extensioN) breidt een RoPE-model uit voorbij zijn training context. Het deelt frequentiedimensies op in drie categorieën en schaalt elke categorie anders. Het paper rapporteert 10x minder fine-tuning tokens en 2,5x minder training steps dan de baseline voor position interpolation.


Deel V — Training en alignment

Dit deel maakt onderscheid tussen het objective dat capabilities creëert, de technieken die ervoor zorgen dat training op de beschikbare hardware past, en de methoden die het gedrag van een model daarna vormgeven.

23. Pretraining, fine-tuning en alignment

Trainingspipeline van next-token pretraining via supervised fine-tuning en preference alignment, met distillation als afzonderlijk teacher-to-student-pad.Trainingspipeline van next-token pretraining via supervised fine-tuning en preference alignment, met distillation als afzonderlijk teacher-to-student-pad.

Pretraining is self-supervised next-token prediction op een groot corpus. De benodigde compute omvat vele ordes van grootte; Llama 3 405B gebruikte bijvoorbeeld 3.8×10253.8 \times 10^{25} FLOPs. Supervised fine-tuning (SFT) past het pretrained model aan voor taakspecifieke gelabelde data. RLHF / RLAIF gebruikt preference data om gedrag vorm te geven: een conventionele RLHF-pipeline verzamelt vergelijkingen, traint vervolgens een reward model en optimaliseert daarna het policy model. RLAIF vervangt een deel van de menselijke beoordelingen door door AI gegenereerde feedback.

Compute is afhankelijk van modelgrootte, sequence length, datavolume, optimizer en methode. PPO houdt ook meer model state bij dan SFT, omdat een typische setup policy-, reference-, reward- en critic-modellen bevat. Het volledige decision framework voor fine-tuning heb ik behandeld in LLM Fine-Tuning Guide.

24. LoRA en QLoRA: parameter-efficient fine-tuning

LoRA bevriest de pretrained weights en voegt trainable low-rank matrices AA (r×kr \times k) en BB (d×rd \times r) toe, zodat de geüpdatete weight W0+BAW_0 + BA wordt. Het LoRA-paper reduceerde GPT-3 175B in de beschreven setup tot ongeveer 18 miljoen trainable parameters. Rank is een tuning parameter, geen regel voor task complexity; selecteer deze met een quality- en memory-sweep. LoRA-adapters kunnen na training in de base weights worden gemerged, zodat inference geen afzonderlijk adapter path nodig heeft.

QLoRA laadt het base model met 4-bit NF4-quantization en traint LoRA-adapters in BF16. NormalFloat4 plaatst meer quantization levels rond nul, waar de weight density het hoogst is. Het paper fine-tunede een 65B-model op één GPU van 48 GB en rapporteerde resultaten die dicht bij de 16-bit baselines lagen. De runtime- en memory trade-offs zijn specifiek voor de geteste stack.

25. Mixed-precision training

Elk floating-point format verdeelt zijn bits over drie velden: sign (altijd 1 bit), exponent (bepaalt het dynamische bereik) en mantissa (bepaalt de precisie). Meer exponentbits betekenen een groter bereik van representable magnitudes; meer mantissabits betekenen fijnere onderscheidingen tussen nabije waarden. Integer formats hebben helemaal geen exponent en representeren alleen gelijkmatig verdeelde gehele getallen binnen een vast bereik.

FormatBitsLayout (S / E / M)BereikPrecisieVeelgebruik
FP32321 / 8 / 23±3.4×1038\pm 3.4 \times 10^{38}~7 decimale cijfersMaster weights, optimizer states (Adam momentum & variantie)
BF16161 / 8 / 7±3.4×1038\pm 3.4 \times 10^{38}~2 decimale cijfersVoorkeursformaat voor training; hetzelfde bereik als FP32 en doorgaans geen loss scaling
FP16161 / 5 / 10±65,504\pm 65{,}504~3 decimale cijfersTraining met loss scaling (oudere GPU’s); inference op hardware van vóór Hopper
FP8 E4M381 / 4 / 3±448\pm 448~1 decimaal cijferForward pass op Hopper (H100) — meer precisie voor weights & activations
FP8 E5M281 / 5 / 2±57,344\pm 57{,}344~0,6 decimaal cijferBackward pass op Hopper — groter bereik voor gradients
INT88fixed-point128-128 tot 127127Exacte gehele getallenPost-training weight quantization voor inference (W8A8); KV-cache-quantisatie
INT44fixed-point8-8 tot 77Exacte gehele getallenAgressieve weight-only quantization (AWQ, GPTQ) voor inference op hardware met beperkte geheugencapaciteit

BF16 heeft hetzelfde bereik als FP32, omdat het bereik wordt bepaald door het exponentveld en BF16 alle 8 exponentbits van FP32 behoudt. In plaats daarvan levert het mantissebits in (7 tegenover 23), waarmee het precisie inruilt voor een halvering van het geheugengebruik en veel range-problemen bij FP16-training voorkomt. FP16 heeft slechts 5 exponentbits, waardoor het eindige bereik wordt beperkt tot ongeveer 65K. Veel gradients zijn voor FP16 juist te klein en underflowen richting nul. Loss scaling vermenigvuldigt de loss vóór backpropagation, zodat deze gradients representabel blijven, en schaalt ze vóór de optimizer step weer terug; dynamic scaling verlaagt de factor als er overflow optreedt. Het grotere exponentbereik van BF16 maakt dit doorgaans overbodig.

Integer-formaten worden zelden gebruikt voor de belangrijkste training arithmetic, omdat backpropagation een groot dynamisch bereik nodig heeft. Ze worden wel veel gebruikt voor inference, waarbij frozen weights aan calibrated scales kunnen worden gekoppeld. INT4 weight quantization verkleint een 7B-model van ongeveer 14 GB naar 3,5 GB vóór runtime-overhead; de kwaliteit moet worden gemeten voor het gekozen model en de gekozen methode.

FP8-training op H100 via Transformer Engine gebruikt E4M3 waar precisie belangrijk is en E5M2 waar een groter bereik belangrijk is. De FP8-LM-paper rapporteert dat het mixed-precision-framework GPT-175B 75% sneller trainde dan de BF16 Megatron-LM-baseline en 37% sneller dan NVIDIA Transformer Engine onder de geteste H100-configuratie. DeepSeek-V3 gebruikte mixed precision met FP8 en rapporteerde ongeveer $5,6 miljoen aan huur-equivalente compute voor de uiteindelijke training run, exclusief R&D en infrastructuur.

26. Gradient checkpointing

Elke laag van de forward pass produceert een tussentijdse output die een activation wordt genoemd:

Input[Layer 1]activation1[Layer 2]activation2[Layer 3]output\text{Input} \rightarrow [\text{Layer 1}] \rightarrow \text{activation}_1 \rightarrow [\text{Layer 2}] \rightarrow \text{activation}_2 \rightarrow [\text{Layer 3}] \rightarrow \text{output}

Normaal gesproken moeten alle activations in het geheugen blijven, omdat backpropagation ze nodig heeft om gradients te berekenen. Bij een diepe transformer kunnen de opgeslagen activations meer geheugen innemen dan de model weights zelf.

Gradient checkpointing ruilt compute in voor geheugen door het merendeel van die activations weg te gooien en ze tijdens backpropagation on the fly opnieuw te berekenen. De standaardstrategie (Chen et al., 2016) verdeelt een network van nn layers in n\sqrt{n} gelijkmatig verdeelde segments en slaat alleen de boundary activation van elk segment op. Deze opgeslagen boundaries zijn de “checkpoints”. Alle intermediate activations binnen een segment worden onmiddellijk verwijderd.

Wanneer de backward pass een layer binnen een segment bereikt, worden de activations ervan opnieuw berekend vanaf het dichtstbijzijnde checkpoint. Bij de gelijkmatig gesegmenteerde strategie daalt het geheugengebruik voor opgeslagen activations van O(n)O(n) naar O(n)O(\sqrt{n}). De werkelijke memory savings en recomputation overhead hangen af van het model, de checkpoint boundaries, sequence length, framework en implementatie. Meet daarom beide tijdens de beoogde training run. FlashAttention past hetzelfde principe toe binnen attention door de volledige attention matrix niet te materialiseren. Schakel dit in HuggingFace in met gradient_checkpointing=True.

27. DeepSpeed ZeRO stages

Bij standaard data parallelism bevat elke GPU een complete kopie van de model weights, gradients en optimizer states. Bij Adam neemt elke parameter 2 bytes in beslag voor de FP16 weight + 4 bytes voor de FP32 master weight + 4 bytes voor momentum + 4 bytes voor variance + 2 bytes voor de gradient: 16 bytes per parameter. Een model met 7.5B parameters heeft ~120 GB per GPU nodig, en elke GPU slaat dezelfde gegevens op. Op 64 GPUs zijn dat 64 identieke kopieën van 120 GB. Dat is veel verspild geheugen.

DeepSpeed ZeRO (Zero Redundancy Optimizer) verwijdert deze duplicatie door deze componenten over de GPUs te sharden in plaats van ze te repliceren:

  • Stage 1 — partitioneer de optimizer states. Elke GPU slaat slechts 1/N van de optimizer states op (de FP32 master weights plus de eerste en tweede momenten van Adam, 12 bytes/param). Wanneer een GPU een weight moet updaten, werkt deze alleen zijn slice bij en broadcast het resultaat. Onder de onderstaande aannames daalt het geheugengebruik van ~120 GB naar ~41.3 GB per GPU.
  • Stage 2 — partitioneer ook de gradients. Gradients worden niet langer naar elke GPU all-reduced. Elke GPU ontvangt via reduce-scatter alleen de gradient slice die hij nodig heeft. Onder dezelfde aannames daalt het geheugengebruik naar ~28.1 GB per GPU.
  • Stage 3 — partitioneer ook de model weights. Elke GPU bevat slechts 1/N van de FP16 weights. Voor elke forward- of backward pass van een layer roept de GPU all-gather aan om de volledige layer weights tijdelijk uit alle andere GPUs te reconstrueren, voert de berekening uit en verwijdert de verzamelde weights. Onder dezelfde aannames daalt het geheugengebruik naar ~15.0 GB per GPU.
ConfiguratieOptimizer statesGradientsGewichtenGeschat geheugen voor model states per GPU (7,5B, 8 GPU’s)
Geen ZeROGerepliceerdGerepliceerdGerepliceerd~120 GB
Stage 1GepartitioneerdGerepliceerdGerepliceerd~41,3 GB
Stage 2GepartitioneerdGepartitioneerdGerepliceerd~28,1 GB
Stage 3GepartitioneerdGepartitioneerdGepartitioneerd~15,0 GB

Dit zijn benaderde waarden voor model states voor een model met 7,5 miljard parameters op 8 GPU’s (world size N=8N=8), met FP16-gewichten en -gradients en FP32-mastergewichten, momentum en variantie voor Adam. Activations, tijdelijke all-gather-buffers, allocator-fragmentatie en framework-/runtime-overhead zijn niet inbegrepen. De berekeningsgrens is 7.5B×7.5B \times bytes per parameter, waarbij elke state alleen door NN wordt gedeeld als de tabel deze als gepartitioneerd markeert.

De trade-off is communication. Stage 1 voegt minimale overhead toe en Stage 2 vervangt all-reduce door reduce-scatter tegen vergelijkbare kosten. Stage 3 vereist all-gather-calls vóór elke layer in zowel de forward- als backward-pass, met ongeveer 1,5× zoveel communication volume als bij standaard data parallelism.

ZeRO-Infinity breidt Stage 3 uit door gepartitioneerde states te offloaden naar CPU-RAM en zelfs NVMe-SSD’s. Daardoor kan het trainen van modellen met biljoenen parameters mogelijk worden op GPU-clusters met beperkte capaciteit. Storage offload brengt PCIe- en storage-transferkosten met zich mee; de gemeten impact hangt af van de drive, PCIe-topologie, partitionering, prefetch, transfer-overlap en workload. Gebruik dit om aan capaciteitsvereisten te voldoen in plaats van een vaste vertraging te veronderstellen, en profile de doelconfiguratie.

28. FSDP: PyTorch-native sharding

Fully Sharded Data Parallel (FSDP) is PyTorch’s ingebouwde tegenhanger van DeepSpeed ZeRO-3. Het shardt parameters, gradients en optimizer states over GPU’s volgens hetzelfde kernidee. De mechanics voor elke layer bestaan uit een eenvoudige loop:

  1. All-gather de volledige parameters van alle GPU’s (reconstrueer tijdelijk de volledige layer).
  2. Compute de forward- of backward-pass voor die layer.
  3. Free de verzamelde parameters onmiddellijk. Elke GPU bewaart alleen zijn eigen shard.
  4. Reduce-scatter de gradients, zodat elke GPU alleen zijn toegewezen slice van de gradients krijgt.

Omdat FSDP native is in PyTorch, integreert het rechtstreeks met PyTorch-debuggingtools, profilers en torch.compile. De performance ten opzichte van DeepSpeed ZeRO-3 hangt af van de wrapping policy, communication topology, offload-instellingen en modelgrootte. Vergelijk ze daarom op hetzelfde cluster.

CriteriaFSDP (PyTorch)DeepSpeed ZeRO
Control styleVolledige sharding via PyTorch-API’sSelecteerbare ZeRO-stages
OffloadingCPU-offloadingCPU + NVMe met ZeRO-Infinity
Framework integrationNative PyTorch, torch.compile-padenAfzonderlijke library en config-systeem
Selection testProfile de beoogde PyTorch-workloadProfile vereiste features en offloading

FSDP2 (2024–2025) is een rewrite die de integratie met torch.compile verbetert voor betere kernel fusion, FP8-training toevoegt via TorchAO en de API vereenvoudigt. Zowel FSDP als DeepSpeed zijn toegankelijk via HuggingFace Accelerate, waarmee je met één wijziging in de config tussen beide kunt schakelen.

29. Scaling laws en de Chinchilla-valkuil

Chinchilla scaling (DeepMind, 2022) wees onder de gehanteerde aannames op een compute-optimal allocatie van ongeveer 20 training tokens per parameter. Die objective houdt geen rekening met downstream serving-kosten. Als een kleiner model dat op meer data is getraind de vereiste kwaliteit bereikt, kan het gedurende een inference-lifecycle met hoge volumes minder kosten.

Een strategie voor lifecycle-kosten is om een kleiner model op veel meer data te trainen:

ModelParamsTraining TokensTokens/ParamTokens/param ÷ 20 (derived)
Chinchilla70B1.4T20:1
Llama 165B1.4T22:1
Llama 270B2.0T29:11.4×
Llama 3 8B8B15T1,875:194×
Qwen3-0.6B0.6B36T60,000:13.000×

Dit is de weergegeven tokens-per-parameter-ratio gedeeld door het benaderde punt van 20 tokens per parameter uit het Chinchilla-paper. Het is een descriptieve ratio, geen gemeten multiplier voor kwaliteit of kosten.

Voor een model dat op hoge volumes wordt geserved, kan extra training compute voor een kleiner model de lifecycle-kosten verlagen. Llama 3 8B illustreert deze strategie, maar of deze wint, hangt af van de vereiste kwaliteit en het verwachte inference-volume. “Chinchilla-optimal” verwijst naar efficiëntie van training compute, wat een andere objective is dan lifecycle-kosten.

30. RLHF, DPO, GRPO en het alignment-landschap

Alignment stuurt een pretrained model in de richting van gewenste instructies, voorkeuren en safety policies. Het biedt op zichzelf geen garantie voor truthfulness of veilig gedrag. De onderstaande methoden maken verschillende afwegingen tussen implementatiecomplexiteit, datavereisten, exploration en trainingsstabiliteit.

De klassieke RLHF-pipeline: SFT → menselijke preference pairs verzamelen → een reward model op die paren trainen → de policy fine-tunen met PPO (Proximal Policy Optimization). PPO houdt tegelijkertijd 4 modelkopieën in het geheugen (policy, reference, critic/value model en reward model) en is gevoelig voor hyperparameters. Het is ook vatbaar voor reward hacking, waarbij het model eigenaardigheden van het reward model uitbuit, zoals uitvoerige antwoorden die zelfverzekerd klinken, in plaats van de kwaliteit daadwerkelijk te verbeteren.

DPO (Direct Preference Optimization) slaat het geleerde reward model en de online RL-loop over door rechtstreeks een loss op preference pairs te optimaliseren. Dat vereenvoudigt de trainingspipeline. Standaard-DPO is offline: het traint op een fixed dataset en verkent tijdens de update-loop geen nieuwe responses. Of die beperking relevant is, hangt af van de taak en de dekking van de data.

GRPO (Group Relative Policy Optimization, DeepSeek) verwijdert de geleerde critic van PPO door per prompt meerdere completions te genereren en group-relative rewards als baseline te gebruiken. Dit vermindert de belasting van de model state ten opzichte van een gebruikelijke PPO-setup. In tegenstelling tot DPO is GRPO on-policy: het model genereert tijdens de training verse responses. DeepSeek-R1 combineert GRPO met RLVR (reinforcement learning from verifiable rewards) en gebruikt daarbij controles zoals wiskundige antwoorden, codecompilatie en unit tests. Deze rewards zijn eenvoudiger te auditen dan een geleerde preference score, maar onvolledige tests en proxy objectives kunnen nog steeds worden uitgebuit.

MethodeTypische model stateReward signalOnline/offlineBelangrijkste beperking
PPO4 (policy, ref, critic, reward)Geleerd reward modelOnlineReward hacking, complexe tuning
DPO2 (policy, reference)Impliciet (preference pairs)OfflineGeen exploration, fixed data
GRPO2 met rule rewards; 3 met learned reward (policy, reference, reward)Expliciet (rule/verifier of learned)OnlineAfhankelijk van reward quality en informatieve variatie binnen de groep

31. Distillation: kennis tussen modellen comprimeren

Knowledge distillation brengt capabilities over van een grote teacher naar een kleinere student. Logit-based distillation traint de student om de output distribution van de teacher te matchen. Bij data-based distillation genereert de teacher examples waarop de student vervolgens wordt gefinetuned. Data-based methoden zijn gebruikelijk voor LLM’s omdat ze over architecturen heen kunnen werken en met teachers die alleen via een API beschikbaar zijn, maar hun waarde wordt begrensd door de kwaliteit van de teacher, de dekking van de data, filtering en generation cost.

DeepSeek-R1 stelde een mixture samen van ongeveer 800.000 examples — circa 600.000 reasoning-gerelateerde samples en 200.000 non-reasoning-samples — en gebruikte die om Qwen2.5- en Llama 3-modellen met 1,5B tot 70B parameters te distilleren. In de evaluatie van het paper:

  • DeepSeek-R1-Distill-Qwen-32B scoort 72,6% op AIME 2024 en 94,3% op MATH-500, hoger dan de door het paper gerapporteerde scores van OpenAI o1-mini.
  • DeepSeek-R1-Distill-Qwen-7B scoort 55,5% op AIME 2024, hoger dan het resultaat van QwQ-32B-Preview in het paper, met een kleiner model.

In de experimenten met kleine modellen van DeepSeek-R1 presteerde distillation beter dan directe GRPO op de geteste basismodellen. Dat resultaat ondersteunt distillation voor deze setup; het stelt geen universele rangorde tussen distillation en RL vast.

32. Synthetic-data generation

LLM-gegenereerde trainingsdata wordt in verschillende terugkerende patronen gebruikt:

  • Self-Instruct begint met een kleine seedset van door mensen geschreven instructies: de LLM genereert nieuwe instructies, inputs en outputs, die worden gefilterd en weer aan de pool worden toegevoegd. Het project Alpaca gebruikte 52.000 voorbeelden die uit 175 seeds waren gegenereerd. Stanford rapporteerde datageneratie onder 500andfinetuningunder500 and fine-tuning under 100, waardoor de initiële reproductiekosten onder $600 lagen; de GPT-3.5-vergelijking was een beperkte projectevaluatie en geen brede equivalentieanalyse.
  • Evol-Instruct (WizardLM) neemt bestaande instructies en evolueert deze iteratief langs complexiteitsassen (constraints toevoegen, reasoning verdiepen en problemen concreter maken) om stapsgewijs moeilijkere trainingsexamples te produceren.
  • Microsoft’s Phi-4 (14B) gebruikte synthetic data voor een groot deel van de pretraining, waaronder generation, critique, self-revision en instruction reversal. Het technical report vergelijkt de resulterende STEM- en coding-prestaties met die van grotere modellen op de geselecteerde benchmarks.

Het relevante risico is hier model collapse: wanneer modellen recursief worden getraind op synthetic data uit eerdere generaties, verdwijnen de uiteinden van de oorspronkelijke distributie geleidelijk. Het model overschat veelvoorkomende patronen en verliest zeldzame maar belangrijke variaties (Shumailov et al., 2024). Een afzonderlijke Ahrefs classifier study samplede in april 2025 per domein één nieuw gedetecteerde Engelstalige pagina uit 900.000 pagina’s en classificeerde 74,2% als pagina’s met enige AI-gegenereerde tekst. Die vendor study is geen census van het web. Mitigatie begint met het combineren van synthetic en real data, filtering en lineage tracking, zodat recursief gegenereerd materiaal kan worden gemeten.


Part VI — Scaling and deployment

Zodra een workload niet langer op één device past of daar niet meer aan zijn SLO voldoet, zijn de keuzes hoe het werk wordt opgesplitst, welke runtime de benodigde controls biedt en of elke request hetzelfde model nodig heeft.

33. Four forms of parallelism

Vier parallelism-strategieën: data parallelism kopieert het model, tensor parallelism splitst layers, pipeline parallelism wijst stage-ranges toe en expert parallelism verdeelt experts.Vier parallelism-strategieën: data parallelism kopieert het model, tensor parallelism splitst layers, pipeline parallelism wijst stage-ranges toe en expert parallelism verdeelt experts.

Tensor Parallelism (TP) splitst individuele weight matrices over GPU’s en communiceert doorgaans na elke layer. Snelle intra-node links zoals NVLink maken dit het meest praktisch binnen één node. Meer shards verlagen het memory- en computegebruik per device, maar verhogen de communicatiekosten. Kies de degree daarom op basis van een latency benchmark.

Pipeline Parallelism (PP) verdeelt layers sequentieel over GPU’s en geeft activations door tussen stages. Het communicatiepatroon kan over nodes heen werken, maar pipeline bubbles en ongelijke stagelatenties verlagen de utilization. Grote deployments combineren TP binnen een node vaak met PP over nodes.

Data Parallelism (DP) repliceert het serving-model, zodat elke replica onafhankelijke requests afhandelt zonder cross-replica-communicatie per request. Dit is efficiënt wanneer het model past en de traffic kan worden gebalanceerd. Bij training wordt DP vaak gecombineerd met ZeRO of FSDP om state te sharden.

Expert Parallelism (EP) distribueert MoE-experts over GPU’s met all-to-all-communicatie voor token routing. De performance hangt af van tokenbalans, expert placement en interconnect-topologie; all-to-all-traffic kan de dominante bottleneck worden.

Een eerste parallelism-heuristiek:

  • Model past op één GPU: begin met onafhankelijke replicas en meet de DP-scaling.
  • Model past binnen één node: test TP binnen de node en replicate de groep vervolgens als de traffic dat vereist.
  • Model beslaat meerdere nodes: test een combinatie van TP en PP tegen de interconnect en de latency target.
  • Mixture of experts: voeg EP alleen toe wanneer expert placement dat vereist.

Decision flow die data-, tensor-, pipeline- of expert parallelism kiest op basis van model fit, nodegrenzen en een mixture-of-experts-architectuur.Decision flow die data-, tensor-, pipeline- of expert parallelism kiest op basis van model fit, nodegrenzen en een mixture-of-experts-architectuur.

34. Serving-frameworks vergeleken

vLLM biedt paged KV allocation, continuous batching, een OpenAI-compatibele API en meerdere parallelism-modi. De model- en hardwareondersteuning verandert regelmatig; controleer het targetmodel daarom aan de hand van de actuele compatibility matrix.

SGLang combineert RadixAttention voor prefix reuse, een custom scheduler en structured generation. De gepubliceerde throughput-winst hangt af van workload en configuratie; vergelijk SGLang met vLLM en TensorRT-LLM met identieke prompts, outputs, hardware en SLO’s.

TensorRT-LLM richt zich met CUDA graph fusion en kernel optimization op een lage latency per request en biedt native ondersteuning voor FP8/FP4. De gepubliceerde cijfers zijn hardware- en modelspecifiek. De trade-off is een steilere leercurve en een NVIDIA-specifiek deploymentoppervlak.

TGI integreert met het Hugging Face-ecosysteem en ondersteunt meerdere hardware-backends. Controleer de actuele maintenance- en featurestatus van de repository voordat je TGI voor een nieuwe deployment selecteert.

Ollama legt de nadruk op een eenvoudige lokale modelworkflow. Gebruik het voor ontwikkelgemak; benchmark een andere serving-stack wanneer hoge concurrency of expliciete SLO-control belangrijk is.

llama.cpp is een portable C/C++-runtime met paden voor ARM, x86, Metal, CUDA, ROCm en Vulkan. GGUF ondersteunt meerdere quantization-levels. De performance varieert sterk per model, quantization, context en backend; gebruik daarom de lokale benchmarktool voor de targetmachine.

35. GPU-selectie voor inference

De tabel vergelijkt gepubliceerde hardwarekarakteristieken. Precision-ondersteuning van de vendor maakt peak-compute-cijfers over verschillende formats niet direct vergelijkbaar. Selecteer daarom eerst op basis van memory fit en benchmark vervolgens de target-workload. Controleer actuele cloudprijzen afzonderlijk, omdat die variëren per provider, regio, commitment en beschikbaarheid.

GPUGeheugenBandbreedte
B200 SXM180 GB HBM3eTot 8 TB/s
H200 SXM141 GB HBM3e4.8 TB/s
H100 SXM80 GB HBM33.35 TB/s
A100 80 GB SXM80 GB HBM2e2.039 TB/s

Selecteer eerst op basis van de benodigde hoeveelheid geheugen en vervolgens op basis van gemeten throughput bij het latencydoel. De capaciteit van 141 GB van de H200 kan sommige deployments van grote modellen vereenvoudigen, terwijl de B200 ondersteuning voor FP4, 180 GB HBM3e en een nieuwere generatie NVLink toevoegt. Kleinere GPU’s op basis van GDDR kunnen kostenefficiënt zijn voor quantized modellen wanneer hun geheugen- en interconnectlimieten bij de workload passen.

AWQ en GPTQ ondersteunen 4-bitmodellen door ondersteunde matrixbewerkingen te dequantizen naar een computeformaat zoals FP16 of BF16. Compatibiliteit en snelheid blijven afhankelijk van de modelarchitectuur, het quantizationformaat, de serving-backend, de kernel en de GPU. Controleer daarom de supportmatrix van de backend en benchmark het exacte artifact. Hopper (H100/H200) en Ada (L40S/4090) versnellen FP8 native, en Blackwell (B200) voegt native FP4 Tensor Cores toe. Alle genoemde GPU’s ondersteunen INT8-matrixbewerkingen.

LLM-decode is vaak memory-bandwidth-bound, waardoor HBM-capaciteit en bandbreedte voor serving-workloads belangrijker kunnen zijn dan piek-TFLOPS. Vergelijk GPU’s terwijl model, precision, batchverdeling, contextlengte en latencydoel constant blijven.

36. Model cascading en routing

Model routing selecteert vóór uitvoering één model, terwijl cascading start met een goedkoper model en opschaalt wanneer de acceptance score te laag is.Model routing selecteert vóór uitvoering één model, terwijl cascading start met een goedkoper model en opschaalt wanneer de acceptance score te laag is.

Model routing bepaalt welk LLM elke query afhandelt op basis van de voorspelde complexiteit of capability. RouteLLM (LMSYS/UC Berkeley, ICLR 2025) rapporteert in de MT-Bench-opstelling een kostenreductie van 85%, terwijl 95% van de GPT-4-kwaliteitsbaseline behouden blijft. Of routing loont, hangt af van de huidige prijzen, de trafficmix, routerfouten en de minimale kwaliteitsdrempel.

Routers variëren van lightweight classifiers tot LLM-based judges. Cascading is de sequentiële variant: een query start bij een goedkoper model en schaalt op wanneer een scoringfunctie het antwoord afwijst. FrugalGPT rapporteert voor zijn geëvalueerde modelpool tot 98% lagere kosten of tot 4% hogere accuracy. Een production cascade vereist gekalibreerde escalatiecriteria en monitoring van queries die het goedkope model ten onrechte accepteert.


Part VII — Applications

Applications brengen hun eigen failure surfaces met zich mee. Retrieval kan mislukken voordat generation begint, agents kunnen een ongeldige actie kiezen en een promptwijziging kan de ene taak verbeteren terwijl een andere wordt verstoord.

37. Embeddingmodellen versus generatieve modellen

Embeddingmodellen coderen tekst naar vectoren met een vaste dimensionaliteit die semantische betekenis vastleggen. In tegenstelling tot generatieve modellen, die tokenreeksen produceren, geven ze voor de input één dense vector terug, doorgaans met enkele honderden tot enkele duizenden dimensies. Hun backbones omvatten bidirectionele encoder-only transformers en van decoders afgeleide modellen die zijn aangepast voor representation learning. Een poolinglaag reduceert representaties per token vaak tot één vector via mean pooling, een speciaal classification token of een modelspecifieke methode op basis van het laatste token. Contrastive fine-tuning brengt semantisch vergelijkbare teksten vervolgens dichter bij elkaar en duwt niet-vergelijkbare teksten verder uit elkaar.

Huidige embeddingsystemen voorzien in verschillende deploymentbehoeften. Qwen3-Embedding-8B ondersteunt configureerbare outputdimensies en veel talen. Gemini Embedding 2 accepteert tekst, afbeeldingen, video, audio en documenten. pplx-embed-v1-4B onderzoekt dense embeddings met lagere precisie. OpenAI text-embedding-3-large ondersteunt verkorte embeddings via de parameter dimensions. Dit zijn voorbeelden, geen rangschikking: evalueer taal, modaliteit, taak, dimensionaliteit en servingkosten op één retrievalset.

Matryoshka Representation Learning (MRL, Kusupati et al., NeurIPS 2022) maakt embeddingdimensies flexibel. MRL is vernoemd naar Russische matroesjka’s en structureert een embedding zo dat de eerste mm dimensies even informatief zijn als een onafhankelijk getraind model met mm dimensies. Tijdens training aggregeert MRL losses over een gekozen O(logd)O(\log d)-set van prefixdimensies, doorgaans consistente halveringen; het voorbeeld in het paper met 2048 dimensies gebruikt {8,16,,1024,2048}\{8, 16, \ldots, 1024, 2048\}. De geaggregeerde loss zorgt ervoor dat de voorste dimensies grove semantische informatie bevatten, terwijl latere dimensies fijnere details toevoegen.

Na training kan een MRL-embedding worden afgekapt tot een ondersteunde prefixdimensie. OpenAI rapporteert dat text-embedding-3-large met 256 dimensies beter presteert dan text-embedding-ada-002 met 1.536 dimensies in de aangehaalde MTEB-vergelijking. Dat levert een 6x-reductie in raw vectoropslag op; zoeklatentie en databasekosten hangen ook af van de index, metadata, filtering en hardware.

Het embeddingmodel is één belangrijke component in een RAG-pipeline, naast parsing, chunking, search, reranking en generation. Als relevante evidence niet wordt opgehaald, kan een sterkere generator die niet betrouwbaar reconstrueren.

38. RAG-architectuur in productie

RAG-architectuur met een offline document-naar-vector-ingestionpad en een online pad dat een query transformeert of direct embedt vóór hybrid search, reranking en generation.RAG-architectuur met een offline document-naar-vector-ingestionpad en een online pad dat een query transformeert of direct embedt vóór hybrid search, reranking en generation.

Retrieval-Augmented Generation voorziet een LLM tijdens query time van opgehaalde documenten. Het kan actuele of private evidence leveren die niet in de modelgewichten aanwezig is, maar retrieval garandeert niet dat het antwoord die evidence correct gebruikt. Een productioneel RAG-systeem is een pipeline met meerdere stages, waarvan elke stage afzonderlijk moet worden geëvalueerd.

De ingestion pipeline draait offline. Ruwe documenten (PDF’s, HTML, Markdown, databases) worden eerst geparsed naar schone tekst. Dat is lastiger dan het klinkt: alleen al PDF-parsing kan tabellen, headers en formatting verliezen. Vervolgens wordt de tekst opgesplitst in chunks, die onafhankelijk worden geëmbed en geïndexeerd.

Chunking beïnvloedt zowel de recall van retrieval als de context die beschikbaar is voor de generator. Geschikte groottes hangen af van de documentstructuur, querygranulariteit en de limieten van de embedder en reranker. Veelgebruikte benaderingen zijn fixed-size met overlap, recursive splitting langs documentgrenzen en semantic chunking op basis van embedding similarity. Vergelijk deze op relevantielabels op pagina- of sectieniveau, in plaats van universeel één tokenbereik over te nemen.

Elke chunk wordt vervolgens geëmbed met een model zoals die in Section 37 en opgeslagen in een vector database (Pinecone, Weaviate, Qdrant, pgvector, enzovoort).

De retrieval pipeline draait tijdens query time. Begin met een meetbare baseline en voeg daarna stages toe wanneer error analysis laat zien dat ze een concreet probleem oplossen:

  • Hybrid search combineert dense vector retrieval met sparse retrieval, zoals BM25, vaak samengevoegd via Reciprocal Rank Fusion (RRF). Dense search verwerkt semantische parafraseringen; sparse search vindt exacte identifiers, error codes en acroniemen. Vendor benchmarks rapporteren verbeteringen ten opzichte van vector-only baselines, maar de omvang daarvan hangt af van het corpus en de relevantielabels.
  • Reranking stuurt opgehaalde kandidaten door een model dat de query en het document gezamenlijk scoort. Dit kan de fijnmazige relevantie verbeteren, ten koste van een extra model call. Het aantal kandidaten, het aantal behouden kandidaten en de latency moeten gezamenlijk worden getuned. Ik heb de volledige multi-stage pipeline behandeld in Building a Modern Search Ranking Stack.
  • Query transformation herschrijft de query van de gebruiker vóór retrieval om de recall te verbeteren. Bij HyDE (Hypothetical Document Embeddings) laat je de LLM een hypothetisch antwoord genereren, dat vervolgens wordt geëmbed en voor retrieval wordt gebruikt. Multi-query expansion genereert meerdere formuleringen van dezelfde vraag. Step-back prompting stelt eerst een algemenere vraag om bredere context op te halen.

De meest voorkomende failure modes:

  • Retrieval failure — het juiste document bestaat, maar wordt niet opgehaald. Test chunking, query transformation, hybrid search en metadata filtering tegen de gemiste hit.
  • Context poisoning — irrelevante opgehaalde chunks misleiden de LLM. Test reranking, contextfilters en kleinere sets van behouden chunks.
  • Lost-in-the-middle — in de geteste settings voor multi-document question answering en key-value retrieval vonden Liu et al. dat de answer performance over het algemeen het hoogst was wanneer relevante informatie aan het begin of einde van de input stond, en lager wanneer die in het midden stond.

GraphRAG (Microsoft, 2024) breidt vector retrieval uit met een geëxtraheerde entity- en relationship graph. Het richt zich op corpus-level vragen en vragen met veel relaties, die flat chunk retrieval mogelijk mist. De trade-off bestaat uit extra werk voor extraction, indexing, storage en evaluation.

Praktijkgidsen publiceren latency ranges voor embedding, search, reranking en generation, maar die cijfers variëren per regio, corpus, hardware en model. Meet elke stage in traces en evalueer de kwaliteitsverandering voordat je de extra latency accepteert.

39. Agentarchitecturen en tool calling

LLM-agents gebruiken modellen om tool calls te selecteren en te sequencen rond een evoluerende state. Drie nuttige orchestration patterns zijn:

  • ReAct — wisselt action selection af met observaties. Het kan zich na elk toolresultaat aanpassen, maar een steeds langere history verhoogt de token- en latencykosten.
  • ReWOO — plant tool calls met placeholders, voert onafhankelijk werk parallel uit en synthetiseert daarna de resultaten. Het bijbehorende paper rapporteert tokenbesparingen ten opzichte van ReAct, maar het vaste plan heeft een expliciet recovery path nodig wanneer een tool faalt.
  • Planner-executor — scheidt planning van execution en kan na een fout een re-planning policy toevoegen. Dit maakt model-specialisatie mogelijk, maar voegt orchestration state en een extra decision boundary toe.
PatternToken tendencyAdaptabilityNuttig startpunt
ReActHogerWordt na observaties bijgewerktOnzeker of exploratief toolgebruik
ReWOOLagerVast plan tenzij uitgebreidVoorspelbaar werk met parallelle stappen
Planner-executorGemiddeldKan het expliciete plan herzienLangere taken die baat hebben bij control

Function calling is een veelgebruikt mechanisme voor tool invocation. API’s stellen tooldefinities beschikbaar en retourneren gestructureerde argumenten, waardoor er minder behoefte is aan het parsen van vrije tekst. Schema-valide argumenten kunnen nog steeds de verkeerde tool selecteren of ongeldige waarden bevatten. Parallel function calling kan het aantal round trips verlagen wanneer operaties onafhankelijk zijn.

Structured output en constrained decoding dwingen een schema af door de beschikbare tokens bij elke generation step te beperken. Engines zoals xgrammar, gebruikt in vLLM en SGLang, kunnen in ondersteunde configuraties veel syntax- en parsingfouten voorkomen met beperkte overhead. Ze garanderen niet dat de geëxtraheerde waarden of beslissingen correct zijn. Schema-Guided Reasoning (SGR) gebruikt field order en de structuur van het schema om intermediate state inspecteerbaar te maken vóór de final decision. De drie patterns zijn Cascade (sequential steps), Routing (union types als semantic switches) en Cycle (bounded lists).

De kwaliteit van tool selection, end-to-end latency en tokenkosten nemen doorgaans af naarmate de toolset en action depth groeien. Meet die curves met de werkelijke tooldescriptions en failure distribution. Frameworks zoals LangGraph kunnen state en recovery paths expliciet maken, maar nemen de evaluatielast niet weg.

40. Prompt engineering voor productie

Prompting voor productie is een evaluatieprobleem: wijzig één onderdeel van de prompt of context en meet vervolgens de task quality en failure modes. De onderstaande technieken zijn gebruikelijke startpunten, geen universele volgorde.

Few-shot examples zijn vaak effectief om het outputformat te sturen. Begin met 3–5 voorbeelden die lege inputs, ambigue queries en antwoorden met meerdere onderdelen afdekken en meet vervolgens het resultaat op een held-out set. Voorbeelden moeten de werkelijke input distribution bestrijken en niet alleen de happy path. Meer voorbeelden gebruiken meer context en garanderen geen verdere verbeteringen.

Chain-of-thought (CoT)-prompting vraagt een model om tussenliggende redeneringen te tonen voordat het antwoordt. Kojima et al. rapporteerden verbeteringen door het suffix “Let’s think step by step” op de door hen geteste reasoning-taken, maar het effect verschilt per model en nieuwere reasoning-API’s tonen mogelijk geen verborgen traces. Geef in productie de voorkeur aan een inspecteerbare taakdecompositie of een beknopte rationale wanneer die nuttig is voor de evaluator. Self-consistency (Wang et al., 2023) samplet meerdere reasoning-paden en aggregeert de antwoorden, waarbij extra inference-kosten worden ingeruild voor robuustheid bij geschikte taken.

Structured output met expliciete JSON-schema’s (Section 39) voorkomt veel parsing-fouten. Constrained decoding-engines zoals xgrammar kunnen de ondersteunde grammar tijdens generation afdwingen; factual accuracy en semantic validity vereisen nog steeds evaluatie, en niet-ondersteunde schemafeatures moeten mogelijk nog steeds worden afgehandeld.

Prompt chaining splitst een taak op in gerichte stages, bijvoorbeeld intent classificeren → context ophalen → response genereren → output valideren. Dit kan failures lokaliseren, verschillende modellen per stage mogelijk maken en cachebare intermediate state blootleggen. Het voegt ook interfaces en latency toe; vergelijk het daarom met een single-call baseline.

Temperature verandert de sampling distribution. Lage waarden zijn een redelijk startpunt voor classificatie of extractie; hogere waarden kunnen de diversiteit bij ideation vergroten. Het exacte gedrag verschilt per model-API en hangt samen met top_p, top_k en provider defaults. Sweep daarom de ondersteunde instellingen voor de taak in plaats van één range te kopiëren.

Scheiding tussen system- en user-messages houdt persistent beleid gescheiden van content per request. Chat templates en instruction tuning geven deze rollen een verschillende prioriteit, maar maken van een system-message geen enforcement boundary. Plaats stabiel gedrag in de system-message, houd untrusted data in user- of tool-content en dwing harde constraints zoals PII-verwijdering ook buiten het model af.

Context engineering breidt promptwerk uit naar het samenstellen van retrieved documents, tool results, conversation history en voorbeelden. Liu et al. vonden een lost-in-the-middle-effect in de long-context-modellen die zij testten. Positionering moet daarom onderdeel van de evaluatie zijn en mag niet als irrelevant worden verondersteld. Ik heb de bredere workflow behandeld in Context Engineering for AI Agents.


Part VIII — Production operations

Production operations vertaalt de eerdere concepten naar admission limits, load tests, alerts en capaciteitsbeslissingen onder real traffic.

41. Rate limiting voor requests met variabele kosten

Traditionele rate limiting op basis van requests per seconde gaat uit van ongeveer gelijke kosten per request. LLM’s doorbreken die aanname. Een classificatieprompt van 10 tokens en een documentanalyse van 100K tokens maken gebruik van hetzelfde API-endpoint, maar verschillen vier ordes van grootte in kosten. Rate limiting op basis van RPS laat dure requests óf ongecontroleerd door, óf onthoudt goedkope requests onnodig toegang.

Productiesystemen hebben token-based rate limiting nodig over meerdere dimensies. OpenAI documenteert request- en tokenlimieten per usage tier. Anthropic maakt onderscheid tussen input-token- en output-tokenlimieten. Exacte quota en algoritmen kunnen veranderen; beschouw daarom de documentatie van de provider als de bron van waarheid. Het architectuurprincipe is dat requests en tokens onafhankelijk van elkaar worden gebudgetteerd.

Het praktische implementatiepatroon is een multi-dimensional limit hierarchy (user → application → organization → global), met priority tiers voor premium access. Op requestniveau is token budget reservation de belangrijkste techniek: schat het totale aantal tokens (input + max_tokens) bij admission time, trek dit af van de bucket en corrigeer dit bij voltooiing van de request op basis van het werkelijke gebruik. Zo voorkomt u dat een burst van requests met lange generaties de capaciteit uitput voordat ze überhaupt output beginnen te produceren.

Voor self-hosted deployments is het equivalent provisioned throughput: dedicated GPU-capaciteit reserveren voor de beoogde token rates. Voor vLLM-deployments betekent dit admission control configureren op basis van actieve decode slots en KV-cache pressure, in plaats van alleen op requestaantallen. Zoals Section 5 uitlegt, moeten zowel throughput als admission token-aware limits gebruiken.

42. Failure modes om rekening mee te houden

LLM-serving introduceert failure modes die samenhangen met variabele sequence lengths, KV-memory en langdurig decodewerk. Ontwerp en load-test de mitigaties voordat productieverkeer ervan afhankelijk wordt.

Out-of-Memory (OOM) is een veelvoorkomende failure. Een 70B FP16-model heeft alleen al voor de weights ongeveer 140 GB nodig, en de KV-cache voor één Llama 3.1 70B-sequence met een context van 128K kan onder de aannames in Section 6 ongeveer 40 GB extra gebruiken. Het verschil tussen “past in het geheugen” en “OOM under load” is kleiner dan het lijkt, omdat een batch met requests met een lange context meer KV-memory kan verbruiken dan verwacht. Preventie combineert een gemeten memory reserve met quantization en paged KV allocation. Voor workloads met hoge KV-pressure kan LMCache KV-data offloaden naar CPU-memory of disk; gebruik de gepubliceerde resultaten als startpunt en benchmark de lokale memory hierarchy.

Preemption treedt op wanneer KV-cache pressure de scheduler dwingt werk te evicten of opnieuw te berekenen. De exacte strategie hangt af van de servingversie en configuratie. Vanuit gebruikersperspectief is het symptoom een hogere end-to-end latency zonder duidelijke application error. Monitor preemption counts en correleer deze met KV-gebruik, queue depth en request lengths.

Tail latency kan sterk toenemen wanneer grote prefills decodewerk vertragen. Chunked prefill (Section 7) en length-aware scheduling richten zich op deze interferentie. De Learning-to-Rank scheduler en de papers over CascadeInfer rapporteren verbeteringen ten opzichte van hun baselines onder de door hen geëvalueerde workloads, maar het exacte resultaat hangt af van de verdeling van request lengths en de schedulerconfiguratie.

Cascading failures kunnen beginnen wanneer trage requests de queue laten groeien, upstream clients een timeout krijgen en retries de load verder verhogen. Mitigaties zijn onder meer admission control, per-tenant concurrency limits, output caps, retry budgets en circuit breakers in de gateway. Disaggregated prefill- en decodepools kunnen helpen wanneer loadtests aanhoudende phase interference aantonen.

43. Monitoring van LLM-systemen

LLM-monitoring verschilt op enkele fundamentele punten van traditionele API-monitoring. Elke request heeft variabele kosten, twee afzonderlijke fasen met verschillende bottlenecks en een memory footprint die afhangt van zowel de inputlengte als de generation length. Standaardmetrics zoals request latency en error rate missen het grootste deel van wat relevant is.

Goodput is het aantal requests per seconde dat aan alle gedefinieerde SLO-thresholds voldoet, zoals TTFT, TPOT en total latency. Het is een nuttige gecombineerde maatstaf, omdat raw throughput er gezond uit kan zien terwijl latency-SLO’s worden geschonden: een systeem dat 100 requests per seconde verwerkt maar bij 40% daarvan de thresholds niet haalt, heeft een goodput van 60 requests per seconde. Optimaliseren voor goodput houdt de performance distribution zichtbaar, in plaats van alleen het gemiddelde te rapporteren.

vLLM stelt een Prometheus-endpoint beschikbaar op /metrics met actieve en wachtende requests, KV-cachegebruik, distributions van generation lengths en prefix-cache-statistieken. Metricnamen kunnen tussen releases wijzigen, dus koppel dashboards aan de gedeployde versie. Een typische stack gebruikt Prometheus voor metrics, Grafana voor visualisatie en OpenTelemetry-compatibele traces over application- en serving-componenten heen.

Nuttige alertpatronen zijn onder meer de volgende. Leid de thresholds af uit load tests in plaats van deze voorbeelden ongewijzigd over te nemen:

  • Preemption count spikes — de runtime swapt of recompute werk, wat latency toevoegt zonder een application error te veroorzaken.
  • KV-cache utilization die de geteste preemption-regio nadert — voeg capaciteit toe of shed load voordat evictions zich opstapelen.
  • Queue depth die persistent boven de geteste batch envelope ligt — admission control moet requests gaan afwijzen of een lagere prioriteit geven.
  • TTFT dat stijgt terwijl TPOT stabiel blijft — deze divergentie wijst eerst op queuing, admission, network of prefill pressure, en niet op decode throughput. Gebruik traces en queue metrics om onderscheid tussen deze oorzaken te maken.

44. Cost optimization: een cumulatieve strategie

Providerprijzen en input-to-output-prijsratio’s veranderen. Haal actuele tarieven op voordat je een aankoopbeslissing neemt; model tier en output length kunnen de factuur al domineren voordat infrastructure optimizations zijn doorgevoerd.

Verschillende benaderingen kunnen worden gestapeld, maar pas nadat is gemeten welke ervan op de workload van toepassing zijn:

  1. Quantization van FP16 naar INT4 reduceert het weight memory met 75%. Of dat de kosten verlaagt, hangt af van kernel speed, batch size en hardware utilization (Section 9).
  2. Model routing stuurt eligible traffic naar goedkopere modellen. Meet de false-accept rate van de router en de end-to-end quality voordat je het aandeel dat door het goedkopere model wordt afgehandeld verhoogt (Section 36).
  3. Prompt caching reduceert werk voor herhaalde prefixes. Providerkortingen en rate-limit-behandeling veranderen in de loop der tijd, dus combineer de gemeten hit rate met de actuele voorwaarden (Section 16).
  4. Batch APIs kunnen korting bieden op non-real-time werk, zoals evaluations, synthetic-data generation en bulk classification. Controleer de actuele prijzen en completion windows.
  5. Self-hosting kan voordelig zijn bij sustained utilization, maar er bestaat geen universeel break-evenpunt op basis van tokenvolume. Neem naast GPU rental ook engineering-, orchestration-, observability-, capacity-slack- en on-call-kosten mee.

Het vermenigvuldigen van de illustratieve factoren levert een grote theoretische reductie op, maar de inputs zijn niet onafhankelijk: quantization verandert de throughput, routing verandert de kwaliteitsmix, en caching en batching gelden alleen voor eligible traffic. Bouw de schatting op basis van gemeten traffic shares en valideer deze aan de hand van de invoice.

45. Capacity planning en autoscaling

Bij capacity planning voor LLM serving moet je rekening houden met variabele requestkosten, langlopende decode-workloads en sequence-afhankelijke memory. Afhankelijk van de workload kan de beperkende resource KV memory, memory bandwidth, compute of de interconnect zijn.

De theoretische memory ceiling voor het aantal gelijktijdige requests volgt uit het KV-cachebudget:

max concurrent sequences=GPU memorymodel weightsoverheadper-sequence KV cache size\text{max concurrent sequences} = \frac{\text{GPU memory} - \text{model weights} - \text{overhead}}{\text{per-sequence KV cache size}}

Voor de capaciteitsberekening nemen we aan dat de runtime een KV-budget van 40 GiB beschikbaar stelt voor Llama 3.1 70B met een FP16 KV-cache. Elke sequence van 4K gebruikt ongeveer 1,25 GiB en elke sequence van 128K ongeveer 40 GiB. Dat budget ondersteunt dus vóór overhead voor de allocator, runtime, workloadvariatie en SLO maximaal ongeveer 32 sequences van 4K of één sequence van 128K. Daarom bepalen GPU selection en KV cache optimization rechtstreeks het capacity plan.

De capacity-formule voor fleet sizing:

required GPUs=peak tokens/s×safety-factor multiplierper-GPU tokens/s at target SLO\text{required GPUs} = \frac{\text{peak tokens/s} \times \text{safety-factor multiplier}}{\text{per-GPU tokens/s at target SLO}}

Zet beide rates om naar dezelfde tijdseenheid voordat je deelt. Het belangrijke detail is “at target SLO.” Een safety-factor multiplier zoals 1,3 reserveert 30% headroom; kies deze op basis van gemeten burstiness, failures en recovery time. Peak token throughput en SLO-compliant throughput kunnen sterk verschillen wanneer de concurrency toeneemt. Benchmark met de echte verdeling van prompt- en outputlengtes bij de vereiste TTFT- en TPOT-thresholds, in plaats van een theoretisch maximum te gebruiken.

GPU utilization is onvoldoende als enige autoscaling-signaal, omdat deze zowel tijdens gezonde verwerking als tijdens overload hoog kan blijven. Combineer deze metric met queue depth, KV cache utilization en goodput degradation. Stel thresholds af op basis van load tests; waarden zoals 80% KV utilization zijn startpunten, geen universele limieten. Deze metrics worden geïntroduceerd in Section 43.

Scale-to-zero kan geschikt zijn voor development- en stagingomgevingen met lange idle periods. Serverless inference-platforms en Kubernetes-gebaseerde autoscalers zoals KEDA kunnen idle capacity verwijderen, maar de besparing en cold-start time hangen af van modelgrootte, het cachen van images en weights, en de infrastructuur. Meet de startup time voordat je hetzelfde policy toepast op latency-sensitive production traffic.


Gebruik de guide om de volgende meting te kiezen

De concepten hangen samen, maar leveren nog steeds een kleine set bruikbare eerste metingen op. De KV-cache demand beperkt de batch size naast weight memory, runtime overhead en request lengths. Grotere batches kunnen de arithmetic intensity verhogen, terwijl continuous batching de churn in KV allocations verhoogt en PagedAttention de daaruit voortkomende fragmentation vermindert.

Independently selectable inference optimizations evaluated against the measured hardware and workload bottleneck and the application's quality, latency, and cost targets.Independently selectable inference optimizations evaluated against the measured hardware and workload bottleneck and the application's quality, latency, and cost targets.

Aan de trainingskant kan lifecycle cost het aantrekkelijk maken om een kleiner model op meer tokens te trainen, zoals Llama 3 8B illustreert. GRPO vermindert de critic-state burden van PPO. In de geteste small-model setup van DeepSeek-R1 presteerde distillation beter dan direct RL. Dit zijn opties om te evalueren, geen vast recept.

Symptoom of beslissingBegin metMeet voordat je de stack wijzigt
Eerste token is traagPrefill en decode, TTFTQueue time, promptlengte, prefill-tijd en P99 TTFT
Tokens worden traag gestreamdRoofline, TPOTTPOT per concurrency-niveau, memory bandwidth en batch shape
Lange contexten veroorzaken preemption of OOMKV cache, PagedAttentionKV-gebruik, requestlengtes, allocator waste en het aantal preemptions
Een model past niet binnen het budgetQuantization, GPU-selectieKwaliteit, kernel-throughput, memory reserve en goodput volgens de target-SLO
Een training run past nietLoRA en QLoRA, ZeRO, FSDPGeheugengebruik van model states, communicatie, throughput en kwaliteit op de held-out set
Kosten stijgenRouting, cost optimizationGeschiktheid van traffic, kwaliteitsfouten, cache hit rate en factuurgegevens

Routing, caching, quantization en hardwarekeuze versterken elkaar alleen wanneer je elke optie afzet tegen dezelfde kwaliteits- en latencydoelstelling. Kies één symptoom, leg die baseline vast en zorg dat de volgende wijziging eenvoudig terug te draaien is.


Verder lezen

Gerelateerde deep-dives uit deze blog, per onderwerp geordend:


Referenties

Geordend per onderwerp.

Inference en attention

Speculative decoding

Quantization

Training en fine-tuning

Alignment

Schaling en architectuur

Embeddings

Agentarchitecturen

Routing

Benchmarks

Servingarchitecturen

Servingframeworks

  • vLLM - Serving engine op basis van PagedAttention
  • SGLang - RadixAttention en structured generation
  • TensorRT-LLM - Door NVIDIA geoptimaliseerde inference
  • llama.cpp - Portable C/C++-inference
  • DeepSpeed - Microsoft-bibliotheek voor distributed training
  • Ollama - Lokale LLM-runner

Operations