Course: Course 3 — LLM Fine-Tuning Masterclass
Module: FTDD-05 — Axolotl: Config-Driven Production Fine-Tuning
Duration: ~45 minutes (spoken at ~140 wpm)
Format: Verbatim transcript with [SLIDE N] cues. Read aloud or use as speaker notes.
[SLIDE 1 — Title]
This is deep-dive FTDD-zero-five — Axolotl. Forty-five minutes. If TRL, from the last module, is the engine of open-weights post-training, Axolotl is the cockpit most practitioners actually sit in for production jobs. But the real lesson of Axolotl is not the tool — it is the pattern. The training recipe becomes a declarative file. Everything good about Axolotl flows from that one decision.
[SLIDE 2 — Config as source of truth]
Here is the core idea, and it is older than Axolotl. The training recipe should be a declarative file, not a program. A YAML that says WHAT to train, not HOW to write the loop. Axolotl's contribution is to apply this pattern thoroughly and with opinionated defaults that work — so thoroughly that for most practitioners, an Axolotl config is synonymous with a reproducible fine-tuning run.
Contrast the old way with the Axolotl way. The old way: a two-hundred-line train-dot-P-Y with hardcoded paths and ad-hoc hyperparameters and a comment that says TODO clean up. That script runs once, on one machine, and is unreproducible a quarter later. The Axolotl way: one config-dot-YAML that captures the base model, the dataset, the PEFT settings, the learning rate, the distributed strategy, the eval cadence — the whole recipe.
[SLIDE 3 — Why config-not-code wins]
Three properties that the hand-written script cannot match. First, reproducibility is a file. The entire recipe lives in one YAML. Reproduce my run means run this file. A colleague — or your future self in six months — does not need to reverse-engineer a Python script.
Second, recipes are diff-able and version-able. Because the recipe is text, it goes in git, and a git diff shows exactly what changed between two runs. We raised the learning rate and added DeepSpeed ZeRO-three is a two-line diff, not a code review of a three-hundred-line script.
Third, CI-validatable. A YAML can be schema-validated, linted, and dry-run-checked in CI before it ever touches a GPU. A Python training script cannot. This is the same reason Kubernetes manifests are YAML, not Python. Declarative config is auditable in a way imperative code is not.
[SLIDE 4 — Under the hood]
Now the fact that keeps Axolotl from being a black box. Axolotl is not a competing training engine. Underneath the YAML, it calls TRL's trainers. When you write an SFT config, the run uses SFT trainer. DPO config, DPO trainer. GRPO config, GRPO trainer. The optimizer, the loss, the checkpointing — all TRL's, which is to say all the HuggingFace Trainer's. Your TRL knowledge transfers directly.
So if it is just TRL under the hood, what justifies the wrapper? Two things, and they are substantial. First, opinionated cross-family defaults. TRL gives you the trainer and the knobs but does not tell you which knobs to turn for a Llama three versus a Mistral versus a Qwen. Axolotl ships defaults that work across families — sensible sequence lengths, gradient accumulation, precision, PEFT configs that are known-good.
Second — and this is the decisive one — battle-tested multi-GPU orchestration. Raw TRL gives you the ABILITY to use FSDP or DeepSpeed, but it hands you the RESPONSIBILITY of writing the config, and those configs are notoriously fiddly. Sharding dimension, CPU offload, the interaction with gradient checkpointing, ZeRO stage selection. Axolotl curates these into known-good recipes. For a two-, four-, or eight-GPU job on a seventy-billion model, Axolotl's multi-GPU path is the path of least resistance in the open-weights world.
The cost is a layer of indirection. Slight latency on the bleeding edge — when a new trainer lands in TRL it takes time to surface in Axolotl. And debuggability — when something breaks you are debugging through Axolotl, TRL, Transformers, and the error may surface far from its cause.
[SLIDE 5 — The three-way decision]
You now have three overlapping tools. The decision is governed by your constraint, not by which is best. Multi-GPU production job, must reproduce, standard recipe — Axolotl. The multi-GPU orchestration and config-as-source-of-truth are decisive. Single GPU, sub-thirty-billion, speed or VRAM constrained — Unsloth. The Triton kernels give you roughly double the throughput at half the memory, often the difference between fits on my forty-ninety and doesn't. Custom reward function, non-standard loop, brand-new method, or full control — raw TRL, the Python API. The wrappers are configured, not programmed; the moment your loop is non-standard you are in raw TRL anyway.
And the hybrid pattern many practitioners use: Unsloth as the default backend for sub-thirty-billion single-GPU work, Axolotl for anything multi-GPU or above thirty-billion. This is not indecision. It is using each tool for its strength. Unsloth's TRL-compatible API means the transition is mostly a config change, not a rewrite.
[SLIDE 6 — Anatomy of an Axolotl YAML]
A real Axolotl config, read as five sections. Section one, model: base model, model type, tokenizer. Section two, data: the dataset path and type and split, plus a held-out validation size. Section three, PEFT: adapter type — QLoRA, LoRA, or none for full — the LoRA rank and alpha and target modules. Section four, hyperparameters, pinned explicitly: sequence length, batch size, gradient accumulation, learning rate, scheduler. Section five, distributed and output: the DeepSpeed or FSDP config, the output directory, the save and eval cadence.
[SLIDE 7 — What to notice]
Four things to notice. Everything is pinned — there are no magic defaults you are trusting blind. Learning rate, LoRA rank, sequence length, all explicit. PEFT is a section, not a script — switching from QLoRA to full fine-tuning is changing the adapter line, one line not a rewrite. Multi-GPU is a config value — deepspeed or FSDP, and Axolotl's curated configs are the value-add over raw TRL. And eval is first-class — val set size and eval steps are declared in the source of truth, not bolted on.
[SLIDE 8 — The reproducibility checklist]
Before you treat a config as production-ready, six questions. Is every hyperparameter pinned? Is the dataset path AND split explicit? Is the distributed strategy declared? Is the precision known — what did B-F-sixteen auto resolve to? Is eval declared? And could a colleague reproduce this from the YAML alone, with no access to you? Six yeses means your run is reproducible. That is the bar Axolotl was built to clear.
[SLIDE 9 — Anti-patterns]
Three anti-patterns. First, treating the config as documentation, not source. Writing a YAML, then tweaking it live with CLI overrides, so the on-disk config no longer matches what ran. The config must be the complete source of truth. If you override, write it into the YAML and commit it.
Second, reaching for Axolotl when you need a custom reward. Axolotl is configured, not programmed. A GRPO job with a custom reward function cannot be fully expressed in YAML. Drop to raw TRL for non-standard loops. Use Axolotl for the standard recipes it excels at.
Third, assuming the wrapper removes the need to understand TRL. Because Axolotl wraps TRL, a TRL-level problem — a bad learning rate, the wrong loss, a misunderstood trainer — is still your problem. The wrapper configures the trainer; it does not absolve you of knowing what the trainer does. Learn TRL first. Axolotl is the layer above.
[SLIDE 10 — What you can now do]
You can now explain the declarative YAML pattern and why config-as-source-of-truth wins in production. You can describe how Axolotl wraps TRL and what the wrapper adds — opinionated defaults and multi-GPU orchestration. You can choose between Axolotl, Unsloth, and raw TRL by constraint. And you can read and write an Axolotl YAML across its five sections.
Next, deep-dive FTDD-zero-six: Dolphin and Hermes, the uncensored lineages from Nous Research. We study them not as advocacy but as engineering case studies — production examples of the alignment-control techniques you will learn in modules sixteen through eighteen. Let's see what a real uncensored recipe looks like.
End of module FTDD-05. Duration: approximately forty-four minutes at one-hundred-forty words per minute.
# Teaching Script — Module FTDD-05: Axolotl **Course**: Course 3 — LLM Fine-Tuning Masterclass **Module**: FTDD-05 — Axolotl: Config-Driven Production Fine-Tuning **Duration**: ~45 minutes (spoken at ~140 wpm) **Format**: Verbatim transcript with `[SLIDE N]` cues. Read aloud or use as speaker notes. --- [SLIDE 1 — Title] This is deep-dive FTDD-zero-five — Axolotl. Forty-five minutes. If TRL, from the last module, is the engine of open-weights post-training, Axolotl is the cockpit most practitioners actually sit in for production jobs. But the real lesson of Axolotl is not the tool — it is the pattern. The training recipe becomes a declarative file. Everything good about Axolotl flows from that one decision. [SLIDE 2 — Config as source of truth] Here is the core idea, and it is older than Axolotl. The training recipe should be a declarative file, not a program. A YAML that says WHAT to train, not HOW to write the loop. Axolotl's contribution is to apply this pattern thoroughly and with opinionated defaults that work — so thoroughly that for most practitioners, an Axolotl config is synonymous with a reproducible fine-tuning run. Contrast the old way with the Axolotl way. The old way: a two-hundred-line train-dot-P-Y with hardcoded paths and ad-hoc hyperparameters and a comment that says TODO clean up. That script runs once, on one machine, and is unreproducible a quarter later. The Axolotl way: one config-dot-YAML that captures the base model, the dataset, the PEFT settings, the learning rate, the distributed strategy, the eval cadence — the whole recipe. [SLIDE 3 — Why config-not-code wins] Three properties that the hand-written script cannot match. First, reproducibility is a file. The entire recipe lives in one YAML. Reproduce my run means run this file. A colleague — or your future self in six months — does not need to reverse-engineer a Python script. Second, recipes are diff-able and version-able. Because the recipe is text, it goes in git, and a git diff shows exactly what changed between two runs. We raised the learning rate and added DeepSpeed ZeRO-three is a two-line diff, not a code review of a three-hundred-line script. Third, CI-validatable. A YAML can be schema-validated, linted, and dry-run-checked in CI before it ever touches a GPU. A Python training script cannot. This is the same reason Kubernetes manifests are YAML, not Python. Declarative config is auditable in a way imperative code is not. [SLIDE 4 — Under the hood] Now the fact that keeps Axolotl from being a black box. Axolotl is not a competing training engine. Underneath the YAML, it calls TRL's trainers. When you write an SFT config, the run uses SFT trainer. DPO config, DPO trainer. GRPO config, GRPO trainer. The optimizer, the loss, the checkpointing — all TRL's, which is to say all the HuggingFace Trainer's. Your TRL knowledge transfers directly. So if it is just TRL under the hood, what justifies the wrapper? Two things, and they are substantial. First, opinionated cross-family defaults. TRL gives you the trainer and the knobs but does not tell you which knobs to turn for a Llama three versus a Mistral versus a Qwen. Axolotl ships defaults that work across families — sensible sequence lengths, gradient accumulation, precision, PEFT configs that are known-good. Second — and this is the decisive one — battle-tested multi-GPU orchestration. Raw TRL gives you the ABILITY to use FSDP or DeepSpeed, but it hands you the RESPONSIBILITY of writing the config, and those configs are notoriously fiddly. Sharding dimension, CPU offload, the interaction with gradient checkpointing, ZeRO stage selection. Axolotl curates these into known-good recipes. For a two-, four-, or eight-GPU job on a seventy-billion model, Axolotl's multi-GPU path is the path of least resistance in the open-weights world. The cost is a layer of indirection. Slight latency on the bleeding edge — when a new trainer lands in TRL it takes time to surface in Axolotl. And debuggability — when something breaks you are debugging through Axolotl, TRL, Transformers, and the error may surface far from its cause. [SLIDE 5 — The three-way decision] You now have three overlapping tools. The decision is governed by your constraint, not by which is best. Multi-GPU production job, must reproduce, standard recipe — Axolotl. The multi-GPU orchestration and config-as-source-of-truth are decisive. Single GPU, sub-thirty-billion, speed or VRAM constrained — Unsloth. The Triton kernels give you roughly double the throughput at half the memory, often the difference between fits on my forty-ninety and doesn't. Custom reward function, non-standard loop, brand-new method, or full control — raw TRL, the Python API. The wrappers are configured, not programmed; the moment your loop is non-standard you are in raw TRL anyway. And the hybrid pattern many practitioners use: Unsloth as the default backend for sub-thirty-billion single-GPU work, Axolotl for anything multi-GPU or above thirty-billion. This is not indecision. It is using each tool for its strength. Unsloth's TRL-compatible API means the transition is mostly a config change, not a rewrite. [SLIDE 6 — Anatomy of an Axolotl YAML] A real Axolotl config, read as five sections. Section one, model: base model, model type, tokenizer. Section two, data: the dataset path and type and split, plus a held-out validation size. Section three, PEFT: adapter type — QLoRA, LoRA, or none for full — the LoRA rank and alpha and target modules. Section four, hyperparameters, pinned explicitly: sequence length, batch size, gradient accumulation, learning rate, scheduler. Section five, distributed and output: the DeepSpeed or FSDP config, the output directory, the save and eval cadence. [SLIDE 7 — What to notice] Four things to notice. Everything is pinned — there are no magic defaults you are trusting blind. Learning rate, LoRA rank, sequence length, all explicit. PEFT is a section, not a script — switching from QLoRA to full fine-tuning is changing the adapter line, one line not a rewrite. Multi-GPU is a config value — deepspeed or FSDP, and Axolotl's curated configs are the value-add over raw TRL. And eval is first-class — val set size and eval steps are declared in the source of truth, not bolted on. [SLIDE 8 — The reproducibility checklist] Before you treat a config as production-ready, six questions. Is every hyperparameter pinned? Is the dataset path AND split explicit? Is the distributed strategy declared? Is the precision known — what did B-F-sixteen auto resolve to? Is eval declared? And could a colleague reproduce this from the YAML alone, with no access to you? Six yeses means your run is reproducible. That is the bar Axolotl was built to clear. [SLIDE 9 — Anti-patterns] Three anti-patterns. First, treating the config as documentation, not source. Writing a YAML, then tweaking it live with CLI overrides, so the on-disk config no longer matches what ran. The config must be the complete source of truth. If you override, write it into the YAML and commit it. Second, reaching for Axolotl when you need a custom reward. Axolotl is configured, not programmed. A GRPO job with a custom reward function cannot be fully expressed in YAML. Drop to raw TRL for non-standard loops. Use Axolotl for the standard recipes it excels at. Third, assuming the wrapper removes the need to understand TRL. Because Axolotl wraps TRL, a TRL-level problem — a bad learning rate, the wrong loss, a misunderstood trainer — is still your problem. The wrapper configures the trainer; it does not absolve you of knowing what the trainer does. Learn TRL first. Axolotl is the layer above. [SLIDE 10 — What you can now do] You can now explain the declarative YAML pattern and why config-as-source-of-truth wins in production. You can describe how Axolotl wraps TRL and what the wrapper adds — opinionated defaults and multi-GPU orchestration. You can choose between Axolotl, Unsloth, and raw TRL by constraint. And you can read and write an Axolotl YAML across its five sections. Next, deep-dive FTDD-zero-six: Dolphin and Hermes, the uncensored lineages from Nous Research. We study them not as advocacy but as engineering case studies — production examples of the alignment-control techniques you will learn in modules sixteen through eighteen. Let's see what a real uncensored recipe looks like. --- *End of module FTDD-05. Duration: approximately forty-four minutes at one-hundred-forty words per minute.*