flash. Run flash --help or flash <command> --help for
inline help.
Global flags
Run-management and serving commands are grouped under
flash runs and
flash models.
Auth & identity
[--api-key KEY] [--freesolo-url URL] [--api-url URL]
Log in with your Freesolo API key. Flash verifies the key against Freesolo,
saves it locally, and prints the resolved identity on success. Defaults:
--api-key from FREESOLO_API_KEY; --freesolo-url from FREESOLO_BASE_URL
(else https://api.freesolo.co); --api-url from FLASH_API_URL.Show the identity your stored key resolves to.
Print the Flash version.
Projects
Every training run and every published environment belongs to one Freesolo project, named by its UUID. Configs carry it as the top-levelproject field; env push and env delete take it as --project.
Create a project in your organization and print its UUID. Names are unique per
org, so reusing one is rejected. On a styled terminal the UUID is printed with
its name; otherwise the bare UUID is printed, so it captures cleanly in a
script (
PROJECT=$(flash projects create my-project)).List your organization’s projects with their UUIDs. Piped or redirected
output is one tab-separated
UUID<TAB>NAME per line. Use this to find the
UUID for a config’s project field or a --project flag.Discovery
List the supported base model ids. See Supported models
for algorithms, reasoning, and pricing.
List validated managed GPU classes with VRAM and estimated $/hr. The command
does not report live capacity or per-provider availability. Selection is
automatic by default;
[gpu] type accepts either one pinned class or a list
of acceptable classes.Environments
Scaffold a starter project into the current directory:
environment.py, a starter evaluations.py, a tiny dataset/train.jsonl,
configs/sft.toml (SFT),
configs/rl.toml (GRPO), and configs/opd.toml (OPD), plus a TRAINING.md
playbook for coding agents with current CLI usage, reward guidance, and common
run mitigations. Existing files are preserved.Setup needs a project, so run flash login first. --project is required
without a TTY or with -y; otherwise an interactive run prompts. The UUID is
written into every generated config. If configs already exist, setup refuses to
continue when one has no valid project or names a different one, rather than
rewriting them.An interactive run surveys the interaction shape and whether to train with
reasoning, then scaffolds to match; the flags below skip the questions. If the
project has recorded traces and no dataset/train.jsonl
exists, it also offers to seed the dataset from them and sizes max_examples
to the export. An existing dataset is never overwritten.Generated configs now carry a filled-in [wandb]
block: project from the Freesolo project you selected and run_name from the
folder and algorithm. Edit either value freely, or delete the block if you do not
use Weights & Biases.Validate a local environment offline before publishing. Loads the same
entrypoint
flash env push would package (PATH defaults to .) and drives
its first few dataset episodes with no GPU and no model: it checks that
prompts, SFT completions, and any multi-turn replies are well-formed chat
messages and that the reward is finite, printing a short prompt/response
preview per episode. It replays the dataset’s gold sft_completion as the
policy answer when one is present, otherwise a canned response. Prints
overall: PASS and exits 0 when every driven episode passes the contract
checks, or overall: FAIL and exits 1 on a load error, an empty dataset,
malformed messages, a hook exception, or a non-finite reward.--algorithm must match the algorithm you plan to train and defaults to grpo
so omitting it cannot disable the reward gate. The GRPO-only gate fails when
every accountable replayed gold answer scores zero, no valid per-turn reward
vector provides separation, and a deliberately wrong answer scores at least as
well. Under --algorithm sft or opd, an all-zero reward is advisory rather
than blocking because those algorithms do not train from env.reward. Episodes with no gold
answer to replay are exempt.--split selects the dataset split to drive, matching [environment.params]
and defaulting to train. Use the split the run actually trains on, for example
--split train_sft. --param KEY=VALUE is repeatable and passes any other
load_environment() keyword argument; values parse as TOML scalars, so 1,
true, and "x" keep their types. --split wins over --param split=....Score a deployed model against the held-out suites in the published
environment its training run used.
TARGET is a bare RUN_ID, a
RUN_ID/step-N checkpoint, or a full immutable adapter revision. There is no
environment PATH positional: Flash reads the target run, downloads that
published managed environment package, and loads environment.py plus
evaluations.py from that package. A run without a published
namespace/project/name environment is refused, so this command is not
available for standalone runs that use generic GitHub references.Define the suites in an evaluations.py beside the published environment.py:score() may return an EvalResult, a float, or a bool. A module-level
EVALUATIONS list works instead of the factory, and the factory receives the
loaded environment when it accepts one, so suites can reuse environment graders.--split and repeatable --param KEY=VALUE configure load_environment() in
the same way as env test. Values parse as TOML scalars, and --split wins over
--param split=.... --suite runs only the named suite, --max-cases caps the
cases taken from each selected suite, and --concurrency (default 1, maximum
32) issues that many model requests in parallel while results stay in case
order. Generation defaults to --temperature 0.0 and --max-tokens 512.Results upload to the dashboard by default under the project that owns the
target run. --project PROJECT_ID selects another accessible project. There is
no first, sole, or example-project fallback. Pass --no-upload to score without
recording results; --project and --no-upload cannot be combined.A multi-turn environment still runs each suite as a one-response check by
default. Set grades_episodes = True on a suite to play one generation per turn.
A state-aware scorer can define score(case, response, state) to receive the
finished transcript state; a two-argument scorer receives only the final response
text. Episode suites are rejected against single-turn environments.A case that never reached the model is recorded as an error and excluded from
pass_rate and mean_score rather than scored as zero, so a broken deployment
does not read as a low-quality model. Errors are printed, uploaded as failures
when upload is enabled, counted in the summary, and still fail the command.Publish a local Freesolo environment to Freesolo’s managed Environments
Hub (private) and print its id
(
your-org/your-project/name). --name is required and is normalized to a
lowercase hyphen slug. You can also pass an explicit namespace/project/name;
Freesolo validates both against your org namespace and the --project you
passed, and rejects a mismatch. PATH defaults to the current directory. Pass . or any folder
with environment.py at its root to upload helper modules, dataset/,
README.md, and common sibling sidecars (what gets
uploaded lists the extensions). A single
.py file, or a folder with one top-level .py file, also works for small
smoke tests; single-file mode packages only that entrypoint, a sibling
README.md/TRAINING.md, and any dataset/ tree. Secrets (.env files,
*.key, *.pem, credentials*, SSH keys) and virtualenvs are never
uploaded.--project is required and must be a project UUID from your organization
(flash projects list). A malformed UUID is rejected before upload, and one
that does not belong to your org fails the push. There is no fallback project.
Environment names are unique per project, so two projects in your organization
can each publish their own math without colliding. The owning project is part
of the id, and renaming a project does not change ids it already published.Download a published environment, or one file from it, to local disk.
ENV_ID
must be a managed Freesolo hub slug your-org/your-project/your-env. Without
PATH, the whole environment is written to a directory. With PATH, only
that file is fetched. -o sets the output path; -f overwrites an existing
output.List your organization’s published environments alongside the local sources
you can publish. Each published id is ready to paste into
[environment] id.
If you are not logged in, the local sources still list and the published
section says so rather than reporting an empty catalog.Delete a managed Freesolo Hub environment.
ENV_ID must be a lowercase
namespace/project/name Hub id; GitHub refs and local paths cannot be deleted
from the Hub. --project is required and must be the UUID of the project that
owns the environment. Pass -y/--yes to skip the confirmation prompt.Traces
Export a project’s recorded traces as freesolo environment
records, ready to train on. By default each trace becomes an
{"input", "output"} row, the same shape flash env setup scaffolds, so the
output drops straight into an environment’s dataset/train.jsonl. A file
exported here matches the dashboard’s trace export.--format picks the export shape (requires Flash 1.0.22; the dashboard export
offers the same three):records(default):{"input", "output"}environment records. Traces with no usable request/response pair are skipped.prompts:{"input"}only. GRPO and OPD both train from prompts alone (GRPO samples its own completions and scores them with the environment; OPD distils from a managed teacher), so no gold reply is needed, and a call whose reply never arrived still exports.raw: the stored trace rows with their spans, unconverted. Raw rows are not a dataset, so they default totraces.raw.jsonlinstead ofdataset/train.jsonl, where a laterenv push+traincould pick them up.
--project, an interactive terminal prompts you to pick from the
projects your key can reach; a non-interactive terminal errors with the
available ids so you can pass --project. An export reads the newest 1000
traces; skipped traces are counted in the summary. Writing an existing file
needs --force.Training
Submit a managed training run from a TOML config and follow its logs.
The config must set a top-level On an OPD config,
project UUID; Flash validates it against
your organization before any GPU is allocated, so a missing, malformed, or
foreign project fails the submit rather than starting paid work.
Before submit, Flash checks your prepaid balance against the pre-flight
estimate. Successful runs are billed at the quoted Flash cost. See
Cost and billing.SFT estimates return directly from the selected packaged dataset without
starting paid training or allocating a training GPU. An unreadable package
fails before allocation. See Cost and
billing.
--dry-run preflights the managed teacher before allocation.
It also checks image rows visible in packaged datasets and inline records
before allocation; images created dynamically by environment code can fail only
at worker time, after allocation.--gpus pins a ceiling, not an exact count: allocation still picks a single card
when one fits, and only rentable shapes (1, 2, 4, 8) are provisioned. It
overrides a [gpu] count in the config, and omitting it leaves an authored count
untouched. See Multi-GPU runs for the
auto-sizing rule.Run management
List your runs with state, algorithm, cost, and model.
Print a run’s status, including its current or final cost record. On a styled
terminal the default is a status panel; redirected output and
--json use the
complete machine-readable object.-f/--follow polls until the run reaches a terminal state without replaying
logs and prints only changed statuses. With --json, follow mode emits one
compact JSON object per line, producing a JSONL stream suitable for
line-by-line processing.Print a run’s full console and error logs.
-f/--follow streams new logs
until the run reaches a terminal state.Cancel a run. The CLI waits for the run to stop before returning, which can
take several minutes.
List a run’s saved SFT, GRPO, or OPD checkpoints available to deploy. Serve
one with
flash models deploy RUN_ID/step-N. When output is not a styled
terminal, each line is single-space separated (step N RUN_ID/step-N), so it
splits cleanly in scripts (awk, grep "step N").Serving
Deploy a final adapter or checkpoint. Every real deploy resolves an immutable
revision, runs a mandatory bounded smoke, and activates the stable run-id alias
only after verification.
--dry-run previews without creating a deployment.
Serving is billed per token.If no final adapter exists, use the RUN_ID/step-N selector listed by
flash runs checkpoint RUN_ID.Without --wait, deploy returns while the revision is still queued. With it, the
command blocks until the revision is servable and exits 0, or exits 1 if the
deployment failed, the wait timed out, or the alias rolled back to the previously
deployed revision. The timeout defaults to 2400 seconds; pass a value
(--wait 600) to set your own, or --wait 0 for a single state read. Interrupting
the wait with Ctrl-C stops waiting, not the deployment.Send a message to a deployment.
TARGET is the stable RUN_ID alias, a full
immutable revision, or RUN_ID/step-N for a checkpoint you have already
deployed, resolving to that checkpoint’s verified revision, so run
flash models deploy RUN_ID/step-N first.List each active run alias and its currently active verified revision. Human
output shows run id, step, revision, state, verification time, OpenAI model,
and detail.
--json includes complete records and openai_base_url.Disable the stable alias and all immutable revisions for the run.
Serving in your own account
flash serve provisions serving in your own Modal or RunPod account, instead
of Freesolo’s managed serving. The GPU runs and bills in your account, and the
endpoint is a provider URL you call directly. See
Serve in your own account.
These are separate from flash models deploy/undeploy, which drive managed
serving. The two do not mix: a customer-owned deployment does not accept
FREESOLO_INTERNAL_KEY and has no adapter-registration surface for
flash models deploy to drive.
flash serve needs the server extra (pip install 'freesolo-flash[server]'), because it resolves the adapter through Hugging
Face and drives the provider SDK.Provision one deployment in your own account for one base model and one run’s
adapter. Prints the endpoint URL, the provider resource ids, and an
identity
string that addresses the same deployment later.Placement flags are per provider, and exactly one provider’s set is required even
though
--help lists them all as optional. Passing the other provider’s flags is
rejected rather than ignored.A broad Modal region (
us-east) is cheaper and draws on a larger capacity pool
than a narrow one (us-east-1).Show the proved state of one deployment. Read-only: it never mutates provider
resources and never reports an unproved deployment as ready or absent. Takes
the same identity flags as
deploy, or pass --deployment-identity with the
identity string deploy printed to skip Hub resolution. Exits 0 for
ready, provisioning, or a confirmed-absent deployment, and 1 when no
state could be proved.Tear down one deployment generation and prove its resources are gone. Takes
the same identity flags as
deploy, plus the provider resource ids that
deploy printed (--modal-app-id, --modal-volume-id,
--modal-inference-secret-id, or --runpod-pod-id,
--runpod-network-volume-id, --runpod-template-id,
--runpod-inference-secret-id), so every deletion binds to the exact
generation. For a RunPod create whose outcome was never confirmed, omit all
the RunPod ids and pass --deployment-identity to reclaim by identity
instead.Export
Export a trained adapter to a HuggingFace repo you own (created if it doesn’t
exist).
--adapter-id is either RUN_ID for the final adapter or
RUN_ID/step-N for a saved checkpoint. --repository is required.