Thomas Piacentini
← Workshop

Cheat sheet

End-to-End LLM and Fine-Tuning Pipeline

Original text · English

Plan, run and gate a hashed stage DAG. Head swap, SFT loss mask and DPO loss from the capstones, with defaults.

Commands

CommandWhat it does
python code/main.py planValidates the manifest, prints DAG and gates
python code/main.py runRuns stages, prints the manifest JSON
python code/main.py gateApplies eval gates. Prints SHIP or HOLD
python code/main.pyDemo: plan, run, a passing and a failing gate
./pipeline.sh config/llama3.3-8b-domainX.yamlCapstone 07: data to model card
run_demo()Capstones 38 to 40. Exits zero on success
Sources

Twelve-stage DAG

01-02 Tokenizervocab, mergesstore03 Datasetshardedstore04-05 Checkpointpre-train, scalegpu06 SFT modelcheckpoint + recipegpu07 Reward + PPOpolicygpu08 DPOpolicygpu09 CAI / GRPOrefined policygpu10 Eval reportscores, diffsprocess11 Quantizedweights + deltastore12 Server specendpointprocessShip gateSHIP or HOLDclient
Nodes and connections
NodeRoleKind
01-02 Tokenizervocab, mergesstore
03 Datasetshardedstore
04-05 Checkpointpre-train, scalegpu
06 SFT modelcheckpoint + recipegpu
07 Reward + PPOpolicygpu
08 DPOpolicygpu
09 CAI / GRPOrefined policygpu
10 Eval reportscores, diffsprocess
11 Quantizedweights + deltastore
12 Server specendpointprocess
Ship gateSHIP or HOLDclient
FromToConnection
01-02 Tokenizer03 Dataset
03 Dataset04-05 Checkpoint
04-05 Checkpoint06 SFT model
06 SFT model07 Reward + PPO
06 SFT model08 DPO
07 Reward + PPO09 CAI / GRPO
08 DPO09 CAI / GRPO
09 CAI / GRPO10 Eval report
09 CAI / GRPO11 Quantized
11 Quantized12 Server spec
10 Eval reportShip gate
12 Server specShip gate
Sources

What the orchestrator does

  1. Orchestrator resolves the DAG from the manifest.
  2. Orchestrator skips a stage if its output already exists at the correct hash.
  3. Stage runs. The orchestrator measures wall clock and cost.
  4. Orchestrator checks the output hash against the next stage input hash.
  5. CostTracker halts with halted_over_budget when total cost passes the budget.
  6. On failure writes a partial manifest and exits nonzero.
Sources

Manifest and gates

pipeline_version: 1.2.3
seed: 42
git_commit: a1b2c3d4
stages:
01_tokenizer:
input_hash: sha256:...output hash of the stage before
output_hash: sha256:...input hash of the next stage
gates:
mmlu: >= baseline + 0.5no regression
humaneval: >= baseline + 1.0
safety_refusal_rate: <= 0.05
kl_from_reference: <= 25.0KL budget gate
cost_total_usd: <= 50000
Sources

Gate defaults in main.py

SettingDefaultNote
mmlu65.0op >=
humaneval40.0op >=
truthfulqa50.0op >=
safety_refusal_rate0.05op <=
kl_from_reference25.0op <=
cost_total_usd50000.0op <=
budget_usd50000.0Run halts above it
seed42In Manifest
Sources

The three capstones side by side

Factor38 Classifier head swap39 Instruction SFT40 DPO
BuildsBody + mean pool + 2-class headTinyGPT trained on response tokensPolicy against a frozen reference
Data800 SMS, 640 train, 160 test200 pairs, 160 train, 40 test12 (prompt, chosen, rejected) triples
Modelhidden 64, 4 heads, 2 blocks, max 32hidden 96, 2 blockshidden 64, 2 blocks
Train20 epochs head-only, 20 full20 epochs, lr 5e-430 epochs, beta 0.2, lr 1e-3
MetricPrecision, recall, F1, confusionExact-match per categoryChosen minus rejected margin
CheckHead-only and full both reportExact-match rises over epochsLoss falls, margin grows
Sources

Key calls in the capstones

TaskCode
Freeze the body for head-only trainingfreeze_body(model)
Pool hidden states with the maskmean_pool(h, mask)
Pad a batch and mask labels with -100sft_collate(batch)
Causal loss on response tokensshifted_loss(logits, labels)
Score a completion under a modelsequence_log_prob(...)
DPO loss and implicit reward margindpo_loss(lp_w_pol, lp_l_pol, lp_w_ref, lp_l_ref, beta=cfg.beta)
Start the policy from the referencepolicy.load_state_dict(reference.state_dict())
Sources

