freesolo-flash-dev 1.2.28__tar.gz → 1.2.33__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.33/CHANGELOG.md +113 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/deploy.py +214 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/scaffold/TRAINING.md +2 -2
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/tables.py +3 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/http.py +62 -18
- freesolo_flash_dev-1.2.33/flash/client/streaming.py +145 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/spec.py +106 -11
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/allocator.py +92 -58
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/__init__.py +16 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/preparation.py +11 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/status.py +14 -2
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/submit.py +9 -4
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/attach.py +2 -5
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/lifecycle.py +8 -6
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/seed_submission.py +6 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/schema/__init__.py +63 -55
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/app.py +3 -2
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/charges.py +4 -3
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/run_registry.py +2 -3
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/runtime.py +2 -5
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_allocator.py +83 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cancel_remote.py +53 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_commands.py +14 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_render_coverage.py +30 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client.py +267 -6
- freesolo_flash_dev-1.2.33/tests/test_deploy_alias_move_warning.py +554 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_publish.py +56 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_idle_endpoint_reaper.py +40 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_routing.py +125 -31
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_spec_and_validation.py +205 -1
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/uv.lock +1 -1
- freesolo_flash_dev-1.2.28/CHANGELOG.md +0 -200
- freesolo_flash_dev-1.2.28/flash/client/streaming.py +0 -94
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.env.example +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/README.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/shims.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.28 → freesolo_flash_dev-1.2.33}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes to `freesolo-flash`. The dev-channel package `freesolo-flash-dev` ships in
|
|
4
|
+
lockstep at the same version.
|
|
5
|
+
|
|
6
|
+
Releases happen by merging a version bump from `dev` into `main`, which publishes to PyPI
|
|
7
|
+
(`.github/workflows/publish.yml`). Versions are `MAJOR.MINOR.PATCH`.
|
|
8
|
+
|
|
9
|
+
This file starts at 1.1.35. Earlier releases are not reconstructed here; use
|
|
10
|
+
`git log` for anything before that.
|
|
11
|
+
|
|
12
|
+
## Unreleased
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- A `flash-cli` console script, the same entry point as `flash` under a name nothing else
|
|
17
|
+
claims. The `server` and `dev` extras install `runpod-flash`, which declares its own `flash`
|
|
18
|
+
script; whichever distribution is installed last wins, so on a control-plane host
|
|
19
|
+
`pip install 'freesolo-flash[server]'` could leave `flash` running RunPod's CLI, which exits 0
|
|
20
|
+
and does nothing. `flash` is unchanged and remains correct on a base (client-only) install.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- CI runs the offline test suite on both supported interpreters (3.11 and 3.12) rather than
|
|
25
|
+
3.11 alone, and sets `HF_HUB_OFFLINE` / `TRANSFORMERS_OFFLINE` so a test that reaches the
|
|
26
|
+
network fails deterministically instead of depending on runner connectivity.
|
|
27
|
+
- Every GitHub Action is pinned to a commit SHA rather than a mutable tag.
|
|
28
|
+
- `mypy` runs in CI as an advisory (non-blocking) job.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- `flash models deploy` now warns before it moves the shared `<run-id>` model id onto a
|
|
33
|
+
different checkpoint. Every checkpoint of a run is served under that one id, so deploying
|
|
34
|
+
`<run-id>/step-50` while `step-100` was live silently changed what `<run-id>` served for
|
|
35
|
+
everyone using it — which made "deploy a second checkpoint to compare" a destructive
|
|
36
|
+
operation on the first, and read as a serving regression rather than the deploy that caused
|
|
37
|
+
it. The warning names both checkpoints and points at `flash models chat <run-id>/step-N`,
|
|
38
|
+
which addresses a checkpoint directly and does not depend on where the id points. It is
|
|
39
|
+
advisory: the deploy still proceeds, the pre-deploy read is abandoned outright once it exceeds
|
|
40
|
+
a few seconds so no shape of slow plane can hold a deploy behind it, and a control plane that
|
|
41
|
+
cannot answer (or answers with a checkpoint step this client cannot read) does not fail the
|
|
42
|
+
command. A deployment whose activation outcome was never settled still warns, but without
|
|
43
|
+
naming a checkpoint: that record's step describes the incoming attempt rather than what the id
|
|
44
|
+
currently serves, and the authoritative target is server-side only, so the warning says the
|
|
45
|
+
live checkpoint cannot be determined and points at `flash models deployments`.
|
|
46
|
+
|
|
47
|
+
- A response deadline did not actually bound a response that arrived slowly. The deadline is
|
|
48
|
+
checked between reads, but each read asked for a fixed number of bytes and blocked until all of
|
|
49
|
+
them arrived, so a peer trickling a short body kept one read inside the socket timeout
|
|
50
|
+
indefinitely and the check never ran: a 2s deadline took 12s on a 42-byte body, and 61s when
|
|
51
|
+
the socket timeout was the client default. Reading whatever has already arrived lets the check
|
|
52
|
+
run, which bounds every stall shape. This affected `flash env list`, whose deadline exists to
|
|
53
|
+
stop a slow environment hub hanging the command, as well as the new pre-deploy read.
|
|
54
|
+
|
|
55
|
+
- A response deadline could still be overrun by a read that began near its end. The socket timeout
|
|
56
|
+
is installed once, when the request opens, and time spent connecting and waiting for headers is
|
|
57
|
+
charged to the deadline but not to that timeout, so a peer that delayed its headers and then
|
|
58
|
+
stalled mid-body held the call open past the deadline: 3.5s against a 2s budget. Each read now
|
|
59
|
+
re-caps the socket to the remaining budget, so the two bounds agree instead of stacking. On a
|
|
60
|
+
body still arriving this surfaces as a timeout rather than the "stalled" message; both bound the
|
|
61
|
+
call, and which one wins is a race not worth depending on.
|
|
62
|
+
|
|
63
|
+
- Commands printed for the operator to run (the resume/cancel hand-off after `flash train`,
|
|
64
|
+
usage strings, `next:` hints) now name the executable actually invoked rather than always
|
|
65
|
+
`flash`. On a host where `runpod-flash` owns the `flash` script, the printed
|
|
66
|
+
`flash runs cancel <run-id>` exited 0 without cancelling, leaving a run billing while the
|
|
67
|
+
operator believed they had stopped it. Reached through the `python -m flash.cli` escape hatch,
|
|
68
|
+
the printed command now names the interpreter that is actually running, rather than a bare
|
|
69
|
+
`python` that is absent on a python3-only host and may resolve to a different environment
|
|
70
|
+
inside a virtualenv.
|
|
71
|
+
|
|
72
|
+
- `flash env setup` scaffolded hosted-only environment instructions on every plane. A
|
|
73
|
+
self-hosted plane cannot publish to Freesolo's managed environment hub, so the generated
|
|
74
|
+
configs left `[environment] id` empty (which fails validation) beside a `flash env push`
|
|
75
|
+
command that could not work. Against a self-hosted plane the scaffold now emits the
|
|
76
|
+
`github:owner/repo@ref:path` id form, which such a plane resolves directly. Output against
|
|
77
|
+
the managed plane is unchanged.
|
|
78
|
+
|
|
79
|
+
- `flash-server` reported missing operator configuration as an unhandled ASGI startup
|
|
80
|
+
exception, so the actionable message arrived under ~20 frames of starlette/contextlib. The
|
|
81
|
+
refusing half of the preflight now runs before uvicorn starts, and `flash-server` prints
|
|
82
|
+
`error: ...` and exits 3 (uvicorn's `STARTUP_FAILURE`, which this path already used, so
|
|
83
|
+
supervision keying on it is unaffected). The advisory warnings still come from the lifespan
|
|
84
|
+
alone, so a booted plane logs them once.
|
|
85
|
+
- `flash env test` blamed the reward function for a gold answer that scored zero, when the
|
|
86
|
+
gold completion is equally likely to be at fault: with no `sft_completion` hook the replayed
|
|
87
|
+
answer is the dataset row's raw `output`, so a dataset whose `output` is a bare value fails a
|
|
88
|
+
grader that (correctly) requires a wrapper. The warning now names both candidates and prints
|
|
89
|
+
the exact text it scored, verbatim rather than through the whitespace-collapsing, 200-character
|
|
90
|
+
preview that hid the formatting faults it exists to reveal. The scaffolded `environment.py`
|
|
91
|
+
documents that `output` is also the gold assistant turn SFT trains on, and that per-row scorer
|
|
92
|
+
state belongs in `metadata`.
|
|
93
|
+
- `flash env test` labelled the replayed dataset turns as the text that scored zero, but a
|
|
94
|
+
multi-turn environment whose `step_episode` returns a `final_response_text` has that override
|
|
95
|
+
replace the episode's response before scoring, so the diagnostic named text the grader never
|
|
96
|
+
saw. It now reports what the scorer actually received, captured at the scoring call.
|
|
97
|
+
- An environment that overrode its answer to the empty string had `flash env test` report the
|
|
98
|
+
replayed turns instead: the captured text was tested for truth, so a graded `""` was
|
|
99
|
+
indistinguishable from an episode that never reached the scorer. The override propagates on
|
|
100
|
+
`is not None`, so `""` really is what the grader saw -- and an empty answer explains a zero
|
|
101
|
+
reward on its own, making it the reading a reader most needs named rather than hidden.
|
|
102
|
+
- A crashed scorer went unreported on an `echo` episode -- a row with no gold answer to replay,
|
|
103
|
+
which is also the case that leaves the GRPO gate with nothing to count. `flash env test` could
|
|
104
|
+
exit `overall: PASS` with every reward coming from a scorer that never ran. The scorer's error is
|
|
105
|
+
now surfaced for any policy.
|
|
106
|
+
- A scorer that crashed behind the SDK's guard reached `flash env test` as a bare `0.000000`,
|
|
107
|
+
indistinguishable from a judged-wrong answer, because the adapter kept only
|
|
108
|
+
`RewardResult.score`. The new `FreesoloEnvironment.reward_with_error` returns the reward and the
|
|
109
|
+
discarded error from a single scoring call, so a missing runtime dependency names itself without
|
|
110
|
+
re-scoring the episode -- which would bill a paid judge twice and, for a non-deterministic
|
|
111
|
+
scorer, could report an error that did not produce the printed reward.
|
|
112
|
+
- Two tests resolved Hugging Face model metadata over the network and passed only on a
|
|
113
|
+
connected runner. They now stub the resolver like their siblings already did.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.33
|
|
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
|
|
@@ -11,6 +11,7 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import json
|
|
13
13
|
import sys
|
|
14
|
+
import threading
|
|
14
15
|
import time
|
|
15
16
|
|
|
16
17
|
from flash.cli.ui import render
|
|
@@ -41,6 +42,10 @@ _DEPLOYMENT_BUSY_STATES = frozenset({"queued", "smoke_testing", "reconciling"})
|
|
|
41
42
|
# plane introduces are both non-busy and non-servable, so `--wait` must fail closed on them
|
|
42
43
|
# rather than let `deploy --wait && evaluate` proceed against nothing.
|
|
43
44
|
_DEPLOYMENT_READY_STATES = frozenset({"ready", "deployed"})
|
|
45
|
+
# an undeploy whose backend cleanup failed (flash/runner/supervise/transitions.py). local serving
|
|
46
|
+
# authority is revoked, but the alias may still resolve to the old target -- neither servable nor
|
|
47
|
+
# safely assumed idle.
|
|
48
|
+
_REVOCATION_FAILED_STATE = "revocation_failed"
|
|
44
49
|
_DEPLOY_POLL_SECONDS = 5.0
|
|
45
50
|
# `--wait 0` still owes the caller its one read, and a read needs a positive timeout. keep that
|
|
46
51
|
# bound short enough that "check once, do not block" stays true against a stalled plane: a longer
|
|
@@ -57,6 +62,14 @@ _DEPLOY_FINAL_READ_FRACTION = 0.9
|
|
|
57
62
|
# an auth or authorization rejection answers the same way every time; polling through it just
|
|
58
63
|
# spends the whole timeout to arrive at the identical error.
|
|
59
64
|
_PERMANENT_POLL_STATUSES = frozenset({401, 403})
|
|
65
|
+
# the pre-deploy alias read is advisory, so it must not spend the client's default 60s budget
|
|
66
|
+
# deciding whether to print a warning: a stalled read would delay every real deploy behind a
|
|
67
|
+
# line nobody asked for. short enough to stay unnoticed, long enough for a healthy plane.
|
|
68
|
+
# it is spent three ways, because the client's own bounds are per-phase: as a socket timeout it
|
|
69
|
+
# bounds one socket operation, and as a body deadline it bounds the body but is only consulted
|
|
70
|
+
# once headers are parsed. a peer trickling headers just inside the socket timeout escapes both.
|
|
71
|
+
# `_read_within` bounds the total in wall-clock time, which is the one that actually holds.
|
|
72
|
+
_ALIAS_WARNING_READ_SECONDS = 5.0
|
|
60
73
|
|
|
61
74
|
|
|
62
75
|
def _await_deployment(client, run_id: str, deployment: dict, timeout: float) -> dict:
|
|
@@ -189,6 +202,196 @@ def _rollback_record(client, run_id: str, timeout: float) -> dict | None:
|
|
|
189
202
|
return None
|
|
190
203
|
|
|
191
204
|
|
|
205
|
+
def _served_step_label(step: int | None) -> str:
|
|
206
|
+
"""Name a deployment's checkpoint the way the user addressed it: `step-N`, or `final`."""
|
|
207
|
+
return "final" if step is None else f"step-{step}"
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _read_within(budget: float, read):
|
|
211
|
+
"""Run an advisory read, giving up on it entirely once ``budget`` seconds have passed.
|
|
212
|
+
|
|
213
|
+
The client's two bounds are both per-phase, not total: `timeout` restarts on every socket
|
|
214
|
+
operation and the body deadline is only checked once `urlopen` has finished parsing headers.
|
|
215
|
+
A peer that trickles the status line or headers just inside the socket timeout therefore
|
|
216
|
+
stalls for timeout x however many pauses it takes -- 12s against a 2s budget, measured -- and
|
|
217
|
+
the whole point of the bound is that the deploy the user actually asked for is waiting behind
|
|
218
|
+
it. Only wall-clock time outside the call bounds every phase at once.
|
|
219
|
+
|
|
220
|
+
A daemon thread rather than a cancellation: a blocked socket read cannot be interrupted from
|
|
221
|
+
outside, so the read is abandoned rather than stopped. That is sound only because this result
|
|
222
|
+
is discardable -- no warning is the documented outcome for a plane that cannot answer, so an
|
|
223
|
+
overrunning read degrades to silence. Daemon, so a stuck thread cannot keep the interpreter
|
|
224
|
+
alive after the deploy finishes.
|
|
225
|
+
"""
|
|
226
|
+
result: list = []
|
|
227
|
+
worker = threading.Thread(
|
|
228
|
+
target=lambda: result.append(_read_or_none(read)),
|
|
229
|
+
daemon=True,
|
|
230
|
+
)
|
|
231
|
+
worker.start()
|
|
232
|
+
worker.join(budget)
|
|
233
|
+
return result[0] if result else None
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def _read_or_none(read):
|
|
237
|
+
"""The advisory read's failure contract: a plane that cannot answer produces no warning.
|
|
238
|
+
|
|
239
|
+
Deliberately broader than `ApiError`/`ClientError`. The client translates urllib's HTTPError
|
|
240
|
+
and URLError, and documents that anything else propagates -- so a connection reset or a
|
|
241
|
+
truncated body mid-read surfaces as the bare `ConnectionResetError` / `IncompleteRead` that
|
|
242
|
+
urllib raised. Those are exactly the "plane cannot answer" case this exists to absorb, and on
|
|
243
|
+
the worker thread an escaping one reaches the thread hook and prints a traceback across a
|
|
244
|
+
deploy that is otherwise proceeding normally: a warning nobody asked for turning into noise
|
|
245
|
+
on a command that worked.
|
|
246
|
+
"""
|
|
247
|
+
try:
|
|
248
|
+
return read()
|
|
249
|
+
except Exception:
|
|
250
|
+
# the deploy itself is the authority on whether it can proceed. failing it here -- or
|
|
251
|
+
# printing a traceback beside it -- would turn a warning nobody asked for into a fault in
|
|
252
|
+
# the command it decorates. BaseException still propagates, so KeyboardInterrupt is
|
|
253
|
+
# unaffected.
|
|
254
|
+
return None
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def _alias_move_warning(client, base_run_id: str, requested_step: int | None) -> str | None:
|
|
258
|
+
"""Warn when deploying moves the shared `<run_id>` alias off a different checkpoint.
|
|
259
|
+
|
|
260
|
+
`deploy` registers under the bare run id whatever step it is given, so deploying a second
|
|
261
|
+
checkpoint of the same run does not stand up a second endpoint -- it repoints the one alias,
|
|
262
|
+
and everyone chatting bare `<run_id>` silently changes model. That makes "deploy another
|
|
263
|
+
checkpoint to compare" a destructive operation on the first, which reads as a serving fault
|
|
264
|
+
rather than the deploy that caused it.
|
|
265
|
+
|
|
266
|
+
Best-effort by construction: the read is advisory, so a plane that cannot answer must not
|
|
267
|
+
stop the deploy. Returns None when nothing is being displaced -- no deployment, the same
|
|
268
|
+
checkpoint again, or an unreadable current record.
|
|
269
|
+
"""
|
|
270
|
+
current = _read_within(
|
|
271
|
+
_ALIAS_WARNING_READ_SECONDS,
|
|
272
|
+
# not `deployment_for`: its step filter hides exactly the record this asks about, a
|
|
273
|
+
# DIFFERENT checkpoint holding the alias.
|
|
274
|
+
lambda: client.deployed_checkpoint(
|
|
275
|
+
base_run_id,
|
|
276
|
+
timeout=_ALIAS_WARNING_READ_SECONDS,
|
|
277
|
+
body_deadline=_ALIAS_WARNING_READ_SECONDS,
|
|
278
|
+
),
|
|
279
|
+
)
|
|
280
|
+
if current is None:
|
|
281
|
+
return None
|
|
282
|
+
# a `reconciling` record whose activation outcome was never recorded may ALREADY hold the
|
|
283
|
+
# alias. the plane permits replacing exactly that record rather than rejecting it as busy,
|
|
284
|
+
# and resolves the authoritative target through `_activation_predecessor` when it does
|
|
285
|
+
# (flash/server/routes/serving.py). reading it as "not serving" suppressed the warning in
|
|
286
|
+
# the very case the alias is most likely to move out from under someone.
|
|
287
|
+
unknown_activation = current.get("activation_outcome_unknown") is True
|
|
288
|
+
# `revocation_failed` is an undeploy whose BACKEND cleanup failed: local authority is revoked
|
|
289
|
+
# but the alias may still resolve to the old target, and `_validate_deploy_request` rejects
|
|
290
|
+
# only the busy set, so a deploy proceeds from here. reading it as "not serving" suppressed
|
|
291
|
+
# the warning in the case where cleanup already left the alias ambiguous.
|
|
292
|
+
revocation_failed = str(current.get("state") or "") == _REVOCATION_FAILED_STATE
|
|
293
|
+
ambiguous = unknown_activation or revocation_failed
|
|
294
|
+
if str(current.get("state") or "") not in _DEPLOYMENT_READY_STATES and not ambiguous:
|
|
295
|
+
# nothing is being served off the alias yet, so nothing is lost by moving it.
|
|
296
|
+
return None
|
|
297
|
+
cli = _commands().CLI_NAME
|
|
298
|
+
# `step-N` is not universally available: `ApiClient.chat` gates a step target behind
|
|
299
|
+
# `_require_chat_step_selector`, which refuses outright on a plane that does not advertise
|
|
300
|
+
# `chat_step_selector_v1`. the capability cannot be read here without spending a /v1/health on
|
|
301
|
+
# an advisory warning, and `_chat_step_selector_available` starts False, so a negative reading
|
|
302
|
+
# cannot tell "unsupported" from "not checked yet". state the condition instead of asserting
|
|
303
|
+
# the command works, and name the selector that works on every plane.
|
|
304
|
+
tail = (
|
|
305
|
+
f"so every client using bare `{base_run_id}` changes model. address a specific "
|
|
306
|
+
f"checkpoint with `{cli} models chat {base_run_id}/step-N` to compare them, or by "
|
|
307
|
+
"immutable adapter revision if this control plane does not support step selectors."
|
|
308
|
+
)
|
|
309
|
+
if revocation_failed:
|
|
310
|
+
# same reason as the unknown-activation arm: this record's `checkpoint_step` describes the
|
|
311
|
+
# deployment whose revocation failed, and whether the backend still answers on the alias
|
|
312
|
+
# is exactly what could not be determined. hedge rather than name a checkpoint.
|
|
313
|
+
return (
|
|
314
|
+
f"{base_run_id} has a deployment whose revocation did not complete, so whether it "
|
|
315
|
+
f"still serves off that shared model id cannot be determined from here; deploying "
|
|
316
|
+
f"{_served_step_label(requested_step)} may move it, "
|
|
317
|
+
f"{tail} run `{cli} models deployments` to see the current state first."
|
|
318
|
+
)
|
|
319
|
+
if unknown_activation:
|
|
320
|
+
# this record's `checkpoint_step` names the INCOMING attempt, not what the alias holds:
|
|
321
|
+
# the plane resolves the live target from `adapter_alias_target` / `previous_deployment`,
|
|
322
|
+
# and both are server-side (`public_deployment` strips the predecessor). naming a
|
|
323
|
+
# checkpoint here would report the wrong one -- worse than naming none -- so say only what
|
|
324
|
+
# this side can actually stand behind.
|
|
325
|
+
return (
|
|
326
|
+
f"{base_run_id} has a deployment whose activation never settled, so the checkpoint "
|
|
327
|
+
f"it currently serves cannot be determined from here; deploying "
|
|
328
|
+
f"{_served_step_label(requested_step)} may move that shared model id, "
|
|
329
|
+
f"{tail} run `{cli} models deployments` to see the current state first."
|
|
330
|
+
)
|
|
331
|
+
raw_step = current.get("checkpoint_step")
|
|
332
|
+
# `int()` does not just reject what it cannot read -- it silently COERCES. `true` becomes 1,
|
|
333
|
+
# `false` becomes 0, and `1.5` truncates to 1, none of them raising. a step this client cannot
|
|
334
|
+
# read as an exact whole number is an unreadable record, not checkpoint 1: reading it as a
|
|
335
|
+
# number either suppresses the warning (deploying step-1 against a `true`) or names a
|
|
336
|
+
# checkpoint that was never live. bool is checked first because it is a subclass of int.
|
|
337
|
+
if isinstance(raw_step, bool):
|
|
338
|
+
return None
|
|
339
|
+
if isinstance(raw_step, float) and not raw_step.is_integer():
|
|
340
|
+
return None
|
|
341
|
+
try:
|
|
342
|
+
served_step = None if raw_step is None else int(raw_step)
|
|
343
|
+
except (TypeError, ValueError, OverflowError):
|
|
344
|
+
# a proxy or older plane can answer 2xx with a step this client cannot read. that is an
|
|
345
|
+
# unreadable current record like any other, NOT a reason to fail the deploy: leaving the
|
|
346
|
+
# conversion unguarded let an advisory read traceback out of the command it decorates.
|
|
347
|
+
# all three arms are reachable from one JSON body: `json.loads` accepts the non-standard
|
|
348
|
+
# `Infinity`/`NaN` literals, and int() answers those with OverflowError and ValueError
|
|
349
|
+
# respectively -- so catching only the obvious two still crashed the deploy.
|
|
350
|
+
return None
|
|
351
|
+
if served_step == requested_step:
|
|
352
|
+
return None
|
|
353
|
+
reach_displaced = ""
|
|
354
|
+
# the record being displaced carries the one identifier that survives the alias move, so name
|
|
355
|
+
# it whenever it is there. `step-N` is not a substitute: it is rejected outright on a plane
|
|
356
|
+
# without `chat_step_selector_v1`, and after this deploy the listing shows only the NEW record
|
|
357
|
+
# -- `public_deployment` strips `previous_deployment` (flash/serve/urls.py) -- so a revision
|
|
358
|
+
# not printed here is not recoverable from anywhere afterwards.
|
|
359
|
+
revision = str(current.get("adapter_revision") or "").strip()
|
|
360
|
+
if served_step is None:
|
|
361
|
+
# the displaced checkpoint is the FINAL adapter, and `_parse_chat_target` accepts only a
|
|
362
|
+
# bare run id, `RUN/step-N`, or a full immutable revision -- there is no `/final`
|
|
363
|
+
# selector. once the alias moves, `step-N` addresses the incoming checkpoint and the bare
|
|
364
|
+
# id is the thing that just changed, so the generic advice cannot reach the final adapter
|
|
365
|
+
# at all. its immutable revision can, and the record being displaced carries one.
|
|
366
|
+
reach_displaced = (
|
|
367
|
+
f" the displaced final adapter has no `/final` selector; reach it by its immutable "
|
|
368
|
+
f"revision `{revision}`."
|
|
369
|
+
if revision
|
|
370
|
+
# without a revision on the record there is nothing to hand the user, and deferring
|
|
371
|
+
# them to a later command would be worse than saying so: `client.deploy` fires as soon
|
|
372
|
+
# as this prints, and the deployments listing then shows only the NEW record --
|
|
373
|
+
# `public_deployment` strips `previous_deployment` (flash/serve/urls.py), so the
|
|
374
|
+
# displaced revision is not in it. promising a selector that the next command cannot
|
|
375
|
+
# produce is the one outcome worse than admitting there is none.
|
|
376
|
+
else (
|
|
377
|
+
" the displaced final adapter has no `/final` selector and this plane did not "
|
|
378
|
+
"report its immutable revision, so it will not be addressable after this deploy; "
|
|
379
|
+
"undeploy and redeploy it to serve it again."
|
|
380
|
+
)
|
|
381
|
+
)
|
|
382
|
+
elif revision:
|
|
383
|
+
# a numbered checkpoint keeps its `step-N` selector, but only on a plane that advertises
|
|
384
|
+
# `chat_step_selector_v1`; where it does not, the qualified advice above leaves the user
|
|
385
|
+
# holding no identifier at all. this is that identifier, and this is the last moment it
|
|
386
|
+
# can be printed.
|
|
387
|
+
reach_displaced = f" the displaced checkpoint's immutable revision is `{revision}`."
|
|
388
|
+
return (
|
|
389
|
+
f"{base_run_id} currently serves {_served_step_label(served_step)}; deploying "
|
|
390
|
+
f"{_served_step_label(requested_step)} moves that shared model id onto the new "
|
|
391
|
+
f"checkpoint, {tail}{reach_displaced}"
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
|
|
192
395
|
def _deployment_attempt_failed(requested: dict, final: dict) -> bool:
|
|
193
396
|
"""True when the requested revision is not the one now served.
|
|
194
397
|
|
|
@@ -229,8 +432,18 @@ def cmd_deploy(args) -> int:
|
|
|
229
432
|
file=sys.stderr,
|
|
230
433
|
)
|
|
231
434
|
return 1
|
|
232
|
-
base_run_id,
|
|
435
|
+
base_run_id, step = parsed
|
|
233
436
|
client = _commands().client_from_config()
|
|
437
|
+
# before the POST: after it the alias has already moved, and a warning about a checkpoint that
|
|
438
|
+
# is no longer served reads as history rather than a decision the reader still has. a dry run
|
|
439
|
+
# registers nothing, so it displaces nothing and gets no warning.
|
|
440
|
+
if not args.dry_run:
|
|
441
|
+
alias_warning = _alias_move_warning(client, base_run_id, step)
|
|
442
|
+
if alias_warning:
|
|
443
|
+
print(
|
|
444
|
+
render.warn(alias_warning) if render.styled() else f"warning: {alias_warning}",
|
|
445
|
+
file=sys.stderr,
|
|
446
|
+
)
|
|
234
447
|
dep = client.deploy(args.run_id, dry_run=args.dry_run)
|
|
235
448
|
wait_seconds = getattr(args, "wait", None)
|
|
236
449
|
# a dry run creates no deployment to poll for, so --wait has nothing to observe. test against
|
|
@@ -668,8 +668,8 @@ spending another GPU run:
|
|
|
668
668
|
| Environment id is blank or stale | A blank id fails config validation. A stale published id can pass `flash train --dry-run` because dry-run does not import or run `environment.py`; the worker then uses old reward/data. | Run `flash env push --project <project-uuid> --name my-env .` after every environment/data edit and paste the returned id into every config you submit. **Self-hosted:** `env push` targets the managed hub, so instead commit the edit and re-point `[environment] id` at the new ref -- see "Publish the environment" above. |
|
|
669
669
|
| Local-only env path in config | Config validation says there is no local path mode | Publish first, then use the returned slug in `[environment] id`. `flash train` only runs published env ids, not local paths. |
|
|
670
670
|
| Config knobs are in the wrong table | Validation rejects `[grpo]`, `[sft]`, or unknown `[train]` keys | Put `epochs`, `group_size`, `max_completion_tokens`, `temperature`, `max_context_tokens`, LoRA, and other training knobs under `[train]`. |
|
|
671
|
-
| GPU selection is not what you expected | Leaving `[gpu] type` unset may select a different fitting class as prices or capacity change | Set `[gpu] type` to an active validated class to hard-pin it, or leave it unset for managed cheapest-fit allocation. `train.hf_repo` remains platform-managed.
|
|
672
|
-
| A pinned run stops after two capacity refusals | The pinned class had no capacity, and no other class was allowed, so there was nowhere to fail over | Widen the search: drop the `[gpu] type` pin for managed allocation, or drop `[gpu] provider`. Flash stops once the class a retry would land on has refused capacity twice, rather than re-queueing on a class the provider keeps refusing. One refusal always earns a retry, since a momentary shortage is not a sold-out class.
|
|
671
|
+
| GPU selection is not what you expected | Leaving `[gpu] type` unset may select a different fitting class as prices or capacity change | Set `[gpu] type` to an active validated class to hard-pin it, to a list (`["A100 PCIe", "A100 SXM"]`) to allow several, or leave it unset for managed cheapest-fit allocation. `train.hf_repo` remains platform-managed. |
|
|
672
|
+
| A pinned run stops after two capacity refusals | The pinned class had no capacity, and no other class was allowed, so there was nowhere to fail over | Widen the search: drop the `[gpu] type` pin for managed allocation, name alternatives with `type = ["A100 PCIe", "A100 SXM"]`, or drop `[gpu] provider`. Flash stops once the class a retry would land on has refused capacity twice, rather than re-queueing on a class the provider keeps refusing. One refusal always earns a retry, since a momentary shortage is not a sold-out class. |
|
|
673
673
|
| Secrets are not available on the worker | Reward code works locally but remote logs show missing API keys or auth failures | List secret names under `[environment] secrets = [...]`, export those env vars locally before submit, or put them in local `.env` / `.env.local`. Never hard-code secret values in the config. |
|
|
674
674
|
| Scorer dependency is missing on the worker | Reward code works locally but every reward is `0.0` remotely; the import your scorer needs is installed in your venv, not the worker's | List the packages your scorer imports under `[environment] pip = ["pymongo>=4.6"]`. They are installed alongside Flash's own worker requirement. `flash env test` names the failing import locally before you spend a GPU on it. Entries name packages only: pip options and URLs with inline credentials are rejected, because the spec is stored and uploaded in plaintext (put the credential in `[environment] secrets`). |
|
|
675
675
|
| Wrong model / thinking setting | Config validation fails, or chat behavior does not match the run | Config validation is authoritative for model and thinking compatibility. Thinking is a run-level choice, and `flash models chat` does not expose an override flag. |
|
|
@@ -30,6 +30,7 @@ from flash.cli.ui.render import (
|
|
|
30
30
|
header,
|
|
31
31
|
run_cost,
|
|
32
32
|
)
|
|
33
|
+
from flash.core.spec import persisted_gpu_types
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
def models_table(rows: list[dict]) -> str:
|
|
@@ -71,7 +72,8 @@ def gpus_table(rows: list[tuple[str, int, float | None]], tip: str) -> str:
|
|
|
71
72
|
|
|
72
73
|
def gpu_label(spec: dict, remote: dict) -> str:
|
|
73
74
|
"""Human-facing GPU label. Provider metadata stays internal."""
|
|
74
|
-
|
|
75
|
+
authored = " | ".join(persisted_gpu_types(spec))
|
|
76
|
+
return remote.get("allocated_gpu") or authored
|
|
75
77
|
|
|
76
78
|
|
|
77
79
|
def runs_table(runs: list[dict]) -> str:
|
|
@@ -661,26 +661,34 @@ class ApiClient:
|
|
|
661
661
|
"GET", "/v1/deployments", timeout=timeout, require={"deployments": [dict]}
|
|
662
662
|
)["deployments"]
|
|
663
663
|
|
|
664
|
-
def
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
that: the default client timeout is 60s, so one stalled read inside a `--wait 5` would
|
|
673
|
-
overshoot the bound the user asked for by an order of magnitude.
|
|
664
|
+
def _serving_deployment(
|
|
665
|
+
self,
|
|
666
|
+
base_run_id: str,
|
|
667
|
+
timeout: float | None,
|
|
668
|
+
*,
|
|
669
|
+
body_deadline: float | None = None,
|
|
670
|
+
) -> dict | None:
|
|
671
|
+
"""The run's servable deployment record, or None when it has none.
|
|
674
672
|
|
|
675
673
|
Read from the run-scoped route rather than the listing. `/v1/deployments` walks every run
|
|
676
|
-
the key owns and loads each one's status before
|
|
677
|
-
account with a long run history the poll's cost grows with that history and
|
|
674
|
+
the key owns and loads each one's status before a caller picks a single record out, so on
|
|
675
|
+
an account with a long run history the poll's cost grows with that history and a wait can
|
|
678
676
|
expire scanning unrelated runs while the requested revision is already ready
|
|
679
677
|
`/v1/runs/{run_id}/deploy` resolves the one run directly.
|
|
678
|
+
|
|
679
|
+
``body_deadline`` additionally bounds the read in WALL-CLOCK time. ``timeout`` alone is a
|
|
680
|
+
per-socket-operation bound, so a peer that trickles bytes just inside it can hold the read
|
|
681
|
+
open indefinitely; a caller that must return within a fixed budget has to pass both (see
|
|
682
|
+
``env_list``). ``--wait`` polling deliberately does not: it owns a deadline spanning many
|
|
683
|
+
reads and recomputes each one's share.
|
|
680
684
|
"""
|
|
681
|
-
base_run_id, step = _parse_adapter_target(run_id)
|
|
682
685
|
try:
|
|
683
|
-
deployment = self._request(
|
|
686
|
+
deployment = self._request(
|
|
687
|
+
"GET",
|
|
688
|
+
f"/v1/runs/{base_run_id}/deploy",
|
|
689
|
+
timeout=timeout,
|
|
690
|
+
body_deadline=body_deadline,
|
|
691
|
+
)
|
|
684
692
|
except ApiError as exc:
|
|
685
693
|
# a run the key cannot see reads the same as one that is not deployed. the listing said
|
|
686
694
|
# "absent" by omitting the row; saying it by raising would turn a vanished deployment
|
|
@@ -695,6 +703,27 @@ class ApiClient:
|
|
|
695
703
|
# the listing's meaning: neither is a revision anyone can serve.
|
|
696
704
|
if str(deployment.get("state") or "") in {"undeployed", "dry_run"}:
|
|
697
705
|
return None
|
|
706
|
+
if not deployment.get("run_id"):
|
|
707
|
+
# `models deploy --wait` prints this record in place of the POST body, so without the
|
|
708
|
+
# id styled output renders an empty run field and the json omits it entirely.
|
|
709
|
+
deployment = {**deployment, "run_id": base_run_id}
|
|
710
|
+
return deployment
|
|
711
|
+
|
|
712
|
+
def deployment_for(self, run_id: str, timeout: float | None = None) -> dict | None:
|
|
713
|
+
"""The deployment record for the checkpoint named in ``run_id``, or None.
|
|
714
|
+
|
|
715
|
+
``deploy`` returns as soon as the record is persisted, which is normally before the
|
|
716
|
+
requested revision is servable. This is the read side a caller needs to tell "queued"
|
|
717
|
+
from "actually ready".
|
|
718
|
+
|
|
719
|
+
``timeout`` bounds the single request. A caller polling against its own deadline needs
|
|
720
|
+
that: the default client timeout is 60s, so one stalled read inside a `--wait 5` would
|
|
721
|
+
overshoot the bound the user asked for by an order of magnitude.
|
|
722
|
+
"""
|
|
723
|
+
base_run_id, step = _parse_adapter_target(run_id)
|
|
724
|
+
deployment = self._serving_deployment(base_run_id, timeout)
|
|
725
|
+
if deployment is None:
|
|
726
|
+
return None
|
|
698
727
|
# the requested step is part of the identity, not decoration. matching on the run id
|
|
699
728
|
# alone lets `deploy RUN/step-40 --wait` settle on whichever revision happens to be
|
|
700
729
|
# deployed -- an older one still marked ready, or a replacement another shell deployed
|
|
@@ -704,12 +733,27 @@ class ApiClient:
|
|
|
704
733
|
# None is the final adapter, an int is RUN/step-N (see the deployments renderer).
|
|
705
734
|
if (listed if listed is None else int(listed)) != step:
|
|
706
735
|
return None
|
|
707
|
-
if not deployment.get("run_id"):
|
|
708
|
-
# `models deploy --wait` prints this record in place of the POST body, so without the
|
|
709
|
-
# id styled output renders an empty run field and the json omits it entirely.
|
|
710
|
-
deployment = {**deployment, "run_id": base_run_id}
|
|
711
736
|
return deployment
|
|
712
737
|
|
|
738
|
+
def deployed_checkpoint(
|
|
739
|
+
self,
|
|
740
|
+
run_id: str,
|
|
741
|
+
timeout: float | None = None,
|
|
742
|
+
*,
|
|
743
|
+
body_deadline: float | None = None,
|
|
744
|
+
) -> dict | None:
|
|
745
|
+
"""Whatever checkpoint the run serves right now, whichever step that is.
|
|
746
|
+
|
|
747
|
+
The counterpart to ``deployment_for``, which answers the narrower "is MY revision live?"
|
|
748
|
+
and hides any other. A caller about to deploy needs the opposite: the record it is about
|
|
749
|
+
to displace is by definition the one the step filter drops.
|
|
750
|
+
|
|
751
|
+
``body_deadline`` bounds the whole read in wall-clock time; ``timeout`` alone bounds each
|
|
752
|
+
socket operation, which a peer trickling bytes just inside it can extend without limit.
|
|
753
|
+
"""
|
|
754
|
+
base_run_id, _ = _parse_adapter_target(run_id)
|
|
755
|
+
return self._serving_deployment(base_run_id, timeout, body_deadline=body_deadline)
|
|
756
|
+
|
|
713
757
|
def chat(
|
|
714
758
|
self,
|
|
715
759
|
run_id: str,
|