freesolo-flash-dev 1.2.89__tar.gz → 1.2.94__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.89 → freesolo_flash_dev-1.2.94}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/__init__.py +11 -24
- freesolo_flash_dev-1.2.94/flash/cli/commands/worker_output.py +67 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/heartbeat.py +27 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/render.py +1 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/kv_sizing.py +20 -8
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/opd_train.py +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/opd_train_runner.py +5 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/verl_config.py +17 -8
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/poll.py +3 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/runtime.py +4 -3
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_commands.py +54 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_render_theme.py +24 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_jobs.py +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_train.py +32 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_resume_on_retry.py +4 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_rl_train.py +67 -16
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_api.py +49 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/uv.lock +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.env.example +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/dev-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/production-kernel-cache-ready.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/README.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/adapters/targets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/setup_wandb.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/image_descriptors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/grpo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/huggingface.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/sft_image_rows.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/multiturn_media.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/verl/process_census.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/direct_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/envs/staged.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/provider_status.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_rollout_identity_actor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/capture_image_sft_processor_oracle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/fixtures/image_sft_processor_oracle.json +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/fixtures/qwen35_08b_target_metadata.json +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_process_census.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_rollout_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_grpo_rollout_identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_environment_capability.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_incremental_processor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_sft_markers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_sft_processor_parity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_nested_rung.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_targeting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_lora_targeting_pinned_verl.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_source_attestation_flow.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_staged_environment.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_warmstart_image_adapters.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/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.94
|
|
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
|
|
@@ -470,16 +470,10 @@ def _log_follow_progress(status: dict | None, fallback_state: str) -> tuple[str,
|
|
|
470
470
|
parts = [state]
|
|
471
471
|
heartbeat = status.get("last_heartbeat") if isinstance(status, dict) else None
|
|
472
472
|
# retries rewind steps while state remains running, so surface the 0-based attempt identity.
|
|
473
|
-
#
|
|
474
|
-
#
|
|
475
|
-
#
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
remote = status.get("remote")
|
|
479
|
-
remote_cleared = "remote" in status and remote is None
|
|
480
|
-
attempt = _attempt_int(remote.get("attempt")) if isinstance(remote, dict) else None
|
|
481
|
-
if attempt is None and not remote_cleared and isinstance(heartbeat, dict):
|
|
482
|
-
attempt = _attempt_int(heartbeat.get("attempt"))
|
|
473
|
+
# `live_attempt` owns the provenance order (live `remote.attempt` first, heartbeat only when
|
|
474
|
+
# `remote` is absent rather than cleared at teardown) and is shared with the worker-artifact
|
|
475
|
+
# labelling below, so the spinner and the appended sections name the same current attempt.
|
|
476
|
+
attempt = render.live_attempt(status)
|
|
483
477
|
if isinstance(heartbeat, dict):
|
|
484
478
|
heartbeat_age_seconds = render._heartbeat_age_seconds(heartbeat.get("ts"))
|
|
485
479
|
# stage and step come from the heartbeat, attempt from `remote` below. during the relaunch
|
|
@@ -712,20 +706,6 @@ def _follow_status(
|
|
|
712
706
|
return 130
|
|
713
707
|
|
|
714
708
|
|
|
715
|
-
def _print_worker_output(client: ApiClient, run_id: str, *, printed_any: bool = False) -> bool:
|
|
716
|
-
for name, text in (client.get_worker_output(run_id) or {}).items():
|
|
717
|
-
if not text:
|
|
718
|
-
continue
|
|
719
|
-
sep = "\n" if printed_any else ""
|
|
720
|
-
if render.styled():
|
|
721
|
-
print(f"{sep}{render.log_section(name)}")
|
|
722
|
-
else:
|
|
723
|
-
print(f"{sep}----- {name} -----")
|
|
724
|
-
print(text, end="" if text.endswith("\n") else "\n")
|
|
725
|
-
printed_any = True
|
|
726
|
-
return printed_any
|
|
727
|
-
|
|
728
|
-
|
|
729
709
|
def cmd_log(args) -> int:
|
|
730
710
|
client = client_from_config()
|
|
731
711
|
if getattr(args, "follow", False):
|
|
@@ -980,3 +960,10 @@ from flash.cli.commands.train_cost import ( # noqa: E402,F401
|
|
|
980
960
|
_sft_cost_rows,
|
|
981
961
|
_warn_if_wandb_requested_without_key,
|
|
982
962
|
)
|
|
963
|
+
|
|
964
|
+
# re-exported so `commands._print_worker_output(...)` keeps resolving for `cmd_log` and the CLI tests.
|
|
965
|
+
from flash.cli.commands.worker_output import ( # noqa: E402,F401
|
|
966
|
+
_artifact_attempt,
|
|
967
|
+
_print_worker_output,
|
|
968
|
+
_worker_section_name,
|
|
969
|
+
)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Printing the worker-uploaded text artifacts that `flash runs log` appends to a run log.
|
|
2
|
+
|
|
3
|
+
These sections are NOT part of the chronological log. `cmd_log` prints the control-plane log first
|
|
4
|
+
and appends these afterwards, so they always land at the tail no matter how old they are -- and the
|
|
5
|
+
plane returns the highest UPLOADED attempt, which during a retry is the attempt that just died, not
|
|
6
|
+
the one now running. Read without a label, the last thing on screen is a traceback from a worker
|
|
7
|
+
that has already been replaced.
|
|
8
|
+
|
|
9
|
+
So the job here is provenance: say which attempt produced each section, and say when that attempt is
|
|
10
|
+
not the live one. The old output is kept rather than hidden because it carries the failure that
|
|
11
|
+
explains why a retry exists at all.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
|
+
|
|
19
|
+
from flash.cli.ui import render
|
|
20
|
+
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from flash.client import ApiClient
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _artifact_attempt(name: str) -> int | None:
|
|
26
|
+
"""Return the bounded attempt encoded by a worker artifact name."""
|
|
27
|
+
from flash.providers._lifecycle.poll import _attempt_int
|
|
28
|
+
|
|
29
|
+
match = re.search(r"_attempt(\d+)\.txt$", name)
|
|
30
|
+
return _attempt_int(int(match.group(1))) if match else None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _worker_section_name(name: str, current_attempt: int | None) -> str:
|
|
34
|
+
"""Label an attempt-scoped artifact and identify superseded output."""
|
|
35
|
+
attempt = _artifact_attempt(name)
|
|
36
|
+
if attempt is None:
|
|
37
|
+
return name
|
|
38
|
+
if current_attempt is None:
|
|
39
|
+
return f"{name} (attempt={attempt})"
|
|
40
|
+
if attempt != current_attempt:
|
|
41
|
+
return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
|
|
42
|
+
return f"{name} (attempt={attempt}, current attempt)"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _print_worker_output(client: ApiClient, run_id: str, *, printed_any: bool = False) -> bool:
|
|
46
|
+
worker_output = client.get_worker_output(run_id) or {}
|
|
47
|
+
if not worker_output:
|
|
48
|
+
return printed_any
|
|
49
|
+
try:
|
|
50
|
+
current_attempt = render.live_attempt(client.get_run(run_id) or {})
|
|
51
|
+
except Exception:
|
|
52
|
+
# artifact text is best-effort diagnostic output; a status refresh failure must not hide it.
|
|
53
|
+
current_attempt = None
|
|
54
|
+
for name, text in worker_output.items():
|
|
55
|
+
if not text:
|
|
56
|
+
continue
|
|
57
|
+
# label provenance from the filename rather than letting the final section, which is merely
|
|
58
|
+
# the last one appended, read as the live attempt's output.
|
|
59
|
+
section_name = _worker_section_name(name, current_attempt)
|
|
60
|
+
sep = "\n" if printed_any else ""
|
|
61
|
+
if render.styled():
|
|
62
|
+
print(f"{sep}{render.log_section(section_name)}")
|
|
63
|
+
else:
|
|
64
|
+
print(f"{sep}----- {section_name} -----")
|
|
65
|
+
print(text, end="" if text.endswith("\n") else "\n")
|
|
66
|
+
printed_any = True
|
|
67
|
+
return printed_any
|
|
@@ -43,6 +43,33 @@ _WARMUP_HEARTBEAT_FRESH_FOR_S = 1200.0
|
|
|
43
43
|
_WARMUP_STAGES = frozenset({"rl_train_start", "rl_initializing"})
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def live_attempt(obj: dict) -> int | None:
|
|
47
|
+
"""The attempt a status payload says is live, or None when it cannot be established.
|
|
48
|
+
|
|
49
|
+
`remote.attempt` is the plane's live attempt. It is preferred over `last_heartbeat.attempt`,
|
|
50
|
+
which is whichever worker produced the ping and may already be superseded. The heartbeat is a
|
|
51
|
+
fallback only when `remote` is ABSENT: an explicitly null `remote` is the teardown window, where
|
|
52
|
+
the attached ping belongs to a worker that is already gone, so falling back there would report a
|
|
53
|
+
dead attempt as the live one.
|
|
54
|
+
|
|
55
|
+
Shared so the status line, the log-follow spinner, and worker-artifact labelling cannot disagree
|
|
56
|
+
about which attempt is current -- three surfaces that a user reads within one screen of each
|
|
57
|
+
other, where a disagreement reads as a run that is on two attempts at once.
|
|
58
|
+
"""
|
|
59
|
+
from flash.providers._lifecycle.poll import _attempt_int
|
|
60
|
+
|
|
61
|
+
remote = obj.get("remote")
|
|
62
|
+
if isinstance(remote, dict):
|
|
63
|
+
attempt = _attempt_int(remote.get("attempt"))
|
|
64
|
+
if attempt is not None:
|
|
65
|
+
return attempt
|
|
66
|
+
elif "remote" in obj:
|
|
67
|
+
# explicitly null: the teardown window. the ping is the dead worker's, so there is no answer.
|
|
68
|
+
return None
|
|
69
|
+
heartbeat = obj.get("last_heartbeat")
|
|
70
|
+
return _attempt_int(heartbeat.get("attempt")) if isinstance(heartbeat, dict) else None
|
|
71
|
+
|
|
72
|
+
|
|
46
73
|
def heartbeat_is_current_attempt(obj: dict, heartbeat: dict) -> bool:
|
|
47
74
|
"""False only when the heartbeat provably belongs to a superseded retry attempt.
|
|
48
75
|
|
|
@@ -19,6 +19,10 @@ _KV_BLOCK_TOKENS = 16
|
|
|
19
19
|
# floor remains authoritative at short context; longer contexts retain 1.5 gb plus 25% fragmentation.
|
|
20
20
|
_KV_PROFILE_OVERHEAD_GB = 1.5
|
|
21
21
|
_KV_FRAGMENTATION_MARGIN = 1.25
|
|
22
|
+
# the smallest share of a card vllm is given. below this the engine has no room for its own runtime
|
|
23
|
+
# once the kv pool is carved out, so a budget that prices under it is not a smaller engine but a
|
|
24
|
+
# broken one. the legacy equation and the multi-rank shard path both bottom out here.
|
|
25
|
+
_MIN_ENGINE_UTIL = 0.10
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
def _round_up(value: int, multiple: int) -> int:
|
|
@@ -138,15 +142,18 @@ def colocate_kv_util(
|
|
|
138
142
|
fp8_kv: bool = False,
|
|
139
143
|
model_info=None,
|
|
140
144
|
preserve_legacy_floor: bool = False,
|
|
145
|
+
tensor_parallel: int = 1,
|
|
141
146
|
) -> float:
|
|
142
|
-
"""vllm_gpu_memory_utilization for
|
|
147
|
+
"""vllm_gpu_memory_utilization for one colocated rollout tensor-parallel rank.
|
|
143
148
|
|
|
144
|
-
Budget
|
|
145
|
-
and an 8 GB floor; uncataloged models retain the
|
|
149
|
+
Budget the rank's weight shard plus a conservative full KV cache. Catalog models use geometry
|
|
150
|
+
with measured overhead and an 8 GB floor; uncataloged models retain the legacy KV equation.
|
|
146
151
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
total_weights_gb = max(0.5, float(params_b or 1.0)) * 2.0
|
|
153
|
+
tp_size = max(1, int(tensor_parallel))
|
|
154
|
+
# tensor parallelism shards vllm's bf16 weights, but kv heads can replicate when tp is wider than
|
|
155
|
+
# the model's kv-head count. shard only the weight term and keep the full kv budget on every rank.
|
|
156
|
+
weights_gb = total_weights_gb if tp_size == 1 else total_weights_gb / tp_size
|
|
150
157
|
# catalog geometry is authoritative. active params remain only for the uncataloged fallback, while
|
|
151
158
|
# the weight copy always uses total parameters.
|
|
152
159
|
kv_params_b = float(active_params_b) if active_params_b else params_b
|
|
@@ -169,7 +176,7 @@ def colocate_kv_util(
|
|
|
169
176
|
preserve_legacy_floor=preserve_legacy_floor,
|
|
170
177
|
),
|
|
171
178
|
)
|
|
172
|
-
return max(
|
|
179
|
+
return max(_MIN_ENGINE_UTIL, min(_util_cap, (weights_gb + kv_gb) / max(1.0, total_vram_gb)))
|
|
173
180
|
# Sleep mode keeps a larger pool (1.5x margin): the engine is offloaded during the backward, so a
|
|
174
181
|
# bigger rollout-phase KV does not compete with the training peak.
|
|
175
182
|
kv_pool_gb = max(
|
|
@@ -184,4 +191,9 @@ def colocate_kv_util(
|
|
|
184
191
|
preserve_legacy_floor=preserve_legacy_floor,
|
|
185
192
|
),
|
|
186
193
|
)
|
|
187
|
-
|
|
194
|
+
sized = min(_util_cap, (weights_gb + kv_pool_gb) / max(1.0, total_vram_gb))
|
|
195
|
+
# sharding the weight term can drive a small model's rank budget low enough that vllm has no
|
|
196
|
+
# room left for its own runtime once the kv pool is carved out -- a 4B model on 2 cards prices
|
|
197
|
+
# under this floor. single-rank sizing carries the whole weight copy and never gets that small,
|
|
198
|
+
# so the floor exists only where sharding created the problem.
|
|
199
|
+
return max(_MIN_ENGINE_UTIL, sized) if tp_size > 1 else sized
|
|
@@ -374,7 +374,7 @@ def run_opd_train(spec=None) -> None:
|
|
|
374
374
|
# and on an image run that fan-out exhausted the grpo worker container's threads.
|
|
375
375
|
"multimodal": bool(multimodal),
|
|
376
376
|
"gpu_mem_util": _resolve_opd_gpu_mem_util(
|
|
377
|
-
request, prompt_state, runtime, model_id, fp8_kv
|
|
377
|
+
request, prompt_state, workload, runtime, model_id, fp8_kv
|
|
378
378
|
),
|
|
379
379
|
"loggers": runtime.loggers,
|
|
380
380
|
# resolved from the out-of-process capability probe, never by opening cuda in this parent -- see fused_ce_backend.
|
{freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/opd_train_runner.py
RENAMED
|
@@ -535,6 +535,7 @@ def _spec_gpu_type(spec: Any) -> str:
|
|
|
535
535
|
def _resolve_opd_gpu_mem_util(
|
|
536
536
|
request: _OpdRequest,
|
|
537
537
|
prompt_state: _PromptState,
|
|
538
|
+
workload: _WorkloadState,
|
|
538
539
|
runtime: _RuntimeState,
|
|
539
540
|
model_id: str,
|
|
540
541
|
fp8_kv: bool,
|
|
@@ -559,12 +560,15 @@ def _resolve_opd_gpu_mem_util(
|
|
|
559
560
|
"model_id": model_id,
|
|
560
561
|
"model_revision": str(getattr(request, "model_revision", "") or ""),
|
|
561
562
|
"engine_len": int(prompt_state.max_model_len),
|
|
562
|
-
|
|
563
|
+
# opd submits prompts_per_step * group_size generations to the rollout engine together.
|
|
564
|
+
# grpo's concurrency is group_size because its resolver receives one prompt group here.
|
|
565
|
+
"group_size": int(workload.prompts_per_step) * int(request.knobs.group_size),
|
|
563
566
|
},
|
|
564
567
|
gpu_type=_spec_gpu_type(getattr(request, "spec", None)),
|
|
565
568
|
n_gpus=int(runtime.gpu_count),
|
|
566
569
|
fp8_kv=bool(fp8_kv),
|
|
567
570
|
sleep_unsupported=rollout_sleep_unsupported(model_id),
|
|
571
|
+
preserve_legacy_floor=True,
|
|
568
572
|
)
|
|
569
573
|
|
|
570
574
|
|
{freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.94}/flash/engine/worker/train/rl/verl_config.py
RENAMED
|
@@ -499,24 +499,28 @@ def resolve_gpu_mem_util(
|
|
|
499
499
|
n_gpus: int,
|
|
500
500
|
fp8_kv: bool,
|
|
501
501
|
sleep_unsupported: bool,
|
|
502
|
+
preserve_legacy_floor: bool = False,
|
|
502
503
|
) -> float:
|
|
503
504
|
"""size vllm's colocated executor budget from this run's geometry.
|
|
504
505
|
|
|
505
506
|
``gpu_memory_utilization`` covers the second bf16 weight copy plus kv pool. using
|
|
506
507
|
``colocate_kv_util`` keeps worker allocation aligned with preflight admission.
|
|
507
508
|
|
|
508
|
-
|
|
509
|
+
for multi-gpu runs, vllm shards its bf16 weight copy across tensor-parallel ranks. the kv term
|
|
510
|
+
remains unsharded here because vllm can replicate kv heads when tensor parallelism is wider than
|
|
511
|
+
the model's kv-head count. the result is explicitly capped at the old 0.5 constant, so this path
|
|
512
|
+
can only lower a rank's reservation and cannot create a new over-reservation.
|
|
513
|
+
|
|
514
|
+
the flat constant is kept where the model does not apply, because a wrong number is worse than
|
|
509
515
|
a conservative one:
|
|
510
516
|
|
|
511
|
-
-
|
|
517
|
+
- unknown card (empty/unmanaged ``gpu.type``): the budget is a fraction of the card, so without
|
|
512
518
|
its size there is nothing to take a fraction of.
|
|
513
|
-
-
|
|
514
|
-
ACROSS cards while ``colocate_kv_util`` sizes one whole copy against one card. a single-card
|
|
515
|
-
number would over-reserve per rank on exactly the shapes already tight.
|
|
516
|
-
- PINNED REVISION with no resolvable parameter count: the weight term dominates, so a guessed
|
|
519
|
+
- pinned revision with no resolvable parameter count: the weight term dominates, so a guessed
|
|
517
520
|
size is not worth acting on.
|
|
521
|
+
- any sizing exception: launch falls back to the previous constant instead of failing.
|
|
518
522
|
"""
|
|
519
|
-
if
|
|
523
|
+
if not (gpu_type or "").strip():
|
|
520
524
|
return _DEFAULT_GPU_MEM_UTIL
|
|
521
525
|
try:
|
|
522
526
|
from flash.core.catalog import MODELS
|
|
@@ -545,7 +549,7 @@ def resolve_gpu_mem_util(
|
|
|
545
549
|
)
|
|
546
550
|
if params_b <= 0:
|
|
547
551
|
return _DEFAULT_GPU_MEM_UTIL
|
|
548
|
-
|
|
552
|
+
sized = colocate_kv_util(
|
|
549
553
|
params_b,
|
|
550
554
|
int(inp["engine_len"]),
|
|
551
555
|
total_vram_gb,
|
|
@@ -558,7 +562,12 @@ def resolve_gpu_mem_util(
|
|
|
558
562
|
active_params_b=float(getattr(info, "active_params_b", 0.0) or 0.0) or None,
|
|
559
563
|
fp8_kv=fp8_kv,
|
|
560
564
|
model_info=info,
|
|
565
|
+
preserve_legacy_floor=preserve_legacy_floor,
|
|
566
|
+
tensor_parallel=n_gpus,
|
|
561
567
|
)
|
|
568
|
+
# multi-rank sizing is strictly one-directional against the previous worker contract: it may
|
|
569
|
+
# free memory but can never claim more than the flat reservation a working run already used.
|
|
570
|
+
return min(_DEFAULT_GPU_MEM_UTIL, sized) if n_gpus > 1 else sized
|
|
562
571
|
except Exception as e: # sizing must never be what stops a run from launching
|
|
563
572
|
print(
|
|
564
573
|
f"[rl-verl] gpu_memory_utilization sizing failed ({e}); using {_DEFAULT_GPU_MEM_UTIL}"
|
|
@@ -224,6 +224,9 @@ def _format_child_tail(tail: object, silent_ticks: object = None) -> str:
|
|
|
224
224
|
|
|
225
225
|
def _format_heartbeat(hb: dict) -> str:
|
|
226
226
|
msg = f"worker: stage={hb.get('stage')}"
|
|
227
|
+
attempt = _attempt_int(hb.get("attempt"))
|
|
228
|
+
if attempt is not None:
|
|
229
|
+
msg += f" attempt={attempt}"
|
|
227
230
|
if hb.get("liveness"):
|
|
228
231
|
msg += " liveness=true"
|
|
229
232
|
for key, digits in (
|
|
@@ -428,9 +428,10 @@ def _deferred_resubmit_loop(spec) -> None:
|
|
|
428
428
|
def _latest_worker_artifact_name(repo: str, prefix: str, phase: str, kind: str) -> str:
|
|
429
429
|
"""Return the newest worker artifact under a prefix.
|
|
430
430
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
431
|
+
Attempt-scoped console and error artifacts use the highest uploaded attempt, which can still be
|
|
432
|
+
older than the live attempt while its replacement has not uploaded yet. Console falls back to its
|
|
433
|
+
canonical final name and errors to attempt 0 when listing fails; derive scoped names from the
|
|
434
|
+
writer's definition to prevent silent reader/writer drift.
|
|
434
435
|
"""
|
|
435
436
|
import re
|
|
436
437
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.94"
|
|
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).
|
|
@@ -137,7 +137,7 @@ artifacts = ["flash/py.typed"]
|
|
|
137
137
|
# auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
|
|
138
138
|
# PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
|
|
139
139
|
# dev-channel release = bump this (and [project].version) and merge to `dev`.
|
|
140
|
-
version = "1.2.
|
|
140
|
+
version = "1.2.94"
|
|
141
141
|
|
|
142
142
|
[tool.pytest.ini_options]
|
|
143
143
|
pythonpath = ["."]
|
|
@@ -1429,6 +1429,60 @@ def test_status_runs_and_log_command(fake_client, capsys, monkeypatch) -> None:
|
|
|
1429
1429
|
assert "cost_usd" not in out
|
|
1430
1430
|
|
|
1431
1431
|
|
|
1432
|
+
def test_log_labels_previous_attempt_artifacts_after_the_live_attempt_log(
|
|
1433
|
+
fake_client, capsys, monkeypatch
|
|
1434
|
+
) -> None:
|
|
1435
|
+
live_heartbeat = {
|
|
1436
|
+
"stage": "rl_step",
|
|
1437
|
+
"step": 4,
|
|
1438
|
+
"ts": 456.0,
|
|
1439
|
+
"attempt": 1,
|
|
1440
|
+
"gpu": {"device_name": "NVIDIA B200"},
|
|
1441
|
+
}
|
|
1442
|
+
fake_client.log_text = _format_heartbeat(live_heartbeat) + "\n"
|
|
1443
|
+
monkeypatch.setattr(
|
|
1444
|
+
fake_client,
|
|
1445
|
+
"get_run",
|
|
1446
|
+
lambda _run_id: {
|
|
1447
|
+
"run_id": "flash-1",
|
|
1448
|
+
"state": "running",
|
|
1449
|
+
"remote": {"attempt": 1},
|
|
1450
|
+
"last_heartbeat": live_heartbeat,
|
|
1451
|
+
},
|
|
1452
|
+
)
|
|
1453
|
+
monkeypatch.setattr(
|
|
1454
|
+
fake_client,
|
|
1455
|
+
"get_worker_output",
|
|
1456
|
+
lambda _run_id: {
|
|
1457
|
+
"console_rl_attempt0.txt": (
|
|
1458
|
+
'HEARTBEAT {"stage":"rl_step","step":0,"attempt":0,'
|
|
1459
|
+
'"gpu":{"device_name":"NVIDIA H200"}}\n'
|
|
1460
|
+
),
|
|
1461
|
+
"error_rl_attempt0.txt": "torch.OutOfMemoryError: CUDA OOM\n",
|
|
1462
|
+
"raylogs_rl_attempt0.txt": "raylet exited\n",
|
|
1463
|
+
},
|
|
1464
|
+
)
|
|
1465
|
+
|
|
1466
|
+
assert _run(["runs", "log", "flash-1"]) == 0
|
|
1467
|
+
out = capsys.readouterr().out
|
|
1468
|
+
|
|
1469
|
+
live_line = "worker: stage=rl_step attempt=1 step=4"
|
|
1470
|
+
previous_header = (
|
|
1471
|
+
"----- console_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----"
|
|
1472
|
+
)
|
|
1473
|
+
assert live_line in out
|
|
1474
|
+
assert previous_header in out
|
|
1475
|
+
assert (
|
|
1476
|
+
"----- error_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----" in out
|
|
1477
|
+
)
|
|
1478
|
+
assert (
|
|
1479
|
+
"----- raylogs_rl_attempt0.txt (attempt=0, previous attempt; current attempt=1) -----"
|
|
1480
|
+
in out
|
|
1481
|
+
)
|
|
1482
|
+
assert out.index(live_line) < out.index(previous_header)
|
|
1483
|
+
assert 'HEARTBEAT {"stage":"rl_step","step":0,"attempt":0' in out
|
|
1484
|
+
|
|
1485
|
+
|
|
1432
1486
|
def test_log_prints_partial_log_line_with_newline(fake_client, capsys) -> None:
|
|
1433
1487
|
fake_client.log_text = "partial log line"
|
|
1434
1488
|
fake_client.get_worker_output = lambda run_id: {}
|
|
@@ -671,6 +671,30 @@ def test_heartbeat_is_current_attempt_rejects_malformed_identities() -> None:
|
|
|
671
671
|
assert is_current({"remote": {"attempt": 2}}, {"attempt": 1}) is False
|
|
672
672
|
|
|
673
673
|
|
|
674
|
+
def test_live_attempt_is_one_rule_for_every_surface_that_names_an_attempt() -> None:
|
|
675
|
+
"""The spinner, the status line, and the worker-artifact labels must not disagree.
|
|
676
|
+
|
|
677
|
+
They are read within one screen of each other, so two provenance rules read as a run that is on
|
|
678
|
+
two attempts at once -- and the artifact labels would call the live attempt's console "previous".
|
|
679
|
+
"""
|
|
680
|
+
live = render.live_attempt
|
|
681
|
+
|
|
682
|
+
# the plane's live attempt wins over the ping, which may be the superseded worker's.
|
|
683
|
+
assert live({"remote": {"attempt": 2}, "last_heartbeat": {"attempt": 1}}) == 2
|
|
684
|
+
# `remote` absent entirely (a managed payload that omits it): the ping is all there is.
|
|
685
|
+
assert live({"last_heartbeat": {"attempt": 3}}) == 3
|
|
686
|
+
# a `remote` that carries no usable attempt is not an answer either, so the ping still applies.
|
|
687
|
+
assert live({"remote": {}, "last_heartbeat": {"attempt": 1}}) == 1
|
|
688
|
+
for bad in ["1", True, 2.7, float("inf"), -1]:
|
|
689
|
+
assert live({"remote": {"attempt": bad}, "last_heartbeat": {"attempt": 4}}) == 4
|
|
690
|
+
# explicitly null `remote` is the teardown window: the attached ping belongs to a dead worker,
|
|
691
|
+
# so there is no live attempt to report rather than that worker's.
|
|
692
|
+
assert live({"remote": None, "last_heartbeat": {"attempt": 1}}) is None
|
|
693
|
+
# nothing usable anywhere reads as unknown, never as attempt 0.
|
|
694
|
+
assert live({}) is None
|
|
695
|
+
assert live({"last_heartbeat": {"attempt": "1"}}) is None
|
|
696
|
+
|
|
697
|
+
|
|
674
698
|
def test_progress_age_always_adds_to_heartbeat_age(monkeypatch):
|
|
675
699
|
from flash.cli.ui import heartbeat as heartbeat_ui
|
|
676
700
|
from flash.cli.ui import render
|
|
@@ -479,7 +479,7 @@ def test_surface_heartbeat_logs_gpu_status(monkeypatch):
|
|
|
479
479
|
assert stage == "sft_step"
|
|
480
480
|
assert len(lines) == 1
|
|
481
481
|
line = lines[0]
|
|
482
|
-
assert "worker: stage=sft_step step=12 loss=1.2346" in line
|
|
482
|
+
assert "worker: stage=sft_step attempt=0 step=12 loss=1.2346" in line
|
|
483
483
|
assert "gpu[RTX 5090" in line
|
|
484
484
|
assert "util=97%" in line
|
|
485
485
|
assert "mem=22.2GB/31.8GB" in line
|
|
@@ -9164,6 +9164,38 @@ def test_normalize_initial_prompt_rejects_a_state_with_no_prompt():
|
|
|
9164
9164
|
normalize_initial_prompt(_Prompt(), state, None)
|
|
9165
9165
|
|
|
9166
9166
|
|
|
9167
|
+
def test_opd_multigpu_gpu_mem_util_matches_the_shared_tp_aware_resolver():
|
|
9168
|
+
request = SimpleNamespace(
|
|
9169
|
+
model_revision="",
|
|
9170
|
+
knobs=SimpleNamespace(group_size=4),
|
|
9171
|
+
spec=SimpleNamespace(gpu=SimpleNamespace(type="H200")),
|
|
9172
|
+
)
|
|
9173
|
+
prompt_state = SimpleNamespace(max_model_len=2048)
|
|
9174
|
+
workload = SimpleNamespace(prompts_per_step=2)
|
|
9175
|
+
runtime = SimpleNamespace(gpu_count=2)
|
|
9176
|
+
model_id = "Qwen/Qwen3.6-35B-A3B"
|
|
9177
|
+
|
|
9178
|
+
got = opd_train._resolve_opd_gpu_mem_util(
|
|
9179
|
+
request, prompt_state, workload, runtime, model_id, fp8_kv=False
|
|
9180
|
+
)
|
|
9181
|
+
want = rl_train.resolve_gpu_mem_util(
|
|
9182
|
+
{
|
|
9183
|
+
"model_id": model_id,
|
|
9184
|
+
"model_revision": "",
|
|
9185
|
+
"engine_len": 2048,
|
|
9186
|
+
"group_size": 8,
|
|
9187
|
+
},
|
|
9188
|
+
gpu_type="H200",
|
|
9189
|
+
n_gpus=2,
|
|
9190
|
+
fp8_kv=False,
|
|
9191
|
+
sleep_unsupported=True,
|
|
9192
|
+
preserve_legacy_floor=True,
|
|
9193
|
+
)
|
|
9194
|
+
|
|
9195
|
+
assert got == want
|
|
9196
|
+
assert got < rl_train._DEFAULT_GPU_MEM_UTIL
|
|
9197
|
+
|
|
9198
|
+
|
|
9167
9199
|
def test_build_opd_overrides_sizes_the_rollout_memory_budget():
|
|
9168
9200
|
# opd emitted no gpu_memory_utilization at all, so verl substituted its own default of 0.5 and
|
|
9169
9201
|
# the engine claimed half the CARD on every wake regardless of what the trainer held. this is
|
|
@@ -1132,6 +1132,7 @@ def test_a_retry_marks_where_the_previous_attempt_ends_in_the_log(orch, monkeypa
|
|
|
1132
1132
|
if attempt == 0:
|
|
1133
1133
|
print("Traceback (most recent call last):\ntorch.OutOfMemoryError: CUDA OOM", file=log)
|
|
1134
1134
|
return PollResult(False, failure="stalled", detail="infra")
|
|
1135
|
+
print("worker: stage=rl_step attempt=1 step=1", file=log)
|
|
1135
1136
|
return PollResult(True, metrics={"train_tokens": 4096})
|
|
1136
1137
|
|
|
1137
1138
|
monkeypatch.setattr(rp_jobs, "submit_run", fake_submit)
|
|
@@ -1147,6 +1148,9 @@ def test_a_retry_marks_where_the_previous_attempt_ends_in_the_log(orch, monkeypa
|
|
|
1147
1148
|
assert text.index("CUDA OOM") < text.index(marker), (
|
|
1148
1149
|
"the marker must sit after the failure it disowns, or it cannot separate the two attempts"
|
|
1149
1150
|
)
|
|
1151
|
+
assert text.index(marker) < text.index("worker: stage=rl_step attempt=1 step=1"), (
|
|
1152
|
+
"the replacement attempt's heartbeat must follow the boundary that assigns its provenance"
|
|
1153
|
+
)
|
|
1150
1154
|
|
|
1151
1155
|
|
|
1152
1156
|
def test_the_marker_does_not_claim_one_previous_attempt_after_two_failures(orch, monkeypatch):
|
|
@@ -1730,7 +1730,19 @@ def test_gpu_mem_util_is_the_sized_budget_not_a_constant():
|
|
|
1730
1730
|
got = rl_train.resolve_gpu_mem_util(
|
|
1731
1731
|
_mem_util_inp(), gpu_type="H100", n_gpus=1, fp8_kv=False, sleep_unsupported=False
|
|
1732
1732
|
)
|
|
1733
|
-
|
|
1733
|
+
explicit_tp_one = colocate_kv_util(
|
|
1734
|
+
float(info.params_b),
|
|
1735
|
+
2048,
|
|
1736
|
+
float(get_gpu_info("H100").vram_gb),
|
|
1737
|
+
sleep_mode=True,
|
|
1738
|
+
num_generations=8,
|
|
1739
|
+
active_params_b=None,
|
|
1740
|
+
fp8_kv=False,
|
|
1741
|
+
model_info=info,
|
|
1742
|
+
tensor_parallel=1,
|
|
1743
|
+
)
|
|
1744
|
+
assert got == want == explicit_tp_one
|
|
1745
|
+
assert got.hex() == "0x1.11eb851eb851ep-2"
|
|
1734
1746
|
# and it is genuinely NOT the old constant, so the test cannot pass on an unwired build.
|
|
1735
1747
|
assert got != rl_train._DEFAULT_GPU_MEM_UTIL
|
|
1736
1748
|
assert got < rl_train._DEFAULT_GPU_MEM_UTIL
|
|
@@ -1791,22 +1803,49 @@ def test_gpu_mem_util_sizing_reaches_the_launch_config():
|
|
|
1791
1803
|
)
|
|
1792
1804
|
|
|
1793
1805
|
|
|
1794
|
-
def
|
|
1795
|
-
"""The three shapes ``colocate_kv_util`` cannot size are left on the conservative constant.
|
|
1796
|
-
|
|
1797
|
-
Multi-gpu is the load-bearing one: the rollout is tensor-parallel, so vLLM's weight copy is
|
|
1798
|
-
sharded ACROSS cards while the model sizes one whole copy against ONE card. Sizing it here would
|
|
1799
|
-
over-reserve per rank on exactly the shapes that are already tight.
|
|
1800
|
-
"""
|
|
1806
|
+
def test_multigpu_gpu_mem_util_shards_only_weights_and_frees_the_observed_shortfall():
|
|
1801
1807
|
default = rl_train._DEFAULT_GPU_MEM_UTIL
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
rl_train.resolve_gpu_mem_util(
|
|
1805
|
-
|
|
1808
|
+
inp = _mem_util_inp(model_id="Qwen/Qwen3.6-35B-A3B", group_size=4)
|
|
1809
|
+
for gpu_type, vram_gb in (("H200", 141.0), ("B200", 180.0)):
|
|
1810
|
+
got = rl_train.resolve_gpu_mem_util(
|
|
1811
|
+
inp, gpu_type=gpu_type, n_gpus=2, fp8_kv=False, sleep_unsupported=True
|
|
1806
1812
|
)
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1813
|
+
assert got < default
|
|
1814
|
+
assert (default - got) * vram_gb > 1.57
|
|
1815
|
+
|
|
1816
|
+
|
|
1817
|
+
def test_multigpu_gpu_mem_util_never_exceeds_the_previous_constant():
|
|
1818
|
+
default = rl_train._DEFAULT_GPU_MEM_UTIL
|
|
1819
|
+
model_ids = ("Qwen/Qwen3.5-0.8B", "Qwen/Qwen3.5-4B", "Qwen/Qwen3.6-35B-A3B")
|
|
1820
|
+
for model_id in model_ids:
|
|
1821
|
+
for gpu_type in ("H100", "H200", "B200"):
|
|
1822
|
+
for tensor_parallel in (2, 4, 8):
|
|
1823
|
+
for engine_len in (1024, 2048, 8192, 32768):
|
|
1824
|
+
for group_size in (2, 4, 8):
|
|
1825
|
+
got = rl_train.resolve_gpu_mem_util(
|
|
1826
|
+
_mem_util_inp(
|
|
1827
|
+
model_id=model_id,
|
|
1828
|
+
engine_len=engine_len,
|
|
1829
|
+
group_size=group_size,
|
|
1830
|
+
),
|
|
1831
|
+
gpu_type=gpu_type,
|
|
1832
|
+
n_gpus=tensor_parallel,
|
|
1833
|
+
fp8_kv=False,
|
|
1834
|
+
sleep_unsupported=True,
|
|
1835
|
+
)
|
|
1836
|
+
assert 0.10 <= got <= default, (
|
|
1837
|
+
model_id,
|
|
1838
|
+
gpu_type,
|
|
1839
|
+
tensor_parallel,
|
|
1840
|
+
engine_len,
|
|
1841
|
+
group_size,
|
|
1842
|
+
got,
|
|
1843
|
+
)
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply(monkeypatch):
|
|
1847
|
+
default = rl_train._DEFAULT_GPU_MEM_UTIL
|
|
1848
|
+
# unknown card: the budget is a fraction of the card, so there is nothing to take a fraction of.
|
|
1810
1849
|
for unknown in ("", " ", "Nonexistent9000"):
|
|
1811
1850
|
assert (
|
|
1812
1851
|
rl_train.resolve_gpu_mem_util(
|
|
@@ -1815,9 +1854,13 @@ def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply():
|
|
|
1815
1854
|
== default
|
|
1816
1855
|
)
|
|
1817
1856
|
# unresolvable model size: the weight copy is the dominant term.
|
|
1857
|
+
monkeypatch.setattr("flash.engine.plan.vram.resolve_params_b", lambda *_args, **_kwargs: None)
|
|
1818
1858
|
assert (
|
|
1819
1859
|
rl_train.resolve_gpu_mem_util(
|
|
1820
|
-
_mem_util_inp(
|
|
1860
|
+
_mem_util_inp(
|
|
1861
|
+
model_id="Qwen/Qwen3.5-4B",
|
|
1862
|
+
model_revision="a" * 40,
|
|
1863
|
+
),
|
|
1821
1864
|
gpu_type="H100",
|
|
1822
1865
|
n_gpus=1,
|
|
1823
1866
|
fp8_kv=False,
|
|
@@ -1825,6 +1868,14 @@ def test_gpu_mem_util_keeps_the_constant_where_the_model_does_not_apply():
|
|
|
1825
1868
|
)
|
|
1826
1869
|
== default
|
|
1827
1870
|
)
|
|
1871
|
+
# any sizing exception keeps launch on the prior constant rather than making sizing fatal.
|
|
1872
|
+
monkeypatch.setattr("flash.providers.base.get_gpu_info", lambda _gpu_type: 1 / 0)
|
|
1873
|
+
assert (
|
|
1874
|
+
rl_train.resolve_gpu_mem_util(
|
|
1875
|
+
_mem_util_inp(), gpu_type="H100", n_gpus=2, fp8_kv=False, sleep_unsupported=False
|
|
1876
|
+
)
|
|
1877
|
+
== default
|
|
1878
|
+
)
|
|
1828
1879
|
|
|
1829
1880
|
|
|
1830
1881
|
def test_gpu_mem_util_does_not_credit_an_offload_a_resident_engine_never_takes():
|