freesolo-flash-dev 1.2.64__tar.gz → 1.2.66__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.64 → freesolo_flash_dev-1.2.66}/PKG-INFO +1 -1
- freesolo_flash_dev-1.2.66/flash/_internal/diagnostics.py +170 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/__init__.py +11 -17
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/__init__.py +2 -2
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/lifecycle.py +48 -85
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/bootstrap_secrets.py +83 -18
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/serverless/endpoints.py +96 -34
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/seed_submission.py +21 -15
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/projects.py +34 -55
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_backend_common.py +81 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_flash_worker.py +176 -1
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_instance_bootstrap_coverage.py +59 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_oom_escalate_gpu.py +125 -32
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_resume_safety.py +96 -21
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_projects.py +232 -49
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_api.py +62 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/uv.lock +1 -1
- freesolo_flash_dev-1.2.64/flash/_internal/diagnostics.py +0 -106
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.env.example +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/README.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/setup_wandb.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/huggingface.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/sft_image_rows.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/capture_image_sft_processor_oracle.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/fixtures/image_sft_processor_oracle.json +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_image_sft_markers.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_image_sft_processor_parity.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.66
|
|
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
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"""Bounded credential-safe diagnostic rendering."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import re
|
|
7
|
+
import urllib.parse
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
_SECRET_KEY_RE = re.compile(
|
|
11
|
+
r"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|secret|password)"
|
|
12
|
+
r"(\s*[:=]\s*)(?:bearer\s+)?([^\s,;]+)"
|
|
13
|
+
)
|
|
14
|
+
_BEARER_RE = re.compile(r"(?i)\bbearer\s+[A-Za-z0-9._~+/=-]+")
|
|
15
|
+
_SECRET_ENV_SUFFIXES = ("_API_KEY", "_TOKEN", "_SECRET", "_PASSWORD")
|
|
16
|
+
|
|
17
|
+
# comma-separated env-variable names whose values are secrets regardless of naming shape: declared
|
|
18
|
+
# runtime secrets can carry any name (AWS_SECRET_ACCESS_KEY, FLASH_TEACHER_CAPABILITY, ...), so the
|
|
19
|
+
# control plane lists them explicitly in the worker env instead of relying on the suffix heuristic.
|
|
20
|
+
SECRET_ENV_KEYS_ENV = "FLASH_SECRET_ENV_KEYS"
|
|
21
|
+
|
|
22
|
+
# multiline secrets may appear only partially in truncated logs. register long component lines as
|
|
23
|
+
# needles, but ignore short common fragments such as ``}`` that would erase innocent diagnostics.
|
|
24
|
+
_MIN_SECRET_COMPONENT = 8
|
|
25
|
+
_PERCENT_ESCAPE_RE = re.compile(r"%([0-9A-Fa-f]{2})")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _percent_pattern(needle: str) -> str:
|
|
29
|
+
"""Regex for ``needle`` with only percent-escape hex digits matched case-insensitively."""
|
|
30
|
+
parts: list[str] = []
|
|
31
|
+
offset = 0
|
|
32
|
+
for match in _PERCENT_ESCAPE_RE.finditer(needle):
|
|
33
|
+
parts.append(re.escape(needle[offset : match.start()]))
|
|
34
|
+
parts.append("%")
|
|
35
|
+
parts.extend(
|
|
36
|
+
f"[{char.lower()}{char.upper()}]" if char.isalpha() else char for char in match.group(1)
|
|
37
|
+
)
|
|
38
|
+
offset = match.end()
|
|
39
|
+
parts.append(re.escape(needle[offset:]))
|
|
40
|
+
return "".join(parts)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _bounded_pattern(needle: str) -> str:
|
|
44
|
+
"""``needle`` anchored so it cannot match as part of a longer word.
|
|
45
|
+
|
|
46
|
+
The guard is applied per EDGE, and only where the needle's own edge is a word character. A
|
|
47
|
+
value with a punctuation edge already separates itself from neighbouring text, and demanding a
|
|
48
|
+
non-word character beyond it asks the wrong question: ``/a`` inside ``https://host/a/repo`` is
|
|
49
|
+
preceded by the ``t`` of ``host``, so an unconditional left guard fails and the secret prints
|
|
50
|
+
verbatim. ``ati`` keeps both guards and so still cannot rewrite ``authentication``.
|
|
51
|
+
Mirrors flash.providers._lifecycle.bootstrap_secrets._bounded_pattern.
|
|
52
|
+
"""
|
|
53
|
+
escaped = re.escape(needle)
|
|
54
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
55
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
56
|
+
return f"{left}{escaped}{right}"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
_ValueMatcher = tuple[str, bool, bool]
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _configured_secrets() -> tuple[tuple[_ValueMatcher, ...], tuple[str, ...], frozenset[str]]:
|
|
63
|
+
"""Credential matchers plus shape-only and exact raw values.
|
|
64
|
+
|
|
65
|
+
Each value matcher carries ``(needle, bounded, encoded)`` metadata. Plain values are replaced as
|
|
66
|
+
substrings. Bounded values are shorter than ``_MIN_SECRET_COMPONENT`` and may only match where
|
|
67
|
+
they are not adjacent to a word character: a 3-char global needle would mangle every diagnostic
|
|
68
|
+
containing those characters (the value ``ati`` rewrites ``authentication``).
|
|
69
|
+
|
|
70
|
+
A short raw candidate with no alphanumeric or underscore character is shape-only because it is
|
|
71
|
+
indistinguishable from ordinary punctuation. Explicit percent-octet forms remain bounded and
|
|
72
|
+
safely distinguishable. Keyed and bearer matching uses the known shape-only value directly.
|
|
73
|
+
|
|
74
|
+
Component lines of a multiline value keep the floor as a hard skip: a short component is
|
|
75
|
+
punctuation such as ``}``, not a credential.
|
|
76
|
+
"""
|
|
77
|
+
declared = {
|
|
78
|
+
name.strip().upper()
|
|
79
|
+
for name in os.environ.get(SECRET_ENV_KEYS_ENV, "").split(",")
|
|
80
|
+
if name.strip()
|
|
81
|
+
}
|
|
82
|
+
matchers: set[_ValueMatcher] = set()
|
|
83
|
+
shaped: set[str] = set()
|
|
84
|
+
raw_values: set[str] = set()
|
|
85
|
+
for key, value in os.environ.items():
|
|
86
|
+
upper = key.upper()
|
|
87
|
+
if not value or not (
|
|
88
|
+
upper in {"AUTHORIZATION", "HF_TOKEN"}
|
|
89
|
+
or upper in declared
|
|
90
|
+
or upper.endswith(_SECRET_ENV_SUFFIXES)
|
|
91
|
+
):
|
|
92
|
+
continue
|
|
93
|
+
raw_values.add(value)
|
|
94
|
+
candidates = {(value, False)}
|
|
95
|
+
encoded = urllib.parse.quote(value, safe="")
|
|
96
|
+
if encoded != value:
|
|
97
|
+
candidates.add((encoded, True))
|
|
98
|
+
if len(value) < _MIN_SECRET_COMPONENT and not any(
|
|
99
|
+
char.isalnum() or char == "_" for char in value
|
|
100
|
+
):
|
|
101
|
+
candidates.add(("".join(f"%{byte:02X}" for byte in value.encode()), True))
|
|
102
|
+
if len(value) >= _MIN_SECRET_COMPONENT:
|
|
103
|
+
matchers.update((candidate, False, is_encoded) for candidate, is_encoded in candidates)
|
|
104
|
+
else:
|
|
105
|
+
for candidate, is_encoded in candidates:
|
|
106
|
+
if any(char.isalnum() or char == "_" for char in candidate):
|
|
107
|
+
matchers.add((candidate, True, is_encoded))
|
|
108
|
+
else:
|
|
109
|
+
shaped.add(candidate)
|
|
110
|
+
if "\n" in value:
|
|
111
|
+
for raw in value.splitlines():
|
|
112
|
+
if len(line := raw.strip()) >= _MIN_SECRET_COMPONENT:
|
|
113
|
+
matchers.add((line, False, False))
|
|
114
|
+
encoded_line = urllib.parse.quote(line, safe="")
|
|
115
|
+
if encoded_line != line:
|
|
116
|
+
matchers.add((encoded_line, False, True))
|
|
117
|
+
return tuple(matchers), tuple(shaped), frozenset(raw_values)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def sanitize_diagnostic(value: Any, *, limit: int = 2000) -> str:
|
|
121
|
+
"""Keep useful failure context while removing credentials and bounding output."""
|
|
122
|
+
text = f"{type(value).__name__}: {value}" if isinstance(value, BaseException) else str(value)
|
|
123
|
+
matchers, shaped, raw_values = _configured_secrets()
|
|
124
|
+
# protect exact punctuation credentials before a separate value can erase their syntax.
|
|
125
|
+
for secret in sorted(shaped, key=len, reverse=True):
|
|
126
|
+
escaped = re.escape(secret)
|
|
127
|
+
text = re.sub(
|
|
128
|
+
rf"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|refresh[-_ ]?token|token|secret|password)(\s*[:=]\s*)(?:bearer\s+)?{escaped}(?=[\s,;]|$)",
|
|
129
|
+
lambda match: (
|
|
130
|
+
"<redacted>"
|
|
131
|
+
if match.group(1) in raw_values
|
|
132
|
+
else f"{match.group(1)}{match.group(2)}<redacted>"
|
|
133
|
+
),
|
|
134
|
+
text,
|
|
135
|
+
)
|
|
136
|
+
text = re.sub(
|
|
137
|
+
rf"(?i)\b(bearer)\s+{escaped}(?=[\s,;]|$)",
|
|
138
|
+
lambda match: "<redacted>" if match.group(1) in raw_values else "Bearer <redacted>",
|
|
139
|
+
text,
|
|
140
|
+
)
|
|
141
|
+
# apply both matcher types in one longest-first order so a shorter plain value cannot consume
|
|
142
|
+
# the prefix of a longer bounded encoded value.
|
|
143
|
+
for secret, is_bounded, is_encoded in sorted(
|
|
144
|
+
matchers, key=lambda item: len(item[0]), reverse=True
|
|
145
|
+
):
|
|
146
|
+
if is_encoded:
|
|
147
|
+
pattern = _percent_pattern(secret)
|
|
148
|
+
if is_bounded:
|
|
149
|
+
left = r"(?<!\w)" if secret[:1].isalnum() or secret[:1] == "_" else ""
|
|
150
|
+
right = r"(?!\w)" if secret[-1:].isalnum() or secret[-1:] == "_" else ""
|
|
151
|
+
pattern = f"{left}{pattern}{right}"
|
|
152
|
+
text = re.sub(pattern, "<redacted>", text)
|
|
153
|
+
elif is_bounded:
|
|
154
|
+
text = re.sub(_bounded_pattern(secret), "<redacted>", text)
|
|
155
|
+
else:
|
|
156
|
+
text = text.replace(secret, "<redacted>")
|
|
157
|
+
text = _BEARER_RE.sub("Bearer <redacted>", text)
|
|
158
|
+
text = _SECRET_KEY_RE.sub(lambda match: f"{match.group(1)}{match.group(2)}<redacted>", text)
|
|
159
|
+
return text[: max(0, int(limit))]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def neutralize_control_chars(value: Any) -> str:
|
|
163
|
+
"""Escape terminal control characters while preserving newlines as separators."""
|
|
164
|
+
text = str(value)
|
|
165
|
+
return "".join(
|
|
166
|
+
char
|
|
167
|
+
if char == "\n" or 0x20 <= ord(char) < 0x7F or ord(char) >= 0xA0
|
|
168
|
+
else f"\\x{ord(char):02x}"
|
|
169
|
+
for char in text
|
|
170
|
+
)
|
|
@@ -18,7 +18,7 @@ import traceback
|
|
|
18
18
|
|
|
19
19
|
from flash._internal.diagnostics import sanitize_diagnostic
|
|
20
20
|
from flash.adapters.fused_experts import lora_target_parameters
|
|
21
|
-
from flash.core.spec import FIXED_SEED, load_job_spec_from_env
|
|
21
|
+
from flash.core.spec import FIXED_SEED, gpu_count_of, load_job_spec_from_env
|
|
22
22
|
from flash.engine.result.accounting import RunMetrics
|
|
23
23
|
from flash.engine.worker.backend_common import collect_ray_failure_logs
|
|
24
24
|
from flash.engine.worker.entry.opd import run_opd
|
|
@@ -80,7 +80,7 @@ from flash.engine.worker.perf import (
|
|
|
80
80
|
grad_checkpointing_on,
|
|
81
81
|
grpo_use_reentrant,
|
|
82
82
|
is_cuda_oom,
|
|
83
|
-
|
|
83
|
+
preflight_gpu_occupancy,
|
|
84
84
|
wait_for_gpu,
|
|
85
85
|
)
|
|
86
86
|
from flash.engine.worker.runtime.kernel_warmup import _current_cuda_sm, load_mega_cache
|
|
@@ -221,22 +221,16 @@ def _worker_failure_flags(exc: BaseException) -> dict[str, bool]:
|
|
|
221
221
|
return {"retriable": retriable, "oom": (not retriable and is_cuda_oom(exc))}
|
|
222
222
|
|
|
223
223
|
|
|
224
|
-
def
|
|
225
|
-
"""
|
|
224
|
+
def _preflight_gpu_occupancy_for_spec() -> None:
|
|
225
|
+
"""Screen every GPU in the allocator-resolved worker allocation for substantial occupancy.
|
|
226
226
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
and wrong in both directions -- see ``preflight_free_vram``. Occupancy needs no requirement, so
|
|
230
|
-
it runs on any shape without reimplementing ``combined_vram_gb``'s non-linear multi-card fit.
|
|
227
|
+
The allocator stamps the chosen count onto ``JOB_SPEC`` before provider launch, so this passes
|
|
228
|
+
only the cards rented for this worker. It does not re-derive required VRAM or claim exact fit.
|
|
231
229
|
|
|
232
|
-
|
|
233
|
-
undetected, which is a gap and not a false alarm -- device 0 occupancy is still evidence of a
|
|
234
|
-
shared host.
|
|
235
|
-
|
|
236
|
-
Must stay the first CUDA-adjacent call in boot: the reading is only trustworthy while this
|
|
230
|
+
This must stay the first CUDA-adjacent call in boot. The reading is trustworthy only while this
|
|
237
231
|
process has no context of its own, and ``_force_fla_triton_gdn_on_sm100`` below creates one.
|
|
238
232
|
"""
|
|
239
|
-
|
|
233
|
+
preflight_gpu_occupancy(gpu_count_of(JOB_SPEC))
|
|
240
234
|
|
|
241
235
|
|
|
242
236
|
THINKING = JOB_SPEC.thinking if JOB_SPEC else False
|
|
@@ -347,14 +341,14 @@ def _run_worker_mode() -> None:
|
|
|
347
341
|
# FIRST, and specifically before `_force_fla_triton_gdn_on_sm100`: that reads
|
|
348
342
|
# `get_device_capability`, which initializes CUDA in this process, and from that moment the
|
|
349
343
|
# driver's "used" includes our own context with no sound way to subtract it -- the occupancy
|
|
350
|
-
# check declines to run rather than guess (see `
|
|
351
|
-
# never calling it at all.
|
|
344
|
+
# check declines to run rather than guess (see `preflight_gpu_occupancy`), so calling it later
|
|
345
|
+
# means never calling it at all. this is also before `_ensure_fla_fastpath_on_hopper`, whose repair
|
|
352
346
|
# path runs pip installs with 600s timeouts: a card handed over with a co-tenant's ~18GB still
|
|
353
347
|
# resident fails the run either way, and the only question is whether that happens now or after
|
|
354
348
|
# dependency repair, the model download and FSDP init have spent paid GPU on the same
|
|
355
349
|
# conclusion. NVML answers without a context, so nothing here dirties the reading for the code
|
|
356
350
|
# below.
|
|
357
|
-
|
|
351
|
+
_preflight_gpu_occupancy_for_spec()
|
|
358
352
|
# run before model imports: sm100 tilelang GDN computes wrong gradients, so use Triton.
|
|
359
353
|
_force_fla_triton_gdn_on_sm100()
|
|
360
354
|
_ensure_fla_fastpath_on_hopper()
|
{freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/__init__.py
RENAMED
|
@@ -28,7 +28,7 @@ from flash.engine.worker.perf.lifecycle import (
|
|
|
28
28
|
RetriableInfraError,
|
|
29
29
|
free_vram_gb,
|
|
30
30
|
is_cuda_oom,
|
|
31
|
-
|
|
31
|
+
preflight_gpu_occupancy,
|
|
32
32
|
total_vram_gb,
|
|
33
33
|
wait_for_gpu,
|
|
34
34
|
)
|
|
@@ -403,7 +403,7 @@ __all__ = [
|
|
|
403
403
|
"grad_checkpointing_on",
|
|
404
404
|
"grpo_use_reentrant",
|
|
405
405
|
"is_cuda_oom",
|
|
406
|
-
"
|
|
406
|
+
"preflight_gpu_occupancy",
|
|
407
407
|
"total_vram_gb",
|
|
408
408
|
"wait_for_gpu",
|
|
409
409
|
]
|
{freesolo_flash_dev-1.2.64 → freesolo_flash_dev-1.2.66}/flash/engine/worker/perf/lifecycle.py
RENAMED
|
@@ -34,36 +34,31 @@ class RetriableInfraError(RuntimeError):
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class DirtyGpuError(RetriableInfraError):
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Infra retry reallocates instead: ``_handle_failure`` records the provider in ``failed_providers``
|
|
46
|
-
and the shape in ``tried_classes``, so the next attempt prefers a DIFFERENT provider, then an
|
|
47
|
-
untried shape, before clamping back. That is the right preference order for this failure --
|
|
48
|
-
co-tenancy is a property of the host pool that handed the instance out, not of the run -- but it
|
|
49
|
-
is a preference, not a guarantee, so nothing here promises which card comes back.
|
|
37
|
+
"""An allocated GPU arrived with substantial pre-existing occupancy.
|
|
38
|
+
|
|
39
|
+
This is retriable infrastructure, deliberately not an OOM. An OOM means the run does not fit
|
|
40
|
+
and retries on a larger card. Substantial boot-time occupancy instead calls for a fresh
|
|
41
|
+
allocation, because a larger card can arrive just as occupied. This error does not claim that an
|
|
42
|
+
accepted card has enough free VRAM for the run: occupancy at or below 5%, unreadable NVML, and
|
|
43
|
+
invalid readings remain fail-open limits of the best-effort screen.
|
|
50
44
|
"""
|
|
51
45
|
|
|
52
46
|
|
|
53
|
-
def _nvml_memory_gb() -> tuple[float, float] | None:
|
|
54
|
-
"""``(free, total)``
|
|
47
|
+
def _nvml_memory_gb(device_index: int = 0) -> tuple[float, float] | None:
|
|
48
|
+
"""``(free, total)`` for one device in GB from NVML, or None if NVML will not answer.
|
|
55
49
|
|
|
56
|
-
NVML, not ``torch.cuda.mem_get_info``: the torch call needs a CUDA context and
|
|
57
|
-
process has none, so the act of measuring adds our own
|
|
58
|
-
|
|
59
|
-
the
|
|
50
|
+
NVML, not ``torch.cuda.mem_get_info``: the torch call needs a CUDA context and creates one if the
|
|
51
|
+
process has none, so the act of measuring adds our own memory to the number being measured. NVML
|
|
52
|
+
queries the driver without initializing CUDA in this process. Device 0 remains the default for
|
|
53
|
+
the diagnostic helpers that expose its free and total memory.
|
|
60
54
|
"""
|
|
61
55
|
try:
|
|
62
56
|
import pynvml
|
|
63
57
|
|
|
64
58
|
pynvml.nvmlInit()
|
|
65
59
|
try:
|
|
66
|
-
|
|
60
|
+
handle = pynvml.nvmlDeviceGetHandleByIndex(device_index)
|
|
61
|
+
info = pynvml.nvmlDeviceGetMemoryInfo(handle)
|
|
67
62
|
return float(info.free) / (1024**3), float(info.total) / (1024**3)
|
|
68
63
|
finally:
|
|
69
64
|
with contextlib.suppress(Exception):
|
|
@@ -110,76 +105,44 @@ def total_vram_gb() -> float | None:
|
|
|
110
105
|
return None if reading is None else reading[1]
|
|
111
106
|
|
|
112
107
|
|
|
113
|
-
def
|
|
114
|
-
"""
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
(``_overridden_train``) that reduce an authored batch 8 to the executed batch 1, so recomputing
|
|
127
|
-
from the authored spec demands more than the card was rented for; and a run sized exactly at a
|
|
128
|
-
catalog tier (24 GB) can exceed a real card's usable total (22.5 GB on a 4090), which no amount
|
|
129
|
-
of free memory can ever satisfy. Both reject a perfectly clean card and retry until the infra
|
|
130
|
-
budget is gone -- strictly worse than the OOM this exists to prevent.
|
|
131
|
-
|
|
132
|
-
Occupancy has neither failure mode: it needs no requirement, no profile, and no catalog number.
|
|
133
|
-
An empty card reads ~0 whatever is scheduled on it, so the threshold can sit near zero rather
|
|
134
|
-
than being padded to cover a requirement it never consults. 5% is the driver's own reserve plus
|
|
135
|
-
slack; the observed dirty card was at 83% with 0.486 GB attributable to us.
|
|
136
|
-
|
|
137
|
-
The floor is low BECAUSE the check is occupancy: a loose threshold has to be justified against
|
|
138
|
-
the biggest run that could be scheduled, and a 5 GB co-tenant that leaves a 20 GB run 17.5 GB on
|
|
139
|
-
a 22.5 GB card is 22% occupied and fatal. Sizing the threshold to survive that means re-deriving
|
|
140
|
-
the requirement, which is the failure above. Refusing every card with a stranger on it needs no
|
|
141
|
-
requirement and covers the close-fitting case too.
|
|
142
|
-
|
|
143
|
-
A threshold that low only works if none of the used memory is OURS, and that is established by
|
|
144
|
-
WHEN the reading is taken, not by trying to attribute it afterwards. Attribution was tried and
|
|
145
|
-
cannot work here: ``nvidia-smi --query-compute-apps`` reports HOST pids, while the worker
|
|
146
|
-
container runs with a private pid namespace (``docker run`` in ``providers/_lifecycle/instance``
|
|
147
|
-
passes no ``--pid=host``), so testing ``/proc/<pid>`` inside the container is not an ownership
|
|
148
|
-
test in either direction -- our own rows fail it and get counted as a stranger's, and under
|
|
149
|
-
``--pid=host`` a real co-tenant passes it and gets credited to us, silently waving through the
|
|
150
|
-
exact card this exists to refuse.
|
|
151
|
-
|
|
152
|
-
So the check simply declines to run once this process has a CUDA context, which makes WHEN it
|
|
153
|
-
runs the whole design. There is exactly one call site, ``_preflight_free_vram_for_spec`` at the
|
|
154
|
-
top of ``_run_worker_mode``, and it is placed before ``_force_fla_triton_gdn_on_sm100`` because
|
|
155
|
-
that reads ``get_device_capability`` and creates the process's first context. Calling from
|
|
156
|
-
anywhere below that point is not a weaker check, it is no check at all: the guard above returns
|
|
157
|
-
immediately and the card is never read. A single early call site is therefore the invariant, not
|
|
158
|
-
an omission -- a later retry could only run after CUDA came up, when the reading is already
|
|
159
|
-
unusable. That also means one NVML failure at boot is one lost reading, not a lost run: the
|
|
160
|
-
guard below returns and training proceeds exactly as it did before this check existed.
|
|
108
|
+
def preflight_gpu_occupancy(gpu_count: int, *, max_occupied_fraction: float = 0.05) -> None:
|
|
109
|
+
"""Screen each allocated GPU for substantial occupancy before CUDA initialization.
|
|
110
|
+
|
|
111
|
+
The worker reads exactly the allocator-resolved device indices ``range(gpu_count)`` through NVML.
|
|
112
|
+
An unreadable device or a non-positive total is skipped without hiding later allocated devices.
|
|
113
|
+
If any valid reading exceeds 5% occupancy, the allocation is rejected as retriable
|
|
114
|
+
infrastructure after every allocated device has been inspected.
|
|
115
|
+
|
|
116
|
+
This is a best-effort occupancy boundary, not an exact-fit guarantee. It deliberately does not
|
|
117
|
+
reconstruct the allocator's run requirement. Occupancy at or below 5%, unreadable NVML, and
|
|
118
|
+
invalid readings remain accepted. Once this process has initialized CUDA, the whole screen is
|
|
119
|
+
fail-open because the driver reading includes memory owned by this process with no sound way to
|
|
120
|
+
subtract it.
|
|
161
121
|
"""
|
|
162
122
|
if cuda_is_initialized():
|
|
163
|
-
# some of `used` would be ours and there is no sound way to tell how much
|
|
164
|
-
# cannot distinguish our context from a co-tenant would either false-reject clean cards or
|
|
165
|
-
# need a threshold too loose to catch the tenant it exists for. staying silent is correct:
|
|
166
|
-
# the boot call already read this card while it was provably untouched.
|
|
123
|
+
# some of `used` would be ours and there is no sound way to tell how much
|
|
167
124
|
return
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
125
|
+
|
|
126
|
+
first_dirty: tuple[int, float, float] | None = None
|
|
127
|
+
for device_index in range(gpu_count):
|
|
128
|
+
reading = _nvml_memory_gb(device_index)
|
|
129
|
+
if reading is None:
|
|
130
|
+
# one unreadable device is not evidence about any later allocated device
|
|
131
|
+
continue
|
|
132
|
+
free, total = reading
|
|
133
|
+
if total <= 0:
|
|
134
|
+
continue
|
|
135
|
+
used = max(0.0, total - free)
|
|
136
|
+
if used > total * max_occupied_fraction and first_dirty is None:
|
|
137
|
+
first_dirty = (device_index, used, total)
|
|
138
|
+
|
|
139
|
+
if first_dirty is None:
|
|
178
140
|
return
|
|
141
|
+
device_index, used, total = first_dirty
|
|
179
142
|
raise DirtyGpuError(
|
|
180
|
-
f"allocated GPU has {used:.1f} GB of {total:.1f} GB
|
|
181
|
-
"before this run has touched it; the card is occupied
|
|
182
|
-
"tenant's leak, so retrying on a freshly allocated instance"
|
|
143
|
+
f"allocated GPU device {device_index} has {used:.1f} GB of {total:.1f} GB "
|
|
144
|
+
f"({used / total:.0%}) already in use before this run has touched it; the card is occupied "
|
|
145
|
+
"by another tenant or a previous tenant's leak, so retrying on a freshly allocated instance"
|
|
183
146
|
)
|
|
184
147
|
|
|
185
148
|
|
|
@@ -22,6 +22,22 @@ _SECRET_RE = re.compile(
|
|
|
22
22
|
# component lines are registered as needles too; the floor keeps a common fragment such as ``}``
|
|
23
23
|
# from erasing innocent output. Mirrors flash._internal.diagnostics.
|
|
24
24
|
_MIN_SECRET_COMPONENT = 8
|
|
25
|
+
_PERCENT_ESCAPE_RE = re.compile(r"%([0-9A-Fa-f]{2})")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _percent_pattern(needle: str) -> str:
|
|
29
|
+
"""Regex for ``needle`` with only percent-escape hex digits matched case-insensitively."""
|
|
30
|
+
parts: list[str] = []
|
|
31
|
+
offset = 0
|
|
32
|
+
for match in _PERCENT_ESCAPE_RE.finditer(needle):
|
|
33
|
+
parts.append(re.escape(needle[offset : match.start()]))
|
|
34
|
+
parts.append("%")
|
|
35
|
+
parts.extend(
|
|
36
|
+
f"[{char.lower()}{char.upper()}]" if char.isalpha() else char for char in match.group(1)
|
|
37
|
+
)
|
|
38
|
+
offset = match.end()
|
|
39
|
+
parts.append(re.escape(needle[offset:]))
|
|
40
|
+
return "".join(parts)
|
|
25
41
|
|
|
26
42
|
|
|
27
43
|
def _bounded_pattern(needle: str) -> str:
|
|
@@ -39,37 +55,86 @@ def _bounded_pattern(needle: str) -> str:
|
|
|
39
55
|
return f"{left}{escaped}{right}"
|
|
40
56
|
|
|
41
57
|
|
|
42
|
-
|
|
43
|
-
|
|
58
|
+
_ValueMatcher = tuple[str, bool, bool]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _needles(values: set[str]) -> tuple[set[_ValueMatcher], set[str]]:
|
|
62
|
+
"""The typed value matchers and shape-only needles for ``values``.
|
|
44
63
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
each value matcher carries ``(needle, bounded, encoded)`` metadata. plain needles are replaced as
|
|
65
|
+
substrings. bounded needles are values under the floor, replaced only where not adjacent to a word
|
|
66
|
+
character. a short raw candidate with no alphanumeric or underscore character is shape-only
|
|
67
|
+
because it is indistinguishable from ordinary punctuation; explicit percent-octet forms remain
|
|
68
|
+
bounded. component lines of a multiline value keep the floor as a hard skip: a short one is
|
|
49
69
|
punctuation such as ``}``, not a credential.
|
|
50
70
|
"""
|
|
51
|
-
|
|
52
|
-
|
|
71
|
+
matchers: set[_ValueMatcher] = set()
|
|
72
|
+
shaped: set[str] = set()
|
|
53
73
|
for secret in values:
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
candidates = {(secret, False)}
|
|
75
|
+
encoded = urllib.parse.quote(secret, safe="")
|
|
76
|
+
if encoded != secret:
|
|
77
|
+
candidates.add((encoded, True))
|
|
78
|
+
if len(secret) < _MIN_SECRET_COMPONENT and not any(
|
|
79
|
+
char.isalnum() or char == "_" for char in secret
|
|
80
|
+
):
|
|
81
|
+
candidates.add(("".join(f"%{byte:02X}" for byte in secret.encode()), True))
|
|
82
|
+
if len(secret) >= _MIN_SECRET_COMPONENT:
|
|
83
|
+
matchers.update((candidate, False, is_encoded) for candidate, is_encoded in candidates)
|
|
84
|
+
else:
|
|
85
|
+
for candidate, is_encoded in candidates:
|
|
86
|
+
if any(char.isalnum() or char == "_" for char in candidate):
|
|
87
|
+
matchers.add((candidate, True, is_encoded))
|
|
88
|
+
else:
|
|
89
|
+
shaped.add(candidate)
|
|
56
90
|
if "\n" in secret:
|
|
57
91
|
for raw in secret.splitlines():
|
|
58
92
|
if len(line := raw.strip()) >= _MIN_SECRET_COMPONENT:
|
|
59
|
-
|
|
60
|
-
|
|
93
|
+
matchers.add((line, False, False))
|
|
94
|
+
encoded_line = urllib.parse.quote(line, safe="")
|
|
95
|
+
if encoded_line != line:
|
|
96
|
+
matchers.add((encoded_line, False, True))
|
|
97
|
+
return matchers, shaped
|
|
61
98
|
|
|
62
99
|
|
|
63
100
|
def _redact_values(text: str, values: set[str]) -> str:
|
|
64
101
|
"""Replace every credential value in ``text``; see ``_needles`` for how each form is matched.
|
|
65
102
|
|
|
66
|
-
Longest-first, so one secret containing another cannot leave a suffix
|
|
103
|
+
Longest-first across both matcher types, so one secret containing another cannot leave a suffix
|
|
104
|
+
of the longer one behind.
|
|
67
105
|
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
text = re.sub(
|
|
106
|
+
matchers, shaped = _needles(values)
|
|
107
|
+
# protect exact punctuation credentials before a separate value can erase their syntax.
|
|
108
|
+
for needle in sorted(shaped, key=len, reverse=True):
|
|
109
|
+
escaped = re.escape(needle)
|
|
110
|
+
text = re.sub(
|
|
111
|
+
rf"(?i)(authorization|api[-_ ]?key|access[-_ ]?token|token|secret|password)(\s*[:=]\s*)(?:bearer\s+)?{escaped}(?=[\s,;]|$)",
|
|
112
|
+
lambda match: (
|
|
113
|
+
"<redacted>"
|
|
114
|
+
if match.group(1) in values
|
|
115
|
+
else f"{match.group(1)}{match.group(2)}<redacted>"
|
|
116
|
+
),
|
|
117
|
+
text,
|
|
118
|
+
)
|
|
119
|
+
text = re.sub(
|
|
120
|
+
rf"(?i)\b(bearer)\s+{escaped}(?=[\s,;]|$)",
|
|
121
|
+
lambda match: "<redacted>" if match.group(1) in values else "Bearer <redacted>",
|
|
122
|
+
text,
|
|
123
|
+
)
|
|
124
|
+
for needle, is_bounded, is_encoded in sorted(
|
|
125
|
+
matchers, key=lambda item: len(item[0]), reverse=True
|
|
126
|
+
):
|
|
127
|
+
if is_encoded:
|
|
128
|
+
pattern = _percent_pattern(needle)
|
|
129
|
+
if is_bounded:
|
|
130
|
+
left = r"(?<!\w)" if needle[:1].isalnum() or needle[:1] == "_" else ""
|
|
131
|
+
right = r"(?!\w)" if needle[-1:].isalnum() or needle[-1:] == "_" else ""
|
|
132
|
+
pattern = f"{left}{pattern}{right}"
|
|
133
|
+
text = re.sub(pattern, "<redacted>", text)
|
|
134
|
+
elif is_bounded:
|
|
135
|
+
text = re.sub(_bounded_pattern(needle), "<redacted>", text)
|
|
136
|
+
else:
|
|
137
|
+
text = text.replace(needle, "<redacted>")
|
|
73
138
|
return text
|
|
74
139
|
|
|
75
140
|
|