Claude Cursor Skill

finetuning-method-selection

Decide whether to fine-tune at all, and route to the right method (SFT, DPO/ORPO/KTO, GRPO/RLVR, continued pretraining) and base model. Use when starting any fine-tuning effort, when unsure whether RAG or prompting would suffice, or when choosing between preference-optimization a

LLM Mart · 0 points · 10 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download wshobson-agents-plugins_llm-finetuning_skills_finetuning-method-selection-554237f.zip · 7 KB
Part of wshobson/agents — 170 skills

Install

skills CLI npx skills add https://github.com/wshobson/agents/tree/main/plugins/llm-finetuning/skills/finetuning-method-selection
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install wshobson-agents@llmmart
Git git clone https://github.com/wshobson/agents.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole wshobson/agents collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Fine-Tuning Method Selection

This is the router skill for the fine-tuning lifecycle: it decides whether fine-tuning is the right tool at all, and if so, which method and which base-model size class. Every other skill in this plugin assumes this routing already happened — start here before opening lora-qlora-recipes, preference-optimization, or grpo-rlvr-training.

When to Use This Skill

  • Starting any fine-tuning effort, before a framework or base model has been chosen.
  • Unsure whether RAG or prompt engineering would solve the problem more cheaply than training.
  • Choosing between preference optimization (DPO family) and a reinforcement method (GRPO/RLVR) for the same underlying task.
  • Sizing a candidate model/method combination before committing to a run.

Quick Reference

Situation Route
Facts change often (prices, docs, news) RAG, not fine-tuning
Desired behavior still being figured out Prompt engineering
Stable domain knowledge, ≥500MB text CPT then SFT — see Off-Ramps First
Have input/output demonstrations SFT — see lora-qlora-recipes
Have preference pairs or thumbs-up/down DPO/ORPO/KTO — see preference-optimization
Have a verifiable pass/fail signal GRPO+RLVR — see grpo-rlvr-training
No eval harness yet Stop — see eval-harness-first

Off-Ramps First

Most requests that sound like "fine-tune this" are served better and cheaper elsewhere. Check these off-ramps before opening a training run:

  • Knowledge-bound and volatile (the gap is facts that change — prices, docs, current events): route to RAG, not fine-tuning. A fine-tuned model bakes in a snapshot; volatile facts go stale immediately.
  • Behavior-bound and shifting (the desired behavior is still being figured out, or changes per request): route to prompt engineering. Fine-tuning locks in a behavior; don't lock in one that hasn't stabilized yet.
  • Stable, dense domain knowledge: this is where continued pretraining (CPT) enters, sized by how much domain text exists:
Domain text volume Route
<10MB RAG only
10MB–500MB RAG + fine-tune
500MB–10GB CPT, then SFT
>10GB CPT required

CPT learning rate ≈ 10% of the pretraining LR. CPT is guidance-only in this plugin — sizing and LR guidance live here, but this plugin does not execute a CPT run.

Method Router

Once the off-ramps are ruled out, this is the full decision tree (verbatim from the research this plugin is built on):

New FACTS?  volatile → RAG | stable+dense → CPT (LR ~10% of pretrain) → SFT
New BEHAVIOR? shifting → prompt-engineering | stable:
  demos → SFT (LoRA/QLoRA, all-linear, α=2r)
  preference pairs → DPO (SimPO if length-bias, ORPO if memory-bound)
  unpaired 👍/👎 → KTO
  verifiable success → RLVR + GRPO (DAPO/GSPO/Dr.GRPO per failure mode)
Deploy: FP8 (Hopper+) | NVFP4 (Blackwell scale) | AWQ (older) | GGUF+imatrix (edge)
BEFORE ANY OF THIS: the eval harness must exist first.

Read the tree top-down: answer "new facts or new behavior," then follow the branch that matches the data shape in hand (demos, preference pairs, thumbs up/down, or verifiable success/failure). The data shape picks the method — not the other way around.

