freesolo-flash-dev 1.2.12__tar.gz → 1.2.14__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.12 → freesolo_flash_dev-1.2.14}/.gitignore +4 -1
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/adapters/lora_rank.py +113 -2
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/__init__.py +3 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/train_cost.py +41 -1
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/scaffold/TRAINING.md +1 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/core/catalog.py +13 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/core/spec.py +6 -0
- freesolo_flash_dev-1.2.14/flash/engine/profiling/reasoning_render.py +299 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/profiling/sft_workload.py +226 -27
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/profiling/workload_profile.py +55 -2
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/opd_train.py +4 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/opd_train_runner.py +37 -8
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/rl_train_runner.py +12 -6
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/sft_train_runner.py +9 -1
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/failures.py +10 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/child/multiturn.py +15 -3
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/inputs.py +5 -5
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/multi_turn.py +103 -16
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/shims.py +15 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/child_io.py +199 -17
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/adapter.py +41 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/allocator.py +3 -2
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/base.py +4 -0
- freesolo_flash_dev-1.2.14/flash/runner/supervise/retry_decision.py +211 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/seed_submission.py +73 -94
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/deploy.py +128 -92
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/export.py +75 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/preflight.py +37 -10
- freesolo_flash_dev-1.2.14/flash/serve/responses.py +107 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/serving_smoke.py +9 -3
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/pyproject.toml +2 -2
- freesolo_flash_dev-1.2.14/tests/live/test_sft_thinking_render_live.py +285 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_backend_common.py +311 -5
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_estimate.py +191 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_export.py +358 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_oom_escalate_gpu.py +1 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_opd_train.py +200 -18
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_provider_routing.py +305 -2
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_resume_on_retry.py +80 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_rl_train.py +225 -9
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_serve.py +330 -2
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_envs_coverage.py +84 -13
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_serving_contract.py +3 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_sft_train.py +77 -0
- freesolo_flash_dev-1.2.14/tests/test_sft_workload.py +1480 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_training_controls.py +9 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_verifiers.py +148 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_workload_profile.py +20 -3
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/uv.lock +1 -1
- freesolo_flash_dev-1.2.12/tests/test_sft_workload.py +0 -459
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.dockerignore +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.env.example +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/Dockerfile +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/LICENSE +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/NOTICE +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/README.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/SELF_HOSTING.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/deploy.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/test_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/test_params.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/env/test_warnings.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/tables.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/backend_common.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/rl_train.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/sft_train.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/overrides.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/single_turn.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/rl/verl_config.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/capabilities.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker/verl/parallelism.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/_lifecycle/worker.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/sharding.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.2.12 → freesolo_flash_dev-1.2.14}/tests/test_zero2_sharding_gate.py +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
__pycache__/
|
|
2
2
|
*.pyc
|
|
3
|
-
|
|
3
|
+
# no trailing slash: a checkout may point `.venv` at a venv stored elsewhere, and a `.venv/` rule
|
|
4
|
+
# matches only a directory, so the symlink itself stays trackable and `git add -A` commits it.
|
|
5
|
+
# committing it breaks CI on the next run, where `uv sync` aborts on an existing `.venv` path.
|
|
6
|
+
.venv
|
|
4
7
|
venv/
|
|
5
8
|
*.egg-info/
|
|
6
9
|
dist/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.14
|
|
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
|
|
@@ -7,11 +7,11 @@ import json
|
|
|
7
7
|
import math
|
|
8
8
|
import re
|
|
9
9
|
from collections.abc import Callable, Mapping
|
|
10
|
-
from dataclasses import dataclass
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
11
|
from decimal import Decimal, InvalidOperation
|
|
12
12
|
from typing import TYPE_CHECKING, Any
|
|
13
13
|
|
|
14
|
-
from flash.core.catalog import serving_context_cap, serving_lora_rank_cap
|
|
14
|
+
from flash.core.catalog import lora_expert_count, serving_context_cap, serving_lora_rank_cap
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class ServingPreflightError(ValueError):
|
|
@@ -279,6 +279,117 @@ def rank_from_adapter_config(config: Mapping[str, Any], *, source: str) -> int:
|
|
|
279
279
|
)
|
|
280
280
|
|
|
281
281
|
|
|
282
|
+
_LORA_A_INFIX = ".lora_A."
|
|
283
|
+
_LORA_B_INFIX = ".lora_B."
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@dataclass(frozen=True)
|
|
287
|
+
class DeclaredLoraRanks:
|
|
288
|
+
"""The default rank, per-module overrides, and parameter-target module paths in a config."""
|
|
289
|
+
|
|
290
|
+
default: int | None = None
|
|
291
|
+
by_module: Mapping[str, int] = field(default_factory=dict)
|
|
292
|
+
stacked_rank_modules: tuple[str, ...] = ()
|
|
293
|
+
stacked_rank_multiplier: int | None = None
|
|
294
|
+
|
|
295
|
+
def __bool__(self) -> bool:
|
|
296
|
+
return self.default is not None or bool(self.by_module)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def declared_lora_ranks(config: Mapping[str, Any]) -> DeclaredLoraRanks:
|
|
300
|
+
"""Read the per-module LoRA rank structure out of ``adapter_config.json``."""
|
|
301
|
+
if not isinstance(config, Mapping):
|
|
302
|
+
return DeclaredLoraRanks()
|
|
303
|
+
try:
|
|
304
|
+
default = _positive_int(config["r"], source="adapter_config.json", field="r")
|
|
305
|
+
except (KeyError, ValueError):
|
|
306
|
+
default = None
|
|
307
|
+
|
|
308
|
+
by_module: dict[str, int] = {}
|
|
309
|
+
pattern = config.get("rank_pattern")
|
|
310
|
+
if isinstance(pattern, Mapping):
|
|
311
|
+
for module, value in pattern.items():
|
|
312
|
+
try:
|
|
313
|
+
by_module[str(module)] = _positive_int(
|
|
314
|
+
value, source="adapter_config.json", field="rank_pattern"
|
|
315
|
+
)
|
|
316
|
+
except ValueError:
|
|
317
|
+
continue
|
|
318
|
+
|
|
319
|
+
stacked_rank_modules: list[str] = []
|
|
320
|
+
targets = config.get("target_parameters")
|
|
321
|
+
if isinstance(targets, list):
|
|
322
|
+
for target in targets:
|
|
323
|
+
if not isinstance(target, str):
|
|
324
|
+
continue
|
|
325
|
+
module, separator, _ = target.rpartition(".")
|
|
326
|
+
if separator and module:
|
|
327
|
+
stacked_rank_modules.append(module)
|
|
328
|
+
|
|
329
|
+
base_model = str(config.get("base_model_name_or_path") or "").strip()
|
|
330
|
+
return DeclaredLoraRanks(
|
|
331
|
+
default=default,
|
|
332
|
+
by_module=by_module,
|
|
333
|
+
stacked_rank_modules=tuple(stacked_rank_modules),
|
|
334
|
+
stacked_rank_multiplier=lora_expert_count(base_model),
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _rank_for_module(module_path: str, declared: DeclaredLoraRanks) -> int | None:
|
|
339
|
+
"""Resolve a module's rank with PEFT's ordered, anchored ``rank_pattern`` matching."""
|
|
340
|
+
for module, rank in declared.by_module.items():
|
|
341
|
+
if not module:
|
|
342
|
+
continue
|
|
343
|
+
try:
|
|
344
|
+
# entries are regexes in PEFT, deliberately not escaped here either
|
|
345
|
+
if re.match(rf"(.*\.)?({module})$", module_path):
|
|
346
|
+
return rank
|
|
347
|
+
except re.error:
|
|
348
|
+
continue
|
|
349
|
+
return declared.default
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def _module_uses_target_parameters(module_path: str, declared: DeclaredLoraRanks) -> bool:
|
|
353
|
+
"""Whether this serialized module came from one of PEFT's targeted parameters."""
|
|
354
|
+
return any(
|
|
355
|
+
module_path == module or module_path.endswith(f".{module}")
|
|
356
|
+
for module in declared.stacked_rank_modules
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def lora_tensor_rank_disagrees(key: str, shape: Any, declared: DeclaredLoraRanks) -> bool:
|
|
361
|
+
"""Return whether a 2-D LoRA weight provably contradicts its configured rank.
|
|
362
|
+
|
|
363
|
+
Ordinary module weights carry exactly ``r`` on the LoRA axis. A 3-D parameter targeted through
|
|
364
|
+
PEFT's ``target_parameters`` serializes under its parent module and stacks every model expert on
|
|
365
|
+
that axis, so only that module may carry exactly ``r * num_experts``. The distinction must be per
|
|
366
|
+
module because one config may contain ordinary ``target_modules`` and fused parameters together.
|
|
367
|
+
"""
|
|
368
|
+
if not declared:
|
|
369
|
+
return False
|
|
370
|
+
is_a = _LORA_A_INFIX in key
|
|
371
|
+
is_b = _LORA_B_INFIX in key
|
|
372
|
+
if is_a == is_b: # neither, or a key somehow claiming both
|
|
373
|
+
return False
|
|
374
|
+
if not isinstance(shape, (list, tuple)) or len(shape) != 2:
|
|
375
|
+
return False
|
|
376
|
+
dims = [d for d in shape if isinstance(d, int) and not isinstance(d, bool) and d > 0]
|
|
377
|
+
if len(dims) != 2:
|
|
378
|
+
return False
|
|
379
|
+
|
|
380
|
+
infix = _LORA_A_INFIX if is_a else _LORA_B_INFIX
|
|
381
|
+
module_path = key.partition(infix)[0]
|
|
382
|
+
rank = _rank_for_module(module_path, declared)
|
|
383
|
+
if rank is None:
|
|
384
|
+
return False
|
|
385
|
+
axis = dims[0] if is_a else dims[1]
|
|
386
|
+
if _module_uses_target_parameters(module_path, declared):
|
|
387
|
+
multiplier = declared.stacked_rank_multiplier
|
|
388
|
+
expected = rank * multiplier if multiplier is not None else rank
|
|
389
|
+
return axis != expected
|
|
390
|
+
return axis != rank
|
|
391
|
+
|
|
392
|
+
|
|
282
393
|
def alpha_from_adapter_config(config: Mapping[str, Any], *, source: str) -> int:
|
|
283
394
|
"""Return the maximum LoRA alpha across default and per-module metadata."""
|
|
284
395
|
return _max_adapter_value(
|
|
@@ -430,6 +430,7 @@ def cmd_train(args) -> int:
|
|
|
430
430
|
else:
|
|
431
431
|
print(json.dumps(status, indent=2))
|
|
432
432
|
_print_unpacked_batch_warning(status, spec) # after the payload, so stdout stays parseable
|
|
433
|
+
_print_reasoning_loss_warning(status)
|
|
433
434
|
return 0
|
|
434
435
|
status = client.create_run(
|
|
435
436
|
payload,
|
|
@@ -438,6 +439,7 @@ def cmd_train(args) -> int:
|
|
|
438
439
|
)
|
|
439
440
|
run_id = status["run_id"]
|
|
440
441
|
_print_unpacked_batch_warning(status, spec) # a real submit overrides batch_size the same way
|
|
442
|
+
_print_reasoning_loss_warning(status) # and trains on whatever reasoning the template kept
|
|
441
443
|
logger.info(
|
|
442
444
|
"submitted run %s: model=%s algorithm=%s gpu=%s",
|
|
443
445
|
run_id,
|
|
@@ -970,6 +972,7 @@ from flash.cli.commands.train_cost import ( # noqa: E402,F401
|
|
|
970
972
|
_cmd_train_cost_offline,
|
|
971
973
|
_cmd_train_cost_sft,
|
|
972
974
|
_legacy_train_key_rejection_detail,
|
|
975
|
+
_print_reasoning_loss_warning,
|
|
973
976
|
_print_sft_cost,
|
|
974
977
|
_print_train_schema_compatibility,
|
|
975
978
|
_print_unpacked_batch_warning,
|
|
@@ -17,7 +17,11 @@ from flash.client import ApiError, ClientError
|
|
|
17
17
|
from flash.client.runtime_secrets import runtime_secrets_from_local_env
|
|
18
18
|
from flash.client.specs import spec_payload
|
|
19
19
|
from flash.cost.spec import runconfig_from_spec
|
|
20
|
-
from flash.engine.profiling.workload_profile import
|
|
20
|
+
from flash.engine.profiling.workload_profile import (
|
|
21
|
+
reasoning_warning_rows,
|
|
22
|
+
rendered_reasoning_loss_warning,
|
|
23
|
+
unpacked_batch_warning,
|
|
24
|
+
)
|
|
21
25
|
from flash.schema import spec_and_train_keys_from_file, train_schema_metadata
|
|
22
26
|
|
|
23
27
|
|
|
@@ -190,6 +194,41 @@ def _print_unpacked_batch_warning(status: object, spec) -> None:
|
|
|
190
194
|
print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
|
|
191
195
|
|
|
192
196
|
|
|
197
|
+
def _print_reasoning_loss_warning(status: object) -> None:
|
|
198
|
+
"""Warn that the chat template drops authored reasoning before a training GPU is allocated.
|
|
199
|
+
|
|
200
|
+
Control-plane profiling runs inside the server, so the measurement's own stderr never reaches
|
|
201
|
+
the submitting client. The counts travel on the quote's profile and the line is rendered here,
|
|
202
|
+
which is the only place the user can act on it while restructuring is still free.
|
|
203
|
+
"""
|
|
204
|
+
profile = status.get("workload_profile") if isinstance(status, dict) else None
|
|
205
|
+
if not isinstance(profile, dict):
|
|
206
|
+
return
|
|
207
|
+
authored = profile.get("authored_reasoning_turns")
|
|
208
|
+
rendered = profile.get("rendered_reasoning_spans")
|
|
209
|
+
if isinstance(authored, bool) or not isinstance(authored, int):
|
|
210
|
+
return
|
|
211
|
+
if isinstance(rendered, bool) or not isinstance(rendered, int):
|
|
212
|
+
return
|
|
213
|
+
truncated = profile.get("truncated_reasoning_spans")
|
|
214
|
+
message = rendered_reasoning_loss_warning(
|
|
215
|
+
authored_turns=authored,
|
|
216
|
+
rendered_spans=rendered,
|
|
217
|
+
# absent on a profile from an older producer, where the two causes were not yet separated.
|
|
218
|
+
# zero reads as "none were truncated", which is the pre-split behaviour.
|
|
219
|
+
truncated_spans=truncated
|
|
220
|
+
if isinstance(truncated, int) and not isinstance(truncated, bool)
|
|
221
|
+
else 0,
|
|
222
|
+
# the counts above cover the rows the update horizon reaches, so the denominator has to
|
|
223
|
+
# cover the same rows. `retained_examples` is the whole retained dataset -- it sizes the
|
|
224
|
+
# allocation -- and pairing it with bounded counts would understate the survival rate.
|
|
225
|
+
rows=reasoning_warning_rows(profile),
|
|
226
|
+
)
|
|
227
|
+
if not message:
|
|
228
|
+
return
|
|
229
|
+
print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
|
|
230
|
+
|
|
231
|
+
|
|
193
232
|
def _print_sft_cost(status: dict, spec) -> None:
|
|
194
233
|
total = status.get("estimated_cost_usd") if isinstance(status, dict) else None
|
|
195
234
|
if not isinstance(total, (int, float)) or isinstance(total, bool):
|
|
@@ -215,6 +254,7 @@ def _print_sft_cost(status: dict, spec) -> None:
|
|
|
215
254
|
file=sys.stderr,
|
|
216
255
|
)
|
|
217
256
|
_print_unpacked_batch_warning(status, spec)
|
|
257
|
+
_print_reasoning_loss_warning(status)
|
|
218
258
|
|
|
219
259
|
|
|
220
260
|
def _legacy_train_key_rejection_detail(
|
|
@@ -669,6 +669,7 @@ spending another GPU run:
|
|
|
669
669
|
| Local-only env path in config | Config validation says there is no local path mode | Publish first, then use the returned slug in `[environment] id`. `flash train` only runs published env ids, not local paths. |
|
|
670
670
|
| Config knobs are in the wrong table | Validation rejects `[grpo]`, `[sft]`, or unknown `[train]` keys | Put `epochs`, `group_size`, `max_completion_tokens`, `temperature`, `max_context_tokens`, LoRA, and other training knobs under `[train]`. |
|
|
671
671
|
| GPU selection is not what you expected | Leaving `[gpu] type` unset may select a different fitting class as prices or capacity change | Set `[gpu] type` to an active validated class to hard-pin it, or leave it unset for managed cheapest-fit allocation. `train.hf_repo` remains platform-managed. |
|
|
672
|
+
| A pinned run stops after two capacity refusals | The pinned class had no capacity, and no other class was allowed, so there was nowhere to fail over | Widen the search: drop the `[gpu] type` pin for managed allocation, or drop `[gpu] provider`. Flash stops once the class a retry would land on has refused capacity twice, rather than re-queueing on a class the provider keeps refusing. One refusal always earns a retry, since a momentary shortage is not a sold-out class. |
|
|
672
673
|
| Secrets are not available on the worker | Reward code works locally but remote logs show missing API keys or auth failures | List secret names under `[environment] secrets = [...]`, export those env vars locally before submit, or put them in local `.env` / `.env.local`. Never hard-code secret values in the config. |
|
|
673
674
|
| Scorer dependency is missing on the worker | Reward code works locally but every reward is `0.0` remotely; the import your scorer needs is installed in your venv, not the worker's | List the packages your scorer imports under `[environment] pip = ["pymongo>=4.6"]`. They are installed alongside Flash's own worker requirement. `flash env test` names the failing import locally before you spend a GPU on it. Entries name packages only: pip options and URLs with inline credentials are rejected, because the spec is stored and uploaded in plaintext (put the credential in `[environment] secrets`). |
|
|
674
675
|
| Wrong model / thinking setting | Config validation fails, or chat behavior does not match the run | Config validation is authoritative for model and thinking compatibility. Thinking is a run-level choice, and `flash models chat` does not expose an override flag. |
|
|
@@ -148,6 +148,9 @@ class ModelInfo:
|
|
|
148
148
|
mamba_block_size: int = 0
|
|
149
149
|
# grouped (in_features, out_features, count) for peft all-linear on the full loaded model.
|
|
150
150
|
lora_target_shapes: tuple[tuple[int, int, int], ...] = ()
|
|
151
|
+
# fused routed experts stacked on the lora rank axis for target_parameters. zero means no
|
|
152
|
+
# catalog-backed stacked allowance; ordinary and unknown target parameters carry exactly r.
|
|
153
|
+
lora_expert_count: int = 0
|
|
151
154
|
|
|
152
155
|
@property
|
|
153
156
|
def is_moe(self) -> bool:
|
|
@@ -174,6 +177,7 @@ class ModelInfo:
|
|
|
174
177
|
"linear_value_head_dim",
|
|
175
178
|
"linear_conv_kernel_dim",
|
|
176
179
|
"lora_target_shapes",
|
|
180
|
+
"lora_expert_count",
|
|
177
181
|
):
|
|
178
182
|
data.pop(key, None)
|
|
179
183
|
serving = data["serving"]
|
|
@@ -500,6 +504,7 @@ MODELS: dict[str, ModelInfo] = {
|
|
|
500
504
|
(4608, 2048, 1),
|
|
501
505
|
(4608, 4608, 1),
|
|
502
506
|
),
|
|
507
|
+
lora_expert_count=256,
|
|
503
508
|
vocab_size=248_320,
|
|
504
509
|
algos=ALGORITHMS,
|
|
505
510
|
min_vram_gb=141,
|
|
@@ -569,6 +574,14 @@ def serving_lora_rank_cap(model: str | ModelInfo | None) -> int | None:
|
|
|
569
574
|
return int(info.serving.max_lora_rank)
|
|
570
575
|
|
|
571
576
|
|
|
577
|
+
def lora_expert_count(model: str | ModelInfo | None) -> int | None:
|
|
578
|
+
"""Return the exact fused-expert stack size for LoRA target parameters, when cataloged."""
|
|
579
|
+
info = _model_info_for_serving(model)
|
|
580
|
+
if info is None or info.lora_expert_count <= 0:
|
|
581
|
+
return None
|
|
582
|
+
return int(info.lora_expert_count)
|
|
583
|
+
|
|
584
|
+
|
|
572
585
|
def serving_context_cap(model: str | ModelInfo | None) -> int | None:
|
|
573
586
|
"""Return the model's served ``max_model_len``, or None without a local serving entry.
|
|
574
587
|
|
|
@@ -364,6 +364,12 @@ class TrainSpec:
|
|
|
364
364
|
save_at_steps = parse_positive_int_tuple(self.save_at_steps, name="train.save_at_steps")
|
|
365
365
|
object.__setattr__(self, "max_steps", max_steps)
|
|
366
366
|
object.__setattr__(self, "save_at_steps", save_at_steps)
|
|
367
|
+
# a nonpositive interval is not a cadence. the public schema already rejects one, but a
|
|
368
|
+
# persisted or internally built spec reaches this dataclass directly, so canonicalize it to
|
|
369
|
+
# the unset sentinel every save_freq site already resolves to its algorithm default. leaving
|
|
370
|
+
# it signed would make the horizon clamp read it as an interval of one and checkpoint every
|
|
371
|
+
# single step.
|
|
372
|
+
object.__setattr__(self, "save_every", parse_max_steps(self.save_every))
|
|
367
373
|
effective_max_steps = max_steps or 0
|
|
368
374
|
if save_at_steps and effective_max_steps <= 0:
|
|
369
375
|
raise ValueError("train.save_at_steps requires positive train.max_steps")
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"""How much of a transcript's authored reasoning survives the chat template into the loss.
|
|
2
|
+
|
|
3
|
+
Qwen3.5's template keeps ``<think>`` only on assistant turns after the last user message and strips
|
|
4
|
+
it from earlier history, so a K-turn gold transcript delivers roughly 1/K of its reasoning to the
|
|
5
|
+
loss. The stored messages are never wrong -- only the render is -- so a correct-looking dataset and
|
|
6
|
+
a green ``flash env test`` both survive it.
|
|
7
|
+
|
|
8
|
+
Survival is answered by IDENTITY: the row is rendered again with each reasoning-authoring turn's
|
|
9
|
+
reasoning marked, and a turn survives exactly when its marker reaches the render. Counting
|
|
10
|
+
``<think>`` tags cannot answer it -- the template opens an EMPTY block on every trailing assistant
|
|
11
|
+
turn, so a transcript stripped of all its reasoning still renders one and scores as a survivor,
|
|
12
|
+
the exact case this exists to catch. A marker also rides inside the reasoning itself, so a
|
|
13
|
+
``<think>`` an answer merely quotes carries none and can never be credited.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import re
|
|
19
|
+
from typing import Any
|
|
20
|
+
|
|
21
|
+
_THINK_OPEN = "<think>"
|
|
22
|
+
_THINK_CLOSE = "</think>"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _message_text(content: object) -> str:
|
|
26
|
+
"""The text of a message's ``content`` in either the string or content-block shape."""
|
|
27
|
+
if isinstance(content, str):
|
|
28
|
+
return content
|
|
29
|
+
if isinstance(content, list):
|
|
30
|
+
return "".join(
|
|
31
|
+
block["text"]
|
|
32
|
+
for block in content
|
|
33
|
+
if isinstance(block, dict)
|
|
34
|
+
and block.get("type") == "text"
|
|
35
|
+
and isinstance(block.get("text"), str)
|
|
36
|
+
)
|
|
37
|
+
return ""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _reasoning_body_end(text: str) -> int | None:
|
|
41
|
+
"""Where this turn's reasoning BODY ends, or ``None`` when the turn authored no reasoning.
|
|
42
|
+
|
|
43
|
+
The template's own rule: the text after the LAST ``<think>`` preceding the FIRST ``</think>``.
|
|
44
|
+
An opener-less ``reasoned</think>answer`` counts, being the shape a completion sampled against a
|
|
45
|
+
prompt-supplied opening tag carries.
|
|
46
|
+
|
|
47
|
+
Emptiness is judged on the body: the template stamps an empty ``<think>\\n\\n</think>`` onto
|
|
48
|
+
qualifying trailing turns, and counting that as authored puts a turn in the denominator that
|
|
49
|
+
never had reasoning to lose.
|
|
50
|
+
|
|
51
|
+
The end excludes trailing whitespace because the template renders reasoning through ``|trim``. A
|
|
52
|
+
marker placed after that whitespace shields it from the trim, so the marked render keeps bytes
|
|
53
|
+
the real one drops and tokenizes one token longer -- a cap at the block's real end then reports
|
|
54
|
+
a block that fits as cut.
|
|
55
|
+
"""
|
|
56
|
+
close = text.find(_THINK_CLOSE)
|
|
57
|
+
if close < 0:
|
|
58
|
+
return None
|
|
59
|
+
open_at = text.rfind(_THINK_OPEN, 0, close)
|
|
60
|
+
body = 0 if open_at < 0 else open_at + len(_THINK_OPEN)
|
|
61
|
+
return len(text[:close].rstrip()) if text[body:close].strip() else None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def reasoned_assistant_turns(messages: list[dict[str, Any]]) -> int:
|
|
65
|
+
"""Assistant turns that author reasoning, counted from the SOURCE messages.
|
|
66
|
+
|
|
67
|
+
Every accepted shape counts -- inline span, content blocks, ``reasoning_content``, opener-less --
|
|
68
|
+
because a shape missed here reads as "authored no reasoning" and silences the warning for a row
|
|
69
|
+
losing all of it.
|
|
70
|
+
|
|
71
|
+
A ``reasoning_content`` STRING is authoritative even when EMPTY: the template renders that field
|
|
72
|
+
and leaves ``content`` whole, so an empty field means the turn authored nothing however the
|
|
73
|
+
answer is written, and falling back to inline detection would read a ``<think>`` the ANSWER
|
|
74
|
+
quotes as reasoning. Absent and ``None`` differ -- both parse the inline span.
|
|
75
|
+
"""
|
|
76
|
+
turns = 0
|
|
77
|
+
for message in messages:
|
|
78
|
+
if message.get("role") != "assistant":
|
|
79
|
+
continue
|
|
80
|
+
reasoning = message.get("reasoning_content")
|
|
81
|
+
if isinstance(reasoning, str):
|
|
82
|
+
turns += 1 if reasoning.strip() else 0
|
|
83
|
+
elif _reasoning_body_end(_message_text(message.get("content"))) is not None:
|
|
84
|
+
turns += 1
|
|
85
|
+
return turns
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def reasoning_marker_prefix(text: str) -> str:
|
|
89
|
+
"""A marker stem guaranteed absent from ``text``, so a marker cannot match user content.
|
|
90
|
+
|
|
91
|
+
Extended rather than assumed unique: a dataset containing the stem would otherwise let its own
|
|
92
|
+
text answer "did this turn's reasoning survive?".
|
|
93
|
+
|
|
94
|
+
Doubling then bisecting, not growing one character at a time: text holding the stem followed by
|
|
95
|
+
N filler characters keeps every one-character extension a substring, so each of N scans walks
|
|
96
|
+
the whole row (1.4s on a 50k row, before tokenization).
|
|
97
|
+
"""
|
|
98
|
+
stem = "flashreasoningmark"
|
|
99
|
+
if stem not in text:
|
|
100
|
+
return stem
|
|
101
|
+
low, high = 0, 1
|
|
102
|
+
while stem + "x" * high in text:
|
|
103
|
+
low, high = high, high * 2
|
|
104
|
+
while low + 1 < high:
|
|
105
|
+
mid = (low + high) // 2
|
|
106
|
+
low, high = (mid, high) if stem + "x" * mid in text else (low, mid)
|
|
107
|
+
return stem + "x" * high
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _turn_marker(prefix: str, index: int) -> str:
|
|
111
|
+
"""The marker naming ONE turn's reasoning.
|
|
112
|
+
|
|
113
|
+
The trailing ``e`` terminates the index: without it ``{prefix}1`` is a substring of
|
|
114
|
+
``{prefix}10``, so a dropped turn 1 reads as surviving whenever turn 10 does.
|
|
115
|
+
"""
|
|
116
|
+
return f"{prefix}{index}e"
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _marks_reasoning(message: dict) -> bool:
|
|
120
|
+
"""Whether this turn gets a marker stamped into it.
|
|
121
|
+
|
|
122
|
+
One predicate for both stamping and listing: a turn listed but not stamped reads as a template
|
|
123
|
+
drop, and a turn stamped but not listed cannot be checked at all.
|
|
124
|
+
"""
|
|
125
|
+
return message.get("role") == "assistant" and bool(reasoned_assistant_turns([message]))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def reasoning_markers(messages: list[dict], prefix: str) -> list[str]:
|
|
129
|
+
"""The marker for each reasoning-authoring turn, in order.
|
|
130
|
+
|
|
131
|
+
Separate markers because survival is asked per turn: searching for the shared prefix answers
|
|
132
|
+
only "did ANY reasoning survive", so one surviving turn would cover a stripped neighbour.
|
|
133
|
+
"""
|
|
134
|
+
return [
|
|
135
|
+
_turn_marker(prefix, index)
|
|
136
|
+
for index, message in enumerate(messages)
|
|
137
|
+
if _marks_reasoning(message)
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _marked_inline_reasoning(content: object, marker: str) -> object:
|
|
142
|
+
"""``content`` with ``marker`` stamped at the end of the reasoning the template will keep."""
|
|
143
|
+
if isinstance(content, str):
|
|
144
|
+
at = _reasoning_body_end(content)
|
|
145
|
+
return content if at is None else content[:at] + marker + content[at:]
|
|
146
|
+
if not isinstance(content, list):
|
|
147
|
+
return content
|
|
148
|
+
# the template concatenates the text blocks before splitting, so the offset is resolved on the
|
|
149
|
+
# joined text and then mapped back into whichever block contains it.
|
|
150
|
+
texts = [
|
|
151
|
+
block["text"]
|
|
152
|
+
if isinstance(block, dict)
|
|
153
|
+
and block.get("type") == "text"
|
|
154
|
+
and isinstance(block.get("text"), str)
|
|
155
|
+
else None
|
|
156
|
+
for block in content
|
|
157
|
+
]
|
|
158
|
+
at = _reasoning_body_end("".join(text or "" for text in texts))
|
|
159
|
+
if at is None:
|
|
160
|
+
return content
|
|
161
|
+
marked: list = []
|
|
162
|
+
consumed = 0
|
|
163
|
+
placed = False
|
|
164
|
+
for block, text in zip(content, texts, strict=True):
|
|
165
|
+
if text is None:
|
|
166
|
+
marked.append(block)
|
|
167
|
+
continue
|
|
168
|
+
local = at - consumed
|
|
169
|
+
consumed += len(text)
|
|
170
|
+
# an offset on a block boundary matches the end of one block and the start of the next, so
|
|
171
|
+
# the guard keeps it stamped exactly once.
|
|
172
|
+
if placed or not 0 <= local <= len(text):
|
|
173
|
+
marked.append(block)
|
|
174
|
+
continue
|
|
175
|
+
placed = True
|
|
176
|
+
marked.append({**block, "text": text[:local] + marker + text[local:]})
|
|
177
|
+
return marked
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def with_marked_reasoning(messages: list[dict], prefix: str) -> list[dict]:
|
|
181
|
+
"""The same messages with each reasoning-authoring assistant turn's reasoning marked.
|
|
182
|
+
|
|
183
|
+
Only reasoning TEXT changes, so the template's ``last_query_index`` rule sees identical roles in
|
|
184
|
+
identical positions and keeps exactly the blocks it would have anyway.
|
|
185
|
+
|
|
186
|
+
Both shapes mark the ``|trim``-ed reasoning; marking after trailing whitespace would shield it
|
|
187
|
+
from the template's trim (see ``_reasoning_body_end``).
|
|
188
|
+
"""
|
|
189
|
+
marked: list[dict] = []
|
|
190
|
+
for index, message in enumerate(messages):
|
|
191
|
+
copied = dict(message)
|
|
192
|
+
if _marks_reasoning(message):
|
|
193
|
+
marker = _turn_marker(prefix, index)
|
|
194
|
+
reasoning = copied.get("reasoning_content")
|
|
195
|
+
if isinstance(reasoning, str) and reasoning.strip():
|
|
196
|
+
# the template reads this field in preference to an inline span, so it is the
|
|
197
|
+
# reasoning and the marker belongs in it
|
|
198
|
+
copied["reasoning_content"] = reasoning.rstrip() + marker
|
|
199
|
+
else:
|
|
200
|
+
copied["content"] = _marked_inline_reasoning(copied.get("content"), marker)
|
|
201
|
+
marked.append(copied)
|
|
202
|
+
return marked
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def strip_reasoning_markers(text: str, prefix: str) -> str:
|
|
206
|
+
"""``text`` with every marker removed, so a marked render can be measured against the cap."""
|
|
207
|
+
return re.sub(rf"{re.escape(prefix)}\d+e", "", text)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def marked_reasoning_end(marked_text: str, marker: str) -> int | None:
|
|
211
|
+
"""Where this turn's rendered reasoning ENDS in the marked render, or ``None`` if it was dropped.
|
|
212
|
+
|
|
213
|
+
``None`` IS the survival answer: a marker rides only inside text the template kept as this
|
|
214
|
+
turn's reasoning, so its absence is exactly a stripped turn.
|
|
215
|
+
|
|
216
|
+
The offset runs through the closing tag -- so the caller asks whether the WHOLE block fit -- and
|
|
217
|
+
stops there rather than at the blank line before the answer, which costs a real token and would
|
|
218
|
+
call a fully retained block truncated.
|
|
219
|
+
"""
|
|
220
|
+
at = marked_text.find(marker)
|
|
221
|
+
if at < 0:
|
|
222
|
+
return None
|
|
223
|
+
close = marked_text.find(_THINK_CLOSE, at)
|
|
224
|
+
return at + len(marker) if close < 0 else close + len(_THINK_CLOSE)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def horizon_row_count(row_count: int, *, examples_per_update: int, updates: int) -> int:
|
|
228
|
+
"""How many retained rows an update horizon reaches, in retained order.
|
|
229
|
+
|
|
230
|
+
Updates wrap at the end of an epoch, so a horizon past one full pass saturates at ``row_count``
|
|
231
|
+
rather than counting a row twice. Shared with the CLI so the denominator matches: a bounded
|
|
232
|
+
count over a whole-dataset denominator would understate the survival rate.
|
|
233
|
+
"""
|
|
234
|
+
per_update = max(int(examples_per_update), 1)
|
|
235
|
+
return min(int(row_count), max(int(updates) * per_update, 0))
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def reasoning_warning_rows(profile: object) -> int:
|
|
239
|
+
"""The row denominator the reasoning counts were totalled over, from a profile OBJECT or dict.
|
|
240
|
+
|
|
241
|
+
Both shapes render the same line: the worker holds the profile, the CLI only sees the dict that
|
|
242
|
+
travelled on the quote. It is serialized rather than re-derived because a horizon-bounded count
|
|
243
|
+
is indistinguishable from a whole-dataset one by inspection -- both carry ``examples_per_update``
|
|
244
|
+
and ``authoritative_steps`` -- so deriving it would pair a binding horizon with unbounded counts.
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
def _int(key: str) -> int | None:
|
|
248
|
+
value = profile.get(key) if isinstance(profile, dict) else getattr(profile, key, None)
|
|
249
|
+
return None if isinstance(value, bool) or not isinstance(value, int) else value
|
|
250
|
+
|
|
251
|
+
rows = _int("reasoning_rows")
|
|
252
|
+
if rows is not None:
|
|
253
|
+
return rows
|
|
254
|
+
retained = _int("retained_examples")
|
|
255
|
+
return 0 if retained is None else retained
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def rendered_reasoning_loss_warning(
|
|
259
|
+
*,
|
|
260
|
+
authored_turns: int,
|
|
261
|
+
rendered_spans: int,
|
|
262
|
+
rows: int,
|
|
263
|
+
truncated_spans: int = 0,
|
|
264
|
+
) -> str | None:
|
|
265
|
+
"""One user-facing line when authored reasoning does not reach the loss.
|
|
266
|
+
|
|
267
|
+
Reasoning is lost two ways with OPPOSITE remedies -- the template strips earlier history, or
|
|
268
|
+
``max_context_tokens`` cuts a block the template KEPT off the end of the row -- so the causes are
|
|
269
|
+
counted separately and each names its own fix. Silent when nothing was authored (the thinking-
|
|
270
|
+
mode check owns that) or when everything survived; any drop is reported, since the count is
|
|
271
|
+
exact rather than sampled and any loss is real lost supervision.
|
|
272
|
+
"""
|
|
273
|
+
if authored_turns <= 0:
|
|
274
|
+
return None
|
|
275
|
+
stripped = authored_turns - rendered_spans
|
|
276
|
+
if stripped <= 0 and truncated_spans <= 0:
|
|
277
|
+
return None
|
|
278
|
+
reaching = rendered_spans - truncated_spans
|
|
279
|
+
causes = []
|
|
280
|
+
if stripped > 0:
|
|
281
|
+
causes.append(
|
|
282
|
+
f"the chat template dropped {stripped} of {authored_turns} authored reasoning blocks "
|
|
283
|
+
"-- it keeps <think> only on assistant turns after the last user message and strips it "
|
|
284
|
+
"from earlier history, so a multi-turn transcript trains on a fraction of its reasoning "
|
|
285
|
+
"and on a tag layout inference never produces. split each K-turn transcript into K "
|
|
286
|
+
"single-turn rows, so every turn's reasoning sits in the final assistant target where "
|
|
287
|
+
"the template keeps it"
|
|
288
|
+
)
|
|
289
|
+
if truncated_spans > 0:
|
|
290
|
+
causes.append(
|
|
291
|
+
f"max_context_tokens cut {truncated_spans} rendered reasoning "
|
|
292
|
+
f"{'block' if truncated_spans == 1 else 'blocks'} off the end of the row -- the "
|
|
293
|
+
"template kept these, so raise max_context_tokens or shorten the rows rather than "
|
|
294
|
+
"restructuring the transcript"
|
|
295
|
+
)
|
|
296
|
+
return (
|
|
297
|
+
f"{'; '.join(causes)}. across {rows} SFT rows, {reaching} of {authored_turns} authored "
|
|
298
|
+
f"reasoning blocks reach the loss ({reaching / authored_turns:.0%})."
|
|
299
|
+
)
|