freesolo-flash-dev 1.2.43__tar.gz → 1.2.49__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.43 → freesolo_flash_dev-1.2.49}/CHANGELOG.md +11 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/scaffold/TRAINING.md +9 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/specs.py +3 -4
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/core/spec.py +92 -189
- freesolo_flash_dev-1.2.49/flash/core/spec_persistence.py +227 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/sft_workload.py +105 -18
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/backend_common.py +34 -30
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/entry/sft.py +25 -9
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/io/heartbeat.py +155 -118
- freesolo_flash_dev-1.2.49/flash/engine/worker/model/chatml_mask.py +551 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/model/packing.py +6 -1
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/opd_train.py +6 -7
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/opd_train_runner.py +40 -28
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/rl_train.py +40 -41
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/rl_train_runner.py +75 -136
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/sft_train.py +20 -32
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/sft_train_runner.py +51 -51
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/teacher/client.py +31 -4
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/core/checkpoint_lifecycle.py +143 -0
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/core/child/runtime.py +416 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/batching.py +12 -4
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/bridge.py +25 -9
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/child/bridge.py +51 -4
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/opd/child/entry.py +22 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/child/multiturn.py +29 -12
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/child/plugin.py +43 -9
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/opd/child/replay_guard.py +163 -0
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/opd/child/runtime.py +27 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/failures.py +17 -2
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/overrides.py +27 -27
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/scoring.py +23 -10
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/state.py +1 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/checkpoints.py +34 -31
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/rl/child/entry.py +24 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/child/multiturn.py +30 -14
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/rl/child/patches.py +459 -0
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/rl/child/plugin.py +173 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/inputs.py +5 -5
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/multi_turn.py +22 -21
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/rl/reward_module.py +41 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/sft/checkpoints.py +35 -14
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/sft/child/entry.py +24 -0
- freesolo_flash_dev-1.2.49/flash/engine/worker/train/sft/child/plugin.py +169 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/sft/config.py +0 -164
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/verl/checkpoints.py +9 -5
- freesolo_flash_dev-1.2.49/flash/engine/worker/verl/child_io.py +371 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/verl/diagnostics.py +170 -6
- freesolo_flash_dev-1.2.49/flash/engine/worker/verl/parent_work.py +40 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/bootstrap.py +19 -18
- freesolo_flash_dev-1.2.49/flash/providers/_lifecycle/bootstrap_console.py +108 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/instance.py +16 -40
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/artifacts/hf.py +10 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/resources.py +2 -2
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/serverless/endpoints.py +65 -20
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/jobs/builders.py +4 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_backend_common.py +13 -914
- freesolo_flash_dev-1.2.49/tests/test_checkpoint_lifecycle.py +132 -0
- freesolo_flash_dev-1.2.49/tests/test_console_upload.py +89 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_flash_worker.py +69 -22
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_grpo_params.py +8 -8
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_grpo_reward_batching.py +4 -1
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_instance_bootstrap_coverage.py +5 -3
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_jobs.py +26 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_lambda_runner.py +26 -9
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_multimodal_training.py +2 -2
- freesolo_flash_dev-1.2.49/tests/test_opd_multiturn_failure_exit.py +161 -0
- freesolo_flash_dev-1.2.49/tests/test_opd_replay_guard.py +219 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_opd_train.py +325 -34
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_packing.py +36 -4
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_rl_train.py +622 -765
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_train.py +1070 -89
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_workload.py +47 -28
- freesolo_flash_dev-1.2.49/tests/test_spec_contract_bytes.py +307 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vast_runner.py +4 -2
- freesolo_flash_dev-1.2.49/tests/test_verl_child_plugins.py +745 -0
- freesolo_flash_dev-1.2.49/tests/test_verl_silence_watchdog.py +223 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_wandb_link.py +4 -3
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_init_heartbeat.py +82 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_stack.py +0 -34
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/uv.lock +1 -1
- freesolo_flash_dev-1.2.43/flash/engine/worker/train/rl/child/plugin.py +0 -33
- freesolo_flash_dev-1.2.43/flash/engine/worker/train/rl/shims.py +0 -995
- freesolo_flash_dev-1.2.43/flash/engine/worker/verl/child_io.py +0 -999
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.env.example +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/README.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.43 → freesolo_flash_dev-1.2.49}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -29,6 +29,17 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
|
29
29
|
|
|
30
30
|
### Fixed
|
|
31
31
|
|
|
32
|
+
- A GRPO or OPD run whose rollout actor exited hard no longer wedges on a paid GPU until the
|
|
33
|
+
wall-time limit. The actor's `os._exit` bypassed verl's own prompt handler, so the prompt
|
|
34
|
+
stayed `running` forever and verl's unbounded replay poll waited on it at ~0% utilization. The
|
|
35
|
+
child now writes durable failure evidence, marks the prompt failed, cleans up, and only then
|
|
36
|
+
exits, and replay sampling fails the step on an explicit failure tag or a positively dead
|
|
37
|
+
actor instead of returning a survivor-only batch that would silently train on fewer rollouts
|
|
38
|
+
than were collected. A child that reaches the fit loop and then stops producing distinct
|
|
39
|
+
output, while the parent has no teacher or environment work in flight, is torn down with a
|
|
40
|
+
named cause rather than running silently to the limit; repeated identical lines count as
|
|
41
|
+
silence, and authoritative OOM, host-RAM, and infrastructure evidence still classifies the
|
|
42
|
+
exit first.
|
|
32
43
|
- `flash models deploy` now warns before it moves the shared `<run-id>` model id onto a
|
|
33
44
|
different checkpoint. Every checkpoint of a run is served under that one id, so deploying
|
|
34
45
|
`<run-id>/step-50` while `step-100` was live silently changed what `<run-id>` served for
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.49
|
|
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
|
|
@@ -844,6 +844,15 @@ Pick SFT when you already have good answers and want the model to imitate them.
|
|
|
844
844
|
`max_context_tokens` that plausibly fits prompt + completion, and only raise it when you see
|
|
845
845
|
truncation (outputs cut off mid-thought, degraded loss). A bigger context just costs
|
|
846
846
|
more.
|
|
847
|
+
- **Multi-turn targets train on the assistant turns only.** When `sft_completion` returns a
|
|
848
|
+
full target transcript (assistant turns interleaved with the environment's tool/user
|
|
849
|
+
observations), Flash supervises the assistant turns and masks the observations out of the
|
|
850
|
+
loss — the model is trained to produce its own replies, not to predict the environment's.
|
|
851
|
+
For every ChatML target, including a single assistant turn, control strings `<|im_start|>` and
|
|
852
|
+
`<|im_end|>` are reserved in every message field the active template renders into the body,
|
|
853
|
+
including text content, reasoning, and tool-call serialization. They are indistinguishable from
|
|
854
|
+
structural turn delimiters after tokenization. The run logs role-aware masked rows and any
|
|
855
|
+
completion-only fallback rows separately.
|
|
847
856
|
- **For Qwen3.5 thinking multi-turn SFT, put reasoning only in the final assistant
|
|
848
857
|
turn.** Qwen3.5's chat template strips literal `<think>` blocks from prior assistant
|
|
849
858
|
history and pre-opens `<think>\n` in the next generation prompt. If every assistant
|
|
@@ -18,10 +18,9 @@ def spec_payload(
|
|
|
18
18
|
# wire without touching the digest, which is computed server-side from the reparsed spec.
|
|
19
19
|
if spec.authored_gpu_count is None:
|
|
20
20
|
out["gpu"] = {key: value for key, value in out["gpu"].items() if key != "count"}
|
|
21
|
-
# [environment] pip is
|
|
22
|
-
# submit paths
|
|
23
|
-
#
|
|
24
|
-
# unauthorable key.
|
|
21
|
+
# [environment] pip DOES travel: it is the author's own scorer dependencies, which only they can
|
|
22
|
+
# declare, and the submit paths append it to worker_pip_for_env rather than replacing it. What
|
|
23
|
+
# travels is the extra requirements, not the worker's own.
|
|
25
24
|
if authored_train_keys is not None:
|
|
26
25
|
out["train"] = {
|
|
27
26
|
key: value for key, value in out["train"].items() if key in authored_train_keys
|
|
@@ -1,16 +1,52 @@
|
|
|
1
|
-
"""Structured job specification shared by CLI/API/runner and GPU workers.
|
|
1
|
+
"""Structured job specification shared by CLI/API/runner and GPU workers.
|
|
2
|
+
|
|
3
|
+
One `JobSpec` value is read through four different contracts, and the serializers below are how
|
|
4
|
+
they are told apart:
|
|
5
|
+
|
|
6
|
+
- authored configuration -- what a user writes. validated by `flash.schema.spec_from_dict`, NOT by
|
|
7
|
+
`JobSpec.from_dict`; the two are not interchangeable.
|
|
8
|
+
- public representation -- `to_dict()`, deliberately lossy: it strips every platform-managed field
|
|
9
|
+
so the result re-validates through the authored parser.
|
|
10
|
+
- persisted recovery record -- `from_dict()`, tolerant of historical spellings. its decoding rules
|
|
11
|
+
live in `flash.core.spec_persistence`.
|
|
12
|
+
- resolved worker payload -- `to_internal_dict()` / `to_json()`, complete, including every managed
|
|
13
|
+
and resolved field the GPU worker needs.
|
|
14
|
+
|
|
15
|
+
`flash/runner/preparation.py::_preparation_digest` hashes the canonical JSON of `to_dict()` and
|
|
16
|
+
`to_internal_dict()`, so the BYTES those two emit are a recovery contract, not an implementation
|
|
17
|
+
detail. See their docstrings before changing either.
|
|
18
|
+
"""
|
|
2
19
|
|
|
3
20
|
from __future__ import annotations
|
|
4
21
|
|
|
5
22
|
import json
|
|
6
|
-
import logging
|
|
7
23
|
import os
|
|
8
24
|
from dataclasses import asdict, dataclass, field, fields
|
|
9
25
|
from typing import Any, Literal
|
|
10
26
|
from uuid import UUID
|
|
11
27
|
|
|
12
28
|
from flash._internal.diagnostics import SECRET_ENV_KEYS_ENV
|
|
13
|
-
from flash.core.catalog import DEFAULT_MODEL, normalize_algorithm
|
|
29
|
+
from flash.core.catalog import DEFAULT_MODEL, normalize_algorithm
|
|
30
|
+
|
|
31
|
+
# `DROPPED_TOP_LEVEL_KEYS` keeps its historical private alias rather than being renamed at its 5 call
|
|
32
|
+
# sites: `flash.runner` re-exports it as a package attribute and `preparation.py` reads it back through
|
|
33
|
+
# `_runner()`, which is the seam the tests patch. Renaming it is a separate change from moving it, and
|
|
34
|
+
# doing both at once would put a live recovery path's patch points inside a refactor whose whole claim
|
|
35
|
+
# is that nothing behavioral moved.
|
|
36
|
+
from flash.core.spec_persistence import (
|
|
37
|
+
DROPPED_TOP_LEVEL_KEYS as _DROPPED_TOP_LEVEL_KEYS,
|
|
38
|
+
)
|
|
39
|
+
from flash.core.spec_persistence import (
|
|
40
|
+
REMOVED_PERSISTED_TRAIN_KEYS,
|
|
41
|
+
announce_dropped_keys,
|
|
42
|
+
migrated_optimizer_batch,
|
|
43
|
+
opt_float,
|
|
44
|
+
opt_int,
|
|
45
|
+
str_tuple,
|
|
46
|
+
validated_persisted_providers,
|
|
47
|
+
validated_section,
|
|
48
|
+
volume_gb,
|
|
49
|
+
)
|
|
14
50
|
from flash.teacher.retry_contract import OPD_RESUME_REVISION_ENV
|
|
15
51
|
|
|
16
52
|
_FALSE_STRINGS = {"", "0", "false", "no", "off", "none"}
|
|
@@ -45,15 +81,6 @@ def _coerce_credit_assignment(value: Any) -> CreditAssignment:
|
|
|
45
81
|
raise ValueError(f"credit_assignment must be one of {CREDIT_ASSIGNMENTS}; got {value!r}")
|
|
46
82
|
|
|
47
83
|
|
|
48
|
-
def _str_tuple(value: Any) -> tuple[str, ...]:
|
|
49
|
-
"""Normalize a string-or-list knob to a tuple of strings; a bare string is one element, not iterated."""
|
|
50
|
-
if value is None:
|
|
51
|
-
return ()
|
|
52
|
-
if isinstance(value, str):
|
|
53
|
-
return (value,) if value else ()
|
|
54
|
-
return tuple(s for s in (str(x) for x in value) if s)
|
|
55
|
-
|
|
56
|
-
|
|
57
84
|
def coerce_bool(value: Any) -> bool:
|
|
58
85
|
"""Parse a bool from loosely-typed sources; treats "false"/"0"/"no"/"off" as False."""
|
|
59
86
|
if isinstance(value, str):
|
|
@@ -90,18 +117,6 @@ def _coerce_wandb(value: Any) -> WandbSpec:
|
|
|
90
117
|
return WandbSpec(project=_label(value.get("project")), run_name=_label(value.get("run_name")))
|
|
91
118
|
|
|
92
119
|
|
|
93
|
-
def _volume_gb(value: Any, default: int = 100) -> int:
|
|
94
|
-
"""Parse volume size in GB; non-positive / non-numeric / missing values return default."""
|
|
95
|
-
if isinstance(value, bool):
|
|
96
|
-
# bool is an int subclass; reject to avoid int(True)==1 becoming a 1 GB volume.
|
|
97
|
-
return default
|
|
98
|
-
try:
|
|
99
|
-
gb = int(value)
|
|
100
|
-
except (TypeError, ValueError):
|
|
101
|
-
return default
|
|
102
|
-
return gb if gb > 0 else default
|
|
103
|
-
|
|
104
|
-
|
|
105
120
|
def _validated_gpu_type(value: Any, *, field_name: str) -> str:
|
|
106
121
|
if not isinstance(value, str):
|
|
107
122
|
raise TypeError(f"{field_name} must be a string")
|
|
@@ -191,55 +206,6 @@ def attributed_gpu_type(status: Any) -> str:
|
|
|
191
206
|
return selected or persisted_gpu_head(field("spec"))
|
|
192
207
|
|
|
193
208
|
|
|
194
|
-
def _opt_int(value: Any) -> int | None:
|
|
195
|
-
"""Parse optional int; rejects bools (bool is int subclass — int(True)==1 is a footgun)."""
|
|
196
|
-
if value is None:
|
|
197
|
-
return None
|
|
198
|
-
if isinstance(value, bool):
|
|
199
|
-
raise TypeError(f"expected a number, got bool {value!r}")
|
|
200
|
-
return int(value)
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def _opt_float(value: Any) -> float | None:
|
|
204
|
-
"""Parse optional float; rejects bools (mirrors _opt_int)."""
|
|
205
|
-
if value is None:
|
|
206
|
-
return None
|
|
207
|
-
if isinstance(value, bool):
|
|
208
|
-
raise TypeError(f"expected a number, got bool {value!r}")
|
|
209
|
-
return float(value)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
def _migrated_optimizer_batch(train: dict, algorithm: str) -> tuple[int | None, int | None]:
|
|
213
|
-
"""``(batch_size, prompts_per_step)`` with the pre-1.1.43 rollout spelling migrated.
|
|
214
|
-
|
|
215
|
-
grpo/opd authored the optimizer batch as ``batch_size`` until it was split into
|
|
216
|
-
``prompts_per_step``. The schema rejects the old name on SUBMISSION, but `from_dict` also
|
|
217
|
-
reparses PERSISTED specs, and the deployed release (1.1.40) has no ``prompts_per_step`` at all
|
|
218
|
-
-- so every rollout run in flight across this upgrade carries only the old key. The workers read
|
|
219
|
-
``prompts_per_step`` alone, so without this a recovered run silently resumes on the recipe
|
|
220
|
-
default: 64 instead of an authored 32 on grpo, which OOMs a card rented for 32, and 8 on opd.
|
|
221
|
-
|
|
222
|
-
The old key is MOVED, not copied, and is dropped whenever the new one is present. Leaving it
|
|
223
|
-
populated would re-emit both names from ``to_dict()``, and a spec carrying both is rejected by
|
|
224
|
-
the schema -- breaking the resubmit that recovery and ``flash runs get`` perform, and leaving
|
|
225
|
-
`vram.py::_optimizer_batch_value` (which takes the larger of the two) free to size a card off
|
|
226
|
-
the stale value that ranking ignores. That applies to a payload written mid-upgrade carrying
|
|
227
|
-
BOTH spellings too: ``prompts_per_step`` wins, so the superseded key has to go with it.
|
|
228
|
-
|
|
229
|
-
A non-positive legacy value is discarded rather than migrated: ``minimum=1`` would have
|
|
230
|
-
rejected it at submission, and carrying it forward only fails later on a rented GPU. It is
|
|
231
|
-
discarded from BOTH names for the same round-trip reason -- retaining it under the old one
|
|
232
|
-
would re-emit a key the schema rejects for this algorithm.
|
|
233
|
-
"""
|
|
234
|
-
batch_size = _opt_int(train.get("batch_size"))
|
|
235
|
-
prompts_per_step = _opt_int(train.get("prompts_per_step"))
|
|
236
|
-
if not samples_on_policy(algorithm):
|
|
237
|
-
return batch_size, prompts_per_step
|
|
238
|
-
if prompts_per_step is not None:
|
|
239
|
-
return None, prompts_per_step
|
|
240
|
-
return None, batch_size if batch_size is not None and batch_size >= 1 else None
|
|
241
|
-
|
|
242
|
-
|
|
243
209
|
_MAX_GPU_COUNT = 8
|
|
244
210
|
|
|
245
211
|
|
|
@@ -370,12 +336,6 @@ class EnvironmentSpec:
|
|
|
370
336
|
resolved_sha: str = ""
|
|
371
337
|
|
|
372
338
|
|
|
373
|
-
# internal persisted-record compatibility only, never public config parsing. #968 removed
|
|
374
|
-
# advantage_clip, but already-provisioned strict records still carry the unused key and otherwise fail
|
|
375
|
-
# attach/recovery. do not generalize this allowlist: removed ``seeds`` must still raise (#536).
|
|
376
|
-
REMOVED_PERSISTED_TRAIN_KEYS = frozenset({"advantage_clip"})
|
|
377
|
-
|
|
378
|
-
|
|
379
339
|
@dataclass(frozen=True)
|
|
380
340
|
class TrainSpec:
|
|
381
341
|
epochs: int | None = field(default=None, metadata={"introduced_in": "0.2.0"})
|
|
@@ -505,55 +465,6 @@ MANAGED_GPU_KEYS = frozenset(
|
|
|
505
465
|
{"disk_gb", "network_volume", "network_volume_gb", "max_retries", "max_wall_seconds"}
|
|
506
466
|
)
|
|
507
467
|
|
|
508
|
-
# Removed public top-level fields that a PERSISTED record can still carry. Stored run records are
|
|
509
|
-
# never rewritten, and effective_preparation.worker_spec is written with to_internal_dict() (asdict),
|
|
510
|
-
# which emitted every field including the defaulted ones -- so every record written before a field
|
|
511
|
-
# was dropped still names it. This registry also drives historical public-digest replay for
|
|
512
|
-
# model_revision, which remains an internal field. Without it a still-running job can lose its
|
|
513
|
-
# recovery, deploy, and serving paths after the upgrade.
|
|
514
|
-
#
|
|
515
|
-
# Ignored on READ only. Most keys here no longer exist as JobSpec fields; model_revision remains an
|
|
516
|
-
# internal runner field, but the public schema rejects it and to_dict omits it. Keeping it in this set
|
|
517
|
-
# lets digest recovery identify the historical public key without weakening JobSpec.from_dict.
|
|
518
|
-
_DROPPED_TOP_LEVEL_KEYS = frozenset(
|
|
519
|
-
{"model_policy", "model_revision", "worker_env", "workload_profile_kind"}
|
|
520
|
-
)
|
|
521
|
-
|
|
522
|
-
# Tolerating a dropped key keeps a pre-upgrade run's recovery path, but the values behind it stop
|
|
523
|
-
# being applied -- so a run that authored them now trains on managed defaults instead of what was
|
|
524
|
-
# submitted. That is announced rather than silent. Only user-authorable keys qualify: model_policy
|
|
525
|
-
# was platform-managed (to_dict popped it), so its loss cannot change what a submitted config asked
|
|
526
|
-
# for. The values are deliberately NOT forwarded -- doing so would reinstate the override table this
|
|
527
|
-
# removal exists to close, and would deliver it without the validation the deleted parser performed.
|
|
528
|
-
_ANNOUNCED_DROPPED_KEYS = frozenset({"worker_env"})
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
def _announce_dropped_keys(data: dict[str, Any]) -> None:
|
|
532
|
-
"""Log the removed user-authored keys a persisted record still carries and no longer applies.
|
|
533
|
-
|
|
534
|
-
Only announced when the payload names the run. A public spec is ``to_dict()`` output, which pops
|
|
535
|
-
the server-assigned run_id, and the same stored run is read through both shapes -- so warning
|
|
536
|
-
without an id would emit an unactionable "run <unknown>" line and duplicate the identified one
|
|
537
|
-
the worker-spec read already produced. Every provisioned run records an internal worker spec
|
|
538
|
-
(asdict, run_id included), and that is the read this fires on.
|
|
539
|
-
"""
|
|
540
|
-
run_id = str(data.get("run_id") or "").strip()
|
|
541
|
-
if not run_id:
|
|
542
|
-
return
|
|
543
|
-
for key in sorted(_ANNOUNCED_DROPPED_KEYS):
|
|
544
|
-
value = data.get(key)
|
|
545
|
-
if not value:
|
|
546
|
-
continue
|
|
547
|
-
names = ", ".join(sorted(str(k) for k in value)) if isinstance(value, dict) else str(value)
|
|
548
|
-
logging.getLogger("flash.spec").warning(
|
|
549
|
-
"run %s was submitted with [%s] (%s); that table was removed and its values are NOT "
|
|
550
|
-
"applied -- this run uses managed defaults instead. resubmit without it if the run "
|
|
551
|
-
"depends on those values.",
|
|
552
|
-
run_id,
|
|
553
|
-
key,
|
|
554
|
-
names,
|
|
555
|
-
)
|
|
556
|
-
|
|
557
468
|
|
|
558
469
|
@dataclass(frozen=True)
|
|
559
470
|
class WandbSpec:
|
|
@@ -651,6 +562,15 @@ class JobSpec:
|
|
|
651
562
|
|
|
652
563
|
omit platform-managed fields because the control plane/runner assigns them and the public
|
|
653
564
|
parser rejects them. internal callers use ``to_internal_dict()``.
|
|
565
|
+
|
|
566
|
+
This is the PUBLIC contract and it is deliberately lossy: what it drops is what the authored
|
|
567
|
+
parser would reject, so the result re-validates through ``flash.schema.spec_from_dict``. Do
|
|
568
|
+
not hand its output to a worker or provider path -- those need ``to_internal_dict()``.
|
|
569
|
+
|
|
570
|
+
Its bytes are a recovery contract. ``_preparation_digest`` hashes this output as canonical
|
|
571
|
+
JSON, so key PRESENCE is load-bearing even though key order is not: adding or dropping one
|
|
572
|
+
key here invalidates the stored digest of every warm-start and workload-profile run in
|
|
573
|
+
flight, which fails integrity validation on recovery.
|
|
654
574
|
"""
|
|
655
575
|
data = asdict(self)
|
|
656
576
|
# server-assigned identity — never authored in a config.
|
|
@@ -696,7 +616,17 @@ class JobSpec:
|
|
|
696
616
|
return data
|
|
697
617
|
|
|
698
618
|
def to_internal_dict(self) -> dict[str, Any]:
|
|
699
|
-
"""Return the complete control-plane and worker representation.
|
|
619
|
+
"""Return the complete control-plane and worker representation.
|
|
620
|
+
|
|
621
|
+
This is the RESOLVED WORKER contract: every managed and resolved field the GPU worker needs,
|
|
622
|
+
including the ones ``to_dict()`` strips. It is what gets persisted as
|
|
623
|
+
``effective_preparation.worker_spec`` and what ``to_json()`` ships to a provider. The
|
|
624
|
+
authored parser rejects this shape, so it must never be offered as a public payload.
|
|
625
|
+
|
|
626
|
+
Its bytes are a recovery contract for the same reason as ``to_dict()`` -- and note the two
|
|
627
|
+
empty-value pops below are part of it: an omitted empty field and an explicit empty one hash
|
|
628
|
+
differently, so removing either pop would break existing digests.
|
|
629
|
+
"""
|
|
700
630
|
data = asdict(self)
|
|
701
631
|
# missing and unset are the same internal state. omitting the empty value preserves that state
|
|
702
632
|
# without serializing it into an explicit empty preference, which every parser rejects.
|
|
@@ -712,13 +642,22 @@ class JobSpec:
|
|
|
712
642
|
|
|
713
643
|
@classmethod
|
|
714
644
|
def from_dict(cls, data: dict[str, Any]) -> JobSpec:
|
|
645
|
+
"""Decode a PERSISTED or internal job spec. This is not the authored-config parser.
|
|
646
|
+
|
|
647
|
+
Authored configuration goes through ``flash.schema.spec_from_dict``, which is strict because
|
|
648
|
+
an unknown key there is a typo the author can still fix. This one reads bytes that were
|
|
649
|
+
already written -- by an older Flash, for a run that may still be training -- so it tolerates
|
|
650
|
+
the historical spellings registered in ``flash.core.spec_persistence``. The two are NOT
|
|
651
|
+
interchangeable: decoding a user's config here would silently accept platform-managed fields
|
|
652
|
+
that the public parser exists to reject.
|
|
653
|
+
"""
|
|
715
654
|
if not isinstance(data, dict):
|
|
716
655
|
raise TypeError("job spec must be an object")
|
|
717
656
|
allowed_top_level = {item.name for item in fields(cls)}
|
|
718
657
|
unknown_top_level = sorted(set(data) - allowed_top_level - _DROPPED_TOP_LEVEL_KEYS)
|
|
719
658
|
if unknown_top_level:
|
|
720
659
|
raise ValueError(f"job spec has unknown key(s): {', '.join(unknown_top_level)}")
|
|
721
|
-
|
|
660
|
+
announce_dropped_keys(data)
|
|
722
661
|
env = data.get("environment") or {}
|
|
723
662
|
# Reject stale payloads carrying a local `path`; worker only runs published env ids.
|
|
724
663
|
if isinstance(env, dict) and env.get("path"):
|
|
@@ -726,51 +665,15 @@ class JobSpec:
|
|
|
726
665
|
"local environment paths are no longer supported; the worker only runs "
|
|
727
666
|
"published Freesolo environment ids"
|
|
728
667
|
)
|
|
729
|
-
train =
|
|
730
|
-
|
|
731
|
-
train
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
train = {
|
|
735
|
-
key: value for key, value in train.items() if key not in REMOVED_PERSISTED_TRAIN_KEYS
|
|
736
|
-
}
|
|
737
|
-
unknown_train = sorted(set(train) - {item.name for item in fields(TrainSpec)})
|
|
738
|
-
if unknown_train:
|
|
739
|
-
raise ValueError(f"train has unknown key(s): {', '.join(unknown_train)}")
|
|
740
|
-
gpu = data.get("gpu")
|
|
741
|
-
if gpu is None:
|
|
742
|
-
gpu = {}
|
|
743
|
-
if not isinstance(gpu, dict):
|
|
744
|
-
raise TypeError("gpu must be an object")
|
|
745
|
-
unknown_gpu = sorted(set(gpu) - {item.name for item in fields(GpuSpec)})
|
|
746
|
-
if unknown_gpu:
|
|
747
|
-
raise ValueError(f"gpu has unknown key(s): {', '.join(unknown_gpu)}")
|
|
748
|
-
gpu_type, gpu_type_fallbacks = _parse_persisted_gpu_types(gpu)
|
|
749
|
-
provider = gpu.get("provider", "")
|
|
750
|
-
if not isinstance(provider, str):
|
|
751
|
-
raise TypeError("gpu.provider must be a string")
|
|
752
|
-
provider = provider.strip().lower()
|
|
753
|
-
providers_raw = gpu.get("providers", ())
|
|
754
|
-
from flash.providers import PROVIDER_NAMES, validated_provider_preferences
|
|
755
|
-
|
|
756
|
-
providers = validated_provider_preferences(
|
|
757
|
-
providers_raw, allow_empty="providers" not in gpu
|
|
668
|
+
train = validated_section(
|
|
669
|
+
data,
|
|
670
|
+
"train",
|
|
671
|
+
{item.name for item in fields(TrainSpec)},
|
|
672
|
+
removed=REMOVED_PERSISTED_TRAIN_KEYS,
|
|
758
673
|
)
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
from flash.providers.base import providers_for
|
|
763
|
-
|
|
764
|
-
if provider and provider not in PROVIDER_NAMES:
|
|
765
|
-
raise ValueError(f"unknown gpu.provider {provider!r}")
|
|
766
|
-
# a hard provider pin must carry every acceptable class.
|
|
767
|
-
for candidate in (gpu_type, *gpu_type_fallbacks):
|
|
768
|
-
if candidate and provider and provider not in providers_for(candidate):
|
|
769
|
-
raise ValueError(
|
|
770
|
-
f"gpu.provider {provider!r} cannot provision gpu.type {candidate!r}"
|
|
771
|
-
)
|
|
772
|
-
# provider preferences are soft. an ineligible named provider contributes no candidate,
|
|
773
|
-
# while eligible named or unnamed configured providers remain available for failover.
|
|
674
|
+
gpu = validated_section(data, "gpu", {item.name for item in fields(GpuSpec)})
|
|
675
|
+
gpu_type, gpu_type_fallbacks = _parse_persisted_gpu_types(gpu)
|
|
676
|
+
provider, providers = validated_persisted_providers(gpu, gpu_type, gpu_type_fallbacks)
|
|
774
677
|
project_raw = data.get("project", "")
|
|
775
678
|
if not isinstance(project_raw, str):
|
|
776
679
|
raise TypeError("project must be a string")
|
|
@@ -778,7 +681,7 @@ class JobSpec:
|
|
|
778
681
|
algorithm = normalize_algorithm(data.get("algorithm", cls.algorithm))
|
|
779
682
|
# one reading of the optimizer batch for both keys: the rollout spelling changed in 1.1.43
|
|
780
683
|
# and a persisted spec can still carry the old one.
|
|
781
|
-
batch_size, prompts_per_step =
|
|
684
|
+
batch_size, prompts_per_step = migrated_optimizer_batch(train, algorithm)
|
|
782
685
|
return cls(
|
|
783
686
|
model=data.get("model", cls.model),
|
|
784
687
|
model_revision=_model_revision(data.get("model_revision", cls.model_revision)),
|
|
@@ -787,11 +690,11 @@ class JobSpec:
|
|
|
787
690
|
id=env.get("id", ""),
|
|
788
691
|
params=dict(env.get("params") or {}),
|
|
789
692
|
pip=tuple(str(p) for p in env.get("pip") or ()),
|
|
790
|
-
secrets=
|
|
693
|
+
secrets=str_tuple(env.get("secrets")),
|
|
791
694
|
resolved_sha=str(env.get("resolved_sha") or ""),
|
|
792
695
|
),
|
|
793
696
|
train=TrainSpec(
|
|
794
|
-
epochs=
|
|
697
|
+
epochs=opt_int(train.get("epochs")),
|
|
795
698
|
lora_rank=int(train.get("lora_rank", 32)),
|
|
796
699
|
# round-trip a stored alpha (authored value, internal carrier, or a warm-start's
|
|
797
700
|
# inherited parent alpha); fall back to 2 x rank when absent.
|
|
@@ -803,22 +706,22 @@ class JobSpec:
|
|
|
803
706
|
init_from_adapter=str(train.get("init_from_adapter") or ""),
|
|
804
707
|
init_from_adapter_revision=str(train.get("init_from_adapter_revision") or ""),
|
|
805
708
|
hf_repo=str(train.get("hf_repo") or ""),
|
|
806
|
-
learning_rate=
|
|
709
|
+
learning_rate=opt_float(train.get("learning_rate")),
|
|
807
710
|
batch_size=batch_size,
|
|
808
711
|
prompts_per_step=prompts_per_step,
|
|
809
|
-
max_context_tokens=
|
|
810
|
-
save_every=
|
|
712
|
+
max_context_tokens=opt_int(train.get("max_context_tokens")),
|
|
713
|
+
save_every=opt_int(train.get("save_every")),
|
|
811
714
|
max_steps=parse_max_steps(train.get("max_steps")),
|
|
812
715
|
save_at_steps=train.get("save_at_steps"),
|
|
813
|
-
max_examples=
|
|
814
|
-
group_size=
|
|
815
|
-
temperature=
|
|
816
|
-
max_completion_tokens=
|
|
817
|
-
kl_penalty_coef=
|
|
818
|
-
entropy_quantile=
|
|
819
|
-
thinking_length_penalty_coef=
|
|
716
|
+
max_examples=opt_int(train.get("max_examples")),
|
|
717
|
+
group_size=opt_int(train.get("group_size")),
|
|
718
|
+
temperature=opt_float(train.get("temperature")),
|
|
719
|
+
max_completion_tokens=opt_int(train.get("max_completion_tokens")),
|
|
720
|
+
kl_penalty_coef=opt_float(train.get("kl_penalty_coef")),
|
|
721
|
+
entropy_quantile=opt_float(train.get("entropy_quantile")),
|
|
722
|
+
thinking_length_penalty_coef=opt_float(train.get("thinking_length_penalty_coef")),
|
|
820
723
|
teacher_model=str(train.get("teacher_model") or ""),
|
|
821
|
-
stop_sequences=
|
|
724
|
+
stop_sequences=str_tuple(train.get("stop_sequences")),
|
|
822
725
|
structured_outputs=str(train.get("structured_outputs") or ""),
|
|
823
726
|
credit_assignment=_coerce_credit_assignment(train.get("credit_assignment")),
|
|
824
727
|
),
|
|
@@ -833,7 +736,7 @@ class JobSpec:
|
|
|
833
736
|
# survives the to_dict()->from_dict() hops in _with_model_disk / _spec_with_gpu /
|
|
834
737
|
# _assign_managed_hf_repo before deploy.
|
|
835
738
|
network_volume=gpu.get("network_volume"),
|
|
836
|
-
network_volume_gb=
|
|
739
|
+
network_volume_gb=volume_gb(gpu.get("network_volume_gb")),
|
|
837
740
|
count=gpu.get("count", 1),
|
|
838
741
|
type_fallbacks=gpu_type_fallbacks,
|
|
839
742
|
),
|