{
  "module": "FT09 — DoRA, rsLoRA, and Modern PEFT",
  "course": "3 — LLM Fine-Tuning Masterclass",
  "version": "1.0.0",
  "duration_minutes": 40,
  "total_questions": 15,
  "bloom_distribution": {
    "target": "20% recall / 40% application / 40% analysis-design",
    "actual": { "recall": 3, "application": 6, "analysis": 6 }
  },
  "passing_score_percent": 70,
  "questions": [
    {
      "id": "Q01", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What is the structural deficit of LoRA that DoRA (arXiv:2402.09353) names and fixes?",
      "options": [
        "LoRA's adapter matrices are too large, inflating VRAM.",
        "LoRA couples magnitude and direction updates proportionally — when the low-rank product B·A shifts a column, both the column's magnitude and its direction move together in a fixed ratio. Full fine-tuning updates them independently; LoRA structurally cannot.",
        "LoRA cannot be merged back into the base weight after training.",
        "LoRA's learning rate must be hand-tuned per layer."
      ],
      "answer_index": 1,
      "rationale": "DoRA's weight-decomposition analysis showed that full FT updates a filter's magnitude and direction INDEPENDENTLY, while LoRA updates them proportionally (locked by the rank and scaling factor). LoRA cannot rotate a direction without also rescaling its magnitude, and vice versa. This is roughly half of what full FT does, and the half LoRA cannot express at any rank. DoRA's fix is to decompose the weight into magnitude (vector m) and direction (normalized matrix + LoRA adapter) and adapt each independently."
    },
    {
      "id": "Q02", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What scaling factor does rsLoRA use, and what problem does it solve?",
      "options": [
        "α/r — same as vanilla LoRA; solves nothing new.",
        "α/√r (instead of α/r). Solves the high-rank instability: vanilla α/r collapses toward zero as rank grows (at r=64, α=16 the scale is 0.25), making the adapter numerically present but functionally inert. α/√r keeps the forward-pass magnitudes stable as rank climbs.",
        "α·r — amplifies the update at high rank.",
        "√α/r — dampens the update at high rank."
      ],
      "answer_index": 1,
      "rationale": "rsLoRA (rank-stabilized LoRA, arXiv:2312.03732) changes the scaling from α/r to α/√r. At rank 64 with α=16, vanilla LoRA scales by 16/64 = 0.25 (the adapter is attenuated almost to nothing); rsLoRA scales by 16/√64 = 2.0 (a meaningful effective update). 'rs' = rank-stabilized: it stabilizes the forward-pass magnitudes across the rank spectrum, so high-rank adapters actually train the way their parameter count suggests. Rule of thumb: above r=32, use rsLoRA."
    },
    {
      "id": "Q03", "bloom": "recall", "type": "multiple_choice",
      "prompt": "Which two PEFT flags turn the FT08 vanilla LoRA config into the 2026 DoRA + rsLoRA default in Hugging Face PEFT?",
      "options": [
        "use_lora=True and use_quant=True.",
        "use_dora=True and use_rslora=True. These two flags enable the magnitude/direction decomposition and the α/√r scaling respectively. No other change to the training loop, optimizer, or export pipeline is required.",
        "init_lora_weights='pissa' and use_galore=True.",
        "merge_after_train=True and shared_random=True."
      ],
      "answer_index": 1,
      "rationale": "The 2026 default is two flags on LoraConfig: use_dora=True (magnitude/direction decomposition) and use_rslora=True (α/√r scaling). That is the entire upgrade from the FT08 vanilla LoRA config. The merged artifact is shape-identical to a LoRA artifact and serves identically (zero inference overhead). PiSSA initialization is a separate, optional init_lora_weights setting; GaLore is a different training strategy, not a LoraConfig flag."
    },
    {
      "id": "Q04", "bloom": "application", "type": "multiple_choice",
      "prompt": "Your team needs to fine-tune a 7B base for a heavy domain shift (a new modality far from pretraining) on a single 24 GB consumer GPU. Per FT09, what is the right starting point?",
      "options": [
        "Vanilla LoRA at r=8 — keep it cheap.",
        "QDoRA — DoRA on top of a 4-bit quantized base. DoRA's magnitude/direction decoupling buys the most headroom on domain shifts, and QDoRA delivers that quality at the QLoRA memory cost that fits a 7B model on a 24 GB card.",
        "Vanilla full fine-tuning — domain shifts need full FT.",
        "VeRA — minimize parameter count for the new modality."
      ],
      "answer_index": 1,
      "rationale": "This is the QDoRA use case. DoRA's advantage is largest on domain shifts (full FT updates magnitude and direction aggressively; DoRA approximates that; LoRA cannot). QDoRA brings the DoRA quality point down to QLoRA's memory cost, fitting a 7B on a 24 GB card. Vanilla full FT would not fit (optimizer state alone is ~56 GB). VeRA is for storage-bottleneck multi-adapter scenarios, not domain shift. If QDoRA were measured-insufficient, the escalation is GaLore (full-param FT at near-LoRA memory), not vanilla full FT."
    },
    {
      "id": "Q05", "bloom": "application", "type": "multiple_choice",
      "prompt": "A team reports: 'We set rank=128 with vanilla LoRA, trained, and saw no improvement over rank=16. Our data must be bad.' Per FT09, what is the likely diagnosis and fix?",
      "options": [
        "The data is bad; collect more.",
        "Rank-stability failure. At rank 128 with α=16, vanilla LoRA's α/r scaling gives 0.125 — the adapter is numerically present but functionally inert. Fix: set use_rslora=True (α/√r scaling ≈ 1.41 at r=128), restoring a meaningful effective update. The data is probably fine.",
        "Reduce the rank to 4; high rank always overfits.",
        "Switch to full fine-tuning; LoRA cannot handle r=128."
      ],
      "answer_index": 1,
      "rationale": "This is the 'ignoring the rank-stability issue at high rank' anti-pattern. Vanilla LoRA attenuates the update by 1/r — at rank 128 with α=16 the scale is 0.125, and the adapter is nearly inert. The model cannot use the capacity the high rank provides. The fix is one flag: use_rslora=True, which switches the scaling to α/√r = 16/√128 ≈ 1.41. If you are above r=32 and not using rsLoRA, you are almost certainly wasting your rank budget and blaming the data."
    },
    {
      "id": "Q06", "bloom": "application", "type": "multiple_choice",
      "prompt": "You are configuring a PEFT run at r=64 on a 16 GB GPU with bf16 weights (no quantization). You want the 2026 default. Which LoraConfig is correct?",
      "options": [
        "LoraConfig(r=64, lora_alpha=64, use_dora=True, use_rslora=True, target_modules=[...]).",
        "LoraConfig(r=64, lora_alpha=64, use_dora=False, use_rslora=False, target_modules=[...]).",
        "LoraConfig(r=64, lora_alpha=64, use_dora=True, use_rslora=False, target_modules=[...]).",
        "LoraConfig(r=8, lora_alpha=16, use_dora=True, use_rslora=True, target_modules=[...])."
      ],
      "answer_index": 0,
      "rationale": "The 2026 default at r=64 is DoRA + rsLoRA: use_dora=True AND use_rslora=True. Option B is vanilla LoRA (no decomposition, no rank-stabilization — wasted at r=64). Option C omits rsLoRA, so the α/r scaling attenuates the update (at α=64, r=64, scale=1.0, borderline; the rsLoRA α/√r=8.0 is more stable). Option D drops the rank to 8, contradicting the r=64 requirement. The correct config enables both flags at the requested rank."
    },
    {
      "id": "Q07", "bloom": "application", "type": "multiple_choice",
      "prompt": "You have concluded (via the FT10 decision tree) that your task genuinely requires full-parameter fine-tuning, but your only GPU has 24 GB VRAM. Vanilla full FT does not fit. Per FT09, what do you use?",
      "options": [
        "DoRA + rsLoRA — it is the default.",
        "VeRA — minimal parameters.",
        "GaLore — it projects the gradient into a low-rank subspace so the optimizer state (the dominant memory cost) is compressed, enabling full-parameter training at near-LoRA memory. GaLore fit a 7B full-param run on a single 24 GB RTX 4090.",
        "PiSSA initialization on a LoRA adapter."
      ],
      "answer_index": 2,
      "rationale": "This is the GaLore use case verbatim: 'I want full-FT quality on a memory-limited node.' GaLore trains ALL parameters (full-param FT) but projects the gradient into a low-rank subspace before the optimizer sees it, so the expensive optimizer state (Adam's first/second moment buffers — ~56 GB for a 7B) lives in the low-rank subspace. DoRA is the default for steering tasks but it freezes the base — it is NOT full-param FT. VeRA and PiSSA are adapter methods. When the decision says 'full FT' and the GPU says 'no,' GaLore is the bridge."
    },
    {
      "id": "Q08", "bloom": "application", "type": "multiple_choice",
      "prompt": "You are running an NLU-heavy task (classification + extraction) with a tight training-compute budget. You want faster convergence than vanilla LoRA without changing parameter count. Which FT09 method fits, and what is the tradeoff?",
      "options": [
        "VeRA — fewer parameters, faster convergence.",
        "GaLore — full-param quality.",
        "PiSSA — it initializes the adapter from the SVD principal components of W₀ instead of random/zero, giving faster convergence and stronger NLU quality at the same parameter count. Tradeoff: it modifies the frozen base (reshuffles principal vs residual), so the merge-back must merge into the residual base, not the original — a one-time accounting cost.",
        "rsLoRA — it stabilizes the scaling."
      ],
      "answer_index": 2,
      "rationale": "PiSSA (arXiv:2404.02948) is the drop-in initialization alternative for exactly this case: NLU-heavy, convergence-speed-sensitive, same parameter count. It seeds the LoRA matrices from the top-r singular vectors of W₀, so the adapter starts from the most important directions already in the weight rather than building from scratch. The tradeoff is a modified merge workflow (merge into the residual base). VeRA is for storage bottlenecks; GaLore is full-param (not what was asked); rsLoRA fixes scaling, not initialization."
    },
    {
      "id": "Q09", "bloom": "application", "type": "multiple_choice",
      "prompt": "In the FT09 lab, why must the vanilla LoRA run and the DoRA + rsLoRA run share the SAME base model, the SAME data, the SAME rank, the SAME epochs, batch size, and learning rate?",
      "options": [
        "Because DoRA requires identical hyperparameters to LoRA.",
        "To isolate the effect of the PEFT method itself. If you also change the rank, the LR, or the dataset, the quality delta is confounded — you can no longer attribute it to DoRA. The discipline of a PEFT A/B: change exactly one thing (the adapter method), hold everything else fixed.",
        "Because the eval harness cannot handle different hyperparameters.",
        "Because PEFT forbids changing hyperparameters between runs."
      ],
      "answer_index": 1,
      "rationale": "A controlled A/B requires changing exactly one variable. If Run A is vanilla LoRA at r=8 and Run B is DoRA at r=64, a quality delta could be caused by DoRA OR by the rank difference — you cannot tell which. By holding base, data, rank, epochs, batch, and LR constant, the only difference is use_dora/use_rslora, and any delta is attributable to the method. This is the only valid basis for adopting a new PEFT method; benchmark-shopping (switching on a paper's claim) is the anti-pattern."
    },
    {
      "id": "Q10", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why does DoRA's lead over LoRA SHRINK as rank increases, and what does this imply about choosing between DoRA and rsLoRA at high rank?",
      "options": [
        "DoRA gets worse at high rank; use vanilla LoRA instead.",
        "At low rank vanilla LoRA is most constrained by the magnitude/direction coupling, so DoRA's decoupling buys the most headroom there. As rank grows, LoRA has more room to express updates and the coupling matters less, so DoRA's relative lead shrinks. But high rank is where rsLoRA becomes essential (vanilla α/r attenuates the update). Implication: the two methods address DIFFERENT high-rank problems — DoRA's advantage shrinks, rsLoRA's advantage grows — so you STACK them rather than choose.",
        "DoRA and rsLoRA are the same at high rank.",
        "At high rank, full FT becomes cheaper than DoRA."
      ],
      "answer_index": 1,
      "rationale": "DoRA and rsLoRA address orthogonal high-rank issues. DoRA's magnitude/direction decoupling matters most at LOW rank (where vanilla LoRA is most constrained) and less at high rank (where the extra capacity gives LoRA room). rsLoRA matters most at HIGH rank (where vanilla α/r scaling collapses the update) and barely at low rank. So as rank climbs, DoRA's contribution shrinks and rsLoRA's contribution grows — they are complementary, not substitutable. This is why the 2026 default is DoRA AND rsLoRA together, not a choice between them."
    },
    {
      "id": "Q11", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "A colleague argues: 'DoRA is strictly better than LoRA, so we should retrain all our existing LoRA adapters as DoRA.' What is the FT09-correct critique of this argument?",
      "options": [
        "Correct — DoRA is always better, retrain everything.",
        "DoRA's advantage is CONTEXT-DEPENDENT — largest at low rank and on domain shifts, smaller on tasks close to the base distribution. The only valid basis for adopting/switching is a controlled A/B on YOUR held-out eval, YOUR data. Retraining every existing adapter without measuring is the 'chasing novelty without measuring' anti-pattern. DoRA is the 2026 default for NEW adapters, not a mandate to retrain working ones without evidence.",
        "Wrong — DoRA is actually worse than LoRA in production.",
        "DoRA requires a new training loop, so it is too expensive to retrain."
      ],
      "answer_index": 1,
      "rationale": "DoRA is the 2026 default for NEW work, but 'strictly better everywhere' overstates the evidence. DoRA's lead is largest at low rank and on domain shifts; for a vanilla instruction-tuning SFT close to the base distribution, the gap can be small. The FT09 discipline: adopt a method based on a controlled A/B on your own held-out eval, not on a paper's benchmark or a blanket claim. Retraining every working LoRA adapter as DoRA, without measuring whether it helps each specific task, is the cardinal anti-pattern — it spends a quarter and may ship nothing."
    },
    {
      "id": "Q12", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why is GaLore described as 'the bridge between PEFT and full FT' rather than as just another PEFT method?",
      "options": [
        "Because GaLore uses LoRA adapters internally.",
        "Because GaLore is slower than LoRA and therefore bridges two performance regimes.",
        "Because GaLore is structurally different from adapter methods: it trains ALL parameters (full-param FT, like full FT) but achieves near-LoRA memory by projecting the GRADIENT into a low-rank subspace so the optimizer state is compressed. Adapter methods (DoRA, rsLoRA, PiSSA, VeRA) freeze the base; GaLore updates it. It is full FT in behavior, PEFT-like in memory — the bridge.",
        "Because GaLore was published between the LoRA and full-FT papers."
      ],
      "answer_index": 2,
      "rationale": "GaLore is categorically different from adapter PEFT. DoRA/rsLoRA/PiSSA/VeRA all freeze the base and train a small adapter. GaLore trains ALL parameters — it IS full-parameter fine-tuning in what it learns. The PEFT-like aspect is the memory mechanism: it projects the gradient into a low-rank subspace before the optimizer sees it, so the expensive optimizer state lives in the low-rank subspace. This is why it 'bridges' — full-FT quality (it updates the whole model) at near-LoRA memory. It is the answer when the decision tree says 'full FT' but the GPU says 'no.'"
    },
    {
      "id": "Q13", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why does DoRA claim 'zero inference overhead after merging', and why is this property load-bearing for production adoption?",
      "options": [
        "Because DoRA's adapter is smaller than LoRA's, so inference is faster.",
        "Because after training, the magnitude vector m and the direction update ΔW are folded back into a single merged weight tensor that is shape-identical to the base (and to a merged LoRA). A merged DoRA model has the same forward-pass cost, memory footprint, and serving path as the base or a merged LoRA — no special kernel, no extra params at inference. Load-bearing because it means adopting DoRA requires NO changes to the serving stack.",
        "Because DoRA disables the adapter at inference.",
        "Because DoRA uses 4-bit quantization by default."
      ],
      "answer_index": 1,
      "rationale": "DoRA's decomposition (magnitude vector + direction LoRA) exists only during training. At merge time, m ⊙ (W₀/‖W₀‖) + ΔW_dir is folded into a single weight tensor of the same shape as the base. The merged DoRA model is indistinguishable from the base (or a merged LoRA) at inference: same forward pass, same memory, same serving path, no special kernel. This is load-bearing for production because it means adopting DoRA requires zero changes downstream — the export (FT19), the quantizer (FT20), and the harness (Course 1) see a normal model. If DoRA added inference overhead, it would not be the 2026 default."
    },
    {
      "id": "Q14", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "AdaLoRA (adaptive rank allocation) and DoRA both aim to improve on vanilla LoRA. Why does FT09 say AdaLoRA is 'largely superseded by DoRA'?",
      "options": [
        "Because AdaLoRA was retracted.",
        "Because DoRA is older and more established.",
        "AdaLoRA's approach is to dynamically redistribute the rank budget across layers during training. DoRA's weight-decomposition analysis showed that the deeper problem is not WHERE to put the rank but the magnitude/direction coupling itself — a problem no rank allocation solves. DoRA addresses the structural deficit directly, with simpler code (two flags) and consistent gains across tasks. AdaLoRA's adaptive-allocation problem is still real but is now better handled by DoRA's decomposition plus an appropriate fixed rank.",
        "Because AdaLoRA requires more memory than DoRA."
      ],
      "answer_index": 2,
      "rationale": "AdaLoRA tried to solve 'where should the rank budget go across layers?' by adapting rank allocation during training. DoRA's contribution reframed the problem: the structural deficit of LoRA is the magnitude/direction coupling, not rank misallocation. No redistribution of rank fixes the coupling; only decomposition does. DoRA also ships as two simple flags (use_dora, use_rslora) versus AdaLoRA's more complex adaptive machinery, and shows consistent gains across tasks. AdaLoRA's underlying intuition (rank allocation matters) is not wrong, but it is now a second-order concern behind DoRA's first-order fix."
    },
    {
      "id": "Q15", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "The FT09 teaching doc places VeRA, AdaLoRA, and MiSS on a 'niche/research' axis rather than the 'standard' axis with DoRA/rsLoRA/PiSSA/GaLore. What distinguishes the two axes, and why does the distinction matter for production?",
      "options": [
        "The standard axis has more recent papers.",
        "The standard axis has higher parameter counts.",
        "The distinction is REPRODUCIBILITY and ECOSYSTEM SUPPORT plus consistent gains across tasks and models, reproduced by independent teams. DoRA/rsLoRA/PiSSA/GaLore meet this bar (default status). VeRA (~10× fewer params but inconsistent quality), AdaLoRA (superseded by DoRA), and MiSS (claims SOTA, not widely reproduced) do not. Matters because adopting a niche method in production risks unreproducible results, fragile pipelines, and switching cost without proven benefit — the 'chasing novelty' anti-pattern.",
        "The niche axis methods are all older than 2023."
      ],
      "answer_index": 2,
      "rationale": "The standard-vs-niche axis is not about recency, parameter count, or age. It is about whether a method has earned default status through (a) consistent gains across many tasks and models, (b) reproduction by independent teams, and (c) ecosystem support (PEFT integration, serving compatibility). DoRA, rsLoRA, PiSSA, GaLore meet this bar. VeRA's quality is not consistently there (useful only for storage-bottleneck multi-adapter), AdaLoRA's problem is better solved by DoRA, and MiSS's claims are not widely reproduced. Adopting niche methods in production risks unreproducible results and switching cost without proven benefit — exactly the 'chasing novelty without measuring' anti-pattern."
    }
  ]
}
