freesolo-flash-dev 1.2.61__tar.gz → 1.2.64__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CHANGELOG.md +4 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/setup.py +40 -20
- freesolo_flash_dev-1.2.64/flash/cli/commands/env/setup_wandb.py +30 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/traces.py +2 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/scaffold/TRAINING.md +4 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/__init__.py +14 -4
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/multimodal.py +135 -19
- freesolo_flash_dev-1.2.64/flash/engine/huggingface.py +61 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/dataset_profile.py +4 -7
- freesolo_flash_dev-1.2.64/flash/engine/profiling/image_tokens.py +294 -0
- freesolo_flash_dev-1.2.64/flash/engine/profiling/sft_image_rows.py +226 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/sft_workload.py +144 -156
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/tokenizer.py +1 -4
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/sft.py +41 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/prefetch.py +3 -37
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/chatml_mask.py +73 -42
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/opd_train_runner.py +35 -17
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/glue.py +158 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/runtime.py +15 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/bridge.py +90 -117
- freesolo_flash_dev-1.2.64/flash/engine/worker/train/opd/bridge_failures.py +117 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/multiturn.py +30 -9
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/plugin.py +3 -21
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/prompts.py +2 -2
- freesolo_flash_dev-1.2.64/flash/engine/worker/train/opd/scoring.py +86 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/multiturn.py +3 -58
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/verl_config.py +2 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/child/plugin.py +3 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/runs.py +7 -5
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/pyproject.toml +2 -2
- freesolo_flash_dev-1.2.64/tests/capture_image_sft_processor_oracle.py +23 -0
- freesolo_flash_dev-1.2.64/tests/fixtures/image_sft_processor_oracle.json +1 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_commands.py +242 -11
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_controlled_experiment_repairs.py +4 -1
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_dataset_profile.py +255 -11
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_dev_channel.py +5 -1
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_envs_coverage.py +8 -2
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flash_worker.py +7 -5
- freesolo_flash_dev-1.2.64/tests/test_image_sft_markers.py +337 -0
- freesolo_flash_dev-1.2.64/tests/test_image_sft_processor_parity.py +549 -0
- freesolo_flash_dev-1.2.64/tests/test_image_tokens.py +464 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_multimodal_training.py +1 -1
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_multiturn_failure_exit.py +10 -1
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_train.py +689 -4
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_train.py +156 -6
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_wandb_link.py +163 -6
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/uv.lock +1 -1
- freesolo_flash_dev-1.2.61/flash/engine/worker/train/opd/scoring.py +0 -73
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.env.example +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/README.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.61 → freesolo_flash_dev-1.2.64}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -54,6 +54,10 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
|
54
54
|
|
|
55
55
|
### Fixed
|
|
56
56
|
|
|
57
|
+
- Completed verl children now finish each captured W&B run before the W&B service shuts down,
|
|
58
|
+
avoiding teardown tracebacks, and `flash env setup` now gives every starter config explicit W&B
|
|
59
|
+
project and folder-derived run metadata.
|
|
60
|
+
|
|
57
61
|
- An ordered `[gpu] type` list is now priced over every class it declares acceptable, not just the
|
|
58
62
|
first. Allocation cost-ranks the whole set, so quoting the head alone priced a shape the run may
|
|
59
63
|
never be given — an authored `["B200", "H100"]` quoted roughly 3x the H100 the allocator would
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.64
|
|
4
4
|
Summary: Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI
|
|
5
5
|
Project-URL: Homepage, https://github.com/freesolo-co/flash
|
|
6
6
|
Project-URL: Repository, https://github.com/freesolo-co/flash
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import json
|
|
6
6
|
import sys
|
|
7
7
|
import tomllib
|
|
8
|
+
from collections.abc import Mapping
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
|
|
10
11
|
from flash._internal.channel import CLI_NAME
|
|
@@ -13,6 +14,7 @@ from flash.cli.commands.env.retained import (
|
|
|
13
14
|
_warn_if_environment_form_disagrees,
|
|
14
15
|
_warn_if_retained_starter_files_describe_another_plane,
|
|
15
16
|
)
|
|
17
|
+
from flash.cli.commands.env.setup_wandb import _wandb_block, _wandb_project
|
|
16
18
|
from flash.cli.scaffold import TRAINING_MD
|
|
17
19
|
from flash.cli.ui import render
|
|
18
20
|
from flash.envs.evaluations import _DEFAULT_EVALUATIONS_PATH
|
|
@@ -358,22 +360,14 @@ _REASONING_OPTIONS = [
|
|
|
358
360
|
_SKIP_TRACES = "" # sentinel option value: scaffold the starter rows instead of importing
|
|
359
361
|
|
|
360
362
|
|
|
361
|
-
def _require_setup_project(args) -> str:
|
|
363
|
+
def _require_setup_project(args, *, api_url: str | None, api_key: str) -> Mapping[str, object]:
|
|
362
364
|
"""Resolve and validate the one explicit project used by the whole scaffold."""
|
|
363
|
-
from flash.client import ClientError, list_projects,
|
|
364
|
-
from flash.client.config import load_credentials
|
|
365
|
+
from flash.client import ClientError, list_projects, resolve_project
|
|
365
366
|
from flash.client.http import has_freesolo_backend
|
|
366
367
|
|
|
367
|
-
api_url, api_key = load_credentials()
|
|
368
|
-
if not api_key:
|
|
369
|
-
raise ClientError(
|
|
370
|
-
f"not logged in. Run `{CLI_NAME} login` before `{CLI_NAME} env setup` "
|
|
371
|
-
"so the project can be validated"
|
|
372
|
-
)
|
|
373
|
-
|
|
374
368
|
supplied = str(getattr(args, "project", "") or "").strip()
|
|
375
369
|
if supplied:
|
|
376
|
-
return
|
|
370
|
+
return resolve_project(supplied, api_key, api_url)
|
|
377
371
|
if not _setup_interactive(args):
|
|
378
372
|
raise ClientError(
|
|
379
373
|
"--project PROJECT_UUID is required in noninteractive mode, with redirected stdin, or with --yes"
|
|
@@ -395,7 +389,7 @@ def _require_setup_project(args) -> str:
|
|
|
395
389
|
f"`{CLI_NAME} projects create NAME`"
|
|
396
390
|
)
|
|
397
391
|
selected = render.select_required("Choose the Freesolo project for this environment", options)
|
|
398
|
-
return
|
|
392
|
+
return resolve_project(selected, api_key, api_url)
|
|
399
393
|
|
|
400
394
|
|
|
401
395
|
# Guidance the starter .py docstrings carry, per plane kind. The templates hold placeholders
|
|
@@ -450,7 +444,7 @@ def _render_starter(template: str, project_id: str, *, can_publish: bool) -> str
|
|
|
450
444
|
return template.replace("PROJECT_UUID", project_id)
|
|
451
445
|
|
|
452
446
|
|
|
453
|
-
def _plane_can_publish_environments() -> bool:
|
|
447
|
+
def _plane_can_publish_environments(api_url: str | None) -> bool:
|
|
454
448
|
"""Whether `flash env push` can actually publish for the logged-in plane.
|
|
455
449
|
|
|
456
450
|
Publishing uploads to the plane, which commits into the managed environment hub
|
|
@@ -462,10 +456,8 @@ def _plane_can_publish_environments() -> bool:
|
|
|
462
456
|
operator-run Freesolo-compatible backend has a project directory (which is what that helper
|
|
463
457
|
answers) but still cannot publish to the hub.
|
|
464
458
|
"""
|
|
465
|
-
from flash.client.config import load_credentials
|
|
466
459
|
from flash.serve.urls import is_freesolo_hosted_url
|
|
467
460
|
|
|
468
|
-
api_url, _ = load_credentials()
|
|
469
461
|
# Unset means the built-in default, which is the managed plane.
|
|
470
462
|
return api_url is None or is_freesolo_hosted_url(api_url)
|
|
471
463
|
|
|
@@ -553,7 +545,7 @@ def _existing_reasoning(configs: tuple[Path, ...]) -> bool | None:
|
|
|
553
545
|
return next(iter(found.values()), None)
|
|
554
546
|
|
|
555
547
|
|
|
556
|
-
def _traces_dataset(args, project_id: str) -> str | None:
|
|
548
|
+
def _traces_dataset(args, project_id: str, api_key: str) -> str | None:
|
|
557
549
|
"""Optionally export traces from the already-selected project."""
|
|
558
550
|
if not _setup_interactive(args):
|
|
559
551
|
return None
|
|
@@ -568,7 +560,7 @@ def _traces_dataset(args, project_id: str) -> str | None:
|
|
|
568
560
|
if use_traces == _SKIP_TRACES:
|
|
569
561
|
return None
|
|
570
562
|
try:
|
|
571
|
-
exported = traces.fetch_records(project_id)
|
|
563
|
+
exported = traces.fetch_records(project_id, api_key)
|
|
572
564
|
except Exception as exc: # trace import is optional after project validation succeeds
|
|
573
565
|
_warn(f"could not export traces from {project_id} ({exc}); using the starter dataset")
|
|
574
566
|
return None
|
|
@@ -692,6 +684,7 @@ def _write_rl_config(
|
|
|
692
684
|
rl: Path,
|
|
693
685
|
project_line: str,
|
|
694
686
|
thinking_line: str,
|
|
687
|
+
wandb_block: str,
|
|
695
688
|
env_comment: str,
|
|
696
689
|
max_examples_line: str,
|
|
697
690
|
rl_reasoning_train: str,
|
|
@@ -704,6 +697,7 @@ def _write_rl_config(
|
|
|
704
697
|
'algorithm = "grpo"\n'
|
|
705
698
|
f"{thinking_line}"
|
|
706
699
|
"\n"
|
|
700
|
+
f"{wandb_block}"
|
|
707
701
|
f"{env_comment}"
|
|
708
702
|
"[train]\n"
|
|
709
703
|
"epochs = 1\n"
|
|
@@ -722,6 +716,7 @@ def _write_sft_config(
|
|
|
722
716
|
sft: Path,
|
|
723
717
|
project_line: str,
|
|
724
718
|
thinking_line: str,
|
|
719
|
+
wandb_block: str,
|
|
725
720
|
env_comment: str,
|
|
726
721
|
max_examples_line: str,
|
|
727
722
|
sft_reasoning_note: str,
|
|
@@ -734,6 +729,7 @@ def _write_sft_config(
|
|
|
734
729
|
'algorithm = "sft"\n'
|
|
735
730
|
f"{thinking_line}"
|
|
736
731
|
"\n"
|
|
732
|
+
f"{wandb_block}"
|
|
737
733
|
f"{env_comment}"
|
|
738
734
|
"[train]\n"
|
|
739
735
|
"epochs = 1\n"
|
|
@@ -766,6 +762,7 @@ def _write_opd_config(
|
|
|
766
762
|
project_line: str,
|
|
767
763
|
project_id: str,
|
|
768
764
|
thinking_line: str,
|
|
765
|
+
wandb_block: str,
|
|
769
766
|
max_examples_line: str,
|
|
770
767
|
*,
|
|
771
768
|
can_publish: bool = True,
|
|
@@ -788,6 +785,7 @@ def _write_opd_config(
|
|
|
788
785
|
'algorithm = "opd" # on-policy distillation from a managed parasail teacher (default glm 5.2)\n'
|
|
789
786
|
f"{thinking_line}"
|
|
790
787
|
"\n"
|
|
788
|
+
f"{wandb_block}"
|
|
791
789
|
+ _environment_comment(
|
|
792
790
|
project_id,
|
|
793
791
|
can_publish=can_publish,
|
|
@@ -816,15 +814,34 @@ def _write_training_guide(training: Path, project_id: str) -> None:
|
|
|
816
814
|
)
|
|
817
815
|
|
|
818
816
|
|
|
817
|
+
def _resolve_setup_identity(args) -> tuple[str, str, str, str, str]:
|
|
818
|
+
"""Resolve the credential, project, and folder identity used by every setup phase."""
|
|
819
|
+
from flash.client import ClientError
|
|
820
|
+
from flash.client.config import load_credentials
|
|
821
|
+
|
|
822
|
+
api_url, api_key = load_credentials()
|
|
823
|
+
if not api_key:
|
|
824
|
+
raise ClientError(
|
|
825
|
+
f"not logged in. Run `{CLI_NAME} login` before `{CLI_NAME} env setup` "
|
|
826
|
+
"so the project can be validated"
|
|
827
|
+
)
|
|
828
|
+
project = _require_setup_project(args, api_url=api_url, api_key=api_key)
|
|
829
|
+
project_id = str(project["id"])
|
|
830
|
+
folder_name = Path.cwd().name
|
|
831
|
+
if not folder_name.strip():
|
|
832
|
+
raise ClientError("the current environment folder name must be nonblank")
|
|
833
|
+
return api_url, api_key, project_id, _wandb_project(project), folder_name
|
|
834
|
+
|
|
835
|
+
|
|
819
836
|
def cmd_env_setup(args) -> int:
|
|
820
|
-
project_id =
|
|
837
|
+
api_url, api_key, project_id, project_name, folder_name = _resolve_setup_identity(args)
|
|
821
838
|
_validate_existing_config_projects(project_id)
|
|
822
839
|
starter_env = Path("environment.py")
|
|
823
840
|
starter_evaluations = Path(_DEFAULT_EVALUATIONS_PATH)
|
|
824
841
|
dataset = Path("dataset/train.jsonl")
|
|
825
842
|
# trace import is optional and can only read the selected project. an existing dataset is never
|
|
826
843
|
# overwritten, so importing into it would be a silently discarded download.
|
|
827
|
-
traces_jsonl = None if dataset.exists() else _traces_dataset(args, project_id)
|
|
844
|
+
traces_jsonl = None if dataset.exists() else _traces_dataset(args, project_id, api_key)
|
|
828
845
|
multi_turn, starter_env_exists = _resolve_turn_mode(args, starter_env, dataset)
|
|
829
846
|
|
|
830
847
|
rl = Path("configs/rl.toml")
|
|
@@ -837,7 +854,7 @@ def cmd_env_setup(args) -> int:
|
|
|
837
854
|
reasoning_configs = (rl, opd, sft)
|
|
838
855
|
reasoning = _resolve_reasoning_mode(args, reasoning_configs)
|
|
839
856
|
|
|
840
|
-
can_publish = _plane_can_publish_environments()
|
|
857
|
+
can_publish = _plane_can_publish_environments(api_url)
|
|
841
858
|
_warn_if_environment_form_disagrees(reasoning_configs, can_publish=can_publish, warn=_warn)
|
|
842
859
|
env_py = _render_starter(
|
|
843
860
|
_STARTER_ENV_MULTITURN_PY if multi_turn else _STARTER_ENV_PY,
|
|
@@ -908,6 +925,7 @@ def cmd_env_setup(args) -> int:
|
|
|
908
925
|
rl,
|
|
909
926
|
project_line,
|
|
910
927
|
thinking_line,
|
|
928
|
+
_wandb_block(project_name, f"{folder_name}-grpo"),
|
|
911
929
|
env_comment,
|
|
912
930
|
max_examples_line,
|
|
913
931
|
rl_reasoning_train,
|
|
@@ -916,6 +934,7 @@ def cmd_env_setup(args) -> int:
|
|
|
916
934
|
sft,
|
|
917
935
|
project_line,
|
|
918
936
|
thinking_line,
|
|
937
|
+
_wandb_block(project_name, f"{folder_name}-sft"),
|
|
919
938
|
env_comment,
|
|
920
939
|
max_examples_line,
|
|
921
940
|
sft_reasoning_note,
|
|
@@ -927,6 +946,7 @@ def cmd_env_setup(args) -> int:
|
|
|
927
946
|
project_line,
|
|
928
947
|
project_id,
|
|
929
948
|
thinking_line,
|
|
949
|
+
_wandb_block(project_name, f"{folder_name}-opd"),
|
|
930
950
|
max_examples_line,
|
|
931
951
|
can_publish=can_publish,
|
|
932
952
|
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""W&B metadata helpers for environment scaffolds."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
|
|
8
|
+
_WANDB_PROJECT_MAX_LENGTH = 128
|
|
9
|
+
_WANDB_PROJECT_FORBIDDEN = frozenset("/\\#?%:")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _wandb_project(project: Mapping[str, object]) -> str:
|
|
13
|
+
"""Adapt a resolved canonical project to a W&B-safe project name."""
|
|
14
|
+
project_id = str(project["id"])
|
|
15
|
+
name = project.get("name")
|
|
16
|
+
if not isinstance(name, str) or not name.strip():
|
|
17
|
+
return project_id
|
|
18
|
+
if len(name) > _WANDB_PROJECT_MAX_LENGTH or any(
|
|
19
|
+
character in _WANDB_PROJECT_FORBIDDEN for character in name
|
|
20
|
+
):
|
|
21
|
+
return project_id
|
|
22
|
+
return name
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _wandb_block(project_name: str, run_name: str) -> str:
|
|
26
|
+
return (
|
|
27
|
+
"[wandb]\n"
|
|
28
|
+
f"project = {json.dumps(project_name, ensure_ascii=False)}\n"
|
|
29
|
+
f"run_name = {json.dumps(run_name, ensure_ascii=False)}\n\n"
|
|
30
|
+
)
|
|
@@ -77,8 +77,8 @@ def fetch_records(
|
|
|
77
77
|
) -> dict:
|
|
78
78
|
"""A project's traces in the requested shape, converted server-side.
|
|
79
79
|
|
|
80
|
-
Omitting `api_key` reads the stored credential
|
|
81
|
-
|
|
80
|
+
Omitting `api_key` reads the stored credential. Callers that already resolved configuration
|
|
81
|
+
should pass the key from that snapshot so a concurrent login cannot change the request identity.
|
|
82
82
|
"""
|
|
83
83
|
key = _require_api_key(api_key or load_credentials()[1])
|
|
84
84
|
return export_trace_records(project_id, key, export_format=export_format)
|
|
@@ -272,8 +272,10 @@ lora_rank = 32 # lora_alpha defaults to 2 x lora_rank; set it to ov
|
|
|
272
272
|
# All knobs live under [train]. Do not add [sft], [grpo], or [opd] tables.
|
|
273
273
|
|
|
274
274
|
[wandb]
|
|
275
|
-
#
|
|
276
|
-
#
|
|
275
|
+
# new scaffolds set `project` from the selected Freesolo project and `run_name` from the folder
|
|
276
|
+
# plus algorithm. edit either value as needed; only `project` and `run_name` are allowed.
|
|
277
|
+
# project = "my-project"
|
|
278
|
+
# run_name = "sft-run-1"
|
|
277
279
|
```
|
|
278
280
|
|
|
279
281
|
**Knobs are scoped by algorithm.** `[train]` is one flat table shared by all three algorithms,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""HTTP client for the managed Flash control plane (used by the CLI)."""
|
|
2
2
|
|
|
3
|
+
from collections.abc import Mapping
|
|
4
|
+
|
|
3
5
|
from flash._internal.channel import CLI_NAME
|
|
4
6
|
from flash.client.config import load_credentials, save_credentials
|
|
5
7
|
from flash.client.http import (
|
|
@@ -20,8 +22,10 @@ from flash.client.http import (
|
|
|
20
22
|
from flash.core.spec import require_project_id
|
|
21
23
|
|
|
22
24
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
+
def resolve_project(
|
|
26
|
+
project_id: str, api_key: str, api_url: str | None = None
|
|
27
|
+
) -> Mapping[str, object]:
|
|
28
|
+
"""Resolve one project, turning "not yours / not there" into the actionable CLI refusal.
|
|
25
29
|
|
|
26
30
|
403 and 404 are the same answer to a CLI user -- this project is not one you can record against
|
|
27
31
|
-- and neither is distinguishable from a typo, so they collapse into one message naming the way
|
|
@@ -48,9 +52,9 @@ def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None
|
|
|
48
52
|
at call time, which is the binding the CLI tests patch.
|
|
49
53
|
"""
|
|
50
54
|
if api_url is not None and not has_freesolo_backend(api_url):
|
|
51
|
-
return require_project_id(project_id)
|
|
55
|
+
return {"id": require_project_id(project_id)}
|
|
52
56
|
try:
|
|
53
|
-
return
|
|
57
|
+
return get_project(project_id, api_key)
|
|
54
58
|
except ApiError as exc:
|
|
55
59
|
if exc.status not in {403, 404}:
|
|
56
60
|
raise
|
|
@@ -60,6 +64,11 @@ def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None
|
|
|
60
64
|
) from exc
|
|
61
65
|
|
|
62
66
|
|
|
67
|
+
def resolve_project_id(project_id: str, api_key: str, api_url: str | None = None) -> str:
|
|
68
|
+
"""Resolve and return one canonical project id."""
|
|
69
|
+
return str(resolve_project(project_id, api_key, api_url)["id"])
|
|
70
|
+
|
|
71
|
+
|
|
63
72
|
__all__ = [
|
|
64
73
|
"ApiClient",
|
|
65
74
|
"ApiError",
|
|
@@ -72,6 +81,7 @@ __all__ = [
|
|
|
72
81
|
"list_projects",
|
|
73
82
|
"list_trace_projects",
|
|
74
83
|
"load_credentials",
|
|
84
|
+
"resolve_project",
|
|
75
85
|
"resolve_project_id",
|
|
76
86
|
"save_credentials",
|
|
77
87
|
"upload_eval_run",
|
|
@@ -9,6 +9,7 @@ import json
|
|
|
9
9
|
import urllib.parse
|
|
10
10
|
from dataclasses import dataclass
|
|
11
11
|
from pathlib import Path
|
|
12
|
+
from typing import Any
|
|
12
13
|
|
|
13
14
|
MAX_IMAGES_PER_EXAMPLE = 8
|
|
14
15
|
MAX_IMAGE_SOURCE_BYTES = 20 * 1024 * 1024
|
|
@@ -140,20 +141,32 @@ def _validate_dimensions(width: int, height: int) -> int:
|
|
|
140
141
|
return pixels * 3
|
|
141
142
|
|
|
142
143
|
|
|
143
|
-
def
|
|
144
|
+
def inspect_image_bytes(data: bytes) -> tuple[int, int, int]:
|
|
145
|
+
"""Validate one image's header and return its (decoded_rgb_bytes, width, height).
|
|
146
|
+
|
|
147
|
+
Reads the header only: the pixels are not decoded here.
|
|
148
|
+
"""
|
|
144
149
|
try:
|
|
145
150
|
from PIL import Image
|
|
146
151
|
except ImportError as exc:
|
|
147
152
|
raise RuntimeError("Pillow is required for multimodal image training") from exc
|
|
148
153
|
try:
|
|
149
154
|
with Image.open(io.BytesIO(data)) as image:
|
|
150
|
-
return
|
|
155
|
+
return (
|
|
156
|
+
_validate_dimensions(image.width, image.height),
|
|
157
|
+
image.width,
|
|
158
|
+
image.height,
|
|
159
|
+
)
|
|
151
160
|
except ValueError:
|
|
152
161
|
raise
|
|
153
162
|
except Exception as exc:
|
|
154
163
|
raise ValueError("image source is not a valid image") from exc
|
|
155
164
|
|
|
156
165
|
|
|
166
|
+
def _inspect_image_bytes(data: bytes) -> int:
|
|
167
|
+
return inspect_image_bytes(data)[0]
|
|
168
|
+
|
|
169
|
+
|
|
157
170
|
def _pil_descriptor(image: object) -> str:
|
|
158
171
|
width = int(getattr(image, "width", 0) or 0)
|
|
159
172
|
height = int(getattr(image, "height", 0) or 0)
|
|
@@ -165,14 +178,26 @@ def _pil_descriptor(image: object) -> str:
|
|
|
165
178
|
return _descriptor("bytes", base64.b64encode(data).decode("ascii"))
|
|
166
179
|
|
|
167
180
|
|
|
168
|
-
def normalize_image_source(
|
|
169
|
-
|
|
181
|
+
def normalize_image_source(
|
|
182
|
+
source: object,
|
|
183
|
+
package_root: str | Path | None,
|
|
184
|
+
*,
|
|
185
|
+
defer_validation: bool = False,
|
|
186
|
+
) -> str:
|
|
187
|
+
"""Convert one supported image source to an Arrow-safe descriptor.
|
|
188
|
+
|
|
189
|
+
``defer_validation`` skips the per-source pixel inspection for EVERY source kind, for a caller
|
|
190
|
+
that validates the resulting descriptors itself. Profiling does exactly that, through one cached
|
|
191
|
+
pass that bounds total decode work; inspecting here as well would decode each image twice and
|
|
192
|
+
charge only some kinds to that budget. Every other caller validates eagerly.
|
|
193
|
+
"""
|
|
170
194
|
root = Path(package_root) if package_root is not None else None
|
|
171
195
|
if isinstance(source, bytearray):
|
|
172
196
|
source = bytes(source)
|
|
173
197
|
if isinstance(source, bytes):
|
|
174
198
|
_check_source_size(len(source))
|
|
175
|
-
|
|
199
|
+
if not defer_validation:
|
|
200
|
+
_inspect_image_bytes(source)
|
|
176
201
|
return _descriptor("bytes", base64.b64encode(source).decode("ascii"))
|
|
177
202
|
if _is_pil_image(source):
|
|
178
203
|
return _pil_descriptor(source)
|
|
@@ -183,7 +208,8 @@ def normalize_image_source(source: object, package_root: str | Path | None) -> s
|
|
|
183
208
|
scheme = parsed.scheme.lower()
|
|
184
209
|
if scheme == "data":
|
|
185
210
|
data = _data_uri_bytes(value)
|
|
186
|
-
|
|
211
|
+
if not defer_validation:
|
|
212
|
+
_inspect_image_bytes(data)
|
|
187
213
|
return _descriptor("data_uri", value)
|
|
188
214
|
if scheme in {"http", "https"}:
|
|
189
215
|
# flash never fetches a user-supplied URL server-side. download the image ahead of time
|
|
@@ -198,8 +224,10 @@ def normalize_image_source(source: object, package_root: str | Path | None) -> s
|
|
|
198
224
|
if scheme:
|
|
199
225
|
raise ValueError(f"unsupported image URL scheme: {scheme}")
|
|
200
226
|
path = _package_image_path(value, root)
|
|
201
|
-
|
|
202
|
-
|
|
227
|
+
descriptor = _descriptor("path", path.relative_to(root.resolve()).as_posix())
|
|
228
|
+
if not defer_validation:
|
|
229
|
+
_inspect_image_bytes(path.read_bytes())
|
|
230
|
+
return descriptor
|
|
203
231
|
|
|
204
232
|
|
|
205
233
|
def _image_source_from_block(block: dict) -> object | None:
|
|
@@ -284,7 +312,11 @@ def text_only_prompt_messages(messages: list[dict]) -> list[dict]:
|
|
|
284
312
|
return stripped
|
|
285
313
|
|
|
286
314
|
|
|
287
|
-
def _reject_literal_image_placeholder(
|
|
315
|
+
def _reject_literal_image_placeholder(
|
|
316
|
+
text: str,
|
|
317
|
+
message_index: int,
|
|
318
|
+
markers: tuple[str, ...] = (IMAGE_TEACHER_PLACEHOLDER, IMAGE_PAD_TOKEN),
|
|
319
|
+
) -> None:
|
|
288
320
|
"""Reject prompt text that already contains a reserved image marker.
|
|
289
321
|
|
|
290
322
|
two distinct markers, one reason. the rendered prompt marks image positions with
|
|
@@ -298,8 +330,12 @@ def _reject_literal_image_placeholder(text: str, message_index: int) -> None:
|
|
|
298
330
|
contributes a run the renderer never produced -- and a run from text can make up for an image
|
|
299
331
|
the provider silently dropped, which is exactly the failure the guard exists to catch. keeping
|
|
300
332
|
it out of the source text is what makes "one run per image" mean what it says.
|
|
333
|
+
|
|
334
|
+
``markers`` narrows the set for callers where only one of the two is live. local sft training
|
|
335
|
+
never renders the teacher placeholder, so a literal ``<|media_pad|>`` there is ordinary text
|
|
336
|
+
for a qwen tokenizer and rejecting it would be a false refusal.
|
|
301
337
|
"""
|
|
302
|
-
for marker in
|
|
338
|
+
for marker in markers:
|
|
303
339
|
if marker in text:
|
|
304
340
|
raise ValueError(
|
|
305
341
|
f"message {message_index} text contains the reserved image marker "
|
|
@@ -364,8 +400,14 @@ def normalize_prompt_images(
|
|
|
364
400
|
record: dict,
|
|
365
401
|
messages: list[dict],
|
|
366
402
|
package_root: str | Path | None,
|
|
403
|
+
*,
|
|
404
|
+
defer_validation: bool = False,
|
|
367
405
|
) -> NormalizedImages:
|
|
368
|
-
"""Normalize prompt image blocks and top-level fields without mutating the record.
|
|
406
|
+
"""Normalize prompt image blocks and top-level fields without mutating the record.
|
|
407
|
+
|
|
408
|
+
``defer_validation`` is forwarded to :func:`normalize_image_source`; see it for when a caller
|
|
409
|
+
may skip the per-source pixel inspection.
|
|
410
|
+
"""
|
|
369
411
|
if not isinstance(messages, list) or not all(isinstance(message, dict) for message in messages):
|
|
370
412
|
raise ValueError("prompt messages must be a list of message objects")
|
|
371
413
|
pending = list(_top_level_sources(record))
|
|
@@ -381,14 +423,18 @@ def normalize_prompt_images(
|
|
|
381
423
|
f"example contains {image_count} images, exceeding the "
|
|
382
424
|
f"{MAX_IMAGES_PER_EXAMPLE}-image limit"
|
|
383
425
|
)
|
|
384
|
-
descriptor = normalize_image_source(
|
|
426
|
+
descriptor = normalize_image_source(
|
|
427
|
+
source,
|
|
428
|
+
package_root,
|
|
429
|
+
defer_validation=defer_validation,
|
|
430
|
+
)
|
|
385
431
|
descriptor_bytes += _descriptor_size(descriptor)
|
|
386
432
|
if descriptor_bytes > MAX_TOTAL_IMAGE_DESCRIPTOR_BYTES:
|
|
387
433
|
raise ValueError(
|
|
388
434
|
f"example encoded image descriptors total {descriptor_bytes} bytes, exceeding the "
|
|
389
435
|
f"{MAX_TOTAL_IMAGE_DESCRIPTOR_BYTES}-byte limit"
|
|
390
436
|
)
|
|
391
|
-
source_bytes +=
|
|
437
|
+
source_bytes += _descriptor_source_size(descriptor, package_root)
|
|
392
438
|
if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
|
|
393
439
|
raise ValueError(
|
|
394
440
|
f"example image sources total {source_bytes} bytes, exceeding the "
|
|
@@ -465,10 +511,27 @@ def normalize_prompt_images(
|
|
|
465
511
|
add_descriptor(source)
|
|
466
512
|
image_blocks.append({"type": "image"})
|
|
467
513
|
normalized[first_user]["content"] = [*content, *image_blocks]
|
|
514
|
+
# checked here, on the finished blocks, rather than inside the loop above: string content never
|
|
515
|
+
# enters that loop, and the top-level-image path appends to a message the loop already passed.
|
|
516
|
+
# this is the one point every shape has converged to the same form.
|
|
517
|
+
#
|
|
518
|
+
# the unit is a RUN of consecutive text blocks, not one block, for the reason the teacher
|
|
519
|
+
# renderer already documents: "<|image_" and "pad|>" are each harmless alone and only become
|
|
520
|
+
# the reserved marker once the template concatenates them. an image block ends a run, since the
|
|
521
|
+
# processor puts its own expansion there and user text cannot reach across it.
|
|
522
|
+
for message_index, message in enumerate(normalized):
|
|
523
|
+
text_run: list[str] = []
|
|
524
|
+
for block in message["content"]:
|
|
525
|
+
if block.get("type") == "text":
|
|
526
|
+
text_run.append(block["text"])
|
|
527
|
+
continue
|
|
528
|
+
_reject_literal_image_placeholder("".join(text_run), message_index, (IMAGE_PAD_TOKEN,))
|
|
529
|
+
text_run = []
|
|
530
|
+
_reject_literal_image_placeholder("".join(text_run), message_index, (IMAGE_PAD_TOKEN,))
|
|
468
531
|
return NormalizedImages(normalized, descriptors)
|
|
469
532
|
|
|
470
533
|
|
|
471
|
-
def
|
|
534
|
+
def _descriptor_source_size(descriptor: str, package_root: str | Path | None) -> int:
|
|
472
535
|
kind, value = _parse_descriptor(descriptor)
|
|
473
536
|
if kind == "bytes":
|
|
474
537
|
return len(base64.b64decode(value, validate=True))
|
|
@@ -481,7 +544,8 @@ def descriptor_source_size(descriptor: str, package_root: str | Path | None) ->
|
|
|
481
544
|
raise ValueError("invalid internal image descriptor kind")
|
|
482
545
|
|
|
483
546
|
|
|
484
|
-
def
|
|
547
|
+
def read_descriptor_source(descriptor: str, package_root: str | Path | None) -> bytes:
|
|
548
|
+
"""Read one descriptor's raw source bytes under the per-source size limit."""
|
|
485
549
|
kind, value = _parse_descriptor(descriptor)
|
|
486
550
|
if kind == "bytes":
|
|
487
551
|
try:
|
|
@@ -532,7 +596,7 @@ def image_descriptors_to_data_uris(
|
|
|
532
596
|
source_bytes = 0
|
|
533
597
|
decoded_bytes = 0
|
|
534
598
|
for descriptor in descriptors:
|
|
535
|
-
data =
|
|
599
|
+
data = read_descriptor_source(descriptor, package_root)
|
|
536
600
|
source_bytes += len(data)
|
|
537
601
|
if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
|
|
538
602
|
raise ValueError(
|
|
@@ -553,20 +617,65 @@ def _decode_image_bytes(data: bytes):
|
|
|
553
617
|
from PIL import Image
|
|
554
618
|
except ImportError as exc:
|
|
555
619
|
raise RuntimeError("Pillow is required for multimodal image training") from exc
|
|
620
|
+
converted = None
|
|
556
621
|
try:
|
|
557
622
|
with Image.open(io.BytesIO(data)) as image:
|
|
558
623
|
_validate_dimensions(image.width, image.height)
|
|
559
624
|
image.load()
|
|
560
|
-
|
|
625
|
+
converted = image.convert("RGB")
|
|
626
|
+
converted.load()
|
|
627
|
+
return converted
|
|
561
628
|
except ValueError:
|
|
629
|
+
if converted is not None:
|
|
630
|
+
converted.close()
|
|
562
631
|
raise
|
|
563
632
|
except Exception as exc:
|
|
633
|
+
if converted is not None:
|
|
634
|
+
converted.close()
|
|
564
635
|
raise ValueError("image source is not a valid image") from exc
|
|
565
636
|
|
|
566
637
|
|
|
638
|
+
def messages_with_decoded_images(messages: list[dict], images: list[object]) -> list[dict]:
|
|
639
|
+
"""Bind decoded images into a message list's image blocks, in order.
|
|
640
|
+
|
|
641
|
+
Shared by sft, opd, and grpo: each algorithm decodes the row's descriptors itself and then
|
|
642
|
+
needs the same binding into the chat-template input.
|
|
643
|
+
"""
|
|
644
|
+
image_iter = iter(images)
|
|
645
|
+
prepared = []
|
|
646
|
+
for message in messages:
|
|
647
|
+
copied = dict(message)
|
|
648
|
+
content = copied.get("content")
|
|
649
|
+
if isinstance(content, list):
|
|
650
|
+
blocks = []
|
|
651
|
+
for block in content:
|
|
652
|
+
copied_block = dict(block)
|
|
653
|
+
if copied_block.get("type") == "image":
|
|
654
|
+
copied_block["image"] = next(image_iter)
|
|
655
|
+
blocks.append(copied_block)
|
|
656
|
+
copied["content"] = blocks
|
|
657
|
+
prepared.append(copied)
|
|
658
|
+
try:
|
|
659
|
+
next(image_iter)
|
|
660
|
+
except StopIteration:
|
|
661
|
+
return prepared
|
|
662
|
+
raise ValueError("unused decoded image while preparing multimodal sft tokens")
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def decode_descriptor_pixels(data: bytes) -> None:
|
|
666
|
+
"""Fully decode one image's pixels for validation, then release it.
|
|
667
|
+
|
|
668
|
+
Header inspection accepts an image whose pixel data is truncated or corrupt; only a full decode
|
|
669
|
+
finds that, and the caller wants the failure, not the image.
|
|
670
|
+
"""
|
|
671
|
+
image = _decode_image_bytes(data)
|
|
672
|
+
image.close()
|
|
673
|
+
|
|
674
|
+
|
|
567
675
|
def decode_image_descriptors(
|
|
568
676
|
descriptors: list[str], package_root: str | Path | None
|
|
569
677
|
) -> list[object]:
|
|
678
|
+
"""decode one row to fully loaded rgb images under aggregate limits."""
|
|
570
679
|
if len(descriptors) > MAX_IMAGES_PER_EXAMPLE:
|
|
571
680
|
raise ValueError(
|
|
572
681
|
f"example contains {len(descriptors)} images, exceeding the {MAX_IMAGES_PER_EXAMPLE}-image limit"
|
|
@@ -575,7 +684,7 @@ def decode_image_descriptors(
|
|
|
575
684
|
source_bytes = 0
|
|
576
685
|
decoded_bytes = 0
|
|
577
686
|
for descriptor in descriptors:
|
|
578
|
-
data =
|
|
687
|
+
data = read_descriptor_source(descriptor, package_root)
|
|
579
688
|
source_bytes += len(data)
|
|
580
689
|
if source_bytes > MAX_TOTAL_IMAGE_SOURCE_BYTES:
|
|
581
690
|
raise ValueError(
|
|
@@ -587,7 +696,14 @@ def decode_image_descriptors(
|
|
|
587
696
|
f"example decoded images exceed the {MAX_TOTAL_DECODED_BYTES}-byte limit"
|
|
588
697
|
)
|
|
589
698
|
prepared.append(data)
|
|
590
|
-
|
|
699
|
+
images: list[Any] = []
|
|
700
|
+
try:
|
|
701
|
+
images.extend(_decode_image_bytes(data) for data in prepared)
|
|
702
|
+
except Exception:
|
|
703
|
+
for image in images:
|
|
704
|
+
image.close()
|
|
705
|
+
raise
|
|
706
|
+
return images
|
|
591
707
|
|
|
592
708
|
|
|
593
709
|
def resolve_image_pad_token_id(processor, tok) -> int:
|