Skip to main content
Most flash errors print one clean line; add the global --debug flag before the subcommand (e.g. flash --debug train config.toml) for the full traceback.

Installation & CLI

The CLI installs a single flash command. Its install location must be on your PATH.
  • If you installed with uv tool install freesolo-flash, make sure uv’s tool bin directory is on your PATH (run uv tool update-shell, then restart your shell).
  • Confirm the install with flash version.
The CLI is published to PyPI as freesolo-flash. The bare flash name belongs to an unrelated project. Reinstall the right one:

Authentication

Commands that contact Freesolo authenticate with a Freesolo API key, verified at login. Local flash train --cost does not submit.
  • Create a key in your dashboard at freesolo.co.
  • Log in once: flash login --api-key <your-key> (or set FREESOLO_API_KEY instead of passing --api-key).
  • Confirm who the stored key resolves to: flash whoami.
By default the CLI talks to https://api.freesolo.co. To target a different deployment, set --freesolo-url (or FREESOLO_BASE_URL) at login.

Environments

The folder you push must contain an environment.py file with a load_environment() function that returns a Freesolo environment. Then:
It prints the published id (your-org/math) to put in your config’s [environment] id. If you pass --name namespace/name, the namespace must match your Freesolo org; otherwise pass a bare name such as math.
Managed training workers have the Freesolo SDK when they import a published environment. Your local Python environment does not get that SDK automatically from the flash CLI. Install it locally to run or test environment.py directly. Local flash train --cost parses the config without importing the environment, and authenticated server-side --dry-run starts no GPU worker:
To pull a published env into your project for local work, use flash env pull your-org/your-env.
flash train --dry-run runs server-side submit preflights, but it does not execute the GPU worker or prove every environment dependency is installed. If flash log <run-id> shows your environment.py failed while importing a task library, add that package to [environment].pip, publish the environment, and submit again:
Only list packages your environment imports. Flash does not install worker dependencies from a pyproject.toml, requirements.txt, or lockfile bundled with the environment; keep managed-run dependencies in [environment].pip.
[environment].pip is for task dependencies imported by your environment. Do not pin Flash’s managed training stack there, such as torch, trl, vllm, peft, or bitsandbytes, unless your environment directly imports that package. Extra pins can conflict with the worker’s tested training recipe. Remove the pin and resubmit.
Pull the specific file you need instead of the whole environment:
Keep published environments focused on source, small sidecars, and datasets needed by the run. Do not publish virtualenvs, local caches, model weights, or generated artifacts.
Use flash env pull to inspect the exact packaged file:
For clean A/B experiments, publish changed datasets under a fresh env name so old runs, new runs, and local files are easy to tell apart.
If your environment module shares a name with an installed Python package, it can shadow or be shadowed by that package. Keep helper module names distinct from installed packages.
The [environment] id must be a published Freesolo environment id, produced by flash env push, for example your-org/your-env. A local file path is not a valid id, so publish it first or reference an existing published id. Use flash env pull your-org/your-env only when you want a local copy to edit or inspect.

Configuration

model must be one of the ids in the curated catalog. List the valid ids:
Managed runs train catalog models only. See Supported models.
Flash rejects unknown config sections and [train] keys at parse time. Check the key against the configuration reference and run authenticated server-side validation:
Dry-run also reports client/server [train] schema differences.
algorithm must be sft (the default), grpo, or opd. Fix the value and re-validate with --dry-run.
Flash rejects a run at submit when its training context is longer than the base model’s serving context (max_model_len). A LoRA trained longer than it is served wastes compute and learns positions never used at inference. SFT checks train.max_context_tokens; GRPO and OPD check the rollout prompt plus max_completion_tokens. Most models serve at 32768; Qwen/Qwen3.6-35B-A3B serves at 4096. Lower max_context_tokens and, for GRPO/OPD, max_completion_tokens to at or below the serving context. See context window.
The source LoRA rank and alpha are authoritative. Remove both train.lora_rank and train.lora_alpha when using init_from_adapter. A pinned model_revision must match the source exactly. Use server-side --dry-run to resolve and validate the source; local --cost may use defaults and warn.
GPU selection is automatic unless you set [gpu] exact_type to an active validated class from flash gpus. Add provider = "runpod", "lambda", or "vast" only when the provider must also be fixed. These constraints persist across retries and cost estimates.

Run fit and resource use

Expected. GRPO samples multiple completions, scores them, and updates from that group of attempts. For the same model, it usually needs more room and costs more than SFT. If a GRPO run is too expensive or too large, use a smaller model, reduce group_size, reduce max_completion_tokens, reduce max_context_tokens, or start with SFT.
The usual causes are long context, long generated completions, a large GRPO group_size, or a larger base model than the task needs. Reduce max_context_tokens, max_completion_tokens, or group_size, or switch to a smaller model. If you recently enabled thinking = true, reasoning and the final answer share the same token budget.

Training runs