Worked Routing Examples

  • "Users want the assistant to follow our support macros exactly." Behavior is stable and demonstrable from transcripts → demos → SFT.
  • "We have pairs of good/bad responses from reviewer thumbs-up/down, unpaired." → unpaired signal → KTO, not DPO (DPO needs paired preferences).
  • "The model can already solve some of these math problems and we can grade correctness automatically." → verifiable success signal → GRPO+RLVR, and only after confirming the model succeeds at least sometimes (see Key Routing Facts below).
  • "We want the model to know this week's pricing page." → volatile facts → RAG, no training run at all.

Key Routing Facts

  • Loss-function choice is low-leverage. A 240-H100-run study found method choice worth ~1 percentage point versus ~50 points for model scale, and zero of 20 DPO variants beat vanilla DPO. Don't spend a routing decision agonizing over DPO-variant selection — spend it on getting the data shape and scale right.
  • DPO is for taste, GRPO+RLVR is for reasoning. Preference pairs that encode a subjective judgment (tone, style, "which answer is better") route to DPO. Tasks with a verifiable pass/fail signal (math, code, tool calls) route to GRPO+RLVR instead.
  • RL is not the fix for a model that never succeeds. GRPO and other RL methods sharpen an existing capability — they don't teach one from zero. If the model doesn't yet understand the task or output format, run SFT first; only bring in RL once the model succeeds at least sometimes.

Common Routing Mistakes

  • Reaching for fine-tuning to fix facts that change weekly — that's a RAG problem, and fine-tuning will just go stale faster than the source data does.
  • Picking a DPO variant before checking whether the actual bottleneck is data quality or model scale — variant choice is the ~1pp lever, not the ~50pp one.
  • Starting an RL run on a model that fails every rollout — route to SFT first so RL has something to sharpen.
  • Treating CPT as the default for "the model doesn't know our domain" — check the data volume thresholds first; under 500MB, RAG or RAG+fine-tune iterates faster than a CPT run.

Model Selection

Base-model choice is size-class first, family second, and it goes stale fast — so it lives in exactly one place: references/model-catalog.md. That file is the only place in this plugin (and in the DGX Spark ops plugin) that names a base model family. Neither this skill nor references/memory-math.md names one; both describe models by size class only (for example, "8B-class LoRA," not a model name).

The catalog is dated on purpose — model rankings turn over quarterly. It carries a "last verified" date and a refresh checklist. Before trusting a row, check that date; if stale, work the refresh checklist in the catalog before recommending a model from it.

Precedence when the catalog and a method skill disagree: the catalog's per-row Notes column states hardware/size-class feasibility, not a method recommendation — lora-qlora-recipes's LoRA vs QLoRA vs Full FT table (routed by task shape) governs the actual method choice.

Memory Feasibility

Before committing to a method, size it: total memory ≈ params × dtype bytes + optimizer state + gradients + activations. Work each term for the chosen dtype and method (full fine-tune, LoRA, or QLoRA) — worked worksheets and size-class examples live in references/memory-math.md.

On DGX Spark specifically, unified-memory behavior breaks the naive estimate (transient load peaks, nvidia-smi underreporting, thermal throttling on long runs). Once the dgx-spark-ops plugin is installed, defer Spark-specific feasibility calls to its spark-memory-thermal-ops skill rather than re-deriving them here.

Related Skills

Once this skill has picked a method, hand off to the skill that executes it:

  • lora-qlora-recipes — SFT via LoRA/QLoRA
  • preference-optimization — DPO, ORPO, KTO
  • grpo-rlvr-training — GRPO with verifiable rewards

No method is selected before the eval harness exists — see eval-harness-first.