DPO loss

diff_w = logp_w_pol - logp_w_refchosen log-ratio
diff_l = logp_l_pol - logp_l_refrejected log-ratio
margin = diff_w - diff_limplicit reward difference
z = beta * margin
loss = -F.logsigmoid(z)numerically stable
for p in reference.parameters():
p.requires_grad = Falsereference never trains
reference.eval()
Sources

Capstone 07 log lines

CommandWhat it does
280k accepted (seed=7)Data stage rows kept
val loss 1.42 -> 1.03SFT, 3 epochs on 8xH100
1 epoch, beta=0.08, 4xH100DPO run
GPTQ-INT4 4.6 GB, AWQ-INT4 4.8 GBQuant sizes
EAGLE-3 acceptance 0.74Speculative decoding check
p99 126ms @ bs=8Tail latency at batch 8
MMLU-Pro +3.2, MT-Bench-v2 +0.41Eval gain over base
Sources

Troubleshooting

SymptomCauseFix
HOLD: missing metric <metric>Eval report has no valueAdd the metric to the eval stage
input hash missing for stageUpstream artifact not in storeRe-run the upstream stage
halted_over_budgetTotal cost above budget_usdFix the cost estimate at plan time
DPO model sent through the SFT pathUntyped artifactsTyped artifacts and stage signatures
Model learns to predict the instructionNo loss mask-100 on instruction, pad, boundary
Full fine-tuning overfits 800 examplesSmall data washes out the bodyTrain the head only
MMLU-Pro accuracy jumpsContamination in training dataMinHash check, reject any overlap
DPO prefers short completionsLength biasDivide log-prob by completion length
Sources

Rollback and tips

  • Run plan first every time. It is free. run is expensive.
  • Cheap to re-run: tokenizer, eval, quantization, inference server.
  • Medium: SFT, DPO, CAI. Keep the base model.
  • Expensive: pre-training. Use the last good checkpoint.
  • A failure at stage 06 invalidates 06 to 12. At stage 11, only 11 and 12.
  • Address artifacts by hash. A filename like latest.pt is a foot-gun.
  • Pre-training FLOPs: 6 x params x tokens.
Sources

Q&A

Which two gates catch most disasters?
A regression gate and a KL budget gate.
Reproducible or deterministic?
Reproducible. Floats differ at the 1e-5 level.
Why does log Z(x) drop out of DPO?
It is the same for chosen and rejected.
Why greedy for exact-match?
Temperature makes the metric stochastic.
Sources
Original source
---
id: llm-pipeline-capstone
title: End-to-End LLM and Fine-Tuning Pipeline
code: EE
subtitle: Plan, run and gate a hashed stage DAG. Head swap, SFT loss mask and DPO loss from the capstones, with defaults.
hue: 215
sources: phases/10-llms-from-scratch/13-building-complete-llm-pipeline, phases/19-capstone-projects/07-end-to-end-fine-tuning-pipeline, phases/19-capstone-projects/38-classifier-finetuning, phases/19-capstone-projects/39-instruction-tuning-sft, phases/19-capstone-projects/40-dpo-from-scratch
source_hash: 2d1fd91ad69bc1db
---

## Commands
type: command-table
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/10-llms-from-scratch/13-building-complete-llm-pipeline/code/main.py, phases/19-capstone-projects/07-end-to-end-fine-tuning-pipeline/docs/en.md, phases/19-capstone-projects/07-end-to-end-fine-tuning-pipeline/code/main.py, phases/19-capstone-projects/38-classifier-finetuning/code/main.py, phases/19-capstone-projects/39-instruction-tuning-sft/code/main.py, phases/19-capstone-projects/40-dpo-from-scratch/code/main.py

| Command | What it does |
|---|---|
| `python code/main.py plan` | Validates the manifest, prints DAG and gates |
| `python code/main.py run` | Runs stages, prints the manifest JSON |
| `python code/main.py gate` | Applies eval gates. Prints `SHIP` or `HOLD` |
| `python code/main.py` | Demo: plan, run, a passing and a failing gate |
| `./pipeline.sh config/llama3.3-8b-domainX.yaml` | Capstone 07: data to model card |
| `run_demo()` | Capstones 38 to 40. Exits zero on success |

