{
  "module": "FTDD-05 — Axolotl: Config-Driven Production Fine-Tuning",
  "course": "3 — LLM Fine-Tuning Masterclass",
  "version": "1.0.0",
  "duration_minutes": 45,
  "total_questions": 10,
  "bloom_distribution": {
    "target": "40% recall / 30% application / 30% analysis",
    "actual": { "recall": 4, "application": 3, "analysis": 3 }
  },
  "passing_score_percent": 70,
  "questions": [
    {
      "id": "Q01", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What is Axolotl, and what is the core pattern it champions?",
      "options": [
        "A competing training engine that replaces TRL with faster kernels.",
        "A config-driven, multi-GPU-capable production wrapper over TRL; the core pattern is config-as-source-of-truth — the training recipe is a declarative YAML, not a program.",
        "A dataset-curation tool for building Axolotl-format preference datasets.",
        "A model-serving framework for deploying fine-tuned models with vLLM."
      ],
      "answer_index": 1,
      "rationale": "Axolotl is a config-driven wrapper over TRL. Its core contribution is the declarative YAML pattern: the entire recipe (model, data, PEFT, hyperparams, distributed, eval) is one reproducible, diff-able, CI-validatable file. It is not a competing engine — underneath it calls TRL's trainers."
    },
    {
      "id": "Q02", "bloom": "recall", "type": "multiple_choice",
      "prompt": "How does Axolotl relate to TRL under the hood?",
      "options": [
        "It replaces TRL's trainers with its own reimplementations.",
        "It wraps TRL — an SFT config uses SFTTrainer, DPO uses DPOTrainer, GRPO uses GRPOTrainer. The optimizer, loss, and checkpointing are all TRL's.",
        "It is unrelated to TRL; the two are independent stacks.",
        "It replaces TRL with PyTorch Lightning."
      ],
      "answer_index": 1,
      "rationale": "Axolotl WRAPS TRL. The resulting run uses TRL's trainer classes (SFTTrainer, DPOTrainer, GRPOTrainer), which themselves subclass the HuggingFace Trainer. Your TRL knowledge transfers directly; Axolotl names and organizes the knobs in YAML."
    },
    {
      "id": "Q03", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What two substantial things does the Axolotl wrapper add over raw TRL?",
      "options": [
        "Custom Triton kernels for 2x speed, and a built-in reward model.",
        "Opinionated cross-family defaults, and battle-tested multi-GPU orchestration (curated FSDP/DeepSpeed configs).",
        "A new loss function, and a built-in dataset synthesizer.",
        "GGUF export, and a built-in harness for safety policy."
      ],
      "answer_index": 1,
      "rationale": "Axolotl adds (1) opinionated cross-family defaults that work across Llama/Mistral/Qwen, and (2) battle-tested multi-GPU orchestration via curated FSDP/DeepSpeed configs that are fiddly and error-prone to write by hand. The multi-GPU curation is the decisive value-add for production."
    },
    {
      "id": "Q04", "bloom": "recall", "type": "multiple_choice",
      "prompt": "State the three properties config-as-source-of-truth gives you that a hand-written training script cannot.",
      "options": [
        "Faster training, lower VRAM, and automatic quantization.",
        "Reproducibility-as-a-file, diff-ability/version-ability, and CI-validatability.",
        "Built-in reward modeling, automatic data cleaning, and free GPUs.",
        "Automatic LoRA rank selection, hyperparameter search, and ensemble training."
      ],
      "answer_index": 1,
      "rationale": "The three properties: reproducibility is a file ('run this file' = 'reproduce my run'); diff-able/version-able (a git diff shows what changed); CI-validatable (a YAML can be linted/schema-validated before touching a GPU). This is the same reason Kubernetes manifests are YAML — declarative config is auditable."
    },
    {
      "id": "Q05", "bloom": "application", "type": "multiple_choice",
      "prompt": "You have a 4-GPU node and need to fine-tune a 70B model with a standard SFT recipe that must be reproducible by your team next quarter. Which tool, and why?",
      "options": [
        "Unsloth — its Triton kernels give ~2x speed on multi-GPU.",
        "Axolotl — its curated multi-GPU orchestration (FSDP/DeepSpeed) and config-as-source-of-truth make the job reproducible and remove the fiddly DeepSpeed config tax. Unsloth's multi-GPU story is limited/OOM-prone.",
        "Raw TRL CLI — it is always the simplest for any multi-GPU job.",
        "A hand-written train.py — full control is needed for 70B."
      ],
      "answer_index": 1,
      "rationale": "Axolotl is the right choice: the constraint is multi-GPU production + reproducibility + standard recipe. Axolotl's curated FSDP/DeepSpeed configs are the path of least resistance for multi-GPU, and the YAML guarantees reproducibility. Unsloth's multi-GPU support is limited and OOM-prone; it excels at single-GPU speed, not this regime."
    },
    {
      "id": "Q06", "bloom": "application", "type": "multiple_choice",
      "prompt": "Your GRPO job needs a custom Python reward function (a domain-specific scorer). Which tool, and why not Axolotl?",
      "options": [
        "Axolotl — its YAML can encode any reward function.",
        "Raw TRL (Python API) — Axolotl is configured not programmed; a custom reward function (Python callable) cannot be fully expressed in a static YAML. Drop to raw TRL for non-standard loops.",
        "Unsloth — it has the best reward-function support.",
        "Any of the three; they all handle custom rewards identically."
      ],
      "answer_index": 1,
      "rationale": "Axolotl is configured, not programmed. A custom reward function is Python code and cannot live in a static YAML. The moment your loop is non-standard (custom rewards, custom data transforms, interleaved eval), you drop to raw TRL's Python API. Use Axolotl for the standard recipes it excels at."
    },
    {
      "id": "Q07", "bloom": "application", "type": "multiple_choice",
      "prompt": "In an Axolotl YAML, how do you switch a run from QLoRA to full fine-tuning, and what does this illustrate?",
      "options": [
        "Delete the YAML and write a new train.py from scratch.",
        "Change `adapter: qlora` to `adapter: none` — one line. This illustrates the declarative pattern: the change is localized to the config, not scattered through code.",
        "Reinstall Axolotl with a different flag.",
        "It cannot be done without changing the base model."
      ],
      "answer_index": 1,
      "rationale": "Changing `adapter: qlora` to `adapter: none` switches the run to full fine-tuning — one config line, not a rewrite. This is the declarative pattern's payoff: the PEFT choice is a section of the config, so changing it is localized and diff-able. (LoRA rank/targets are separate keys when an adapter is used.)"
    },
    {
      "id": "Q08", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why is assuming 'Axolotl removes the need to understand TRL' a dangerous mistake?",
      "options": [
        "Because Axolotl will soon deprecate TRL support.",
        "Because Axolotl wraps TRL, a TRL-level problem (wrong learning rate, wrong loss, misunderstood trainer, wrong data shape) is still your problem. The wrapper configures the trainer; it does not absolve you of knowing what it does.",
        "Because TRL is faster than Axolotl, so you should always use TRL.",
        "Because Axolotl configs are automatically generated by TRL."
      ],
      "answer_index": 1,
      "rationale": "Axolotl is a layer OVER TRL. A TRL-level problem — a bad learning rate, the wrong trainer for the data, a misunderstood loss — manifests inside the Axolotl run and is still yours to diagnose and fix. The wrapper configures the trainer; it does not eliminate the need to understand the trainer. Learn TRL first (FTDD-04)."
    },
    {
      "id": "Q09", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "A team's config.yml runs successfully on the lead engineer's machine, but a teammate cannot reproduce the loss curve on an identical GPU. Which is the LEAST likely cause?",
      "options": [
        "An unspecified hyperparameter default that differs between their TRL versions.",
        "CLI overrides applied at runtime that were never written back into the YAML.",
        "Axolotl secretly rewriting the base model weights during training.",
        "The dataset split not being pinned, so a different data slice was used."
      ],
      "answer_index": 2,
      "rationale": "Axolotl does not secretly rewrite base weights — that violates the Steering Stack's swappability property (FT00). The likely causes are all config-as-source-of-truth failures: riding an unspecified default, undocumented runtime overrides, an unpinned dataset split, or precision ambiguity (bf16:auto resolving differently on different hardware). All stem from the config not being the complete, pinned source of truth."
    },
    {
      "id": "Q10", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why do many practitioners run a 'hybrid pattern' of Unsloth for sub-30B single-GPU and Axolotl for multi-GPU/above-30B, rather than picking one tool?",
      "options": [
        "Because they are indecisive about which tool is better.",
        "Because each tool optimizes a different constraint: Unsloth's Triton kernels give ~2x throughput / ~half VRAM on a single GPU (sub-30B), while Axolotl's curated multi-GPU orchestration and config-as-source-of-truth win for multi-GPU production. Using each for its strength is optimal, and Unsloth's TRL-compatible API makes the switch mostly a config change.",
        "Because Axolotl cannot run on a single GPU at all.",
        "Because Unsloth cannot do SFT, only RL."
      ],
      "answer_index": 1,
      "rationale": "The hybrid pattern is rational tool-selection by constraint, not indecision. Unsloth dominates the single-GPU sub-30B speed/VRAM regime; Axolotl dominates multi-GPU production/reproducibility. Because Unsloth exposes a TRL-compatible API and Axolotl wraps TRL, the transition between them is mostly a config change rather than a rewrite, making the hybrid pattern practical."
    }
  ]
}