Files (agents)
  • references
    • memory-math.md 5.3 KB
      Last verified: 2026-07-13 — refresh when a new
      size-class anchor is validated or optimizer/dtype
      defaults change.
      
      # Memory Math
      
      A worksheet for estimating whether a model
      size-class, method, and batch/pack combination
      fits available memory before a run. This is
      planning math, not a guarantee — leave headroom
      rather than sizing to the byte. Base models are
      never named here; every example is labeled by
      size class only (for example, "8B-class LoRA
      bf16"). See `model-catalog.md` for which actual
      model to use at a given size class.
      
      ## The Four Terms
      
      Total footprint ≈ **weights + optimizer states +
      gradients + activations**, plus a near-zero term
      for LoRA/QLoRA adapters. Work each term from
      parameter count and dtype, then sum.
      
      ### 1. Weights
      
      `params × bytes/param`, by dtype:
      
      | dtype | bytes/param |
      |---|---|
      | fp32 | 4 |
      | bf16 / fp16 | 2 |
      | int8 | 1 |
      | int4 (QLoRA NF4) | 0.5 |
      
      This term dominates for full fine-tuning, and the
      calculation (`params × bytes/param`) is the same
      formula regardless of method — but the dtype, and
      so the result, is not: bf16 LoRA loads weights at
      2 bytes/param while int4 QLoRA loads the same
      parameter count at 0.5 bytes/param, a 4x gap.
      Reuse the formula across methods; never reuse the
      resulting weight-memory number from one method's
      dtype for another's.
      
      ### 2. Optimizer states
      
      Full fine-tuning carries optimizer state for
      every trainable parameter; LoRA and QLoRA carry
      it only for the adapter parameters, which is why
      this term is negligible for them regardless of
      base model size.
      
      | Optimizer | bytes/param (trainable only) |
      |---|---|
      | AdamW, fp32 states | 8 (4B momentum + 4B variance) |
      | AdamW 8-bit | ≈2 (quantized momentum + variance) |
      
      8-bit AdamW roughly quarters this term versus the
      fp32 variant for any run that isn't LoRA/QLoRA-
      adapter-only, where it's already negligible.
      
      ### 3. Gradients
      
      Same dtype as compute precision — typically bf16,
      so 2 bytes/param — and, like optimizer state,
      only for trainable parameters. Full fine-tuning
      pays this for every weight; LoRA and QLoRA pay it
      only for the adapter, since frozen base weights
      never accumulate a gradient.
      
      ### 4. Activations
      
      The hardest term to pin to a single number — it
      scales with batch size, sequence/packing length,
      and architecture, not just parameter count. Two
      levers matter more than exact estimation:
      
      - **Gradient checkpointing** trades recompute for
        memory: expect roughly **30% savings** on this
        term versus no checkpointing, at the cost of a
        recompute pass per checkpointed segment.
      - Packing/sequence length is a more direct lever
        than batch size for this term.
      
      ### 5. LoRA/QLoRA adapter overhead
      
      A rank-`r` adapter on a linear layer adds
      `r × (in + out)` parameters — `A` is `r×in` and `B`
      is `out×r`, so together they contribute
      `r·in + r·out`. At normal rank sizes (1–32 for RL,
      up to ~256 for SFT-at-scale),
      this is a small fraction of a percent of base
      model size — round it to zero in the worksheet
      unless an unusually high rank is in play.
      
      ## Worked Examples
      
      ### 8B-class LoRA, bf16
      
      Weights dominate; optimizer state and gradients
      are adapter-only and small.
      
      ```python
      params = 8e9
      weights_gb = params * 2 / 1e9   # bf16, step 1
      adapter_gb = 0.2                # step 5, negligible
      total_gb = weights_gb + adapter_gb  # + activations
      print(f"{total_gb:.0f}GB before activations")
      ```
      
      Weights alone land around 16GB — the reference
      point for "an 8B-class model fits comfortably on
      a single high-memory GPU in bf16 LoRA."
      
      ### 8B-class QLoRA
      
      Same parameter count, quantized weights:
      
      ```python
      params = 8e9
      weights_gb = params * 0.5 / 1e9  # int4 NF4, step 1
      adapter_gb = 0.2                 # step 5, negligible
      total_gb = weights_gb + adapter_gb  # + activations
      print(f"{total_gb:.0f}GB before activations")
      ```
      
      Weights land around 4GB — roughly a 4x reduction
      versus bf16 LoRA, which is why QLoRA is the
      method that buys headroom for larger batch size
      or longer packing at the same size class, not
      just a way to fit bigger models.
      
      ### 70B-class QLoRA (≈40GB anchor)
      
      ```python
      params = 70e9
      weights_gb = params * 0.5 / 1e9  # int4 NF4, step 1
      adapter_gb = 0.5                 # step 5, negligible
      total_gb = weights_gb + adapter_gb  # + activations
      print(f"{total_gb:.0f}GB before activations")
      ```
      
      The idealized formula lands weights at **≈35GB**
      (decimal GB, weights only); treat **≈40GB** as the
      real-world anchor once quantization metadata
      (NF4 double-quant constants) and runtime overhead
      are included — the reference point for "a 70B-class
      model is reachable via QLoRA, not bf16," where
      bf16 weights alone (≈140GB) would already exceed
      most single-device budgets before optimizer state,
      gradients, or activations are added. A plan
      estimating far above the ≈40GB anchor for the same
      size class is a signal to recheck dtype and
      method, not just add headroom.
      
      ## Using These Numbers
      
      1. Pick the size class and method from
         `model-catalog.md`.
      2. Sum weights + optimizer + gradients from the
         tables above for that combination.
      3. Add activations, applying the ~30% gradient-
         checkpointing saving if it's enabled.
      4. Compare against the closest worked example or
         anchor above rather than trusting the estimate
         in isolation — a plan far off an anchor for the
         same size class and method is a signal to
         recheck inputs before assuming the hardware
         won't work.
      
    • model-catalog.md 2.7 KB
      # Model Catalog
      
      Last verified: 2026-07-14
      Refresh checklist: (1) check Unsloth supported-models page, (2) check the current open-weights leaderboards for each size class, (3) update rows + bump this date. Refresh at least quarterly; this file is the ONLY place base models are named in the llm-finetuning and dgx-spark-ops plugins.
      
      ## How to Read This Table
      
      Pick the row matching the target parameter count,
      then read across: a text recommendation, a vision
      (VLM) recommendation for the same size class, what
      that class can do on a single DGX Spark, and any
      notes that change the recommendation. Cross-check
      the "last verified" date above before trusting a
      row — if it's stale, work the refresh checklist
      first.
      
      ## Catalog (2026-07)
      
      | Size class | Text recommendation | Vision recommendation | Spark feasibility | Notes |
      |---|---|---|---|---|
      | ≤4B | Qwen3 4B class | SmolVLM / Gemma 3 4B | Full fine-tune feasible | Smallest class where full FT is still *feasible* by default — a hardware/size-class note, not a method recommendation. Method choice (LoRA vs. full FT) is `lora-qlora-recipes`'s LoRA vs QLoRA vs Full FT table, routed by task shape (demonstrations vs. dense knowledge injection); that table governs over this feasibility note whenever the two appear to disagree. |
      | 7–9B | Qwen3 8B, Llama-class 8B | Qwen2.5-VL-7B | Full fine-tune ceiling | Above this class, full FT stops being the default on Spark — see 12–32B row. |
      | 12–32B | Qwen3 14B/32B, Gemma 3 27B | Qwen2.5-VL-32B | LoRA-only; 27B is the LoRA ceiling at pack≤1024 | 27B is the largest dense model that fits a LoRA run on a single Spark in practice. |
      | 70B+ | Llama 3.3 70B class | Use the 12–32B vision class instead — no 70B+ VLM recommendation at this size | QLoRA-only, ≈40GB, 30–48h for 3 epochs | bf16 is not feasible at this class on a single Spark; QLoRA is the only path in. |
      | 100B+ MoE | gpt-oss-120b class | Use the 12–32B vision class instead — no 100B+ MoE VLM recommendation at this size | NVFP4-native LoRA via community recipe (`nvfp4-lora-spark`), experimental | Not the default assumption for other 100B+ MoE models — verify per-model before relying on this row. |
      
      ## Vision Model Notes
      
      - **LLaVA is legacy.** Do not recommend it for new
        work; it is listed here only so a stale
        recommendation can be recognized as such.
      - **InternVL3.5 MoE variants are the MoE VLM
        alternative** to the dense Qwen2.5-VL / Qwen3-VL
        and Gemma 3 vision models above, for cases that
        specifically call for a mixture-of-experts
        vision-language architecture — InternVL3.5 also
        ships dense checkpoints, so pick the MoE variant
        explicitly rather than assuming every InternVL3.5
        release is MoE.
      
  • SKILL.md 7.7 KB
    ---
    name: finetuning-method-selection
    description: Decide whether to fine-tune at all, and route to the right method (SFT, DPO/ORPO/KTO, GRPO/RLVR, continued pretraining) and base model. Use when starting any fine-tuning effort, when unsure whether RAG or prompting would suffice, or when choosing between preference-optimization and reinforcement methods.
    ---
    
    # Fine-Tuning Method Selection
    
    This is the router skill for the fine-tuning
    lifecycle: it decides whether fine-tuning is the
    right tool at all, and if so, which method and
    which base-model size class. Every other skill
    in this plugin assumes this routing already
    happened — start here before opening
    `lora-qlora-recipes`, `preference-optimization`,
    or `grpo-rlvr-training`.
    
    ## When to Use This Skill
    
    - Starting any fine-tuning effort, before a
      framework or base model has been chosen.
    - Unsure whether RAG or prompt engineering would
      solve the problem more cheaply than training.
    - Choosing between preference optimization (DPO
      family) and a reinforcement method (GRPO/RLVR)
      for the same underlying task.
    - Sizing a candidate model/method combination
      before committing to a run.
    
    ## Quick Reference
    
    | Situation | Route |
    |---|---|
    | Facts change often (prices, docs, news) | RAG, not fine-tuning |
    | Desired behavior still being figured out | Prompt engineering |
    | Stable domain knowledge, ≥500MB text | CPT then SFT — see Off-Ramps First |
    | Have input/output demonstrations | SFT — see `lora-qlora-recipes` |
    | Have preference pairs or thumbs-up/down | DPO/ORPO/KTO — see `preference-optimization` |
    | Have a verifiable pass/fail signal | GRPO+RLVR — see `grpo-rlvr-training` |
    | No eval harness yet | Stop — see `eval-harness-first` |
    
    ## Off-Ramps First
    
    Most requests that sound like "fine-tune this"
    are served better and cheaper elsewhere. Check
    these off-ramps before opening a training run:
    
    - **Knowledge-bound and volatile** (the gap is
      facts that change — prices, docs, current
      events): route to RAG, not fine-tuning. A
      fine-tuned model bakes in a snapshot; volatile
      facts go stale immediately.
    - **Behavior-bound and shifting** (the desired
      behavior is still being figured out, or
      changes per request): route to prompt
      engineering. Fine-tuning locks in a behavior;
      don't lock in one that hasn't stabilized yet.
    - **Stable, dense domain knowledge**: this is
      where continued pretraining (CPT) enters, sized
      by how much domain text exists:
    
    | Domain text volume | Route |
    |---|---|
    | <10MB | RAG only |
    | 10MB–500MB | RAG + fine-tune |
    | 500MB–10GB | CPT, then SFT |
    | >10GB | CPT required |
    
    CPT learning rate ≈ **10% of the pretraining
    LR**. CPT is guidance-only in this plugin —
    sizing and LR guidance live here, but this
    plugin does not execute a CPT run.
    
    ## Method Router
    
    Once the off-ramps are ruled out, this is the
    full decision tree (verbatim from the research
    this plugin is built on):
    
    ```
    New FACTS?  volatile → RAG | stable+dense → CPT (LR ~10% of pretrain) → SFT
    New BEHAVIOR? shifting → prompt-engineering | stable:
      demos → SFT (LoRA/QLoRA, all-linear, α=2r)
      preference pairs → DPO (SimPO if length-bias, ORPO if memory-bound)
      unpaired 👍/👎 → KTO
      verifiable success → RLVR + GRPO (DAPO/GSPO/Dr.GRPO per failure mode)
    Deploy: FP8 (Hopper+) | NVFP4 (Blackwell scale) | AWQ (older) | GGUF+imatrix (edge)
    BEFORE ANY OF THIS: the eval harness must exist first.
    ```
    
    Read the tree top-down: answer "new facts or new
    behavior," then follow the branch that matches
    the data shape in hand (demos, preference pairs,
    thumbs up/down, or verifiable success/failure).
    The data shape picks the method — not the other
    way around.
    
    ### Worked Routing Examples
    
    - *"Users want the assistant to follow our
      support macros exactly."* Behavior is stable
      and demonstrable from transcripts → demos →
      **SFT**.
    - *"We have pairs of good/bad responses from
      reviewer thumbs-up/down, unpaired."* → unpaired
      signal → **KTO**, not DPO (DPO needs paired
      preferences).
    - *"The model can already solve some of these
      math problems and we can grade correctness
      automatically."* → verifiable success signal →
      **GRPO+RLVR**, and only after confirming the
      model succeeds at least sometimes (see Key
      Routing Facts below).
    - *"We want the model to know this week's
      pricing page."* → volatile facts → **RAG**, no
      training run at all.
    
    ## Key Routing Facts
    
    - **Loss-function choice is low-leverage.** A
      240-H100-run study found method choice worth
      ~1 percentage point versus ~50 points for model
      scale, and zero of 20 DPO variants beat vanilla
      DPO. Don't spend a routing decision agonizing
      over DPO-variant selection — spend it on
      getting the data shape and scale right.
    - **DPO is for taste, GRPO+RLVR is for
      reasoning.** Preference pairs that encode a
      subjective judgment (tone, style, "which answer
      is better") route to DPO. Tasks with a
      verifiable pass/fail signal (math, code, tool
      calls) route to GRPO+RLVR instead.
    - **RL is not the fix for a model that never
      succeeds.** GRPO and other RL methods sharpen
      an existing capability — they don't teach one
      from zero. If the model doesn't yet understand
      the task or output format, run SFT first; only
      bring in RL once the model succeeds at least
      sometimes.
    
    ### Common Routing Mistakes
    
    - Reaching for fine-tuning to fix facts that
      change weekly — that's a RAG problem, and
      fine-tuning will just go stale faster than the
      source data does.
    - Picking a DPO variant before checking whether
      the actual bottleneck is data quality or model
      scale — variant choice is the ~1pp lever, not
      the ~50pp one.
    - Starting an RL run on a model that fails every
      rollout — route to SFT first so RL has
      something to sharpen.
    - Treating CPT as the default for "the model
      doesn't know our domain" — check the data
      volume thresholds first; under 500MB, RAG or
      RAG+fine-tune iterates faster than a CPT run.
    
    ## Model Selection
    
    Base-model choice is size-class first, family
    second, and it goes stale fast — so it lives in
    exactly one place: `references/model-catalog.md`.
    That file is the only place in this plugin (and
    in the DGX Spark ops plugin) that names a base
    model family. Neither this skill nor
    `references/memory-math.md` names one; both
    describe models by size class only (for example,
    "8B-class LoRA," not a model name).
    
    The catalog is dated on purpose — model rankings
    turn over quarterly. It carries a "last verified"
    date and a refresh checklist. Before trusting a
    row, check that date; if stale, work the refresh
    checklist in the catalog before recommending a
    model from it.
    
    **Precedence when the catalog and a method skill
    disagree:** the catalog's per-row Notes column
    states hardware/size-class *feasibility*, not a
    method recommendation — `lora-qlora-recipes`'s
    LoRA vs QLoRA vs Full FT table (routed by task
    shape) governs the actual method choice.
    
    ## Memory Feasibility
    
    Before committing to a method, size it: total
    memory ≈ **params × dtype bytes + optimizer
    state + gradients + activations**. Work each
    term for the chosen dtype and method (full
    fine-tune, LoRA, or QLoRA) — worked worksheets
    and size-class examples live in
    `references/memory-math.md`.
    
    On DGX Spark specifically, unified-memory
    behavior breaks the naive estimate (transient
    load peaks, `nvidia-smi` underreporting, thermal
    throttling on long runs). Once the
    `dgx-spark-ops` plugin is installed, defer
    Spark-specific feasibility calls to its
    `spark-memory-thermal-ops` skill rather than
    re-deriving them here.
    
    ## Related Skills
    
    Once this skill has picked a method, hand off to
    the skill that executes it:
    
    - `lora-qlora-recipes` — SFT via LoRA/QLoRA
    - `preference-optimization` — DPO, ORPO, KTO
    - `grpo-rlvr-training` — GRPO with verifiable
      rewards
    
    No method is selected before the eval harness
    exists — see `eval-harness-first`.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related