freesolo-flash-dev 1.2.98__tar.gz → 1.2.102__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.98 → freesolo_flash_dev-1.2.102}/PKG-INFO +1 -1
- freesolo_flash_dev-1.2.102/flash/cli/commands/worker_output.py +139 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/overrides.py +10 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/verl_config.py +6 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/capabilities.py +39 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_backend_common.py +38 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_commands.py +4 -1
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_commands_coverage.py +123 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_train.py +23 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_rl_train.py +23 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/uv.lock +1 -1
- freesolo_flash_dev-1.2.98/flash/cli/commands/worker_output.py +0 -76
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.env.example +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/dev-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/production-kernel-cache-ready.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.gitignore +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/README.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/adapters/fused_experts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/adapters/targets.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/setup_wandb.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/errors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/scaffold/TRAINING.md +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/content/image_descriptors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/core/grpo.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/core/spec_persistence.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/huggingface.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/reasoning_render.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/sft_image_rows.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/profiling/workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/chatml_mask.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/opd_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/rl_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/sft_train_runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/core/step_timing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/bridge_failures.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/runtime.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/multiturn_media.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/reporting.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/state.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/patches.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/identity.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/multi_turn.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/reward_module.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/child/entry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/child_io.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/parent_work.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/process_census.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/package/direct_tokens.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/envs/staged.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_console.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/deadline_sleep.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/failmark.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/host/hostlog.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/retry_decision.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/build.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/manifest.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/runtime_capsule/profiles.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/responses.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/teacher/provider_status.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/check_rollout_identity_actor.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/capture_image_sft_processor_oracle.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/fixtures/image_sft_processor_oracle.json +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/fixtures/qwen35_08b_target_metadata.json +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/test_sft_thinking_render_live.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_checkpoint_lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_console_upload.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_deploy_alias_move_warning.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_fused_expert_warmstart.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_process_census.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_rollout_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_grpo_rollout_identity.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_image_environment_capability.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_image_incremental_processor.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_image_sft_markers.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_image_sft_processor_parity.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_image_tokens.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_nested_rung.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lora_targeting.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_lora_targeting_pinned_verl.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_multiturn_failure_exit.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_replay_guard.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_persisted_spec_envelope.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_prompt_budget.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_runtime_capsule.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_startup_block.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_source_attestation_flow.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_source_snapshot.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_spec_contract_bytes.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_staged_environment.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_step_timing.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_terminal_artifacts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_verl_checkpoint_export.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_verl_child_plugins.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_verl_silence_watchdog.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_warmstart_image_adapters.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_workload_profile.py +0 -0
- {freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/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.102
|
|
4
4
|
Summary: Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI
|
|
5
5
|
Project-URL: Homepage, https://github.com/freesolo-co/flash
|
|
6
6
|
Project-URL: Repository, https://github.com/freesolo-co/flash
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
from flash.client import ClientError
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from collections.abc import Mapping
|
|
24
|
+
|
|
25
|
+
from flash.client import ApiClient
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# stands in for the live attempt during the teardown window, when the plane has PROVEN there is no
|
|
29
|
+
# live worker (an explicitly null ``remote``). distinct from ``None``, which means UNKNOWN.
|
|
30
|
+
_NO_LIVE_WORKER = "no-live-worker"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _artifact_attempt(name: str) -> int | None:
|
|
34
|
+
"""Return the bounded attempt encoded by a worker artifact name."""
|
|
35
|
+
from flash.providers._lifecycle.poll import _attempt_int
|
|
36
|
+
|
|
37
|
+
match = re.search(r"_attempt(\d+)\.txt$", name)
|
|
38
|
+
return _attempt_int(int(match.group(1))) if match else None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _worker_section_name(name: str, current_attempt: int | str | None) -> str:
|
|
42
|
+
"""Label an attempt-scoped artifact and identify superseded output."""
|
|
43
|
+
attempt = _artifact_attempt(name)
|
|
44
|
+
if attempt is None:
|
|
45
|
+
return name
|
|
46
|
+
if current_attempt == _NO_LIVE_WORKER:
|
|
47
|
+
return f"{name} (attempt={attempt}, worker torn down; no live attempt)"
|
|
48
|
+
if current_attempt is None:
|
|
49
|
+
return f"{name} (attempt={attempt})"
|
|
50
|
+
if attempt != current_attempt:
|
|
51
|
+
return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
|
|
52
|
+
return f"{name} (attempt={attempt}, current attempt)"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_HEARTBEAT_LINE_RE = re.compile(r"(?m)^(HEARTBEAT )(?!\[superseded)")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _mark_superseded_heartbeats(text: str, attempt: int, current_attempt: int | str) -> str:
|
|
59
|
+
"""Tag every HEARTBEAT line in a dead attempt's console dump.
|
|
60
|
+
|
|
61
|
+
The section heading already says which attempt produced this text, but a heading is only read
|
|
62
|
+
by a human looking at the whole screen. The monitoring idiom is
|
|
63
|
+
``runs log | grep HEARTBEAT | tail -1``, which sees ONE line and no heading -- and because the
|
|
64
|
+
plane appends the highest uploaded attempt after the chronological log, that one line is the
|
|
65
|
+
dead attempt's last heartbeat.
|
|
66
|
+
|
|
67
|
+
That is not merely stale, it inverts the reading: the reporter's monitor showed
|
|
68
|
+
``step 0, 0 completions, device H200`` for twenty minutes while the run was in fact live on
|
|
69
|
+
B200, because H200 was the card that had already OOMed and been torn down.
|
|
70
|
+
|
|
71
|
+
Tagging the line itself means the provenance survives the pipe. A consumer that filters on the
|
|
72
|
+
tag gets only live heartbeats; one that does not at least sees the attempt in the line it
|
|
73
|
+
printed rather than silently trusting a dead worker's last words.
|
|
74
|
+
"""
|
|
75
|
+
current = (
|
|
76
|
+
"worker torn down"
|
|
77
|
+
if current_attempt == _NO_LIVE_WORKER
|
|
78
|
+
else f"current attempt={current_attempt}"
|
|
79
|
+
)
|
|
80
|
+
return _HEARTBEAT_LINE_RE.sub(f"\\1[superseded attempt={attempt}; {current}] ", text)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _worker_sections(client: ApiClient, run_id: str) -> dict[str, str]:
|
|
84
|
+
"""Fetch only worker artifacts with printable text."""
|
|
85
|
+
return {name: text for name, text in (client.get_worker_output(run_id) or {}).items() if text}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _snapshot_live_attempt(client: ApiClient, run_id: str) -> int | str | None:
|
|
89
|
+
"""The live attempt, ``_NO_LIVE_WORKER`` during teardown, or ``None`` when unknown.
|
|
90
|
+
|
|
91
|
+
``live_attempt`` answers ``None`` for two opposite situations: an explicitly null ``remote``,
|
|
92
|
+
which is PROOF the attached heartbeat belongs to a worker that is already gone, and a run whose
|
|
93
|
+
shape carries no attempt at all. Collapsing both to ``None`` disabled heartbeat tagging exactly
|
|
94
|
+
during the retry window the tagging exists for -- the dead attempt's heartbeat went back to
|
|
95
|
+
reaching ``grep HEARTBEAT | tail -1`` unmarked while replacement capacity was still being
|
|
96
|
+
acquired. Keep the two apart so teardown can be labelled as what it is.
|
|
97
|
+
|
|
98
|
+
A lookup failure stays ``None``: not knowing the live attempt must not make this claim there
|
|
99
|
+
is no live worker.
|
|
100
|
+
"""
|
|
101
|
+
try:
|
|
102
|
+
run = client.get_run(run_id) or {}
|
|
103
|
+
except ClientError:
|
|
104
|
+
return None
|
|
105
|
+
attempt = render.live_attempt(run)
|
|
106
|
+
if attempt is None and run.get("remote", False) is None:
|
|
107
|
+
return _NO_LIVE_WORKER
|
|
108
|
+
return attempt
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _print_worker_output(
|
|
112
|
+
sections: Mapping[str, str],
|
|
113
|
+
*,
|
|
114
|
+
printed_any: bool = False,
|
|
115
|
+
current_attempt: int | str | None = None,
|
|
116
|
+
) -> bool:
|
|
117
|
+
"""Print worker artifacts under headings naming the attempt that produced them."""
|
|
118
|
+
for name, text in sections.items():
|
|
119
|
+
# label provenance from the filename rather than letting the final section, which is merely
|
|
120
|
+
# the last one appended, read as the live attempt's output.
|
|
121
|
+
section_name = _worker_section_name(name, current_attempt)
|
|
122
|
+
# the heading is invisible to `grep HEARTBEAT | tail -1`, so a superseded attempt's
|
|
123
|
+
# heartbeats carry their own provenance into the pipe. `_NO_LIVE_WORKER` tags every
|
|
124
|
+
# attempt: during teardown the plane has PROVEN no worker is live, so every heartbeat on
|
|
125
|
+
# screen is a dead one and none of them may reach a monitor unmarked.
|
|
126
|
+
attempt = _artifact_attempt(name)
|
|
127
|
+
supersedes = current_attempt is not None and (
|
|
128
|
+
current_attempt == _NO_LIVE_WORKER or attempt != current_attempt
|
|
129
|
+
)
|
|
130
|
+
if attempt is not None and supersedes:
|
|
131
|
+
text = _mark_superseded_heartbeats(text, attempt, current_attempt)
|
|
132
|
+
sep = "\n" if printed_any else ""
|
|
133
|
+
if render.styled():
|
|
134
|
+
print(f"{sep}{render.log_section(section_name)}")
|
|
135
|
+
else:
|
|
136
|
+
print(f"{sep}----- {section_name} -----")
|
|
137
|
+
print(text, end="" if text.endswith("\n") else "\n")
|
|
138
|
+
printed_any = True
|
|
139
|
+
return printed_any
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/opd/overrides.py
RENAMED
|
@@ -23,6 +23,7 @@ from flash.engine.worker.backend_common import (
|
|
|
23
23
|
trainer_dtype_overrides,
|
|
24
24
|
)
|
|
25
25
|
from flash.engine.worker.sft_train import _build_verl_child_env, _hydra_val
|
|
26
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
26
27
|
from flash.teacher.limits import OPD_NO_SIGNAL_ATTEMPTS
|
|
27
28
|
|
|
28
29
|
_REQUIRED_OVERRIDE_KEYS = (
|
|
@@ -214,6 +215,15 @@ def _actor_rollout_overrides(config: dict, *, max_tokens: int) -> list[str]:
|
|
|
214
215
|
"actor_rollout_ref.rollout.agent.num_workers="
|
|
215
216
|
f"{agent_loop_workers(int(config['train_batch_size']) * int(config['group_size']), cap=4 if config.get('multimodal') else 8)}"
|
|
216
217
|
),
|
|
218
|
+
# one opd step submits exactly train_batch_size * group_size student generations. verl's
|
|
219
|
+
# 1024 default makes vllm reserve cuda-graph capture sizes -- and, on a gdn/mamba hybrid,
|
|
220
|
+
# one recurrent state block per decode slot -- for a batch this run never submits. both are
|
|
221
|
+
# allocated before the first token, so the over-provisioning OOMs a card that stays mostly
|
|
222
|
+
# free. `rollout.max_num_seqs` is a real verl field, so this is a plain override.
|
|
223
|
+
(
|
|
224
|
+
"actor_rollout_ref.rollout.max_num_seqs="
|
|
225
|
+
f"{rollout_max_num_seqs(int(config['train_batch_size']) * int(config['group_size']))}"
|
|
226
|
+
),
|
|
217
227
|
]
|
|
218
228
|
|
|
219
229
|
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/train/rl/verl_config.py
RENAMED
|
@@ -26,6 +26,7 @@ from flash.engine.worker.backend_common import (
|
|
|
26
26
|
)
|
|
27
27
|
from flash.engine.worker.runtime.pkg_proxy import W as _w
|
|
28
28
|
from flash.engine.worker.sft_train import _hydra_val, _verl_image_message_content
|
|
29
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
29
30
|
from flash.engine.worker.verl.parallelism import (
|
|
30
31
|
ULYSSES_SEQUENCE_PARALLEL_SIZE,
|
|
31
32
|
resolve_reshard_after_forward,
|
|
@@ -321,6 +322,11 @@ def _rollout_overrides(cfg: dict) -> list[str]:
|
|
|
321
322
|
# child-silence watchdog kills it 1200s later. capping the pool leaves group_size and
|
|
322
323
|
# prompts_per_step exactly as authored -- only scheduling parallelism narrows.
|
|
323
324
|
f"actor_rollout_ref.rollout.agent.num_workers={agent_loop_workers(int(cfg['prompts_per_step']) * int(cfg['group_size']), cap=4 if cfg.get('multimodal') else 8)}",
|
|
325
|
+
# one grpo step submits exactly prompts_per_step * group_size sequences. left unset verl
|
|
326
|
+
# keeps its 1024 default, and vllm sizes cuda-graph capture and (on a gdn/mamba hybrid)
|
|
327
|
+
# per-slot recurrent state from that number, both up front -- so a 32-sequence run paid a
|
|
328
|
+
# 1024-sequence reservation and OOMed during capture with most of the card still free.
|
|
329
|
+
f"actor_rollout_ref.rollout.max_num_seqs={rollout_max_num_seqs(int(cfg['prompts_per_step']) * int(cfg['group_size']))}",
|
|
324
330
|
# multi-turn runs flash's own agent loop, registered in the child by flash_grpo_plugin. the
|
|
325
331
|
# stock single_turn_agent generates once and returns; it has no notion of an environment
|
|
326
332
|
# reply, so a multi-turn env on the default loop would train on first turns only.
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/flash/engine/worker/verl/capabilities.py
RENAMED
|
@@ -773,6 +773,45 @@ def rollout_fp8_kv(cc_ok: bool, gdn_hybrid: bool, model_id: str) -> bool:
|
|
|
773
773
|
return rollout_sleep_unsupported(model_id)
|
|
774
774
|
|
|
775
775
|
|
|
776
|
+
_MIN_ROLLOUT_MAX_NUM_SEQS = 16
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
def rollout_max_num_seqs(rollout_batch: int) -> int:
|
|
780
|
+
"""concurrent sequence slots to provision the rollout engine for.
|
|
781
|
+
|
|
782
|
+
verl leaves ``rollout.max_num_seqs`` at its yaml default of 1024 (rollout.yaml:79) and passes
|
|
783
|
+
it straight to the vllm engine (vllm_async_server.py:261). vllm sizes two up-front, fixed
|
|
784
|
+
allocations from that number, neither of which shrinks to the batch actually submitted:
|
|
785
|
+
|
|
786
|
+
* cuda-graph capture. ``_set_cudagraph_sizes`` (vllm ``config/vllm.py``, 0.19.1 -- the version
|
|
787
|
+
``Dockerfile.worker`` pins) derives a capture ladder from
|
|
788
|
+
``max_cudagraph_capture_size = min(max_num_seqs * 2, 512, max_num_batched_tokens)``, taking
|
|
789
|
+
``[1,2,4]``, then ``range(8, min(size+1, 256), 8)``, then ``range(256, size+1, 16)`` -- each
|
|
790
|
+
rung clamped by that ceiling. verl's ``max_num_batched_tokens`` default is 8192
|
|
791
|
+
(``rollout.yaml:73``), so it does not bind. at 1024 the ceiling is 512 and the ladder is 51
|
|
792
|
+
sizes; a lora run captures each size twice, since the dispatcher takes
|
|
793
|
+
``product(cudagraph_capture_sizes, lora_cases)`` with ``lora_cases == [0, 1]`` when
|
|
794
|
+
``cudagraph_specialize_lora`` is on (``v1/cudagraph_dispatcher.py:110-193``, default True) --
|
|
795
|
+
exactly the ``0/102`` seen in the failing console. the ladder saturates at 512, so 1024, 512
|
|
796
|
+
and 256 are indistinguishable; only dropping below 256 shortens it, and 32 yields a ceiling
|
|
797
|
+
of 64, 11 sizes, and 22 graphs. note the prose comment above that function omits the per-rung
|
|
798
|
+
clamp and predicts 34 sizes for any small value; the implementation is authoritative.
|
|
799
|
+
* recurrent state. a gdn/mamba hybrid reserves one state block per decode slot, a dense
|
|
800
|
+
allocation that -- unlike paged kv -- cannot be shared, paged out, or grown on demand.
|
|
801
|
+
|
|
802
|
+
both are paid before the first rollout token, inside the ``gpu_memory_utilization`` budget. a
|
|
803
|
+
grpo/opd step submits exactly ``prompts_per_step * group_size`` sequences, so a run with 32
|
|
804
|
+
concurrent generations was provisioning for 1024 and dying during graph capture with ~80% of
|
|
805
|
+
the card free -- on 234, 358, and 460 GB alike, since the cost is fixed rather than
|
|
806
|
+
proportional to the card.
|
|
807
|
+
|
|
808
|
+
the floor keeps small runs on a usable capture ladder rather than collapsing it to one size.
|
|
809
|
+
"""
|
|
810
|
+
if rollout_batch <= 0:
|
|
811
|
+
raise ValueError("rollout_batch must be positive")
|
|
812
|
+
return max(_MIN_ROLLOUT_MAX_NUM_SEQS, int(rollout_batch))
|
|
813
|
+
|
|
814
|
+
|
|
776
815
|
def rollout_resident_overrides(sleep_unsupported: bool) -> list[str]:
|
|
777
816
|
"""verl overrides that pin the rollout engine resident, or ``[]`` to keep verl's default.
|
|
778
817
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.2.
|
|
3
|
+
version = "1.2.102"
|
|
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.102"
|
|
141
141
|
|
|
142
142
|
[tool.pytest.ini_options]
|
|
143
143
|
pythonpath = ["."]
|
|
@@ -4779,3 +4779,41 @@ def test_the_lora_rollout_guard_does_not_wrap_itself_twice(monkeypatch):
|
|
|
4779
4779
|
|
|
4780
4780
|
assert module.vLLMHttpServer.generate is first
|
|
4781
4781
|
assert asyncio.run(module.vLLMHttpServer().generate([1], {}, "req-3"))[0] == "generated"
|
|
4782
|
+
|
|
4783
|
+
|
|
4784
|
+
@pytest.mark.parametrize(
|
|
4785
|
+
("rollout_batch", "expected"),
|
|
4786
|
+
[(1, 16), (4, 16), (16, 16), (32, 32), (64, 64), (512, 512)],
|
|
4787
|
+
)
|
|
4788
|
+
def test_rollout_max_num_seqs_tracks_the_rollout_batch_above_the_floor(rollout_batch, expected):
|
|
4789
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
4790
|
+
|
|
4791
|
+
assert rollout_max_num_seqs(rollout_batch) == expected
|
|
4792
|
+
|
|
4793
|
+
|
|
4794
|
+
def test_rollout_max_num_seqs_never_returns_verls_default_for_a_small_batch():
|
|
4795
|
+
# the regression this exists for: verl leaves rollout.max_num_seqs at 1024, and vllm sizes
|
|
4796
|
+
# cuda-graph capture (min(max_num_seqs * 2, 512) over a 51-rung ladder, doubled when lora
|
|
4797
|
+
# specialization is on) and per-slot gdn/mamba recurrent state from it, both before the first
|
|
4798
|
+
# rollout token. a 32-sequence grpo step paid a 1024-sequence reservation and OOMed during
|
|
4799
|
+
# capture with ~80% of the card free.
|
|
4800
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
4801
|
+
|
|
4802
|
+
for batch in (8, 32, 64, 128):
|
|
4803
|
+
assert rollout_max_num_seqs(batch) < 1024
|
|
4804
|
+
|
|
4805
|
+
|
|
4806
|
+
def test_rollout_max_num_seqs_is_never_below_the_batch_it_must_serve():
|
|
4807
|
+
# provisioning FEWER slots than the step submits would queue sequences instead of running them,
|
|
4808
|
+
# turning one rollout into several scheduler passes.
|
|
4809
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
4810
|
+
|
|
4811
|
+
for batch in range(1, 600):
|
|
4812
|
+
assert rollout_max_num_seqs(batch) >= batch
|
|
4813
|
+
|
|
4814
|
+
|
|
4815
|
+
def test_rollout_max_num_seqs_rejects_a_nonpositive_batch():
|
|
4816
|
+
from flash.engine.worker.verl.capabilities import rollout_max_num_seqs
|
|
4817
|
+
|
|
4818
|
+
with pytest.raises(ValueError, match="rollout_batch must be positive"):
|
|
4819
|
+
rollout_max_num_seqs(0)
|
|
@@ -1606,7 +1606,10 @@ def test_log_labels_previous_attempt_artifacts_after_the_live_attempt_log(
|
|
|
1606
1606
|
in out
|
|
1607
1607
|
)
|
|
1608
1608
|
assert out.index(live_line) < out.index(previous_header)
|
|
1609
|
-
|
|
1609
|
+
# the dead attempt's heartbeat is still printed -- it explains why a retry exists -- but it
|
|
1610
|
+
# carries its provenance inline, because a section heading does not survive
|
|
1611
|
+
# `grep HEARTBEAT | tail -1`.
|
|
1612
|
+
assert 'HEARTBEAT [superseded attempt=0; current attempt=1] {"stage":"rl_step"' in out
|
|
1610
1613
|
|
|
1611
1614
|
|
|
1612
1615
|
def test_log_still_prints_artifacts_when_the_attempt_lookup_fails(
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/tests/test_cli_commands_coverage.py
RENAMED
|
@@ -365,3 +365,126 @@ def test_chat_keeps_stdout_empty_when_a_styled_stream_carries_no_text(monkeypatc
|
|
|
365
365
|
assert result == 1
|
|
366
366
|
assert captured.out == ""
|
|
367
367
|
assert "no response text from flash-1" in captured.err
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def test_superseded_attempt_heartbeats_are_tagged_in_the_log_stream(capsys) -> None:
|
|
371
|
+
"""`runs log | grep HEARTBEAT | tail -1` must not silently return a dead attempt's heartbeat.
|
|
372
|
+
|
|
373
|
+
The plane appends the highest UPLOADED attempt after the chronological log, so during a retry
|
|
374
|
+
the last heartbeat on screen belongs to the attempt that just died. The section heading says
|
|
375
|
+
so, but a heading does not survive a pipe: the reporter's monitor read
|
|
376
|
+
``step 0, 0 completions, device H200`` for twenty minutes while the run was live on B200,
|
|
377
|
+
because H200 was the card that had already OOMed and been torn down.
|
|
378
|
+
"""
|
|
379
|
+
commands._print_worker_output(
|
|
380
|
+
{
|
|
381
|
+
"console_rl_attempt0.txt": (
|
|
382
|
+
'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
|
|
383
|
+
"Traceback (most recent call last):\n"
|
|
384
|
+
)
|
|
385
|
+
},
|
|
386
|
+
printed_any=True,
|
|
387
|
+
current_attempt=1,
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
out = capsys.readouterr().out
|
|
391
|
+
lines = [line for line in out.splitlines() if "HEARTBEAT" in line]
|
|
392
|
+
assert lines, "the dead attempt's console dump must still be printed"
|
|
393
|
+
# the stale line carries its own provenance, so it cannot be mistaken for the live attempt
|
|
394
|
+
assert "[superseded attempt=0; current attempt=1]" in lines[-1]
|
|
395
|
+
# and the failure dump itself is preserved -- it is why the retry exists
|
|
396
|
+
assert "Traceback (most recent call last):" in out
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
def test_filtering_superseded_heartbeats_leaves_the_live_attempt_last(capsys) -> None:
|
|
400
|
+
"""A consumer that drops tagged lines gets the LIVE attempt's heartbeat, not the dead one."""
|
|
401
|
+
print('HEARTBEAT {"stage":"rl_step","step":1,"attempt":1,"device_name":"B200"}')
|
|
402
|
+
commands._print_worker_output(
|
|
403
|
+
{
|
|
404
|
+
"console_rl_attempt0.txt": (
|
|
405
|
+
'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
|
|
406
|
+
)
|
|
407
|
+
},
|
|
408
|
+
printed_any=True,
|
|
409
|
+
current_attempt=1,
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
heartbeats = [line for line in capsys.readouterr().out.splitlines() if "HEARTBEAT" in line]
|
|
413
|
+
live = [line for line in heartbeats if "[superseded" not in line]
|
|
414
|
+
assert live[-1].endswith('{"stage":"rl_step","step":1,"attempt":1,"device_name":"B200"}')
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def test_current_attempt_heartbeats_are_left_untouched(capsys) -> None:
|
|
418
|
+
"""Only a SUPERSEDED attempt is tagged; the live attempt's own artifact must read normally."""
|
|
419
|
+
commands._print_worker_output(
|
|
420
|
+
{"console_rl_attempt1.txt": 'HEARTBEAT {"stage":"rl_step","step":4,"attempt":1}\n'},
|
|
421
|
+
printed_any=True,
|
|
422
|
+
current_attempt=1,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
out = capsys.readouterr().out
|
|
426
|
+
assert "[superseded" not in out
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def test_teardown_window_still_tags_the_dead_workers_heartbeat(capsys) -> None:
|
|
430
|
+
"""An explicitly null ``remote`` is PROOF no worker is live, so every heartbeat is a dead one.
|
|
431
|
+
|
|
432
|
+
``live_attempt`` answers ``None`` both for "the worker is torn down" and for "no attempt is
|
|
433
|
+
known", and collapsing the two disabled tagging exactly during the retry window the tagging
|
|
434
|
+
exists for -- the dead attempt's heartbeat reached ``grep HEARTBEAT | tail -1`` unmarked while
|
|
435
|
+
replacement capacity was still being acquired.
|
|
436
|
+
"""
|
|
437
|
+
from flash.cli.commands.worker_output import _NO_LIVE_WORKER
|
|
438
|
+
|
|
439
|
+
commands._print_worker_output(
|
|
440
|
+
{
|
|
441
|
+
"console_rl_attempt0.txt": (
|
|
442
|
+
'HEARTBEAT {"stage":"rl_step","step":76,"attempt":0,"device_name":"H200"}\n'
|
|
443
|
+
)
|
|
444
|
+
},
|
|
445
|
+
printed_any=True,
|
|
446
|
+
current_attempt=_NO_LIVE_WORKER,
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
out = capsys.readouterr().out
|
|
450
|
+
lines = [line for line in out.splitlines() if "HEARTBEAT" in line]
|
|
451
|
+
assert lines, "the dead attempt's console dump must still be printed"
|
|
452
|
+
assert "[superseded attempt=0; worker torn down]" in lines[-1], (
|
|
453
|
+
f"a torn-down worker's heartbeat reached the pipe unmarked: {lines[-1]}"
|
|
454
|
+
)
|
|
455
|
+
assert "worker torn down; no live attempt" in out, "the heading must say so too"
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def test_snapshot_distinguishes_teardown_from_an_unknown_attempt() -> None:
|
|
459
|
+
"""``remote: null`` means torn down; a failed lookup means unknown. They are not the same."""
|
|
460
|
+
from flash.cli.commands.worker_output import _NO_LIVE_WORKER, _snapshot_live_attempt
|
|
461
|
+
from flash.client import ClientError
|
|
462
|
+
|
|
463
|
+
class _Run:
|
|
464
|
+
def __init__(self, payload):
|
|
465
|
+
self._payload = payload
|
|
466
|
+
|
|
467
|
+
def get_run(self, _run_id):
|
|
468
|
+
if isinstance(self._payload, Exception):
|
|
469
|
+
raise self._payload
|
|
470
|
+
return self._payload
|
|
471
|
+
|
|
472
|
+
torn_down = {"state": "running", "remote": None, "last_heartbeat": {"attempt": 0}}
|
|
473
|
+
assert _snapshot_live_attempt(_Run(torn_down), "flash-1") == _NO_LIVE_WORKER
|
|
474
|
+
live = {"state": "running", "remote": {"attempt": 1}, "last_heartbeat": {"attempt": 0}}
|
|
475
|
+
assert _snapshot_live_attempt(_Run(live), "flash-1") == 1
|
|
476
|
+
# a lookup failure must NOT claim there is no live worker
|
|
477
|
+
assert _snapshot_live_attempt(_Run(ClientError("boom")), "flash-1") is None
|
|
478
|
+
# nor must a payload that simply carries no remote key
|
|
479
|
+
no_remote = {"state": "running", "last_heartbeat": {"attempt": 0}}
|
|
480
|
+
assert _snapshot_live_attempt(_Run(no_remote), "flash-1") == 0
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def test_heartbeat_tagging_is_idempotent() -> None:
|
|
484
|
+
"""Re-printing an already-tagged dump must not stack a second marker onto the line."""
|
|
485
|
+
from flash.cli.commands.worker_output import _mark_superseded_heartbeats
|
|
486
|
+
|
|
487
|
+
once = _mark_superseded_heartbeats('HEARTBEAT {"step":1}\n', 0, 1)
|
|
488
|
+
twice = _mark_superseded_heartbeats(once, 0, 1)
|
|
489
|
+
assert once == twice
|
|
490
|
+
assert once.count("[superseded") == 1
|
|
@@ -9255,3 +9255,26 @@ def test_opd_accounting_gate_keeps_the_first_failure_reason():
|
|
|
9255
9255
|
state.fail("bridge shutdown")
|
|
9256
9256
|
with pytest.raises(RuntimeError, match="exited with code 1"):
|
|
9257
9257
|
state.checkpoint_state(1, timeout_s=600.0)
|
|
9258
|
+
|
|
9259
|
+
|
|
9260
|
+
def test_overrides_size_max_num_seqs_to_the_opd_rollout_batch():
|
|
9261
|
+
"""OPD colocates the student engine with the trainer, so a wasted reservation is fatal.
|
|
9262
|
+
|
|
9263
|
+
Left unset, verl passes its 1024 default to vllm, which sizes cuda-graph capture and (on a
|
|
9264
|
+
gdn/mamba hybrid) one recurrent state block per decode slot from it -- both before the first
|
|
9265
|
+
student generation and inside the same gpu_memory_utilization budget the resident trainer
|
|
9266
|
+
already shares.
|
|
9267
|
+
"""
|
|
9268
|
+
overrides = dict(
|
|
9269
|
+
value.split("=", 1)
|
|
9270
|
+
for value in build_opd_overrides(_config(train_batch_size=8, group_size=4))
|
|
9271
|
+
)
|
|
9272
|
+
assert overrides["actor_rollout_ref.rollout.max_num_seqs"] == "32"
|
|
9273
|
+
|
|
9274
|
+
|
|
9275
|
+
def test_overrides_floor_max_num_seqs_for_a_tiny_opd_rollout_batch():
|
|
9276
|
+
overrides = dict(
|
|
9277
|
+
value.split("=", 1)
|
|
9278
|
+
for value in build_opd_overrides(_config(train_batch_size=1, group_size=1))
|
|
9279
|
+
)
|
|
9280
|
+
assert overrides["actor_rollout_ref.rollout.max_num_seqs"] == "16"
|
|
@@ -9273,3 +9273,26 @@ def test_resumed_grpo_seeds_the_dump_watermark_at_the_resume_boundary():
|
|
|
9273
9273
|
ledger = RolloutIdentityLedger(1, 2)
|
|
9274
9274
|
with pytest.raises(ValueError, match="no registered rollout identity set"):
|
|
9275
9275
|
ledger.seal(2)
|
|
9276
|
+
|
|
9277
|
+
|
|
9278
|
+
def test_build_verl_overrides_sizes_max_num_seqs_to_the_rollout_batch():
|
|
9279
|
+
"""The rollout engine must be provisioned for the batch the step submits, not verl's default.
|
|
9280
|
+
|
|
9281
|
+
verl leaves ``rollout.max_num_seqs`` at 1024 (rollout.yaml:79). vllm derives
|
|
9282
|
+
``max_cudagraph_capture_size = min(max_num_seqs * 2, 512)`` over the ladder
|
|
9283
|
+
``[1,2,4] + range(8,256,8) + range(256,513,16)`` -- 51 sizes at the default, captured twice
|
|
9284
|
+
when lora specialization is on -- and a gdn/mamba hybrid additionally reserves one recurrent
|
|
9285
|
+
state block per decode slot. Both are paid up front, inside the gpu_memory_utilization budget,
|
|
9286
|
+
so a 32-sequence run died at graph capture on 234, 358 and 460 GB alike.
|
|
9287
|
+
"""
|
|
9288
|
+
o = rl_train.build_verl_overrides(_overrides_cfg(prompts_per_step=8, group_size=4))
|
|
9289
|
+
assert "actor_rollout_ref.rollout.max_num_seqs=32" in o
|
|
9290
|
+
# and never verl's default, which is what made the reservation fixed rather than proportional.
|
|
9291
|
+
assert not any(override == "actor_rollout_ref.rollout.max_num_seqs=1024" for override in o)
|
|
9292
|
+
|
|
9293
|
+
|
|
9294
|
+
def test_build_verl_overrides_floors_max_num_seqs_for_a_tiny_rollout_batch():
|
|
9295
|
+
# a batch of 1 would otherwise capture a single graph size and push every wider decode step
|
|
9296
|
+
# onto the eager path.
|
|
9297
|
+
o = rl_train.build_verl_overrides(_overrides_cfg(prompts_per_step=1, group_size=1))
|
|
9298
|
+
assert "actor_rollout_ref.rollout.max_num_seqs=16" in o
|
|
@@ -1,76 +0,0 @@
|
|
|
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
|
-
from flash.client import ClientError
|
|
21
|
-
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from collections.abc import Mapping
|
|
24
|
-
|
|
25
|
-
from flash.client import ApiClient
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def _artifact_attempt(name: str) -> int | None:
|
|
29
|
-
"""Return the bounded attempt encoded by a worker artifact name."""
|
|
30
|
-
from flash.providers._lifecycle.poll import _attempt_int
|
|
31
|
-
|
|
32
|
-
match = re.search(r"_attempt(\d+)\.txt$", name)
|
|
33
|
-
return _attempt_int(int(match.group(1))) if match else None
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _worker_section_name(name: str, current_attempt: int | None) -> str:
|
|
37
|
-
"""Label an attempt-scoped artifact and identify superseded output."""
|
|
38
|
-
attempt = _artifact_attempt(name)
|
|
39
|
-
if attempt is None:
|
|
40
|
-
return name
|
|
41
|
-
if current_attempt is None:
|
|
42
|
-
return f"{name} (attempt={attempt})"
|
|
43
|
-
if attempt != current_attempt:
|
|
44
|
-
return f"{name} (attempt={attempt}, previous attempt; current attempt={current_attempt})"
|
|
45
|
-
return f"{name} (attempt={attempt}, current attempt)"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def _worker_sections(client: ApiClient, run_id: str) -> dict[str, str]:
|
|
49
|
-
"""Fetch only worker artifacts with printable text."""
|
|
50
|
-
return {name: text for name, text in (client.get_worker_output(run_id) or {}).items() if text}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _snapshot_live_attempt(client: ApiClient, run_id: str) -> int | None:
|
|
54
|
-
"""Read the live attempt without letting a heading lookup hide diagnostic artifacts."""
|
|
55
|
-
try:
|
|
56
|
-
return render.live_attempt(client.get_run(run_id) or {})
|
|
57
|
-
except ClientError:
|
|
58
|
-
return None
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def _print_worker_output(
|
|
62
|
-
sections: Mapping[str, str], *, printed_any: bool = False, current_attempt: int | None = None
|
|
63
|
-
) -> bool:
|
|
64
|
-
"""Print worker artifacts under headings naming the attempt that produced them."""
|
|
65
|
-
for name, text in sections.items():
|
|
66
|
-
# label provenance from the filename rather than letting the final section, which is merely
|
|
67
|
-
# the last one appended, read as the live attempt's output.
|
|
68
|
-
section_name = _worker_section_name(name, current_attempt)
|
|
69
|
-
sep = "\n" if printed_any else ""
|
|
70
|
-
if render.styled():
|
|
71
|
-
print(f"{sep}{render.log_section(section_name)}")
|
|
72
|
-
else:
|
|
73
|
-
print(f"{sep}----- {section_name} -----")
|
|
74
|
-
print(text, end="" if text.endswith("\n") else "\n")
|
|
75
|
-
printed_any = True
|
|
76
|
-
return printed_any
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/bug_report.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/ISSUE_TEMPLATE/feature_request.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/bake-kernel-cache.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/dev-kernel-cache.yml
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/main-source-guard.yml
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/notify-tests-repo.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/publish-image.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.2.98 → freesolo_flash_dev-1.2.102}/.github/workflows/version-parity.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|