freesolo-flash-dev 1.2.49__tar.gz → 1.2.53__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.49 → freesolo_flash_dev-1.2.53}/CHANGELOG.md +38 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cost/analytical.py +86 -35
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cost/spec.py +5 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cost/types.py +24 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/io/heartbeat.py +41 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/__init__.py +3 -3
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/identity.py +5 -1
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/loader.py +5 -1
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/bootstrap.py +21 -5
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/bootstrap_console.py +9 -5
- freesolo_flash_dev-1.2.53/flash/providers/_lifecycle/host/__init__.py +5 -0
- freesolo_flash_dev-1.2.53/flash/providers/_lifecycle/host/deadline_sleep.py +63 -0
- freesolo_flash_dev-1.2.53/flash/providers/_lifecycle/host/failmark.py +89 -0
- freesolo_flash_dev-1.2.53/flash/providers/_lifecycle/host/hostlog.py +60 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/instance.py +47 -228
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/poll_instance.py +79 -174
- freesolo_flash_dev-1.2.53/flash/providers/_lifecycle/terminal_artifacts.py +261 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/worker.py +3 -56
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/artifacts/preload_runpod.py +1 -2
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/artifacts/weight_cache.py +0 -1
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/jobs/builders.py +2 -2
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/job_execution.py +2 -12
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/jobs.py +2 -39
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/serverless/__init__.py +0 -3
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/serverless/endpoints.py +1 -93
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/jobs/builders.py +21 -25
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/recovery.py +33 -54
- freesolo_flash_dev-1.2.53/flash/runtime_capsule/__init__.py +48 -0
- freesolo_flash_dev-1.2.53/flash/runtime_capsule/build.py +231 -0
- freesolo_flash_dev-1.2.53/flash/runtime_capsule/manifest.py +240 -0
- freesolo_flash_dev-1.2.53/flash/runtime_capsule/profiles.py +65 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/scripts/check_function_size.py +4 -3
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cancel_remote.py +3 -59
- freesolo_flash_dev-1.2.53/tests/test_console_upload.py +145 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cost_estimate.py +6 -2
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_rate_limit_resolve.py +26 -6
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_flash_worker.py +129 -28
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_instance_bootstrap_coverage.py +49 -5
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_jobs.py +9 -47
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_kernel_fingerprint.py +36 -23
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_lambda_runner.py +171 -119
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_provider_teardown_robustness.py +1 -1
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_runmgmt.py +110 -1
- freesolo_flash_dev-1.2.53/tests/test_runtime_capsule.py +434 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_spec_and_validation.py +88 -0
- freesolo_flash_dev-1.2.53/tests/test_terminal_artifacts.py +181 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vast_runner.py +128 -29
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_weight_cache.py +8 -5
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_image.py +0 -11
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_init_heartbeat.py +219 -17
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_stack.py +28 -40
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/uv.lock +1 -1
- freesolo_flash_dev-1.2.49/tests/test_console_upload.py +0 -89
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.env.example +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/README.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -21,6 +21,16 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
|
21
21
|
|
|
22
22
|
### Changed
|
|
23
23
|
|
|
24
|
+
- An attempt's terminal artifacts (its strict marker plus `metrics.json`) are now interpreted by
|
|
25
|
+
one shared protocol instead of being decoded separately by live instance polling and by each
|
|
26
|
+
recovery path. The two decoders disagreed about identical bytes. A marker that could not be tied
|
|
27
|
+
to the attempt was a terminal failure to the live poller but indistinguishable from "no marker
|
|
28
|
+
yet" to recovery, so the same corrupt artifact produced a different story depending on which
|
|
29
|
+
layer happened to observe it; recovery now names it rather than logging silence. Neither path
|
|
30
|
+
ever adopted such a marker as completed work, and neither does now. Recovery also computed a
|
|
31
|
+
fresh observation window for the marker and then another for `metrics.json`, so the real ceiling
|
|
32
|
+
was their sum and moved with however long the first read took; both reads now share one window,
|
|
33
|
+
which makes the bound the cutoff rather than the sum.
|
|
24
34
|
- CI runs the offline test suite on both supported interpreters (3.11 and 3.12) rather than
|
|
25
35
|
3.11 alone, and sets `HF_HUB_OFFLINE` / `TRANSFORMERS_OFFLINE` so a test that reaches the
|
|
26
36
|
network fails deterministically instead of depending on runner connectivity.
|
|
@@ -29,6 +39,34 @@ This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
|
29
39
|
|
|
30
40
|
### Fixed
|
|
31
41
|
|
|
42
|
+
- An ordered `[gpu] type` list is now priced over every class it declares acceptable, not just the
|
|
43
|
+
first. Allocation cost-ranks the whole set, so quoting the head alone priced a shape the run may
|
|
44
|
+
never be given — an authored `["B200", "H100"]` quoted roughly 3x the H100 the allocator would
|
|
45
|
+
really rent, and the submit-time affordability check runs on that estimate, so a run the
|
|
46
|
+
organization could afford could be refused before allocation ever got to choose. A single
|
|
47
|
+
authored class is still a hard pin, and a no-fit rejection now names every acceptable class
|
|
48
|
+
rather than whichever happened to be written first.
|
|
49
|
+
|
|
50
|
+
- A provider preference that exhausts every configured provider no longer falls back to quoting
|
|
51
|
+
hardware this plane cannot rent. The final fallback dropped the restriction and ranked the
|
|
52
|
+
registered RunPod pool regardless of credentials, so a vast-only plane could quote a B200: the
|
|
53
|
+
estimate passed affordability and the run was recorded, only for live allocation to fail. The
|
|
54
|
+
quote now raises against the eligible set, which names the real constraint.
|
|
55
|
+
|
|
56
|
+
- A GitHub token that is invalid, expired, or missing a scope now fails during preparation instead
|
|
57
|
+
of after a GPU is rented. Non-rate-limit 401 and 403 responses were left as untyped errors, which
|
|
58
|
+
the submit-time preflight treats as a transient blip worth deferring, so the run proceeded
|
|
59
|
+
through affordability and allocation and hit the same permanent credential error on the worker.
|
|
60
|
+
They are now classified permanent, like 404 and 422. The rate-limit 403 is still transient.
|
|
61
|
+
|
|
62
|
+
- A slow heartbeat upload no longer stalls every other heartbeat behind it. The throttle clock only
|
|
63
|
+
advances once a commit lands, so during a slow HuggingFace commit other callers still saw an
|
|
64
|
+
upload as due and blocked on the upload lock for up to its acquire timeout — 30s, or 120s on a
|
|
65
|
+
critical stage — which stalled the liveness daemon and delayed leaving the wrapped stage by the
|
|
66
|
+
same window. A throttled heartbeat now skips while a commit is in flight, since that commit
|
|
67
|
+
already carries the stage's state. Terminal, error, initial, and forced step commits still queue
|
|
68
|
+
and land: they carry state no later heartbeat would repair.
|
|
69
|
+
|
|
32
70
|
- A GRPO or OPD run whose rollout actor exited hard no longer wedges on a paid GPU until the
|
|
33
71
|
wall-time limit. The actor's `os._exit` bypassed verl's own prompt handler, so the prompt
|
|
34
72
|
stayed `running` forever and verl's unbounded replay poll waited on it at ~0% utilization. The
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.53
|
|
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
|
|
@@ -597,7 +597,15 @@ def _offline_preferred_gpu_shape(config: RunConfig) -> tuple[str, int, int, str,
|
|
|
597
597
|
quote[4] * quote[2] * sharded_step_seconds(config, quote[0], quote[2], quote[3])
|
|
598
598
|
),
|
|
599
599
|
)
|
|
600
|
-
#
|
|
600
|
+
# every eligible provider has now been tried and none has a structural fit. dropping the
|
|
601
|
+
# restriction here to reach the unpinned `provider="auto"` diagnostic would rank the registered
|
|
602
|
+
# runpod pool regardless of credentials, quoting a shape this plane cannot rent -- the same
|
|
603
|
+
# defect the eligibility filter above exists to prevent, reintroduced at the last step. that
|
|
604
|
+
# quote would then pass affordability and only fail once live allocation runs, after the run is
|
|
605
|
+
# recorded. re-raise the eligible set's own failure instead, which names the real constraint.
|
|
606
|
+
if eligible:
|
|
607
|
+
return _offline_gpu_shape(replace(config, provider=eligible[0], providers=()))
|
|
608
|
+
# no provider is registered at all (an empty registry): keep the historical unpinned answer.
|
|
601
609
|
return _offline_gpu_shape(replace(config, providers=()))
|
|
602
610
|
|
|
603
611
|
|
|
@@ -629,11 +637,18 @@ def _offline_gpu_shape(config: RunConfig) -> tuple[str, int, int, str, float]:
|
|
|
629
637
|
providers_for,
|
|
630
638
|
rentable_gpu_counts,
|
|
631
639
|
)
|
|
632
|
-
from flash.providers.fit_errors import vram_fit_error_message, vram_knob_advice
|
|
633
640
|
|
|
634
641
|
provider = config.provider if config.provider != "auto" else "auto"
|
|
635
642
|
if config.gpu_type:
|
|
636
|
-
|
|
643
|
+
# rank every class the author declared acceptable, not just the head. `allocate()` cost-ranks
|
|
644
|
+
# the whole ordered set, so quoting the head alone prices a shape the run may never be given
|
|
645
|
+
# -- an authored ["B200", "H100"] quotes 3x the H100 the allocator would actually rent, and
|
|
646
|
+
# the submit-time affordability precheck refuses an affordable run on that inflated number.
|
|
647
|
+
names = tuple(
|
|
648
|
+
dict.fromkeys(
|
|
649
|
+
canonical_gpu(name) for name in (config.gpu_type, *config.gpu_type_fallbacks)
|
|
650
|
+
)
|
|
651
|
+
)
|
|
637
652
|
elif provider == "auto":
|
|
638
653
|
# `auto` ranks the RunPod pool: it is the default substrate, and the allocator only reaches a
|
|
639
654
|
# lambda-only class after the cheaper runpod classes exhaust, so quoting one here would name
|
|
@@ -700,43 +715,79 @@ def _offline_gpu_shape(config: RunConfig) -> tuple[str, int, int, str, float]:
|
|
|
700
715
|
)
|
|
701
716
|
)
|
|
702
717
|
if not ranked:
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
raise ValueError(
|
|
712
|
-
f"exact GPU {info.name!r} cannot fit this run: it requires at least {need} GB"
|
|
713
|
-
+ (
|
|
714
|
-
remedy
|
|
715
|
-
or _catalog_check_remedy(config, need, names)
|
|
716
|
-
or f". {vram_knob_advice(config.method).capitalize()}."
|
|
717
|
-
)
|
|
718
|
-
)
|
|
719
|
-
raise ValueError(
|
|
720
|
-
vram_fit_error_message(
|
|
721
|
-
config.method,
|
|
722
|
-
need,
|
|
723
|
-
requested_gpu_count=ceiling,
|
|
724
|
-
effective_gpu_count=safe_gpu_count,
|
|
725
|
-
max_gpu_count=auto_cap,
|
|
726
|
-
gpu_names=names,
|
|
727
|
-
providers=None if provider == "auto" else (provider,),
|
|
728
|
-
# same rule the ranking loop rejected shapes with, so the advice cannot name a
|
|
729
|
-
# width the retry will not launch on.
|
|
730
|
-
executed_width=lambda count: executed_gpu_count(config, count),
|
|
731
|
-
# an offline quote does not know the configured fleet, so it cannot claim that
|
|
732
|
-
# dropping a provider pin would make a wider shape purchasable.
|
|
733
|
-
widenable_without_pin=None,
|
|
734
|
-
)
|
|
718
|
+
_raise_no_fitting_shape(
|
|
719
|
+
config,
|
|
720
|
+
need,
|
|
721
|
+
names,
|
|
722
|
+
provider=provider,
|
|
723
|
+
ceiling=ceiling,
|
|
724
|
+
safe_gpu_count=safe_gpu_count,
|
|
725
|
+
auto_cap=auto_cap,
|
|
735
726
|
)
|
|
736
727
|
_cost, count, _combined, _per_card, gpu, hourly = min(ranked)
|
|
737
728
|
return gpu, need, count, provider, hourly
|
|
738
729
|
|
|
739
730
|
|
|
731
|
+
def _raise_no_fitting_shape(
|
|
732
|
+
config: RunConfig,
|
|
733
|
+
need: float,
|
|
734
|
+
names: tuple[str, ...],
|
|
735
|
+
*,
|
|
736
|
+
provider: str,
|
|
737
|
+
ceiling: int | None,
|
|
738
|
+
safe_gpu_count: int,
|
|
739
|
+
auto_cap: int,
|
|
740
|
+
) -> None:
|
|
741
|
+
"""Reject a run no rentable shape fits, naming what the quote was allowed to rank."""
|
|
742
|
+
from flash.providers.base import GPU_INFO, canonical_gpu
|
|
743
|
+
from flash.providers.fit_errors import vram_fit_error_message, vram_knob_advice
|
|
744
|
+
|
|
745
|
+
# a pinned class is blocked by the class itself, so name it -- the pool-wide message would
|
|
746
|
+
# report the widest validated shape, which is not hardware this quote was ever allowed to
|
|
747
|
+
# use. `_wider_shape_remedy` searches only `names`, already narrowed to the pin, so the
|
|
748
|
+
# `--gpus N` clause it appends can never name a shape the pin forbids. an unpinned run
|
|
749
|
+
# falls through to the pool-wide message, which reports the count that would fit.
|
|
750
|
+
remedy = _wider_shape_remedy(config, need, names)
|
|
751
|
+
if config.gpu_type:
|
|
752
|
+
# name every acceptable class, not just the head: with fallbacks authored, reporting the
|
|
753
|
+
# head alone tells the user to fix a class that may not be the one that failed, and
|
|
754
|
+
# hides that the whole declared set was ranked and rejected.
|
|
755
|
+
declared = tuple(
|
|
756
|
+
GPU_INFO[canonical_gpu(name)].name
|
|
757
|
+
for name in (config.gpu_type, *config.gpu_type_fallbacks)
|
|
758
|
+
)
|
|
759
|
+
label = (
|
|
760
|
+
repr(declared[0])
|
|
761
|
+
if len(declared) == 1
|
|
762
|
+
else "none of " + ", ".join(repr(name) for name in declared)
|
|
763
|
+
)
|
|
764
|
+
raise ValueError(
|
|
765
|
+
f"exact GPU {label} cannot fit this run: it requires at least {need} GB"
|
|
766
|
+
+ (
|
|
767
|
+
remedy
|
|
768
|
+
or _catalog_check_remedy(config, need, names)
|
|
769
|
+
or f". {vram_knob_advice(config.method).capitalize()}."
|
|
770
|
+
)
|
|
771
|
+
)
|
|
772
|
+
raise ValueError(
|
|
773
|
+
vram_fit_error_message(
|
|
774
|
+
config.method,
|
|
775
|
+
need,
|
|
776
|
+
requested_gpu_count=ceiling,
|
|
777
|
+
effective_gpu_count=safe_gpu_count,
|
|
778
|
+
max_gpu_count=auto_cap,
|
|
779
|
+
gpu_names=names,
|
|
780
|
+
providers=None if provider == "auto" else (provider,),
|
|
781
|
+
# same rule the ranking loop rejected shapes with, so the advice cannot name a
|
|
782
|
+
# width the retry will not launch on.
|
|
783
|
+
executed_width=lambda count: executed_gpu_count(config, count),
|
|
784
|
+
# an offline quote does not know the configured fleet, so it cannot claim that
|
|
785
|
+
# dropping a provider pin would make a wider shape purchasable.
|
|
786
|
+
widenable_without_pin=None,
|
|
787
|
+
)
|
|
788
|
+
)
|
|
789
|
+
|
|
790
|
+
|
|
740
791
|
def _allocation_quote_shape(config: RunConfig, allocation) -> tuple[str, int, int, str, float]:
|
|
741
792
|
"""The (gpu, need, count, provider, per-card rate) billed against a SELECTED live candidate.
|
|
742
793
|
|
|
@@ -213,6 +213,11 @@ def runconfig_from_spec(spec) -> RunConfig:
|
|
|
213
213
|
# and a caller that predates the preference has no such attribute to offer.
|
|
214
214
|
providers=getattr(g, "providers", ()) or (),
|
|
215
215
|
gpu_type=g.type,
|
|
216
|
+
# the rest of an ordered `[gpu] type` list. allocation cost-ranks every acceptable class, so
|
|
217
|
+
# dropping these here quotes the head alone and the affordability precheck can refuse a run
|
|
218
|
+
# whose cheaper authored fallback it would really have rented. read defensively for the same
|
|
219
|
+
# reason as `providers` above: this is not always a GpuSpec.
|
|
220
|
+
gpu_type_fallbacks=tuple(getattr(g, "type_fallbacks", ()) or ()),
|
|
216
221
|
model_revision=spec.model_revision,
|
|
217
222
|
disk_gb=float(getattr(g, "disk_gb", 0.0) or 0.0),
|
|
218
223
|
# deliberately NOT spec.authored_gpu_count: this asks whether a shape has been RESOLVED
|
|
@@ -61,6 +61,12 @@ class RunConfig:
|
|
|
61
61
|
sft_retained_examples: int | None = None
|
|
62
62
|
# appended for the same positional-constructor reason as sft_retained_examples above.
|
|
63
63
|
providers: tuple[str, ...] = ()
|
|
64
|
+
# the remaining classes an ordered `[gpu] type` list accepts, after gpu_type takes the head.
|
|
65
|
+
# allocation cost-ranks the whole acceptable set, so quoting the head alone prices a shape the
|
|
66
|
+
# run may never be given: an authored ["B200", "H100"] is quoted on B200 while allocate() would
|
|
67
|
+
# rent the cheaper H100, and the affordability precheck runs on that inflated estimate.
|
|
68
|
+
# appended for the same positional-constructor reason as the two fields above.
|
|
69
|
+
gpu_type_fallbacks: tuple[str, ...] = ()
|
|
64
70
|
|
|
65
71
|
def __post_init__(self) -> None:
|
|
66
72
|
object.__setattr__(self, "method", normalize_algorithm(self.method))
|
|
@@ -87,6 +93,24 @@ class RunConfig:
|
|
|
87
93
|
if prov != "auto" and prov not in providers_for(exact):
|
|
88
94
|
raise ValueError(f"provider {prov!r} cannot provision gpu_type {exact!r}")
|
|
89
95
|
object.__setattr__(self, "gpu_type", exact)
|
|
96
|
+
# canonicalized and validated exactly like the head above, so a quote cannot rank a class the
|
|
97
|
+
# spec layer would have rejected. deduped against the head and each other because the
|
|
98
|
+
# ranking loop would otherwise price the same class twice.
|
|
99
|
+
fallbacks: list[str] = []
|
|
100
|
+
for entry in self.gpu_type_fallbacks or ():
|
|
101
|
+
if not isinstance(entry, str):
|
|
102
|
+
raise TypeError("gpu_type_fallbacks entries must be strings")
|
|
103
|
+
name = canonical_gpu(entry)
|
|
104
|
+
info = GPU_INFO.get(name)
|
|
105
|
+
if info is None or not info.validated:
|
|
106
|
+
raise ValueError(
|
|
107
|
+
f"gpu_type_fallbacks entry {name!r} must name an active validated GPU class"
|
|
108
|
+
)
|
|
109
|
+
if name != exact and name not in fallbacks:
|
|
110
|
+
fallbacks.append(name)
|
|
111
|
+
if fallbacks and not exact:
|
|
112
|
+
raise ValueError("gpu_type_fallbacks requires gpu_type")
|
|
113
|
+
object.__setattr__(self, "gpu_type_fallbacks", tuple(fallbacks))
|
|
90
114
|
if not isinstance(self.model_revision, str):
|
|
91
115
|
raise TypeError("model_revision must be a string")
|
|
92
116
|
object.__setattr__(self, "model_revision", self.model_revision.strip())
|
|
@@ -97,6 +97,19 @@ _HB_UPLOAD_LOCK = threading.Lock()
|
|
|
97
97
|
# Terminal/error commits wait longer — no later heartbeat can repair them.
|
|
98
98
|
_HB_UPLOAD_LOCK_TIMEOUT_S = 30.0
|
|
99
99
|
_HB_CRITICAL_UPLOAD_LOCK_TIMEOUT_S = 120.0
|
|
100
|
+
# True while a thread holds _HB_UPLOAD_LOCK and is inside the HF commit. Read under _HB_LOCK.
|
|
101
|
+
#
|
|
102
|
+
# The throttle clock (_HB_LAST_UPLOAD) only advances AFTER a commit lands, so during a slow HF
|
|
103
|
+
# commit every other throttled caller still computes upload_due=True, walks into
|
|
104
|
+
# _HB_UPLOAD_LOCK.acquire() and blocks there for up to the acquire timeout -- 30s, or 120s on a
|
|
105
|
+
# critical stage. That stalls the liveness daemon, and `liveness_heartbeat`'s join delays leaving
|
|
106
|
+
# the wrapped stage by the same window.
|
|
107
|
+
#
|
|
108
|
+
# A marker rather than claiming the clock before the upload: an optimistic claim has to be rolled
|
|
109
|
+
# back when the commit fails, and the rollback has to decide whether a NEWER heartbeat already
|
|
110
|
+
# moved the clock (the reason the old code carried a claim sequence). This says only "a commit is
|
|
111
|
+
# in flight right now", is cleared in a finally, and so cannot strand the throttle on a failure.
|
|
112
|
+
_HB_UPLOAD_IN_FLIGHT = False
|
|
100
113
|
# retain at least one metric row per second across the 900s training heartbeat throttle window.
|
|
101
114
|
GRPO_METRIC_HISTORY_LIMIT = 1024
|
|
102
115
|
|
|
@@ -127,6 +140,12 @@ def _console_heartbeat_snapshot(
|
|
|
127
140
|
return json.dumps(console_payload)
|
|
128
141
|
|
|
129
142
|
|
|
143
|
+
def _set_upload_in_flight(value: bool) -> None:
|
|
144
|
+
"""Mark whether an HF heartbeat commit is running. Call with _HB_LOCK held."""
|
|
145
|
+
global _HB_UPLOAD_IN_FLIGHT
|
|
146
|
+
_HB_UPLOAD_IN_FLIGHT = value
|
|
147
|
+
|
|
148
|
+
|
|
130
149
|
def _heartbeat_upload_due(
|
|
131
150
|
stage: str,
|
|
132
151
|
*,
|
|
@@ -140,6 +159,22 @@ def _heartbeat_upload_due(
|
|
|
140
159
|
"""return eligibility from committed throttle state while _HB_LOCK is held."""
|
|
141
160
|
if initial or _is_critical_stage(stage):
|
|
142
161
|
return True
|
|
162
|
+
# a commit is already in flight and will advance the throttle clock when it lands. an unforced
|
|
163
|
+
# ping would only queue behind it on _HB_UPLOAD_LOCK, publish a snapshot older than the one
|
|
164
|
+
# being written, and block its caller for the acquire timeout -- 30s, or 120s on a critical
|
|
165
|
+
# stage. that is what stalls the liveness daemon, whose `join` then delays leaving the wrapped
|
|
166
|
+
# stage by the same window. skipping loses nothing: the in-flight commit carries this stage.
|
|
167
|
+
#
|
|
168
|
+
# three exemptions, all above or inside this check:
|
|
169
|
+
# - initial and critical stages return True earlier: a terminal or error snapshot has no later
|
|
170
|
+
# heartbeat to repair it, so it must queue and land.
|
|
171
|
+
# - `force` is excluded here because it carries billing state. a forced commit marks a
|
|
172
|
+
# DISTINCT completed step, and a cancel bills the last step a heartbeat recorded, so
|
|
173
|
+
# dropping one to avoid a wait could under-report a step the run really finished.
|
|
174
|
+
# the daemon's own pings are never forced (liveness and keepalive both leave it False), so this
|
|
175
|
+
# exemption does not reopen the stall it fixes.
|
|
176
|
+
if _HB_UPLOAD_IN_FLIGHT and not force:
|
|
177
|
+
return False
|
|
143
178
|
if _w._HB_TERMINAL_ONLY:
|
|
144
179
|
return (
|
|
145
180
|
_w._HB_LAST_UPLOAD == 0.0 or (now - _w._HB_LAST_UPLOAD) >= _HB_TERMINAL_ONLY_INTERVAL_S
|
|
@@ -234,12 +269,18 @@ def heartbeat(
|
|
|
234
269
|
up = f"/tmp/.hb-upload-{os.getpid()}-{threading.get_ident()}.json"
|
|
235
270
|
with open(up, "w") as f:
|
|
236
271
|
f.write(snapshot)
|
|
272
|
+
with _HB_LOCK:
|
|
273
|
+
_set_upload_in_flight(True)
|
|
237
274
|
try:
|
|
238
275
|
if initial:
|
|
239
276
|
committed = _w.hf_upload_file(up, "heartbeat.json", required=True)
|
|
240
277
|
else:
|
|
241
278
|
committed = _w.hf_upload_file(up, "heartbeat.json")
|
|
242
279
|
finally:
|
|
280
|
+
# cleared before the throttle clock is advanced below, and in a finally so a
|
|
281
|
+
# raising upload cannot leave every later heartbeat permanently skipped.
|
|
282
|
+
with _HB_LOCK:
|
|
283
|
+
_set_upload_in_flight(False)
|
|
243
284
|
with contextlib.suppress(OSError):
|
|
244
285
|
os.remove(up)
|
|
245
286
|
if committed is False:
|
{freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/engine/worker/perf/__init__.py
RENAMED
|
@@ -5,7 +5,7 @@ The fla/tilelang/cudart fixup group stays IN THIS MODULE on purpose: tests monke
|
|
|
5
5
|
through the patched module globals. Do NOT move this group into a submodule.
|
|
6
6
|
|
|
7
7
|
NOTE: ``tests/test_worker_stack.py`` reads THIS file as TEXT to assert the fla SHA /
|
|
8
|
-
TILELANG_PIN stay in lockstep with
|
|
8
|
+
TILELANG_PIN stay in lockstep with Dockerfile.worker.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from __future__ import annotations
|
|
@@ -315,7 +315,7 @@ def _ensure_fla_fastpath_on_hopper() -> None:
|
|
|
315
315
|
return False
|
|
316
316
|
return rc == 0
|
|
317
317
|
|
|
318
|
-
# 0.1.12 double-registers the TVM-FFI runtime -> `import tilelang` aborts; keep in lockstep with
|
|
318
|
+
# 0.1.12 double-registers the TVM-FFI runtime -> `import tilelang` aborts; keep in lockstep with Dockerfile.worker.
|
|
319
319
|
TVM_FFI_PIN = "0.1.11"
|
|
320
320
|
TILELANG_PIN = "0.1.11"
|
|
321
321
|
|
|
@@ -334,7 +334,7 @@ def _ensure_fla_fastpath_on_hopper() -> None:
|
|
|
334
334
|
fla_ok = True
|
|
335
335
|
if not (_have("fla") and _have("fla.modules")):
|
|
336
336
|
_remove_fla_from_disk()
|
|
337
|
-
# Pinned commit — keep in lockstep with
|
|
337
|
+
# Pinned commit — keep in lockstep with Dockerfile.worker.
|
|
338
338
|
fla_ok = _pip(
|
|
339
339
|
"--no-deps",
|
|
340
340
|
"git+https://github.com/fla-org/flash-linear-attention.git"
|
|
@@ -46,7 +46,7 @@ class GitHubUnavailableError(GitHubTransientError):
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class GitHubPermanentError(RuntimeError):
|
|
49
|
-
"""GitHub answered, and the answer will not change on a retry:
|
|
49
|
+
"""GitHub answered, and the answer will not change on a retry: 401, 403, 404, or 422.
|
|
50
50
|
|
|
51
51
|
Deliberately NOT a GitHubTransientError. Waiting is the right response to a blip and the wrong
|
|
52
52
|
response to a typo, and the two are indistinguishable once both are a bare RuntimeError -- which
|
|
@@ -57,6 +57,10 @@ class GitHubPermanentError(RuntimeError):
|
|
|
57
57
|
read, rather than leaking its existence with a 403. Both are permanent for this caller: no
|
|
58
58
|
amount of retrying makes an unreadable ref resolvable, and the fix (check the name, or grant the
|
|
59
59
|
token access) is the user's either way. The message carries GitHub's own text so it names which.
|
|
60
|
+
|
|
61
|
+
The credential codes reach here only after the rate-limit shapes (429, and the 403 that says
|
|
62
|
+
rate limit) have been claimed as transient, so a 401 or a surviving 403 is a token this plane
|
|
63
|
+
cannot fix by waiting: invalid, expired, or missing the scope. Same user-side fix as a typo.
|
|
60
64
|
"""
|
|
61
65
|
|
|
62
66
|
|
|
@@ -285,9 +285,13 @@ def _urlopen(
|
|
|
285
285
|
) from exc
|
|
286
286
|
# 404 (no such repo, or one the token cannot read) and 422 (a ref that does not exist,
|
|
287
287
|
# e.g. "No commit found for SHA: main" on a master-default repo) are settled answers.
|
|
288
|
+
# 401 and a non-rate-limit 403 join them: the rate-limit shapes are already claimed
|
|
289
|
+
# above, so what is left is a token this plane cannot fix by waiting -- invalid,
|
|
290
|
+
# expired, or lacking the scope. deferring those rents a GPU to rediscover the same
|
|
291
|
+
# credential error on the worker.
|
|
288
292
|
# Typed so the submit-time pin can fail closed on them while still deferring a blip;
|
|
289
293
|
# every other code keeps the untyped RuntimeError it has always raised.
|
|
290
|
-
if exc.code in (404, 422):
|
|
294
|
+
if exc.code in (401, 403, 404, 422):
|
|
291
295
|
raise GitHubPermanentError(
|
|
292
296
|
f"GitHub environment request failed ({exc.code}): {body[:500]}"
|
|
293
297
|
) from exc
|
{freesolo_flash_dev-1.2.49 → freesolo_flash_dev-1.2.53}/flash/providers/_lifecycle/bootstrap.py
RENAMED
|
@@ -257,15 +257,31 @@ def hf_upload(
|
|
|
257
257
|
return False
|
|
258
258
|
|
|
259
259
|
|
|
260
|
-
def _upload_console_snapshot(
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
def _upload_console_snapshot(
|
|
261
|
+
payload: dict, console: str, mode: str, extra: str = "", final: bool = False
|
|
262
|
+
) -> bool:
|
|
263
|
+
"""Upload one console snapshot from an isolated process.
|
|
264
|
+
|
|
265
|
+
The periodic snapshot and the terminal one never share a scratch file or a repo destination.
|
|
266
|
+
Reaping the periodic child at teardown is best-effort, so one killed mid-write would otherwise
|
|
267
|
+
truncate the scratch file the terminal snapshot is uploading, or overwrite the terminal artifact
|
|
268
|
+
itself -- losing the failure detail the control plane reads, including the wall-clock-cap marker.
|
|
269
|
+
|
|
270
|
+
The terminal snapshot keeps the canonical ``console_<mode>.txt`` the control plane reads; the
|
|
271
|
+
periodic one takes the attempt-scoped name it reads separately, matching the serverless handler,
|
|
272
|
+
so a retry cannot overwrite the attempt that reproduced the failure. This module can never
|
|
273
|
+
import flash, so the format is spelled out here and pinned against
|
|
274
|
+
``flash.adapters.artifacts.attempt_scoped_artifact_name`` by test rather than by coincidence --
|
|
275
|
+
a name the reader does not expect looks exactly like a worker that uploaded nothing.
|
|
276
|
+
"""
|
|
277
|
+
kind = "" if final else f"_attempt{payload.get('attempt', 0)}"
|
|
278
|
+
tail_path = f"{console}{kind}.tail"
|
|
263
279
|
tail = _read_console_tail(console, 64_000, secrets=_payload_secrets(payload))
|
|
264
280
|
if extra:
|
|
265
281
|
tail += extra
|
|
266
282
|
with open(tail_path, "w", encoding="utf-8", errors="replace") as f:
|
|
267
283
|
f.write(_safe_detail(tail, 64_000, secrets=_payload_secrets(payload)))
|
|
268
|
-
return hf_upload(payload, tail_path, f"console_{mode}.txt")
|
|
284
|
+
return hf_upload(payload, tail_path, f"console_{mode}{kind}.txt")
|
|
269
285
|
|
|
270
286
|
|
|
271
287
|
def _console_upload_loop(
|
|
@@ -453,7 +469,7 @@ def _upload_console_tail_bounded(
|
|
|
453
469
|
context = multiprocessing.get_context("spawn")
|
|
454
470
|
process = context.Process(
|
|
455
471
|
target=_upload_console_snapshot,
|
|
456
|
-
args=(payload, console, mode, extra),
|
|
472
|
+
args=(payload, console, mode, extra, True),
|
|
457
473
|
daemon=True,
|
|
458
474
|
)
|
|
459
475
|
process.start()
|
|
@@ -77,8 +77,13 @@ def _run_console_upload_loop(console: str, interval_s: float, stop_upload, *, up
|
|
|
77
77
|
prevents a flapping run from turning the poll cadence into the commit cadence.
|
|
78
78
|
|
|
79
79
|
Before any heartbeat commits, one additional setup snapshot lands before the fixed 3000-second
|
|
80
|
-
teardown. It does not enter the steady rate: the first committed heartbeat
|
|
81
|
-
the normal interval
|
|
80
|
+
teardown. It does not enter the steady rate: the first committed heartbeat promotes the deadline
|
|
81
|
+
to the normal interval, so a run that commits before 600 seconds never spends that write. the
|
|
82
|
+
promotion is skipped while ``due`` holds, so it only ever moves a deadline that has not arrived.
|
|
83
|
+
A 600-second deadline that already expired with nothing committed still spends its snapshot --
|
|
84
|
+
the startup evidence it exists for -- and a failed upload on that same poll leaves the deadline
|
|
85
|
+
due, so the next poll retries rather than waiting out the hour. Once promoted the deadline is the
|
|
86
|
+
hourly interval, so the guard cannot re-fire early and needs no separate first-commit flag.
|
|
82
87
|
"""
|
|
83
88
|
poll_s = min(_CONSOLE_UPLOAD_POLL_S, interval_s)
|
|
84
89
|
due_s = min(_CONSOLE_UPLOAD_FIRST_SNAPSHOT_S, interval_s)
|
|
@@ -87,14 +92,13 @@ def _run_console_upload_loop(console: str, interval_s: float, stop_upload, *, up
|
|
|
87
92
|
while not stop_upload.wait(poll_s):
|
|
88
93
|
since += poll_s
|
|
89
94
|
cursor, eof, staged, beats = _console_progress(console, max(cursor, 0))
|
|
90
|
-
had_committed = ever
|
|
91
95
|
ever = ever or bool(staged)
|
|
92
|
-
|
|
96
|
+
due = since >= due_s
|
|
97
|
+
if ever and not due:
|
|
93
98
|
due_s = interval_s
|
|
94
99
|
made_progress = staged if ever else beats
|
|
95
100
|
armed = armed or bool(made_progress)
|
|
96
101
|
quiet = 0.0 if made_progress else quiet + 1
|
|
97
|
-
due = since >= due_s
|
|
98
102
|
cap = armed and quiet >= _CONSOLE_UPLOAD_QUIET_POLLS
|
|
99
103
|
wedged = cap and spent < _CONSOLE_UPLOAD_CREDITS and not due
|
|
100
104
|
if eof == sent or not (due or wedged):
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""host helper: cap every cloud-init polling and retry delay at the canonical run deadline.
|
|
2
|
+
|
|
3
|
+
Runs as a standalone program on the rented box (`python3 capsule.pyz deadline_sleep <seconds>`),
|
|
4
|
+
shipped as a declared member of the instance-bootstrap capsule.
|
|
5
|
+
|
|
6
|
+
The work lives under a ``__main__`` guard because this is a program, not a library: the capsule
|
|
7
|
+
dispatches into it with ``runpy.run_module(run_name="__main__")``, while merely IMPORTING it (a
|
|
8
|
+
module walker, a test collector, a packaging probe) must do nothing at all. Without the guard the
|
|
9
|
+
import reads argv, reads the box payload, and exits the importing process.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import math
|
|
14
|
+
import sys
|
|
15
|
+
import time
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> None:
|
|
19
|
+
"""Sleep for at most the requested seconds, never past the run deadline.
|
|
20
|
+
|
|
21
|
+
Exit 124 means the deadline is reached (the caller must stop waiting); exit 125 means the
|
|
22
|
+
deadline could not be established, which is treated the same way rather than sleeping blind.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
requested = float(sys.argv[1])
|
|
26
|
+
with open("/opt/flash/payload.json") as _payload_file:
|
|
27
|
+
p = json.load(_payload_file)
|
|
28
|
+
deadline = p.get("deadline_at")
|
|
29
|
+
created_at = p.get("run_created_at")
|
|
30
|
+
max_wall_seconds = p.get("run_max_wall_seconds")
|
|
31
|
+
clocks = (deadline, created_at, max_wall_seconds)
|
|
32
|
+
if (
|
|
33
|
+
not math.isfinite(requested)
|
|
34
|
+
or requested < 0
|
|
35
|
+
or any(
|
|
36
|
+
isinstance(value, bool) or not isinstance(value, (int, float)) for value in clocks
|
|
37
|
+
)
|
|
38
|
+
):
|
|
39
|
+
raise ValueError("invalid deadline sleep")
|
|
40
|
+
deadline, created_at, max_wall_seconds = map(float, clocks)
|
|
41
|
+
now = time.time()
|
|
42
|
+
if (
|
|
43
|
+
not all(math.isfinite(value) and value > 0 for value in clocks)
|
|
44
|
+
or not math.isfinite(now)
|
|
45
|
+
or now <= 0
|
|
46
|
+
or not math.isclose(deadline, created_at + max_wall_seconds, rel_tol=0.0, abs_tol=1e-6)
|
|
47
|
+
):
|
|
48
|
+
raise ValueError("invalid deadline clock")
|
|
49
|
+
remaining = deadline - now
|
|
50
|
+
if remaining <= 0:
|
|
51
|
+
raise SystemExit(124)
|
|
52
|
+
delay = min(requested, remaining)
|
|
53
|
+
if delay > 0:
|
|
54
|
+
time.sleep(delay)
|
|
55
|
+
if requested >= remaining:
|
|
56
|
+
raise SystemExit(124)
|
|
57
|
+
except Exception:
|
|
58
|
+
# SystemExit is a BaseException, so the 124 exits above pass straight through.
|
|
59
|
+
raise SystemExit(125) from None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
main()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""host helper: write the terminal failure marker for a boot that died before the worker.
|
|
2
|
+
|
|
3
|
+
Runs as a standalone program on the rented box, shipped as a declared member of the
|
|
4
|
+
instance-bootstrap capsule.
|
|
5
|
+
|
|
6
|
+
The work lives under a ``__main__`` guard because this is a program, not a library: the capsule
|
|
7
|
+
dispatches into it with ``runpy.run_module(run_name="__main__")``, while merely IMPORTING it (a
|
|
8
|
+
module walker, a test collector, a packaging probe) must do nothing at all. Unguarded, an import
|
|
9
|
+
would read the box payload and write a FAILURE MARKER for a run that is fine -- and the blanket
|
|
10
|
+
``except`` below would hide that it had.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import math
|
|
15
|
+
import time
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main() -> None:
|
|
19
|
+
"""Write the retriable host failure marker, unless the worker already wrote its own.
|
|
20
|
+
|
|
21
|
+
Marker-aware in both directions: a container that fast-failed on a real user error has already
|
|
22
|
+
written ok=false at this path, and relabeling it retriable would turn a user error into an
|
|
23
|
+
endless retry. Best effort -- a marker upload must never be what kills the box.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
with open("/opt/flash/payload.json") as _payload_file:
|
|
27
|
+
p = json.load(_payload_file)
|
|
28
|
+
arm = p.get("flash_arm", "instance")
|
|
29
|
+
att = p.get("attempt")
|
|
30
|
+
run_id = p.get("run_id")
|
|
31
|
+
deadline = p.get("deadline_at")
|
|
32
|
+
created_at = p.get("run_created_at")
|
|
33
|
+
max_wall_seconds = p.get("run_max_wall_seconds")
|
|
34
|
+
if isinstance(att, bool) or not isinstance(att, int) or att < 0:
|
|
35
|
+
raise ValueError("invalid attempt")
|
|
36
|
+
if not isinstance(run_id, str) or not run_id:
|
|
37
|
+
raise ValueError("invalid run id")
|
|
38
|
+
clocks = (deadline, created_at, max_wall_seconds)
|
|
39
|
+
if any(isinstance(value, bool) or not isinstance(value, (int, float)) for value in clocks):
|
|
40
|
+
raise ValueError("invalid deadline")
|
|
41
|
+
deadline, created_at, max_wall_seconds = map(float, clocks)
|
|
42
|
+
now = time.time()
|
|
43
|
+
if (
|
|
44
|
+
not all(math.isfinite(value) and value > 0 for value in clocks)
|
|
45
|
+
or not math.isfinite(now)
|
|
46
|
+
or now <= 0
|
|
47
|
+
or now >= deadline
|
|
48
|
+
or not math.isclose(deadline, created_at + max_wall_seconds, rel_tol=0.0, abs_tol=1e-6)
|
|
49
|
+
):
|
|
50
|
+
raise ValueError("invalid clock")
|
|
51
|
+
marker_path = p["hf_prefix"] + "/" + arm + "_attempt" + str(att) + ".json"
|
|
52
|
+
from huggingface_hub import HfApi
|
|
53
|
+
|
|
54
|
+
api = HfApi(token=(p.get("env") or {}).get("HF_TOKEN"))
|
|
55
|
+
|
|
56
|
+
def worker_marker_present():
|
|
57
|
+
try:
|
|
58
|
+
return api.file_exists(
|
|
59
|
+
repo_id=p["hf_repo"], filename=marker_path, repo_type="dataset"
|
|
60
|
+
)
|
|
61
|
+
except Exception:
|
|
62
|
+
return True # conservative: on a read error, never risk clobbering
|
|
63
|
+
|
|
64
|
+
if not worker_marker_present():
|
|
65
|
+
marker = {
|
|
66
|
+
"attempt": att,
|
|
67
|
+
"error": "host bootstrap failure",
|
|
68
|
+
"ok": False,
|
|
69
|
+
"retriable": True,
|
|
70
|
+
"run_id": run_id,
|
|
71
|
+
"ts": now,
|
|
72
|
+
}
|
|
73
|
+
with open("/opt/flash/fm.json", "w") as _marker_file:
|
|
74
|
+
_marker_file.write(json.dumps(marker))
|
|
75
|
+
# re-check right before the upload: the worker may have written its own ok=false marker in
|
|
76
|
+
# the gap since the first check; honor it instead of clobbering with the retriable host one.
|
|
77
|
+
if not worker_marker_present():
|
|
78
|
+
api.upload_file(
|
|
79
|
+
path_or_fileobj="/opt/flash/fm.json",
|
|
80
|
+
path_in_repo=marker_path,
|
|
81
|
+
repo_id=p["hf_repo"],
|
|
82
|
+
repo_type="dataset",
|
|
83
|
+
)
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
main()
|