Flash checks your prepaid org balance against the pre-flight estimate before submit, then bills successful runs at the quoted Flash cost. Cancelled runs are repriced to the training steps they reached, and setup time is reported separately without being billed. Preview the estimate before you submit:
Add funds or reduce the run estimate before submitting again. Smaller base models, fewer GRPO/OPD epochs, lower group_size, shorter max_completion_tokens, and SFT smoke tests are the fastest ways to lower the pre-flight estimate.
The task is too hard for the model at its current ability: if no rollout ever scores, there’s nothing for GRPO to reinforce. Try a stronger or larger base model, make the task easier to start, or double-check that your reward returns a positive reward for good answers.
Usually the reward is not discriminative: it scores almost everything the same. Make the reward function separate better answers from worse ones so GRPO has a spread of scores to learn from. See Environments.
When thinking = true, the model emits a reasoning trace before its answer, and that trace counts against the same max_completion_tokens budget as the answer. A max_completion_tokens tuned for a non-thinking run is usually too small once reasoning is added: the reasoning eats the budget and the actual answer is truncated or never emitted. If your reward parses the answer (e.g. extracts a JSON object), it then sees nothing and scores ~0 across the board — even though the model is “working”.Fixes:
  • Raise max_completion_tokens so the reasoning and the answer both fit (e.g. a task that needs ~200 answer tokens may need max_completion_tokens = 2048 with thinking on), and make sure max_context_tokens is large enough to hold the prompt plus that budget.
  • Optionally set thinking_length_penalty_coef to nudge the model toward shorter reasoning so the answer reliably lands inside the budget.
  • Score the answer text by default. In thinking mode response_text remains string-compatible answer text and also exposes response_text.completion, response_text.thinking, and response_text.raw for rewards that intentionally inspect reasoning.
The same trap applies to any reasoning model you call as an LLM judge from a reward: give the judge call enough max_tokens or it returns empty content and the judge silently scores 0.
In Qwen3.5 thinking mode, the chat template treats prior and next assistant turns differently: it strips literal <think> blocks from non-final assistant history, then pre-opens <think>\n in the next generation prompt. A naive multi-turn SFT transcript that puts <think>...</think> in every assistant turn can therefore train on a tag layout that inference will never render. The symptom is doubled, missing, or misplaced thinking tags, or an adapter that behaves differently in training-style evals than it does when served.Fixes:
  • For message-shaped multi-turn SFT targets, keep intermediate assistant turns as the actual code, tool, or action text only.
  • Put <think>...</think> plus the final answer only in the final assistant target.
  • Do not add a second opener for the template’s pre-opened <think>\n. Flash’s completion-only SFT masking uses the longest shared token prefix, so that pre-opened tag is treated as prompt text.
OPD refines a model that already has the output format. Warm-start from a finished SFT run, and omit lora_rank and lora_alpha because the source values are authoritative:
You can also use "<sft-run-id>/step-N" for a saved checkpoint. Verify that the selected teacher clearly beats the student on held-out task examples.There is no auxiliary EOS loss. For rollouts that reach max_completion_tokens without stopping:
  • Start from an SFT adapter with the desired stopping behavior.
  • Give the teacher a hard answer or reasoning budget in the system prompt.
  • Add stop_sequences when the task has reliable textual terminators.
  • Track truncated_rollouts to diagnose termination.
OPD supports single- and multi-turn environments but not tool-calling ones, and kl_penalty_coef must be greater than 0.
No. Ctrl-C during flash train detaches you; the run keeps going on Freesolo. Re-follow it any time, and cancel explicitly if you mean to:
Expected. Cancellation waits for the managed worker to stop and clean up before confirming, which can take several minutes. The CLI waits this teardown out; the run is marked cancelled when it completes.
Flash uses bounded retries. SFT, GRPO, and OPD resume only from a validated full-state checkpoint at a clean optimizer-step boundary.OPD may start a replacement fresh only when Flash can prove that no earlier attempt may have mutated optimizer state. If checkpoint or mutation evidence is missing, incomplete, unreadable, incompatible, or ambiguous, replacement fails closed instead of searching for an older checkpoint or restarting from fresh state.Watch logs with flash log <run-id> -f or poll status with flash status <run-id> -f. If the same shape repeatedly fails before useful metrics, reduce max_context_tokens, max_completion_tokens, or group_size.

Serving

A run cancelled or preempted before finalizing has no final adapter, so a plain flash deploy <run-id> cannot serve it. The error lists the run’s saved checkpoint steps and the exact command to use — deploy one of them instead:
Every real deploy resolves an immutable revision and runs a bounded smoke before activating the stable alias. Large models can take a few minutes to warm and verify. A failed smoke leaves the alias unchanged. See Deploy & chat.
Serving is billed per token for requests. Prompt, completion, and cached prompt token rates are listed in Supported models. flash undeploy <run-id> disables the alias and immutable revisions.
Use openai_base_url from flash deployments --json, set model to the run alias or a full immutable revision, and pass your Freesolo API key.
  • 401: missing or invalid key.
  • 402: insufficient org balance.
  • 403: the key’s org does not own the adapter.
  • 503: backend temporarily unavailable; retry with backoff.
See Use it from your own code.

Getting help

Still stuck? Add --debug to surface the full traceback, then reach out through freesolo.co/contact with the run id (flash runs) and the failing command.

Next steps

CLI reference

Flags and commands for every step.

Configuration reference

Valid config keys and sections.