> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fireworks.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Training Overview

export const TrainingDecisionFlow = () => {
  const DESTINATIONS = {
    managed: {
      label: "Managed Training",
      meta: "SFT · DPO · RFT · LoRA only",
      run: "Skill · UI · CLI · API",
      href: "/fine-tuning/managed-finetuning-intro",
      accent: "#7c3aed",
      edge: "rgba(124,58,237,0.35)",
      tint: "rgba(124,58,237,0.07)"
    },
    serverless: {
      label: "Serverless Training API",
      meta: "Custom loop · LoRA · per-token",
      run: "Skill · Python SDK",
      href: "/fine-tuning/training-api/serverless",
      accent: "#2563eb",
      edge: "rgba(37,99,235,0.35)",
      tint: "rgba(37,99,235,0.07)"
    },
    dedicated: {
      label: "Dedicated Training API",
      meta: "Custom loop · LoRA + full-parameter · per GPU/hour",
      run: "Skill · Python SDK",
      href: "/fine-tuning/training-api/dedicated",
      accent: "#ea580c",
      edge: "rgba(234,88,12,0.35)",
      tint: "rgba(234,88,12,0.07)"
    }
  };
  const QUESTIONS = {
    q1: {
      number: 1,
      question: "Does a standard SFT, DPO, or RL job do what you need?",
      branches: [{
        answer: "Yes",
        to: "managed"
      }, {
        answer: "No",
        detail: "I need a custom loss, reward, rollout, or per-step control.",
        next: "q2"
      }]
    },
    q2: {
      number: 2,
      question: "Does your custom loop need DPO, ORPO, distillation, or full-parameter training?",
      branches: [{
        answer: "No",
        detail: "I am writing a custom LoRA SFT or RL loop.",
        next: "q3"
      }, {
        answer: "Yes",
        detail: "These methods require dedicated Training API infrastructure.",
        to: "dedicated"
      }]
    },
    q3: {
      number: 3,
      question: "Is your base model available on serverless?",
      branches: [{
        answer: "Yes",
        to: "serverless"
      }, {
        answer: "No, or I want my own GPUs",
        to: "dedicated"
      }]
    }
  };
  const ORDER = ["q1", "q2", "q3"];
  const [trail, setTrail] = useState([]);
  const [showAll, setShowAll] = useState(false);
  const last = trail.length ? trail[trail.length - 1] : null;
  const currentId = last ? last.branch.next : "q1";
  const current = currentId ? QUESTIONS[currentId] : null;
  const destination = last && last.branch.to ? DESTINATIONS[last.branch.to] : null;
  const Badge = ({n, muted}) => <span style={{
    backgroundColor: muted ? "rgba(113,113,122,0.45)" : "#71717a"
  }} className="inline-flex items-center justify-center w-5 h-5 rounded-full text-[11px] font-bold text-white shrink-0">
      {n}
    </span>;
  const Chevron = () => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" className="shrink-0 text-zinc-400 dark:text-zinc-500">
      <path d="M9 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
    </svg>;
  const ArrowRight = () => <div className="hidden md:flex items-center px-1 shrink-0" aria-hidden="true">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" className="text-zinc-400 dark:text-zinc-500">
        <path d="M4 12h14M13 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    </div>;
  const ArrowDown = () => <div className="flex md:hidden justify-center py-0.5" aria-hidden="true">
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" className="text-zinc-400 dark:text-zinc-500">
        <path d="M12 4v14M6 13l6 6 6-6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    </div>;
  const StaticAnswer = ({branch}) => <div style={{
    border: "1px solid rgba(113,113,122,0.35)",
    borderRadius: 10
  }} className="px-3.5 py-2.5 md:flex-1 bg-zinc-50 dark:bg-zinc-800/40">
      <div className="text-[13px] font-semibold text-zinc-800 dark:text-zinc-100">
        {branch.answer}
      </div>
      {branch.detail && <div className="mt-0.5 text-[12px] leading-snug text-zinc-500 dark:text-zinc-400">
          {branch.detail}
        </div>}
    </div>;
  const StaticOutcome = ({branch}) => {
    if (branch.next) {
      return <div style={{
        border: "1px dashed rgba(113,113,122,0.45)",
        borderRadius: 10
      }} className="px-3.5 py-2.5 md:w-64 md:shrink-0 flex items-center">
          <span className="text-[12px] font-medium text-zinc-500 dark:text-zinc-400">
            Go to question {QUESTIONS[branch.next].number}
          </span>
        </div>;
    }
    const d = DESTINATIONS[branch.to];
    return <a href={d.href} style={{
      border: "1px solid " + d.edge,
      backgroundColor: d.tint,
      borderRadius: 10
    }} className="px-3.5 py-2.5 md:w-64 md:shrink-0 block no-underline hover:opacity-80">
        <div style={{
      color: d.accent
    }} className="text-[13px] font-bold">
          {d.label}
        </div>
        <div className="mt-0.5 text-[11.5px] leading-snug text-zinc-500 dark:text-zinc-400">
          {d.meta}
        </div>
        <div className="mt-1 text-[11px] text-zinc-500 dark:text-zinc-400">
          Run from <span className="font-semibold">{d.run}</span>
        </div>
      </a>;
  };
  return <div className="not-prose mt-4 mb-6 p-4 md:p-5 rounded-2xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900">
      {!showAll && trail.map((step, i) => <button key={step.id} type="button" onClick={() => setTrail(trail.slice(0, i))} className="group w-full text-left flex items-baseline gap-2 mb-2.5">
          <Badge n={QUESTIONS[step.id].number} muted />
          <span className="flex-1 text-[13px] leading-snug text-zinc-500 dark:text-zinc-400">
            {QUESTIONS[step.id].question}{" "}
            <span className="font-semibold text-zinc-700 dark:text-zinc-200">{step.branch.answer}</span>
          </span>
          <span className="text-[11px] font-medium text-zinc-400 dark:text-zinc-500 opacity-0 group-hover:opacity-100">
            Change
          </span>
        </button>)}

      {!showAll && current && <div className={trail.length ? "mt-4" : ""}>
          <div className="flex items-baseline gap-2">
            <Badge n={current.number} />
            <span className="text-sm font-semibold text-zinc-800 dark:text-zinc-100">
              {current.question}
            </span>
          </div>
          <div className="mt-3 md:pl-7 flex flex-col gap-2">
            {current.branches.map(b => <button key={b.answer} type="button" onClick={() => setTrail(trail.concat([{
    id: currentId,
    branch: b
  }]))} className="w-full text-left flex items-center gap-3 px-3.5 py-2.5 rounded-xl border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/40 hover:border-zinc-400 dark:hover:border-zinc-500 hover:bg-white dark:hover:bg-zinc-800 transition-colors">
                <span className="flex-1">
                  <span className="block text-[13px] font-semibold text-zinc-800 dark:text-zinc-100">
                    {b.answer}
                  </span>
                  {b.detail && <span className="mt-0.5 block text-[12px] leading-snug text-zinc-500 dark:text-zinc-400">
                      {b.detail}
                    </span>}
                </span>
                <Chevron />
              </button>)}
          </div>
        </div>}

      {!showAll && destination && <div className="mt-4 md:pl-7">
          <a href={destination.href} style={{
    border: "1px solid " + destination.edge,
    backgroundColor: destination.tint,
    borderRadius: 12
  }} className="block px-4 py-3.5 no-underline hover:opacity-80">
            <div className="text-[11px] font-semibold uppercase tracking-wide text-zinc-400 dark:text-zinc-500">
              Your surface
            </div>
            <div style={{
    color: destination.accent
  }} className="mt-1 text-base font-bold">
              {destination.label}
            </div>
            <div className="mt-0.5 text-[12px] leading-snug text-zinc-500 dark:text-zinc-400">
              {destination.meta}
            </div>
            <div className="mt-1 text-[12px] text-zinc-500 dark:text-zinc-400">
              Run from <span className="font-semibold">{destination.run}</span> · Open the guide →
            </div>
          </a>
        </div>}

      <div className={showAll ? "flex items-center gap-4" : "mt-4 flex items-center gap-4"}>
        {!showAll && trail.length > 0 && <button type="button" onClick={() => setTrail([])} className="text-[12px] font-medium text-zinc-500 dark:text-zinc-400 hover:text-zinc-800 dark:hover:text-zinc-200">
            Start over
          </button>}
        <button type="button" onClick={() => setShowAll(!showAll)} className="text-[12px] font-medium text-zinc-500 dark:text-zinc-400 hover:text-zinc-800 dark:hover:text-zinc-200">
          {showAll ? "Back to the questions" : "Show every path"}
        </button>
      </div>

      {showAll && <div className="mt-3 pt-4 border-t border-zinc-200 dark:border-zinc-800">
          {ORDER.map((id, i) => <div key={id} className={i > 0 ? "mt-5" : ""}>
              <div className="flex items-baseline gap-2">
                <Badge n={QUESTIONS[id].number} />
                <span className="text-sm font-semibold text-zinc-800 dark:text-zinc-100">
                  {QUESTIONS[id].question}
                </span>
              </div>
              <div className="mt-2 md:pl-7">
                {QUESTIONS[id].branches.map((b, j) => <div key={b.answer} className={j > 0 ? "mt-2 flex flex-col md:flex-row md:items-stretch" : "flex flex-col md:flex-row md:items-stretch"}>
                    <StaticAnswer branch={b} />
                    <ArrowDown />
                    <ArrowRight />
                    <StaticOutcome branch={b} />
                  </div>)}
              </div>
            </div>)}
        </div>}
    </div>;
};

