freesolo-flash-dev 1.2.89__tar.gz → 1.2.95__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.95}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/__init__.py +14 -19
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/__init__.py +11 -24
- freesolo_flash_dev-1.2.95/flash/cli/commands/worker_output.py +67 -0
- freesolo_flash_dev-1.2.95/flash/cli/errors.py +277 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/heartbeat.py +27 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/render.py +1 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/kv_sizing.py +20 -8
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/opd_train.py +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/opd_train_runner.py +5 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/verl_config.py +17 -8
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/poll.py +3 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/runtime.py +4 -3
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_commands.py +54 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_render_theme.py +254 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_jobs.py +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_train.py +32 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_resume_on_retry.py +4 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_rl_train.py +67 -16
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_api.py +49 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/uv.lock +1 -1
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.env.example +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/dev-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/production-kernel-cache-ready.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/README.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/adapters/targets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/setup_wandb.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/content/image_descriptors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/core/grpo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/huggingface.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/sft_image_rows.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/multiturn_media.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker/verl/process_census.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/package/direct_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/envs/staged.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/teacher/provider_status.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/check_rollout_identity_actor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/capture_image_sft_processor_oracle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/fixtures/image_sft_processor_oracle.json +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/fixtures/qwen35_08b_target_metadata.json +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_backend_common.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_process_census.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_rollout_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_grpo_rollout_identity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_image_environment_capability.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_image_incremental_processor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_image_sft_markers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_image_sft_processor_parity.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lora_rank_nested_rung.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lora_targeting.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_lora_targeting_pinned_verl.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_source_attestation_flow.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_staged_environment.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_warmstart_image_adapters.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.89 → freesolo_flash_dev-1.2.95}/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.95
|
|
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
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
|
-
import difflib
|
|
7
6
|
import math
|
|
8
|
-
import re
|
|
9
7
|
import shlex
|
|
10
8
|
import sys
|
|
11
9
|
from typing import NoReturn
|
|
@@ -57,6 +55,7 @@ from flash.cli.commands.traces import (
|
|
|
57
55
|
RECORDS_FORMAT,
|
|
58
56
|
cmd_traces_export,
|
|
59
57
|
)
|
|
58
|
+
from flash.cli.errors import friendly_error
|
|
60
59
|
from flash.cli.ui import render
|
|
61
60
|
from flash.client.config import shadowed_login_warning
|
|
62
61
|
from flash.core.catalog import ALGORITHMS
|
|
@@ -170,20 +169,6 @@ def _gpu_count_override(value: str) -> str:
|
|
|
170
169
|
raise argparse.ArgumentTypeError(f"expected a number of gpus, got {value!r}") from None
|
|
171
170
|
|
|
172
171
|
|
|
173
|
-
def _friendly_message(message: str) -> str:
|
|
174
|
-
"""Shorten argparse's verbose ``invalid choice: 'x' (choose from a, b, c, ...)`` into a concise
|
|
175
|
-
``unknown command 'x' (did you mean 'y'?)`` — the single closest match instead of dumping the
|
|
176
|
-
whole list. Other messages pass through untouched. Styled path only; the machine path keeps
|
|
177
|
-
argparse's exact text (scripts and the error tests match on the literal `invalid choice`)."""
|
|
178
|
-
m = re.search(r"invalid choice: '([^']*)'(?: \(choose from (.*)\))?", message)
|
|
179
|
-
if not m:
|
|
180
|
-
return message
|
|
181
|
-
bad, raw_choices = m.group(1), m.group(2) or ""
|
|
182
|
-
choices = [c.strip().strip("'\"") for c in raw_choices.split(",") if c.strip()]
|
|
183
|
-
near = difflib.get_close_matches(bad, choices, n=1)
|
|
184
|
-
return f"unknown command '{bad}'" + (f" (did you mean '{near[0]}'?)" if near else "")
|
|
185
|
-
|
|
186
|
-
|
|
187
172
|
class _ThemedParser(argparse.ArgumentParser):
|
|
188
173
|
"""Base parser whose usage errors match the rest of the themed CLI.
|
|
189
174
|
|
|
@@ -201,9 +186,13 @@ class _ThemedParser(argparse.ArgumentParser):
|
|
|
201
186
|
if not render.styled():
|
|
202
187
|
super().error(message) # argparse's raw usage + `prog: error: msg`, then exit 2
|
|
203
188
|
# themed twin: the red ✗ error line (same idiom as main()'s catch-all and `flash login`),
|
|
204
|
-
# then a dimmed pointer at this parser's own --help instead of the raw usage block.
|
|
205
|
-
#
|
|
206
|
-
|
|
189
|
+
# then a dimmed pointer at this parser's own --help instead of the raw usage block. unknown
|
|
190
|
+
# commands and flags get a short "did you mean" suggestion (see `friendly_error`). the argv
|
|
191
|
+
# stash is what tells it which subcommand was selected; only the root parser carries one.
|
|
192
|
+
print(
|
|
193
|
+
render.error(friendly_error(message, self, getattr(self, "_flash_argv", None))),
|
|
194
|
+
file=sys.stderr,
|
|
195
|
+
)
|
|
207
196
|
# dimmed pointer at THIS parser's own --help (argparse sets prog per parser: `flash --help`
|
|
208
197
|
# for the root, `flash <cmd> --help` for a subcommand) instead of the raw usage block.
|
|
209
198
|
print(render.arrow(f"run `{self.prog} --help` for usage"), file=sys.stderr)
|
|
@@ -902,6 +891,12 @@ def _redacted_args(raw_args: list[str]) -> list[str]:
|
|
|
902
891
|
def main(argv: list[str] | None = None) -> int:
|
|
903
892
|
raw_args = list(argv) if argv is not None else sys.argv[1:]
|
|
904
893
|
parser = _build_parser()
|
|
894
|
+
# the tokens this invocation was actually given, for the error hook: argparse reports a
|
|
895
|
+
# subcommand's unknown flags from the ROOT parser, so scoping the suggestion to the selected
|
|
896
|
+
# command needs the argv `main` was called with. reading sys.argv there instead would be right
|
|
897
|
+
# only for the console-script path and wrong for every embedded caller -- including the tests,
|
|
898
|
+
# where it silently reads pytest's own argv and restores the whole-tree pool.
|
|
899
|
+
parser._flash_argv = raw_args
|
|
905
900
|
args = parser.parse_args(argv)
|
|
906
901
|
configure_logging(verbosity=getattr(args, "verbose", 0))
|
|
907
902
|
debug = getattr(args, "debug", False)
|
|
@@ -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
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"""Turning argparse's usage errors into the themed CLI's short suggestions.
|
|
2
|
+
|
|
3
|
+
argparse reports a mistyped flag by printing the whole usage block, which buries the one token that
|
|
4
|
+
was actually wrong. These helpers reduce that to a single line naming the token and, where one
|
|
5
|
+
exists, the closest real alternative.
|
|
6
|
+
|
|
7
|
+
The hard part is making the suggestion one the user can actually follow. A subcommand's unknown
|
|
8
|
+
tokens are handed back to the root parser to report, so candidate options must be recovered from the
|
|
9
|
+
parser in effect at the rejected token's argv position. Looking only at the final selected command
|
|
10
|
+
crosses nested command boundaries, while looking through the whole tree offers unrelated flags.
|
|
11
|
+
|
|
12
|
+
Root flags are also positional here (`flash --debug login`, never `flash login --debug`), and `--`
|
|
13
|
+
stops option parsing. The suggestion context therefore carries both boundaries, plus the original
|
|
14
|
+
spelling of a repeated short root flag that must be moved without changing its count.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import difflib
|
|
21
|
+
import re
|
|
22
|
+
from collections.abc import Iterable
|
|
23
|
+
from dataclasses import dataclass
|
|
24
|
+
|
|
25
|
+
from flash._internal.channel import CLI_NAME
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class _SuggestionContext:
|
|
30
|
+
options: tuple[str, ...]
|
|
31
|
+
root_only: frozenset[str]
|
|
32
|
+
reposition: str | None = None
|
|
33
|
+
after_terminator: bool = False
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def friendly_error(
|
|
37
|
+
message: str, parser: argparse.ArgumentParser, argv: Iterable[str] | None
|
|
38
|
+
) -> str:
|
|
39
|
+
"""Rewrite one argparse usage error for the themed CLI.
|
|
40
|
+
|
|
41
|
+
The whole suggestion policy lives behind this call: which parser's flags are candidates, which
|
|
42
|
+
of them need repositioning, and how the message reads. The caller is an ``error()`` override on
|
|
43
|
+
every parser in the tree and should stay a two-liner -- deciding a candidate pool inline there
|
|
44
|
+
would put policy in a hook that exists to print.
|
|
45
|
+
"""
|
|
46
|
+
if argv is None:
|
|
47
|
+
# a subparser raising its own error is already the parser in effect at the rejected token.
|
|
48
|
+
context = _SuggestionContext(tuple(sorted(_direct_options(parser))), frozenset())
|
|
49
|
+
else:
|
|
50
|
+
context = _suggestion_context(message, parser, tuple(argv))
|
|
51
|
+
return _friendly_message(message, context)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _friendly_message(message: str, context: _SuggestionContext) -> str:
|
|
55
|
+
"""Shorten argparse's verbose errors into concise suggestions on the styled path.
|
|
56
|
+
|
|
57
|
+
An ``invalid choice: 'x' (choose from a, b, c, ...)`` becomes ``unknown command 'x' (did you
|
|
58
|
+
mean 'y'?)`` instead of dumping the whole list. An ``unrecognized arguments: --flag value``
|
|
59
|
+
suggests the closest option registered on the parser that rejected it. Other messages pass
|
|
60
|
+
through untouched. The machine path keeps argparse's exact text for scripts and error tests.
|
|
61
|
+
"""
|
|
62
|
+
m = re.search(r"invalid choice: '([^']*)'(?: \(choose from (.*)\))?", message)
|
|
63
|
+
if m:
|
|
64
|
+
bad, raw_choices = m.group(1), m.group(2) or ""
|
|
65
|
+
choices = [c.strip().strip("'\"") for c in raw_choices.split(",") if c.strip()]
|
|
66
|
+
near = difflib.get_close_matches(bad, choices, n=1)
|
|
67
|
+
return f"unknown command '{bad}'" + (f" (did you mean '{near[0]}'?)" if near else "")
|
|
68
|
+
|
|
69
|
+
prefix = "unrecognized arguments: "
|
|
70
|
+
if not message.startswith(prefix):
|
|
71
|
+
return message
|
|
72
|
+
# a bare `-` starts with a dash but names no option, so it is an ordinary positional argparse
|
|
73
|
+
# could not place. requiring a character after the dash keeps it out of the typo machinery,
|
|
74
|
+
# which would otherwise answer it with the nearest short flag.
|
|
75
|
+
bad = next(
|
|
76
|
+
(
|
|
77
|
+
token.split("=", 1)[0]
|
|
78
|
+
for token in message[len(prefix) :].split()
|
|
79
|
+
if token.startswith("-") and len(token.split("=", 1)[0]) > 1
|
|
80
|
+
),
|
|
81
|
+
None,
|
|
82
|
+
)
|
|
83
|
+
if bad is None:
|
|
84
|
+
return message
|
|
85
|
+
if context.after_terminator:
|
|
86
|
+
return message
|
|
87
|
+
# a root flag in the wrong position is a placement error, not a typo. repeatable short flags
|
|
88
|
+
# retain the complete spelling so moving `-vv` never downgrades it to one `-v`.
|
|
89
|
+
if context.reposition is not None:
|
|
90
|
+
return _reposition_message(context.reposition)
|
|
91
|
+
if bad in context.root_only:
|
|
92
|
+
return _reposition_message(bad)
|
|
93
|
+
# the position-scoped pool can still include an exact spelling shared with the root. dropping it
|
|
94
|
+
# keeps a rejected token from being echoed back as its own correction.
|
|
95
|
+
candidates = [option for option in context.options if option != bad]
|
|
96
|
+
near = difflib.get_close_matches(bad, candidates, n=1)
|
|
97
|
+
if not near:
|
|
98
|
+
return message
|
|
99
|
+
suggestion = near[0]
|
|
100
|
+
if suggestion in context.root_only:
|
|
101
|
+
# a root flag only parses before the subcommand, so naming it alone hands back a correction
|
|
102
|
+
# that fails the same way. say where it goes, or the second attempt is the first error again.
|
|
103
|
+
return f"unrecognized argument '{bad}' (did you mean '{suggestion}'? {_placement_hint(suggestion)})"
|
|
104
|
+
return f"unrecognized argument '{bad}' (did you mean '{suggestion}'?)"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _placement_hint(flag: str) -> str:
|
|
108
|
+
"""Say where a root flag belongs, and claim nothing about the rest of the line.
|
|
109
|
+
|
|
110
|
+
This hint knows one thing: the flag parses only ahead of the subcommand. It does not know what
|
|
111
|
+
removing the flag from where it sat exposes. `--wait` takes an optional value, so a flag lifted
|
|
112
|
+
from between `--wait` and a run id leaves the run id to be swallowed as the timeout -- which
|
|
113
|
+
`_wait_seconds` then catches and explains precisely. Stating the destination and stopping there
|
|
114
|
+
keeps this hint true for every line; the one case it cannot see already answers itself.
|
|
115
|
+
|
|
116
|
+
Both the repositioning message and the respelling-plus-repositioning message end in this same
|
|
117
|
+
advice, so they share it rather than each spelling it out and drifting apart.
|
|
118
|
+
"""
|
|
119
|
+
return f"it goes before the command, as `{CLI_NAME} {flag} ...`"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _reposition_message(flag: str) -> str:
|
|
123
|
+
"""Answer a correctly spelled root flag that landed after the subcommand."""
|
|
124
|
+
return f"unrecognized argument '{flag}' ({_placement_hint(flag)})"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _suggestion_context(
|
|
128
|
+
message: str, root: argparse.ArgumentParser, argv: tuple[str, ...]
|
|
129
|
+
) -> _SuggestionContext:
|
|
130
|
+
root_only = _root_only_options(root)
|
|
131
|
+
bad = _unrecognized_option(message)
|
|
132
|
+
if bad is None:
|
|
133
|
+
return _SuggestionContext((), root_only)
|
|
134
|
+
location = _option_location(root, argv, bad)
|
|
135
|
+
if location is None:
|
|
136
|
+
return _SuggestionContext((), root_only)
|
|
137
|
+
current, after_terminator = location
|
|
138
|
+
reposition = bad if _is_repeated_root_short_option(root, bad, root_only) else None
|
|
139
|
+
options = tuple(sorted({*_direct_options(current), *root_only}))
|
|
140
|
+
return _SuggestionContext(options, root_only, reposition, after_terminator)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _unrecognized_option(message: str) -> str | None:
|
|
144
|
+
prefix = "unrecognized arguments: "
|
|
145
|
+
if not message.startswith(prefix):
|
|
146
|
+
return None
|
|
147
|
+
return next(
|
|
148
|
+
(
|
|
149
|
+
token.split("=", 1)[0]
|
|
150
|
+
for token in message[len(prefix) :].split()
|
|
151
|
+
if token.startswith("-")
|
|
152
|
+
),
|
|
153
|
+
None,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _option_location(
|
|
158
|
+
root: argparse.ArgumentParser, argv: tuple[str, ...], bad: str
|
|
159
|
+
) -> tuple[argparse.ArgumentParser, bool] | None:
|
|
160
|
+
"""Return the parser and terminator state at the rejected token's argv position."""
|
|
161
|
+
current = root
|
|
162
|
+
path_open = True
|
|
163
|
+
after_terminator = False
|
|
164
|
+
fallback: tuple[argparse.ArgumentParser, bool] | None = None
|
|
165
|
+
|
|
166
|
+
for token in argv:
|
|
167
|
+
if token == "--":
|
|
168
|
+
after_terminator = True
|
|
169
|
+
path_open = False
|
|
170
|
+
continue
|
|
171
|
+
if token.split("=", 1)[0] == bad:
|
|
172
|
+
location = (current, after_terminator)
|
|
173
|
+
fallback = location
|
|
174
|
+
# repeated spellings can include one accepted root occurrence and one rejected
|
|
175
|
+
# subcommand occurrence. choose the occurrence argparse could not consume here.
|
|
176
|
+
if after_terminator or len(_option_tuples(current, token)) != 1:
|
|
177
|
+
return location
|
|
178
|
+
if after_terminator or token.startswith("-") or not path_open:
|
|
179
|
+
continue
|
|
180
|
+
subparsers = next(
|
|
181
|
+
(a for a in current._actions if isinstance(a, argparse._SubParsersAction)), None
|
|
182
|
+
)
|
|
183
|
+
if subparsers is None:
|
|
184
|
+
path_open = False
|
|
185
|
+
continue
|
|
186
|
+
nxt = subparsers.choices.get(token)
|
|
187
|
+
if nxt is None:
|
|
188
|
+
path_open = False
|
|
189
|
+
continue
|
|
190
|
+
current = nxt
|
|
191
|
+
|
|
192
|
+
return fallback
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _option_tuples(parser: argparse.ArgumentParser, token: str) -> list:
|
|
196
|
+
"""The prefix matches for a token, for tokens argparse's own helper cannot be asked about.
|
|
197
|
+
|
|
198
|
+
`_get_option_tuples` indexes the token's second character, so a bare ``-`` raises IndexError
|
|
199
|
+
there. A lone dash is an ordinary unrecognized positional and must reach argparse's own message
|
|
200
|
+
rather than crash the code that was trying to improve it.
|
|
201
|
+
"""
|
|
202
|
+
if len(token) < 2:
|
|
203
|
+
return []
|
|
204
|
+
return parser._get_option_tuples(token)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _parse_optional_fields(
|
|
208
|
+
parser: argparse.ArgumentParser, token: str
|
|
209
|
+
) -> tuple[object, str | None, str | None] | None:
|
|
210
|
+
"""The action, option spelling and explicit remainder argparse reads out of a token.
|
|
211
|
+
|
|
212
|
+
`_parse_optional` has three shapes across the interpreters `requires-python` admits: a 3-tuple
|
|
213
|
+
before 3.11.9/3.12.3, a 4-tuple once a separator was inserted, and from 3.12.11 a LIST of those
|
|
214
|
+
tuples, one per prefix match. Normalizing here keeps that churn in one place, and keeps the
|
|
215
|
+
separator out of the caller: the exact-spelling reconstruction the caller does already settles
|
|
216
|
+
what the separator would have told it. An unfamiliar shape returns None rather than raising,
|
|
217
|
+
because this runs inside the handler whose whole job is to render someone else's error.
|
|
218
|
+
"""
|
|
219
|
+
parsed = parser._parse_optional(token)
|
|
220
|
+
if isinstance(parsed, list):
|
|
221
|
+
# several prefix matches means the spelling is ambiguous, so it is not one repeated flag.
|
|
222
|
+
parsed = parsed[0] if len(parsed) == 1 else None
|
|
223
|
+
if not isinstance(parsed, tuple) or len(parsed) not in (3, 4):
|
|
224
|
+
return None
|
|
225
|
+
return parsed[0], parsed[1], parsed[-1]
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def _is_repeated_root_short_option(
|
|
229
|
+
root: argparse.ArgumentParser, token: str, root_only: frozenset[str]
|
|
230
|
+
) -> bool:
|
|
231
|
+
"""Whether token is a compact repeat of a count-style root option, such as ``-vv``."""
|
|
232
|
+
if not token.startswith("-") or token.startswith("--"):
|
|
233
|
+
return False
|
|
234
|
+
fields = _parse_optional_fields(root, token)
|
|
235
|
+
if fields is None:
|
|
236
|
+
return False
|
|
237
|
+
action, option, explicit = fields
|
|
238
|
+
return (
|
|
239
|
+
isinstance(action, argparse._CountAction)
|
|
240
|
+
and option in root_only
|
|
241
|
+
and isinstance(explicit, str)
|
|
242
|
+
and bool(explicit)
|
|
243
|
+
# the whole token must be that one short flag repeated, so `-vx` and `-v=2` are not repeats.
|
|
244
|
+
and token == option + option[-1] * len(explicit)
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def _direct_options(parser: argparse.ArgumentParser) -> Iterable[str]:
|
|
249
|
+
for action in parser._actions:
|
|
250
|
+
yield from action.option_strings
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def _parser_options(parser: argparse.ArgumentParser) -> Iterable[str]:
|
|
254
|
+
"""Yield option strings registered on a parser and its subparsers."""
|
|
255
|
+
yield from _direct_options(parser)
|
|
256
|
+
for action in parser._actions:
|
|
257
|
+
if isinstance(action, argparse._SubParsersAction):
|
|
258
|
+
for subparser in action.choices.values():
|
|
259
|
+
yield from _parser_options(subparser)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _root_only_options(parser: argparse.ArgumentParser) -> frozenset[str]:
|
|
263
|
+
"""Option strings accepted only BEFORE the subcommand.
|
|
264
|
+
|
|
265
|
+
This CLI's root flags are positional: `flash --debug login` parses, `flash login --debug` does
|
|
266
|
+
not. A suggestion drawn from the whole option pool can therefore name a real flag that still
|
|
267
|
+
fails in the position the user typed it, so the caller needs to know which ones to reposition.
|
|
268
|
+
"""
|
|
269
|
+
root: set[str] = set()
|
|
270
|
+
sub: set[str] = set()
|
|
271
|
+
for action in parser._actions:
|
|
272
|
+
if isinstance(action, argparse._SubParsersAction):
|
|
273
|
+
for subparser in action.choices.values():
|
|
274
|
+
sub.update(_parser_options(subparser))
|
|
275
|
+
else:
|
|
276
|
+
root.update(action.option_strings)
|
|
277
|
+
return frozenset(root - sub)
|
|
@@ -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.95}/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
|
|