## Twelve-stage DAG
type: architecture
span: 2
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/10-llms-from-scratch/13-building-complete-llm-pipeline/code/main.py

```arch
node | tok | 1,1 | 01-02 Tokenizer | vocab, merges | store
node | data | 2,1 | 03 Dataset | sharded | store
node | base | 3,1 | 04-05 Checkpoint | pre-train, scale | gpu
node | sft | 4,1 | 06 SFT model | checkpoint + recipe | gpu
node | ppo | 4,2 | 07 Reward + PPO | policy | gpu
node | dpo | 3,2 | 08 DPO | policy | gpu
node | cai | 2,2 | 09 CAI / GRPO | refined policy | gpu
node | eval | 1,2 | 10 Eval report | scores, diffs | process
node | quant | 2,3 | 11 Quantized | weights + delta | store
node | srv | 3,3 | 12 Server spec | endpoint | process
node | gate | 1,3 | Ship gate | SHIP or HOLD | client
edge | tok | data |
edge | data | base |
edge | base | sft |
edge | sft | ppo |
edge | sft | dpo |
edge | ppo | cai |
edge | dpo | cai |
edge | cai | eval |
edge | cai | quant |
edge | quant | srv |
edge | eval | gate |
edge | srv | gate |
```

## What the orchestrator does
type: flow
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/10-llms-from-scratch/13-building-complete-llm-pipeline/code/main.py

1. **Orchestrator**: resolves the DAG from the manifest.
2. **Orchestrator**: skips a stage if its output already exists at the correct hash.
3. **Stage**: runs. The orchestrator measures wall clock and cost.
4. **Orchestrator**: checks the output hash against the next stage input hash.
5. **CostTracker**: halts with `halted_over_budget` when total cost passes the budget.
6. **On failure**: writes a partial manifest and exits nonzero.

## Manifest and gates
type: annotated-code
lang: yaml
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md

```yaml
pipeline_version: 1.2.3
seed: 42
git_commit: a1b2c3d4
stages:
  01_tokenizer:
    input_hash: sha256:...  # output hash of the stage before
    output_hash: sha256:...  # input hash of the next stage
gates:
  mmlu:      >= baseline + 0.5   # no regression
  humaneval: >= baseline + 1.0
  safety_refusal_rate: <= 0.05
  kl_from_reference: <= 25.0  # KL budget gate
  cost_total_usd: <= 50000
```

## Gate defaults in main.py
type: defaults
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/code/main.py

| Setting | Default | Note |
|---|---|---|
| `mmlu` | 65.0 | op `>=` |
| `humaneval` | 40.0 | op `>=` |
| `truthfulqa` | 50.0 | op `>=` |
| `safety_refusal_rate` | 0.05 | op `<=` |
| `kl_from_reference` | 25.0 | op `<=` |
| `cost_total_usd` | 50000.0 | op `<=` |
| `budget_usd` | 50000.0 | Run halts above it |
| `seed` | 42 | In `Manifest` |

## The three capstones side by side
type: comparison
span: 2
from: phases/19-capstone-projects/38-classifier-finetuning, phases/19-capstone-projects/39-instruction-tuning-sft, phases/19-capstone-projects/40-dpo-from-scratch

| Factor | 38 Classifier head swap | 39 Instruction SFT | 40 DPO |
|---|---|---|---|
| Builds | Body + mean pool + 2-class head | `TinyGPT` trained on response tokens | Policy against a frozen reference |
| Data | 800 SMS, 640 train, 160 test | 200 pairs, 160 train, 40 test | 12 (prompt, chosen, rejected) triples |
| Model | hidden 64, 4 heads, 2 blocks, max 32 | hidden 96, 2 blocks | hidden 64, 2 blocks |
| Train | 20 epochs head-only, 20 full | 20 epochs, lr 5e-4 | 30 epochs, beta 0.2, lr 1e-3 |
| Metric | Precision, recall, F1, confusion | Exact-match per category | Chosen minus rejected margin |
| Check | Head-only and full both report | Exact-match rises over epochs | Loss falls, margin grows |

## Key calls in the capstones
type: task-table
span: 2
from: phases/19-capstone-projects/38-classifier-finetuning/code/main.py, phases/19-capstone-projects/39-instruction-tuning-sft/code/main.py, phases/19-capstone-projects/40-dpo-from-scratch/code/main.py