Training adapts a base model to your task by training it on your own data, so it learns your formats, tone, tools, and edge cases instead of relying on prompt instructions alone. Fireworks runs the training for you, without the burden of building and maintaining your own GPU or training infrastructure.

Training is worth it when you want:

* **Higher task quality** - beat a general-purpose model on your specific workload, and often match or exceed a larger closed model.
* **Lower latency and cost** - a smaller specialized model can replace a bigger one at a fraction of the per-token cost.
* **Consistent behavior** - bake in formats, style, and tool-use so you stop paying for long prompts and few-shot examples on every request.
* **Ownership and no infra** - you keep the resulting weights, and Fireworks handles the GPUs, scheduling, and checkpointing.

<Info>
  **Coming from OpenAI?** Fireworks uses the same **OpenAI-compatible chat completion format** for training data — the same `messages` array with `role`, `content`, `tool_calls`, and `weight` fields. You can use your existing SFT datasets with no conversion required. See the [SFT dataset format](/fine-tuning/fine-tuning-models#fine-tuning-a-model-using-sft) for the full schema and examples.
</Info>

<h2 id="choose-a-method">
  Choose a method
</h2>

Pick a method based on the data or signal you have. All three run as standard jobs on [Managed Training](/fine-tuning/managed-finetuning-intro), or as custom loops you write yourself on the [Training API](/fine-tuning/training-api/introduction).

|                              | SFT                                                                                                                                                      | DPO                                                                                                         | RL                                                                                                                                                     |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Good for**                 | Classification, extraction, format and tone adherence, distillation                                                                                      | Steering the model toward a goal you cannot measure objectively, such as style, helpfulness, or safety      | Tasks where you have no verified outputs to learn from, but you can tell whether an outcome was good or bad. Pushing the model beyond state-of-the-art |
| **Data you supply**          | Verified input/output pairs, or successful trajectories                                                                                                  | Preference pairs, single-turn only: one prompt, a chosen and a rejected response                            | Prompts, plus an evaluator that can tell a good outcome from a bad one                                                                                 |
| **Dataset size**             | Hundreds of examples, or roughly 10M+ tokens                                                                                                             | Hundreds to thousands of pairs                                                                              | Dozens to thousands of prompts, sometimes more. Often fewer than 100 is enough                                                                         |
| **Consider alternatives if** | You have very few examples, or no high-quality verified outputs to learn from                                                                            | Outputs can be judged objectively, or you already have high-quality verified pairs. Both point to SFT or RL | You have no way at all to judge an outcome, including an LLM judge. Simpler methods are untried, or you want a quick training experiment               |
| **Guides**                   | [Text](/fine-tuning/fine-tuning-models) · [Vision](/fine-tuning/fine-tuning-models#vision-training) · [Cookbook](/fine-tuning/training-api/cookbook/sft) | [Managed DPO / ORPO](/fine-tuning/dpo-fine-tuning) · [Cookbook](/fine-tuning/training-api/cookbook/dpo)     | [Managed RFT](/fine-tuning/reinforcement-fine-tuning-models) · [Cookbook](/fine-tuning/training-api/cookbook/rl)                                       |

<Tip>
  **Verifiable** means you can reliably judge whether a model output is good (rules, unit tests, programmatic checks). RL fits reasoning and agentic tasks where full ground-truth labels are hard to write.
</Tip>

The Training API also supports custom methods (GRPO, distillation, and others) via the Python SDK. See [Cookbook recipes](/fine-tuning/training-api/cookbook/overview) and [Managed Training](/fine-tuning/managed-finetuning-intro) for model support and pricing.

<h2 id="choose-a-surface">
  Choose a surface
</h2>

Pick a **surface** (managed or Training API, serverless or dedicated). The surface decides how much of the model you update and which **interfaces** are available to you.

Answer the question below and the flow takes you to your surface, which links to its guide. Click any answered question to change it, or show every path at once.

<TrainingDecisionFlow />

Compare the last branch in detail on [serverless versus dedicated](/fine-tuning/training-api/introduction#infrastructure), and check per-model support on [Models](/fine-tuning/models).

<h3 id="managed-training-vs-training-api">
  Managed Training vs Training API
</h3>

Fireworks offers two ways to train: **Managed Training** (Fireworks runs the loop) and the **Training API** (you write the loop in Python).

| Choose Managed Training when                                      | Choose the Training API when                                                               |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| You need a standard SFT, DPO, ORPO, or RFT job                    | You need a custom loss, reward, rollout, trajectory, or optimizer-step loop                |
| You want Fireworks to own scheduling, training, and checkpointing | You want to fork or write Python training logic                                            |
| A supported model and managed configuration cover the task        | You need inference in the loop, distillation, per-step diagnostics, or research algorithms |

<CardGroup cols={2}>
  <Card title="Managed Training" icon="wand-magic-sparkles" href="/fine-tuning/managed-finetuning-intro">
    Standard jobs with a platform-managed loop.
  </Card>

  <Card title="Training API" icon="code" href="/fine-tuning/training-api/introduction">
    Programmable loops built from cookbook recipes or the SDK.
  </Card>
</CardGroup>

### Serverless vs Dedicated infrastructure

Infrastructure applies to the **Training API** only. Managed Training uses platform-managed compute.

| Choose Serverless Training when                                                   | Choose Dedicated Training when                                                     |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| Supported LoRA SFT or RL covers the workload                                      | You need full-parameter, DPO, ORPO, distillation, or broader model support         |
| You want shared pooled compute with no trainer or sampler deployment provisioning | You need explicit trainer, deployment, checkpoint, reconnect, or promotion control |
| Per-token billing fits a small or bursty experiment                               | A sustained, highly utilized time-based run fits the workload                      |
| In-session sampling is sufficient                                                 | You need provisioned rollout or evaluation deployments                             |

<CardGroup cols={2}>
  <Card title="Serverless Training" icon="bolt" href="/fine-tuning/training-api/serverless">
    Shared pooled trainer, no provisioning, per-token billing.
  </Card>

  <Card title="Dedicated Training" icon="server" href="/fine-tuning/training-api/dedicated">
    Provisioned trainer and deployment resources with explicit lifecycle control.
  </Card>
</CardGroup>

See the detailed [serverless versus dedicated comparison](/fine-tuning/training-api/introduction#infrastructure).

## Choose how to interact

* **Skill** — the only interface that drives both surfaces. Your coding agent configures, runs, and troubleshoots training through the [Fireworks training skill](/fine-tuning/agent/use-with-coding-agents).
* **Fireworks UI, `firectl`, or the REST API** — managed jobs only. Guided creation and monitoring in the UI, reproducible job and resource automation from the CLI or API.
* **Python SDK** — Training API loops only, on serverless or dedicated. Start from a [cookbook recipe](/fine-tuning/training-api/cookbook/overview).

<Note>
  **CLI or API vs Python SDK:** `firectl` and the REST API manage **managed** jobs and platform resources. The **Python SDK** runs **Training API** loops you author yourself (loss, rollouts, optimizer steps).
</Note>

### GPU quota prerequisite

Managed jobs and dedicated Training API runs need training GPU quota, granted automatically by [spending tier](/guides/quotas_usage/account-quotas#training-gpu-quota). [Serverless Training](/fine-tuning/training-api/serverless) uses a shared pool with its own model, concurrency, and rate limits instead of dedicated training GPU quota.

<Accordion title="Training GPU quota by spending tier">
  | Tier              | How to reach it                          | B200 / B300 (Blackwell) | H200 | H100 / A100 |
  | ----------------- | ---------------------------------------- | :---------------------: | :--: | :---------: |
  | No payment method | —                                        |            0            |   0  |      0      |
  | Tier 1            | Valid payment method and billing profile |            0            |  16  |      8      |
  | Tier 2            | Spend or add \$50 in credits             |            16           |  16  |      16     |
  | Tier 3            | Spend or add \$500 in credits            |            24           |  24  |      24     |
  | Tier 4            | Spend or add \$5,000 in credits          |            32           |  32  |      32     |

  Check your quota with the Fireworks CLI (`firectl quota list`). A job rejected with HTTP 429 `quota_exceeded` (sometimes a `403` on the job poll) is a tier issue, not a dataset/config problem.
</Accordion>

<Note>
  Need more training quota than your tier allows? [Reach out for enterprise support](https://fireworks.ai/contact-training) and we'll help size the right allocation for your workload.
</Note>

## Models

Model availability is decided per model and per surface — managed jobs by method (SFT, DPO, RFT), Training API jobs by parameter mode (LoRA or full-parameter). Check the live catalog before you launch.

<Card title="Models" icon="microchip" href="/fine-tuning/models">
  Browse the base model catalog with per-model surface, method, and training-shape support.
</Card>

<h2 id="training-security">
  Training security
</h2>

Across every training surface, one principle holds: **your training data is never used to train Fireworks-owned or shared models**. Inference follows [Zero Data Retention](/guides/security_compliance/data_handling) by default. This section summarizes the training surfaces; step-by-step BYOB IAM setup, CMEK KMS setup, and secure RFT are in [Secure Training](/guides/security_compliance/secure_training) and [CMEK](/guides/security_compliance/secure_training/cmek).

### Choose a surface by data-privacy needs

| Surface              | Where your training data lives                                  | What Fireworks retains       | Your deletion controls                                            |
| -------------------- | --------------------------------------------------------------- | ---------------------------- | ----------------------------------------------------------------- |
| **Managed Training** | Fireworks-managed storage (GCS); reference link in our database | Dataset, checkpoints, traces | Delete dataset after job; request checkpoint/trace deletion       |
| **Managed + BYOB**   | Your cloud bucket; read in-place during training only           | Checkpoints and traces only  | Revoke bucket access after job; request checkpoint/trace deletion |
| **Training API**     | No dataset file on Fireworks — transient tokenized batches only | Checkpoints and traces only  | Request checkpoint/trace deletion                                 |

Checkpoints and traces are retained \~30 days by default (deletable on request). Strictest governance: [BYOB](#dataset-storage-byob) (dataset never copied to Fireworks) or the [Training API](/fine-tuning/training-api/introduction) (no stored dataset file).

<h3 id="dataset-storage-byob">
  Bring your own bucket (BYOB)
</h3>

Register an external URL so Fireworks reads your dataset during the job without persisting a copy, then revoke access after the job:

```bash theme={null}
firectl dataset create my-dataset --external-url gs://your-bucket/path/train.jsonl
```

Supported: GCS, AWS S3, and Azure Blob, with least-privilege IAM to Fireworks service accounts provided at onboarding. For AWS S3, lock the IAM trust policy with both `accounts.google.com:sub` and `accounts.google.com:oaud` (your Fireworks account ID) so tokens for other accounts are rejected. Full IAM trust policies, OIDC audience, and rotation are in [Secure Training](/guides/security_compliance/secure_training/byob).

<h3 id="cmek">
  Customer-managed encryption keys (CMEK)
</h3>

CMEK encrypts datasets and checkpoints on Fireworks-managed storage with **your** cloud KMS key — revoke the key and Fireworks cannot decrypt. Supported on AWS KMS, Google Cloud KMS, and Azure Key Vault. It does not cover in-memory training compute or inference request/response. Setup, IAM, and rotation detail: [CMEK](/guides/security_compliance/secure_training/cmek) · [Data Security Overview](/guides/security_compliance/data_security).

### Secure RFT and customer controls

For RFT under strict governance, combine a [BYOB](#dataset-storage-byob) dataset with evaluators and rollout servers kept in your own environment (see [Remote Environment Setup](/fine-tuning/connect-environments)). To delete checkpoints, traces, or rollout data, contact your Fireworks account team; datasets are deletable from the console or API after a job completes.

## Before launch

Verify current model support, shapes, access status, pricing, limits, and quota in the linked live pages. A coding agent asks for confirmation before upload, registration, paid inference, job creation, promotion, deployment, or another mutation. Material changes require approval again; promotion and deployment are confirmed separately.
