Skip to main content
The CLI is 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-level project 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 to traces.raw.jsonl instead of dataset/train.jsonl, where a later env push + train could pick them up.
There is no per-algorithm format: every algorithm reads the same environment records.Traces are stored per-project, so an export always reads exactly one project. Without --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 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.
On an OPD config, --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.
Credentials are request-only: they are read from the environment for the duration of one call and are never stored, logged, or written into the deployment record - so each command needs them exported again.
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.
If deploy reports provisioning, outcome_unknown, or an artifact-cleanup failure, provider resources may be live and billing. Run flash serve status to inspect, then flash serve undeploy to stop them - do not retry the deploy, which would provision and bill twice.

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.