freesolo-flash-dev 1.0.97__tar.gz → 1.0.99__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.0.97 → freesolo_flash_dev-1.0.99}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/backend_common.py +128 -2
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_train.py +11 -15
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/lifecycle.py +11 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rl_train.py +10 -19
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/lifecycle.py +27 -8
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_backend_common.py +202 -6
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_oom_escalate_gpu.py +81 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd.py +1 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_stack.py +71 -7
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/uv.lock +1 -1
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.dockerignore +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.env.example +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.gitignore +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/Dockerfile +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/LICENSE +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/NOTICE +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/README.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/Dockerfile +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_channel.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_fileio.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_logging.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_paths.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/adapter_artifacts.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/catalog.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/TRAINING.md +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/_tty.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/commands.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_eval.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_setup.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_test.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/envpush.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/render.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/traces.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/training_doc.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/diagnostics.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/accounting.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/multiturn_reward_scoring.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/recipe.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/reward_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/rollout_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/sft_workload.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/steps.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/vram.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/_pkg.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/adapter.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/decoding.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/finalize.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo_multiturn.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo_plugin.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/heartbeat.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/hf.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/lora.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/multiturn_glue.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_gkd.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_multiturn.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_plugin.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_structured.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/packing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/attn.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/loraplus.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rl.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rng.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/teacher.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/teacher_encoding.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/wandb_log.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/archive.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/archive_policy.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/registry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/lora_rank.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/multimodal.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_limits.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_retry_contract.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_validation.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_auth.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_deadline.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_hf_artifacts.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_hf_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_http.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_bootstrap.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_poll.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_provider.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_poll.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_worker.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/auth.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/gpus.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/pricing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/keys.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/slots.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/train/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/train/endpoints.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/weight_cache_preload.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/deploy.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/pricing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_deps.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_internal_client.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_locks.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_runtime.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/auth.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/billing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/billing_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/db.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/environment_registry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/envs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/projects.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/reconcile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/run_registry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/spec.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/thinking.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/workload_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_async_uploads.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_rewards.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_infisical_overlay.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multimodal_input_grads.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_train.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_open_model_policy.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_reward_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rl_train.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_profile_quote.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_profile_sampling.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_workload_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_slots.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_pricing_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_profile_worker.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_log_coverage.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_workload_profile_lifecycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.99
|
|
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
|
{freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/backend_common.py
RENAMED
|
@@ -21,9 +21,12 @@ import re
|
|
|
21
21
|
import shutil
|
|
22
22
|
import signal
|
|
23
23
|
import subprocess
|
|
24
|
+
import threading
|
|
24
25
|
import time
|
|
26
|
+
import weakref
|
|
25
27
|
from collections.abc import Callable
|
|
26
28
|
from concurrent.futures import ThreadPoolExecutor
|
|
29
|
+
from concurrent.futures import thread as _thread_module
|
|
27
30
|
from http.server import ThreadingHTTPServer
|
|
28
31
|
|
|
29
32
|
from flash.diagnostics import sanitize_diagnostic
|
|
@@ -192,6 +195,49 @@ def agent_loop_workers(rollout_batch: int, *, cap: int = 8) -> int:
|
|
|
192
195
|
_BRIDGE_WORKER_THREADS = 16
|
|
193
196
|
|
|
194
197
|
|
|
198
|
+
class _DaemonBridgeThreadPool(ThreadPoolExecutor):
|
|
199
|
+
"""A ``ThreadPoolExecutor`` whose workers cannot hold the interpreter open.
|
|
200
|
+
|
|
201
|
+
The stock executor registers every worker in ``concurrent.futures.thread._threads_queues``,
|
|
202
|
+
which an interpreter-exit hook joins. ``shutdown(wait=False, cancel_futures=True)`` does not
|
|
203
|
+
change that: cancelling drops only the QUEUED futures, and a handler already running keeps its
|
|
204
|
+
thread alive, so exit blocks on it. Measured: a 30-second handler delays exit by the full 30
|
|
205
|
+
seconds even after ``shutdown(wait=False)`` returns.
|
|
206
|
+
|
|
207
|
+
That is the opposite of what a bridge needs. A hung environment reward or teacher callback must
|
|
208
|
+
not stop the worker from publishing its terminal result and releasing a paid GPU -- and it is
|
|
209
|
+
also the property the old daemon ``ThreadingHTTPServer`` had before requests moved onto a pool.
|
|
210
|
+
|
|
211
|
+
So: start the workers as daemons and skip the exit-hook registration. Only the thread creation
|
|
212
|
+
differs from the stdlib; queueing, idle reuse, and shutdown are inherited unchanged.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
def _adjust_thread_count(self) -> None:
|
|
216
|
+
if self._idle_semaphore.acquire(timeout=0):
|
|
217
|
+
return
|
|
218
|
+
|
|
219
|
+
def weakref_cb(_, q=self._work_queue):
|
|
220
|
+
q.put(None)
|
|
221
|
+
|
|
222
|
+
num_threads = len(self._threads)
|
|
223
|
+
if num_threads < self._max_workers:
|
|
224
|
+
thread = threading.Thread(
|
|
225
|
+
name=f"{self._thread_name_prefix or self}_{num_threads}",
|
|
226
|
+
target=_thread_module._worker,
|
|
227
|
+
args=(
|
|
228
|
+
weakref.ref(self, weakref_cb),
|
|
229
|
+
self._work_queue,
|
|
230
|
+
self._initializer,
|
|
231
|
+
self._initargs,
|
|
232
|
+
),
|
|
233
|
+
daemon=True,
|
|
234
|
+
)
|
|
235
|
+
thread.start()
|
|
236
|
+
self._threads.add(thread)
|
|
237
|
+
# deliberately NOT added to _thread_module._threads_queues: that mapping is exactly
|
|
238
|
+
# what the interpreter-exit hook walks to join workers.
|
|
239
|
+
|
|
240
|
+
|
|
195
241
|
class BoundedThreadingHTTPServer(ThreadingHTTPServer):
|
|
196
242
|
"""an http server that serves requests from a fixed thread pool instead of one thread each.
|
|
197
243
|
|
|
@@ -212,13 +258,16 @@ class BoundedThreadingHTTPServer(ThreadingHTTPServer):
|
|
|
212
258
|
"""
|
|
213
259
|
|
|
214
260
|
# daemon threads so a stuck handler can never keep the worker process alive at shutdown.
|
|
261
|
+
# `daemon_threads` is a ThreadingMixIn flag, read only by the `process_request` this class
|
|
262
|
+
# overrides, so it does nothing here on its own -- _DaemonBridgeThreadPool below is what
|
|
263
|
+
# actually delivers the property it names.
|
|
215
264
|
daemon_threads = True
|
|
216
265
|
|
|
217
266
|
# measured: at the socketserver default of 5, 13 of 64 simultaneous callers were reset by peer.
|
|
218
267
|
request_queue_size = 128
|
|
219
268
|
|
|
220
269
|
def __init__(self, *args, worker_threads: int = _BRIDGE_WORKER_THREADS, **kwargs):
|
|
221
|
-
self._bridge_pool =
|
|
270
|
+
self._bridge_pool = _DaemonBridgeThreadPool(
|
|
222
271
|
max_workers=worker_threads, thread_name_prefix="flash-bridge"
|
|
223
272
|
)
|
|
224
273
|
super().__init__(*args, **kwargs)
|
|
@@ -438,8 +487,31 @@ if %(gdn_module)r:
|
|
|
438
487
|
torch.zeros(4, 3, device="cuda", dtype=torch.bfloat16),
|
|
439
488
|
)
|
|
440
489
|
torch.cuda.synchronize()
|
|
490
|
+
if not ok:
|
|
491
|
+
# say WHY on a clean negative too: which of the three checks failed is the difference
|
|
492
|
+
# between "install fla" and "rebuild causal_conv1d for this arch".
|
|
493
|
+
print(
|
|
494
|
+
"[verl] gdn boundary resets unavailable in the child: fla="
|
|
495
|
+
+ str(is_flash_linear_attention_available())
|
|
496
|
+
+ " causal_conv1d="
|
|
497
|
+
+ str(is_causal_conv1d_available()),
|
|
498
|
+
flush=True,
|
|
499
|
+
)
|
|
441
500
|
emit("gdn_boundary_resets", bool(ok))
|
|
442
|
-
except Exception:
|
|
501
|
+
except Exception as e:
|
|
502
|
+
# a bare False here is what made this invisible. the caller raises on a hybrid that cannot
|
|
503
|
+
# reset, and an operator reading only that has no way back to which check fell over --
|
|
504
|
+
# a missing wheel, a broken ABI, or a conv kernel compiled without this arch all look
|
|
505
|
+
# identical from the parent. printed to STDOUT, which probe_verl_capabilities forwards
|
|
506
|
+
# on the '[verl] ' prefix -- stderr would be dropped, it is only reported when the
|
|
507
|
+
# child answers nothing at all.
|
|
508
|
+
import traceback
|
|
509
|
+
|
|
510
|
+
print(
|
|
511
|
+
"[verl] gdn boundary resets unavailable in the child: "
|
|
512
|
+
+ " | ".join(traceback.format_exc(limit=3).strip().splitlines()),
|
|
513
|
+
flush=True,
|
|
514
|
+
)
|
|
443
515
|
emit("gdn_boundary_resets", False)
|
|
444
516
|
"""
|
|
445
517
|
|
|
@@ -523,6 +595,14 @@ def probe_verl_capabilities(python_bin: str, gdn_module: str = "") -> dict:
|
|
|
523
595
|
# fail-closed default rather than vanishing from the dict.
|
|
524
596
|
caps.update({k: v for k, v in answered.items() if k in caps})
|
|
525
597
|
answered_any = True
|
|
598
|
+
# the child's own diagnostics, forwarded BEFORE the early return. the gdn question prints why it
|
|
599
|
+
# answered no, and it is answered LAST -- so every real run answers something earlier, and a
|
|
600
|
+
# bare `return caps` here would discard the one line the gate's raise tells operators to read.
|
|
601
|
+
# matched on the prefix rather than forwarded wholesale: the child's stdout also carries verl's
|
|
602
|
+
# own import chatter, which is not worth a parent log line.
|
|
603
|
+
for line in (stdout or "").splitlines():
|
|
604
|
+
if line.startswith("[verl] "):
|
|
605
|
+
print(line, flush=True)
|
|
526
606
|
if answered_any:
|
|
527
607
|
return caps
|
|
528
608
|
if not timed_out:
|
|
@@ -609,6 +689,52 @@ def gdn_reset_arch_from_caps(caps: dict, gdn_module: str) -> str | None:
|
|
|
609
689
|
return gdn_module.split(".")[2]
|
|
610
690
|
|
|
611
691
|
|
|
692
|
+
def require_gdn_boundary_resets(caps: dict, gdn_module: str) -> str | None:
|
|
693
|
+
"""The arch to patch for a gdn hybrid, raising if the child cannot honor boundary resets.
|
|
694
|
+
|
|
695
|
+
A thin gate over ``gdn_reset_arch_from_caps``: same answer for the two cases that have one, but
|
|
696
|
+
a raise where that returns None for a gdn model. Returns None only for a NON-gdn model, which
|
|
697
|
+
is what an empty ``gdn_module`` means -- the parent never asked the child, because there was
|
|
698
|
+
nothing to ask about.
|
|
699
|
+
|
|
700
|
+
There is no third outcome for a gdn hybrid. One whose child lacks fla/causal_conv1d used to fall
|
|
701
|
+
back to verl's padded path (``use_remove_padding=False``), which is boundary-correct but cannot
|
|
702
|
+
complete a single training step on grpo or opd: flash sets ``use_fused_kernels=True``
|
|
703
|
+
unconditionally, and verl's fsdp engine has no guard for that pair (its megatron engine does,
|
|
704
|
+
``megatron/transformer_impl.py:869-874``). The padded+fused branch returns a dense
|
|
705
|
+
``[bsz, response_len]`` where every sibling path re-nests via ``cu_seqlens``, so
|
|
706
|
+
``no_padding_2_padding`` asserts ``sequence_offsets[-1] == values.shape[0]`` -- total tokens
|
|
707
|
+
against batch size, which fails at EVERY batch size. Measured on four matched real-gpu arms, all
|
|
708
|
+
four dead at ``padding.py:144``.
|
|
709
|
+
|
|
710
|
+
So the run cannot finish, and the failure names neither gdn nor this decision -- letting it
|
|
711
|
+
launch spends the full gpu rental on an untraceable shape error. Raise here instead. Dropping
|
|
712
|
+
``use_fused_kernels`` is NOT the alternative fix: ``engine/vram.py:386-392`` sizes on the
|
|
713
|
+
assumption that no dense ``[b, s, vocab]`` logits tensor exists (~130 GB at 32k on a 248k
|
|
714
|
+
vocab), so that would trade this crash for an OOM. The fix is to give the child the kernels.
|
|
715
|
+
|
|
716
|
+
SFT is deliberately not a caller. It reaches the same padded+fused branch but is safe without
|
|
717
|
+
resets for a different reason: every gdn model profiles as exact-unpacked, which pins
|
|
718
|
+
``examples_per_update`` to 1 (``sft_workload.py:410``), so there are no packed neighbours to
|
|
719
|
+
contaminate -- and its remove-padding flag stays on regardless, because that is the only tensor
|
|
720
|
+
layout ``FlashTokenizedSFTDataset`` fits. Grpo and opd have no such profile: their batch size is
|
|
721
|
+
the user's ``prompts_per_step``, routinely greater than 1, so they genuinely pack.
|
|
722
|
+
"""
|
|
723
|
+
if not gdn_module:
|
|
724
|
+
return None
|
|
725
|
+
arch = gdn_reset_arch_from_caps(caps, gdn_module)
|
|
726
|
+
if arch is None:
|
|
727
|
+
raise RuntimeError(
|
|
728
|
+
"gdn hybrid without child-side boundary resets: the padded fallback "
|
|
729
|
+
"(use_remove_padding=False) is incompatible with the use_fused_kernels=True this "
|
|
730
|
+
"recipe sets, and cannot complete a training step on verl's fsdp engine. see the "
|
|
731
|
+
"'[verl] gdn boundary resets unavailable' line above for why the child could not "
|
|
732
|
+
"honor resets -- installing fla + causal_conv1d in the verl interpreter is the fix, "
|
|
733
|
+
"not disabling fused kernels."
|
|
734
|
+
)
|
|
735
|
+
return arch
|
|
736
|
+
|
|
737
|
+
|
|
612
738
|
def resolve_verl_python(workdir: str, *, install_wandb: bool = False) -> str:
|
|
613
739
|
"""return an interpreter that can import verl.
|
|
614
740
|
|
|
@@ -38,7 +38,6 @@ from flash.engine.worker.backend_common import (
|
|
|
38
38
|
agent_loop_workers,
|
|
39
39
|
clamp_engine_len,
|
|
40
40
|
gdn_probe_module,
|
|
41
|
-
gdn_reset_arch_from_caps,
|
|
42
41
|
latest_global_step_dir,
|
|
43
42
|
model_max_position_embeddings,
|
|
44
43
|
parse_verl_metric,
|
|
@@ -48,6 +47,7 @@ from flash.engine.worker.backend_common import (
|
|
|
48
47
|
render_gdn_varlen_shim,
|
|
49
48
|
render_tf32_shim,
|
|
50
49
|
render_wandb_link_shim,
|
|
50
|
+
require_gdn_boundary_resets,
|
|
51
51
|
resolve_blackwell_attention_backends,
|
|
52
52
|
resolve_rollout_enforce_eager,
|
|
53
53
|
resolve_verl_loggers,
|
|
@@ -1551,9 +1551,10 @@ def build_opd_overrides(config: dict) -> list[str]:
|
|
|
1551
1551
|
f"actor_rollout_ref.model.path={_hydra_val(config['model_path'])}",
|
|
1552
1552
|
"actor_rollout_ref.model.trust_remote_code=true",
|
|
1553
1553
|
# packing the micro-batch into one row is only safe for a gdn hybrid when the child can
|
|
1554
|
-
# reset linear-attention state at the example boundaries
|
|
1555
|
-
|
|
1556
|
-
|
|
1554
|
+
# reset linear-attention state at the example boundaries -- and the caller's gdn gate now
|
|
1555
|
+
# RAISES when it cannot, because the padded alternative cannot complete a step alongside the
|
|
1556
|
+
# fused kernels below. always true by the time we get here.
|
|
1557
|
+
"actor_rollout_ref.model.use_remove_padding=true",
|
|
1557
1558
|
# 32k contexts: the fused linear-CE forward computes per-token log_probs from hidden states
|
|
1558
1559
|
# + lm_head in chunks (FusedLinearForPPO), never materializing the [tokens, vocab] logits
|
|
1559
1560
|
# tensor (~130 GB at 32k on a 248k vocab). the distillation loss consumes exactly
|
|
@@ -2480,15 +2481,11 @@ def run_opd_train(spec=None) -> None:
|
|
|
2480
2481
|
|
|
2481
2482
|
# a gdn hybrid may only pack when the CHILD can honor seq_idx + cu_seqlens; the no-fla fallbacks
|
|
2482
2483
|
# accept both and discard them, which silently bleeds state across packed example boundaries.
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
"[opd] gdn hybrid without child-side boundary resets: disabling remove-padding so "
|
|
2489
|
-
"packed examples cannot contaminate each other (slower, correct)",
|
|
2490
|
-
flush=True,
|
|
2491
|
-
)
|
|
2484
|
+
# raises when the child cannot -- opd reaches no_padding_2_padding through
|
|
2485
|
+
# trainer/distillation/losses.py exactly as grpo reaches it through ray_trainer, so the padded
|
|
2486
|
+
# fallback that used to handle this cannot complete a step either. see
|
|
2487
|
+
# require_gdn_boundary_resets.
|
|
2488
|
+
gdn_reset_arch = require_gdn_boundary_resets(caps, gdn_module)
|
|
2492
2489
|
|
|
2493
2490
|
# sm86's vllm 0.19.1 graph capture degenerates, so only that arch runs the rollout eagerly. grpo
|
|
2494
2491
|
# has resolved this since the trl driver; opd never did, and opd is the MORE exposed of the two
|
|
@@ -2581,7 +2578,6 @@ def run_opd_train(spec=None) -> None:
|
|
|
2581
2578
|
bridge.start()
|
|
2582
2579
|
try:
|
|
2583
2580
|
config = {
|
|
2584
|
-
"use_remove_padding": use_remove_padding,
|
|
2585
2581
|
"train_files": [train_file],
|
|
2586
2582
|
"val_files": [val_file],
|
|
2587
2583
|
"train_batch_size": prompts_per_step,
|
|
@@ -2912,7 +2908,7 @@ def run_opd_train(spec=None) -> None:
|
|
|
2912
2908
|
# whether it packed with resets or took the padded fallback. for a gate whose failure
|
|
2913
2909
|
# mode is silent contamination that is the one thing worth recording. None for a
|
|
2914
2910
|
# non-gdn model, where the question does not arise.
|
|
2915
|
-
"gdn_boundary_resets":
|
|
2911
|
+
"gdn_boundary_resets": gdn_hybrid or None,
|
|
2916
2912
|
"peak_gpu_gb": peak_gpu_gb,
|
|
2917
2913
|
"warm_started": bool(warmstart_adapter),
|
|
2918
2914
|
"resumed": bool(resume_step),
|
{freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/lifecycle.py
RENAMED
|
@@ -10,6 +10,14 @@ _CUDA_OOM_PREFLIGHT_RE = re.compile(
|
|
|
10
10
|
r"free memory on device\s+cuda:\d+.*less than desired gpu memory utilization"
|
|
11
11
|
)
|
|
12
12
|
_CUDA_OOM_CACHE_BLOCKS = "no available memory for the cache blocks"
|
|
13
|
+
# torch's own allocator OOM, which the two vllm STARTUP signatures above do not cover. the parent
|
|
14
|
+
# classifies an in-process OOM off `torch.cuda.OutOfMemoryError` and the allocator counter, but a
|
|
15
|
+
# verl child is a separate process: neither the exception type nor its `num_ooms` crosses, and the
|
|
16
|
+
# terminal raise carries only "subprocess exited with status N". without this the one OOM shape that
|
|
17
|
+
# happens DURING training reads as a permanent job_failed, so the lifecycle never retries it on a
|
|
18
|
+
# larger gpu. anchored on torch's exact wording rather than a bare "out of memory", which a host-ram
|
|
19
|
+
# OOM or an env's own error text would also match -- and those must not escalate the gpu.
|
|
20
|
+
_CUDA_OOM_TORCH_RE = re.compile(r"(?:torch\.)?(?:cuda\.)?outofmemoryerror|cuda out of memory")
|
|
13
21
|
|
|
14
22
|
|
|
15
23
|
class RetriableInfraError(RuntimeError):
|
|
@@ -42,6 +50,9 @@ def cuda_oom_message_evidence(message: str) -> str | None:
|
|
|
42
50
|
return preflight.group(0)
|
|
43
51
|
if _CUDA_OOM_CACHE_BLOCKS in normalized:
|
|
44
52
|
return _CUDA_OOM_CACHE_BLOCKS
|
|
53
|
+
torch_oom = _CUDA_OOM_TORCH_RE.search(normalized)
|
|
54
|
+
if torch_oom is not None:
|
|
55
|
+
return torch_oom.group(0)
|
|
45
56
|
return None
|
|
46
57
|
|
|
47
58
|
|
|
@@ -60,7 +60,6 @@ from flash.engine.worker.backend_common import (
|
|
|
60
60
|
clamp_engine_len,
|
|
61
61
|
export_peft_adapter,
|
|
62
62
|
gdn_probe_module,
|
|
63
|
-
gdn_reset_arch_from_caps,
|
|
64
63
|
kill_process_group,
|
|
65
64
|
latest_global_step_dir,
|
|
66
65
|
model_max_position_embeddings,
|
|
@@ -74,6 +73,7 @@ from flash.engine.worker.backend_common import (
|
|
|
74
73
|
render_gdn_varlen_shim,
|
|
75
74
|
render_tf32_shim,
|
|
76
75
|
render_wandb_link_shim,
|
|
76
|
+
require_gdn_boundary_resets,
|
|
77
77
|
resolve_blackwell_attention_backends,
|
|
78
78
|
resolve_rollout_enforce_eager,
|
|
79
79
|
resolve_verl_loggers,
|
|
@@ -387,8 +387,10 @@ def build_verl_overrides(cfg: dict) -> list[str]:
|
|
|
387
387
|
# chunks (FusedLinearForPPO), never materializing the [tokens, vocab] logits tensor
|
|
388
388
|
# (~130 GB at 32k on a 248k vocab). torch backend = numerically exact, no extra deps.
|
|
389
389
|
# packing the micro-batch into one row is only boundary-safe for a gdn hybrid when the child
|
|
390
|
-
# can honor seq_idx + cu_seqlens
|
|
391
|
-
|
|
390
|
+
# can honor seq_idx + cu_seqlens -- and run_rl_train now RAISES when it cannot, because the
|
|
391
|
+
# padded alternative cannot complete a step alongside the fused kernels below. so this is
|
|
392
|
+
# always true by the time we get here; there is no longer a configuration that turns it off.
|
|
393
|
+
"actor_rollout_ref.model.use_remove_padding=True",
|
|
392
394
|
"actor_rollout_ref.model.use_fused_kernels=True",
|
|
393
395
|
"actor_rollout_ref.model.fused_kernel_options.impl_backend=torch",
|
|
394
396
|
*(
|
|
@@ -665,12 +667,10 @@ def _build_verl_training_cfg(
|
|
|
665
667
|
experiment_name: str,
|
|
666
668
|
gpu_type: str = "",
|
|
667
669
|
n_gpus: int = 1,
|
|
668
|
-
use_remove_padding: bool = True,
|
|
669
670
|
) -> dict:
|
|
670
671
|
engine_len = int(inp["engine_len"])
|
|
671
672
|
sleep_unsupported = rollout_sleep_unsupported(inp["model_id"])
|
|
672
673
|
return {
|
|
673
|
-
"use_remove_padding": use_remove_padding,
|
|
674
674
|
"train_files": train_files,
|
|
675
675
|
"val_files": val_files,
|
|
676
676
|
"model_id": model_id,
|
|
@@ -3470,18 +3470,12 @@ def run_rl_train():
|
|
|
3470
3470
|
# the shim is appended here rather than with the shims above because the answer needs
|
|
3471
3471
|
# python_bin, resolved in the block above; sitecustomize is imported by the child, which has
|
|
3472
3472
|
# not started yet.
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3473
|
+
# raises when a gdn child cannot honor resets: the padded fallback that used to handle that
|
|
3474
|
+
# case cannot complete a step on verl's fsdp engine. see require_gdn_boundary_resets.
|
|
3475
|
+
gdn_reset_arch = require_gdn_boundary_resets(caps, gdn_module)
|
|
3476
3476
|
if gdn_reset_arch is not None:
|
|
3477
3477
|
with open(shim_py, "a") as f:
|
|
3478
3478
|
f.write(render_gdn_varlen_shim(gdn_reset_arch))
|
|
3479
|
-
elif gdn_hybrid:
|
|
3480
|
-
print(
|
|
3481
|
-
"[grpo] gdn hybrid without child-side boundary resets: disabling remove-padding so "
|
|
3482
|
-
"packed examples cannot contaminate each other (slower, correct)",
|
|
3483
|
-
flush=True,
|
|
3484
|
-
)
|
|
3485
3479
|
|
|
3486
3480
|
expected_steps = int(inp["steps"])
|
|
3487
3481
|
# verl logs from its own interpreter; gate wandb on that env (see resolve_verl_loggers).
|
|
@@ -3500,9 +3494,7 @@ def run_rl_train():
|
|
|
3500
3494
|
)
|
|
3501
3495
|
except Exception: # no cuda / probe failure -> conservative bf16 kv
|
|
3502
3496
|
_cc_ok = False
|
|
3503
|
-
# reuse the gdn answer resolved above rather than re-probing
|
|
3504
|
-
# False when its own probe raises, so a second call can disagree with the first and turn
|
|
3505
|
-
# fp8 kv ON for the very hybrid the comment above says it crashes.
|
|
3497
|
+
# reuse the gdn answer resolved above rather than re-probing; see gdn_hybrid.
|
|
3506
3498
|
fp8_kv = _cc_ok and not gdn_hybrid
|
|
3507
3499
|
# one capability probe, both rollout decisions below. asked of the verl interpreter, whose
|
|
3508
3500
|
# torch/vllm stack is the one that has to run the rollout.
|
|
@@ -3528,7 +3520,6 @@ def run_rl_train():
|
|
|
3528
3520
|
enforce_eager=enforce_eager,
|
|
3529
3521
|
attention_backend=attention_backend,
|
|
3530
3522
|
mm_encoder_attn_backend=mm_encoder_attn_backend,
|
|
3531
|
-
use_remove_padding=use_remove_padding,
|
|
3532
3523
|
reward_path=reward_py,
|
|
3533
3524
|
local_dir=local_dir,
|
|
3534
3525
|
project_name=project_name,
|
|
@@ -3865,6 +3856,6 @@ def run_rl_train():
|
|
|
3865
3856
|
reward_profile=reward_profile,
|
|
3866
3857
|
step_intervals=_step_intervals(step_line_times),
|
|
3867
3858
|
reward_bridge_batching=not inp["multi_turn"],
|
|
3868
|
-
gdn_boundary_resets=
|
|
3859
|
+
gdn_boundary_resets=gdn_hybrid or None,
|
|
3869
3860
|
),
|
|
3870
3861
|
)
|
|
@@ -558,13 +558,31 @@ def _projected_retry_class(
|
|
|
558
558
|
)
|
|
559
559
|
|
|
560
560
|
|
|
561
|
-
def
|
|
561
|
+
def _candidate_usable_vram_gb(candidate) -> float:
|
|
562
|
+
"""Run-usable VRAM for a candidate, under the same fit model the allocator selected it with.
|
|
563
|
+
|
|
564
|
+
`combined_vram_gb` is documented as THE single fit model, and every sizing path calls it. The raw
|
|
565
|
+
`gpu_count * vram_gb` product is NOT interchangeable with it for a sharded shape: it ignores the
|
|
566
|
+
replicated-per-card floor and the shard efficiency, so it overstates a multi-card box. Comparing
|
|
567
|
+
the two measures is what let an OOM retry move SIDEWAYS or DOWNWARDS -- 2x80 raw-counts as 160 GB
|
|
568
|
+
against a 141 GB single card that just OOM'd, but the allocator models that pair as 130.4 GB
|
|
569
|
+
usable, i.e. smaller than the shape that already failed.
|
|
570
|
+
"""
|
|
571
|
+
from flash.providers.base import combined_vram_gb
|
|
572
|
+
|
|
573
|
+
return combined_vram_gb(candidate.vram_gb, int(getattr(candidate, "gpu_count", 1) or 1))
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def _oom_escalated(candidates, oom_vram_floor: float):
|
|
562
577
|
"""Candidates strictly LARGER than the VRAM that just OOM'd. ``oom_vram_floor == 0`` (no prior OOM)
|
|
563
578
|
leaves the list unchanged; otherwise an 80GB OOM leaves only the >80GB classes (a same-size retry
|
|
564
|
-
would just OOM again). EMPTY means the run already OOM'd the largest available class.
|
|
579
|
+
would just OOM again). EMPTY means the run already OOM'd the largest available class.
|
|
580
|
+
|
|
581
|
+
Both sides are measured with `_candidate_usable_vram_gb`, and the floor recorded on OOM uses it
|
|
582
|
+
too -- the filter is only meaningful if the floor and the candidates are on one scale."""
|
|
565
583
|
if not oom_vram_floor:
|
|
566
584
|
return list(candidates)
|
|
567
|
-
return [c for c in candidates if
|
|
585
|
+
return [c for c in candidates if _candidate_usable_vram_gb(c) > oom_vram_floor]
|
|
568
586
|
|
|
569
587
|
|
|
570
588
|
def _await_runpod_completed_metrics(
|
|
@@ -743,7 +761,7 @@ def _submit_seed_supervised(
|
|
|
743
761
|
# Grow only when an attempt actually provisioned a class and lost it to infra.
|
|
744
762
|
failed_providers: set[str] = set()
|
|
745
763
|
tried_classes: set[tuple[str, str, int]] = set()
|
|
746
|
-
oom_vram_floor = 0
|
|
764
|
+
oom_vram_floor = 0.0
|
|
747
765
|
# Pin the environment ref ONCE, here, before any attempt runs -- not per attempt. Submit's pin
|
|
748
766
|
# is best-effort, so a GitHub blip there leaves resolved_sha empty, and a managed slug points at
|
|
749
767
|
# environment-hub@main, which moves. attempt_start > 0 means a previous invocation already ran an
|
|
@@ -906,9 +924,9 @@ def _submit_seed_supervised(
|
|
|
906
924
|
raise _cancel()
|
|
907
925
|
cands = _oom_escalated(alloc.candidates, oom_vram_floor)
|
|
908
926
|
if not cands:
|
|
909
|
-
last_detail = f"oom: exceeded the largest available GPU ({oom_vram_floor} GB)"
|
|
927
|
+
last_detail = f"oom: exceeded the largest available GPU ({oom_vram_floor:g} GB)"
|
|
910
928
|
print(
|
|
911
|
-
f"seed={seed} OOM on the largest GPU class ({oom_vram_floor} GB); not retrying",
|
|
929
|
+
f"seed={seed} OOM on the largest GPU class ({oom_vram_floor:g} GB); not retrying",
|
|
912
930
|
file=log,
|
|
913
931
|
flush=True,
|
|
914
932
|
)
|
|
@@ -1112,7 +1130,8 @@ def _submit_seed_supervised(
|
|
|
1112
1130
|
last_detail = f"{res.failure}: {res.detail}"
|
|
1113
1131
|
oom_shaped = res.failure == "oom"
|
|
1114
1132
|
if oom_shaped and chosen is not None:
|
|
1115
|
-
|
|
1133
|
+
# same measure the filter compares against, see _candidate_usable_vram_gb
|
|
1134
|
+
oom_vram_floor = max(oom_vram_floor, _candidate_usable_vram_gb(chosen))
|
|
1116
1135
|
run_had_cache = bool(
|
|
1117
1136
|
chosen is not None
|
|
1118
1137
|
and getattr(get_provider(chosen.provider), "supports_weight_cache", False)
|
|
@@ -1166,7 +1185,7 @@ def _submit_seed_supervised(
|
|
|
1166
1185
|
else:
|
|
1167
1186
|
retry_target = "retrying (resume from last checkpoint)"
|
|
1168
1187
|
action = (
|
|
1169
|
-
f"retrying on a larger GPU (> {oom_vram_floor} GB)"
|
|
1188
|
+
f"retrying on a larger GPU (> {oom_vram_floor:g} GB)"
|
|
1170
1189
|
if (will_retry and oom_mode)
|
|
1171
1190
|
else retry_target
|
|
1172
1191
|
if will_retry
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.99"
|
|
4
4
|
description = "Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
# RunPod Flash supports Python 3.11-3.12 (not 3.13 yet).
|
|
@@ -121,7 +121,7 @@ artifacts = ["flash/py.typed"]
|
|
|
121
121
|
# auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
|
|
122
122
|
# PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
|
|
123
123
|
# dev-channel release = bump this (and [project].version) and merge to `dev`.
|
|
124
|
-
version = "1.0.
|
|
124
|
+
version = "1.0.99"
|
|
125
125
|
|
|
126
126
|
[tool.pytest.ini_options]
|
|
127
127
|
pythonpath = ["."]
|