| Task | Code |
|---|---|
| Freeze the body for head-only training | `freeze_body(model)` |
| Pool hidden states with the mask | `mean_pool(h, mask)` |
| Pad a batch and mask labels with -100 | `sft_collate(batch)` |
| Causal loss on response tokens | `shifted_loss(logits, labels)` |
| Score a completion under a model | `sequence_log_prob(...)` |
| DPO loss and implicit reward margin | `dpo_loss(lp_w_pol, lp_l_pol, lp_w_ref, lp_l_ref, beta=cfg.beta)` |
| Start the policy from the reference | `policy.load_state_dict(reference.state_dict())` |

## DPO loss
type: annotated-code
lang: python
from: phases/19-capstone-projects/40-dpo-from-scratch/code/main.py

```python
diff_w = logp_w_pol - logp_w_ref  # chosen log-ratio
diff_l = logp_l_pol - logp_l_ref  # rejected log-ratio
margin = diff_w - diff_l  # implicit reward difference
z = beta * margin
loss = -F.logsigmoid(z)  # numerically stable
for p in reference.parameters():
    p.requires_grad = False  # reference never trains
reference.eval()
```

## Capstone 07 log lines
type: command-table
from: phases/19-capstone-projects/07-end-to-end-fine-tuning-pipeline/docs/en.md

| Command | What it does |
|---|---|
| `280k accepted (seed=7)` | Data stage rows kept |
| `val loss 1.42 -> 1.03` | SFT, 3 epochs on 8xH100 |
| `1 epoch, beta=0.08, 4xH100` | DPO run |
| `GPTQ-INT4 4.6 GB, AWQ-INT4 4.8 GB` | Quant sizes |
| `EAGLE-3 acceptance 0.74` | Speculative decoding check |
| `p99 126ms @ bs=8` | Tail latency at batch 8 |
| `MMLU-Pro +3.2, MT-Bench-v2 +0.41` | Eval gain over base |

## Troubleshooting
type: troubleshooting
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/10-llms-from-scratch/13-building-complete-llm-pipeline/code/main.py, phases/19-capstone-projects/39-instruction-tuning-sft/docs/en.md, phases/19-capstone-projects/38-classifier-finetuning/docs/en.md, phases/19-capstone-projects/40-dpo-from-scratch/docs/en.md, phases/19-capstone-projects/07-end-to-end-fine-tuning-pipeline/docs/en.md

| Symptom | Cause | Fix |
|---|---|---|
| `HOLD: missing metric <metric>` | Eval report has no value | Add the metric to the eval stage |
| `input hash missing for stage` | Upstream artifact not in store | Re-run the upstream stage |
| `halted_over_budget` | Total cost above `budget_usd` | Fix the cost estimate at plan time |
| DPO model sent through the SFT path | Untyped artifacts | Typed artifacts and stage signatures |
| Model learns to predict the instruction | No loss mask | `-100` on instruction, pad, boundary |
| Full fine-tuning overfits 800 examples | Small data washes out the body | Train the head only |
| MMLU-Pro accuracy jumps | Contamination in training data | MinHash check, reject any overlap |
| DPO prefers short completions | Length bias | Divide log-prob by completion length |

## Rollback and tips
type: tips
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/19-capstone-projects/40-dpo-from-scratch/docs/en.md

- Run `plan` first every time. It is free. `run` is expensive.
- Cheap to re-run: tokenizer, eval, quantization, inference server.
- Medium: SFT, DPO, CAI. Keep the base model.
- Expensive: pre-training. Use the last good checkpoint.
- A failure at stage 06 invalidates 06 to 12. At stage 11, only 11 and 12.
- Address artifacts by hash. A filename like `latest.pt` is a foot-gun.
- Pre-training FLOPs: 6 x params x tokens.

## Q&A
type: qa
from: phases/10-llms-from-scratch/13-building-complete-llm-pipeline/docs/en.md, phases/19-capstone-projects/40-dpo-from-scratch/docs/en.md, phases/19-capstone-projects/39-instruction-tuning-sft/docs/en.md

- **Which two gates catch most disasters?** A regression gate and a KL budget gate.
- **Reproducible or deterministic?** Reproducible. Floats differ at the 1e-5 level.
- **Why does log Z(x) drop out of DPO?** It is the same for chosen and rejected.
- **Why greedy for exact-match?** Temperature makes the metric stochastic.
Code and artifacts 1
What you take away

Saved in your notebook on this device.

Sources and limits

Reading checkpoints are self-reported. Test results are recorded separately and apply to the executed cases.

AI Engineering from Scratch · 3f9715c · MIT

Download this file ↓