Skip to main content
flash train --cost prints a pre-flight estimate before you submit a run:
Use it before any non-trivial run: it validates the config, prices the training loop, and exits without submitting a training run. GRPO, OPD, and an already-profiled SFT config print the quoted USD cost immediately; an uncached SFT config first starts a separately billed profile run and exits without a quote, so rerun --cost once that finishes (see below). On an SFT config, omitting max_examples (or setting it to 0) trains on every row. The submit-time quote is the amount Flash checks against your prepaid org balance. Successful runs are billed at the quoted Flash cost. A cancelled run is prorated from that quote by the share of the work it completed, capped at the quote - see Charges and cancellations.

GRPO and OPD quote locally; SFT is measured

GRPO and OPD quote offline from the catalog, so --cost returns immediately without contacting the server. They need a stated horizon to price: set [train] max_steps for an exact update count, or [train] max_examples for the prompt-pool size epochs run over. A config that states neither is refused rather than quoted:
Because it stays local, that quote checks only local things: the TOML, the algorithm’s knobs, the catalog, the resource fit, the horizon, and the price. It cannot tell you whether your project and environment are reachable, whether your balance covers the run, or whether the teacher is available. Run --dry-run for those before a real submit. SFT is priced from a measured workload profile rather than a guessed row count. SFT cost depends on the exact tokenized dataset, so the first --cost, --dry-run, or train for a given config starts a short profile run that loads your environment and tokenizes exactly the rows the training would consume. While it is running, the command tells you so and exits without a quote:
Follow it with flash runs status <profile-run-id> -f, which polls until the profile reaches a terminal state; then re-run your command and the exact quote is available. Without -f the command prints one status and returns, so re-running too early only rejoins the unfinished profile. A few things worth knowing:
  • The profile run is real work and is billed on its own. No training run is created and no training GPU is allocated by it; nothing is charged for training. The message includes its estimated charge.
  • It is measured once per exact config and then reused. Re-running while your own profile is still going joins it rather than starting or billing a second one, and a profile already being measured for the same config is reused.
  • Changing what the profile measured re-profiles. Editing the dataset, environment contents, model, or the [train] settings that shape the workload produces a different profile.
Because the quote is backed by real tokenization, the SFT preview reports what was actually measured - rows trained of rows selected, compute and supervised token counts, and the packing mode - rather than an estimate from a row count.

How cost is calculated

flash train --cost reprices a run the same way the platform bills it:
The rate is per card, so a multi-card run is priced for every card it held. A single-card run occupies one and the last term drops out. Billable training time is the training loop only — derived optimizer steps times per-step time. Setup before the first training step is reported as wall-clock time but is not billed. Per-step time reflects the work in a step: a GRPO step samples a group of completions, grades them with your reward, and updates the policy, so it scales with how many and how long those completions are (prompts_per_step × group_size × max_completion_tokens); an SFT step is one forward/backward pass, priced on the training tokens counted from your environment; an OPD step samples the model’s completions and has the managed teacher grade them before updating. OPD is priced on GPU time like the others, and teacher tokens are not billed to you. The estimator prices the cheapest eligible GPU automatically. If you pin [gpu] type, the estimate uses that same constraint, and it persists across submissions and retries. When you omit both [gpu] type and [gpu] count, the quote prices the shape Flash will actually auto-size to: the smallest geometry-safe card count your configuration fits on, ranked by cost per step. A configuration that needs more memory than one card holds is therefore quoted - and billed - as a multi-card run rather than rejected. Set [gpu] count (or --gpus N) to cap that. Pinning [gpu] type without a count stays a single-card pin, so an oversized run on a pinned card is rejected at preflight rather than quoted across several. See Multi-GPU runs. Serving is priced separately; see Serving billing.

What affects training cost

You control the main levers in the config:
  • Base model. Smaller models are cheaper and faster for smoke tests.
  • Algorithm. SFT usually costs least. GRPO and OPD both sample and score the model’s own completions before each update, so they cost more per step. Every algorithm is billed on GPU time; OPD’s managed teacher is not billed to you.
  • Epochs and exact step horizons. More epochs increases cost when Flash derives the update count. For SFT, GRPO, and OPD, positive max_steps sets the exact optimizer-update horizon; GRPO and OPD need that or max_examples to be quotable at all.
  • Required saves. save_at_steps adds the synchronous upload work for each required deployable adapter and full resume checkpoint to the estimate.
  • Sequence length. Larger max_context_tokens and max_completion_tokens increase work per example. Keep them large enough for your prompt and answer, but do not oversize them by default.
  • Batch size and dataset size. For SFT, cost scales with the number of examples trained over and the batch/epoch settings.
  • On-policy sample count. For GRPO and OPD, group_size controls how many completions are sampled per prompt. Larger groups cost more.
  • Reward latency. If your GRPO reward calls an external model or service, slow grading can increase wall-clock time.

Reading the preview

A preview includes the model, algorithm, setup estimate, training estimate, billable training time, and total:
Treat the preview as the quote for the config you submit. If you edit the environment, dataset, model, algorithm, or [train] settings, run --cost again. When max_steps is positive, the preview uses it as the exact update count for SFT, GRPO, or OPD. Otherwise the count is derived from epochs, retained examples, and the optimizer batch (batch_size for SFT, prompts_per_step for GRPO and OPD).

Charges and cancellations

  • A run that completes successfully is billed at the submitted quote.
  • A run cancelled before its first training step is not charged for training.
  • A run cancelled after training starts is prorated from the quote you accepted, on the basis of the hardware it actually rented, and is capped at that quote - a cancellation can never cost more than letting the run finish.
  • Setup time is reported separately and is not billed as training time.
  • flash runs status <run-id> shows the current or final cost record.

Serving billing

Serving is billed per token after deployment: (prompt − cached) × input + completion × output + cached × cached, at the per-model rates in Supported models. Prefix caching is automatic; the cached rate applies to a reused prefix. See Billing for how it works. Serving a base model with no adapter (a base-model id in the model field) is billed the same way, to the org whose API key made the request — not to an adapter owner. Tear down deployments you are done using:

Lowering cost

Validate on a smaller base model with short smoke tests before scaling epochs, max_steps, or the retained dataset size, and lower group_size and max_completion_tokens until the reward or teacher wiring is proven. For SFT, keep a held-out split and stop adding epochs once held-out quality stops improving. flash runs checkpoint <run-id> lets you deploy a good intermediate checkpoint rather than assuming the final step is best.

Why a later quote can change

The quote can change when you edit the config, publish different environment contents, change the dataset size, or submit after catalog/pricing updates. The authoritative number is the quote returned for the run you submit.