freesolo-flash-dev 1.1.95__tar.gz → 1.2.7__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.1.95 → freesolo_flash_dev-1.2.7}/Dockerfile.worker +4 -2
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/PKG-INFO +3 -2
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/README.md +2 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/SELF_HOSTING.md +27 -4
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/__init__.py +65 -5
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/__init__.py +30 -9
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/deploy.py +266 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/scaffold/TRAINING.md +8 -8
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/tables.py +11 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cost/analytical.py +12 -60
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cost/facts.py +0 -28
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cost/spec.py +0 -57
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cost/types.py +0 -7
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/profiling/workload_profile.py +1 -281
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/__init__.py +30 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/backend_common.py +8 -3
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/opd_train_runner.py +30 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/perf/__init__.py +9 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/perf/lifecycle.py +150 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/rl_train.py +4 -14
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/rl_train_runner.py +2 -24
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/sft_train.py +1 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/sft_train_runner.py +5 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/overrides.py +6 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/multi_turn.py +15 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/single_turn.py +3 -89
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/verl_config.py +27 -63
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/verl/capabilities.py +5 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/verl/child_io.py +190 -1
- freesolo_flash_dev-1.2.7/flash/engine/worker/verl/parallelism.py +76 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/worker.py +4 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/base.py +13 -27
- freesolo_flash_dev-1.2.7/flash/providers/sharding.py +114 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_allocator.py +0 -24
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_backend_common.py +428 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_commands.py +746 -4
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_errors.py +60 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_help.py +2 -1
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_render_coverage.py +19 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_render_theme.py +7 -0
- freesolo_flash_dev-1.2.7/tests/test_cost_equation.py +34 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cost_estimate.py +2 -3
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_oom_escalate_gpu.py +221 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_opd_train.py +69 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_rl_train.py +21 -295
- freesolo_flash_dev-1.2.7/tests/test_zero2_sharding_gate.py +266 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/uv.lock +1 -1
- freesolo_flash_dev-1.1.95/flash/engine/profiling/reward_profile.py +0 -173
- freesolo_flash_dev-1.1.95/flash/engine/worker/verl/parallelism.py +0 -27
- freesolo_flash_dev-1.1.95/tests/test_cost_equation.py +0 -56
- freesolo_flash_dev-1.1.95/tests/test_cost_rewards.py +0 -213
- freesolo_flash_dev-1.1.95/tests/test_reward_profile.py +0 -694
- freesolo_flash_dev-1.1.95/tests/test_rollout_profile_quote.py +0 -110
- freesolo_flash_dev-1.1.95/tests/test_rollout_workload_profile.py +0 -488
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.dockerignore +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.env.example +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/CODEOWNERS +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/dependabot.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/.gitignore +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/CHANGELOG.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/CODE_OF_CONDUCT.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/CONTRIBUTING.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/Dockerfile +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/LICENSE +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/NOTICE +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/SECURITY.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/deploy/infisical/README.md +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/deploy/infisical/entrypoint.sh +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/extract_cudart_fix.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/channel.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/diagnostics.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/fileio.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/logging.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/_internal/paths.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/adapters/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/adapters/artifacts.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/adapters/lora_rank.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/episode.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/eval.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/eval_args.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/imports.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/list.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/push.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/retained.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/setup.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/env/test.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/traces.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/commands/train_cost.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/scaffold/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/cost.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/env_panels.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/heartbeat.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/render.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cli/ui/tty.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/freesolo_api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/shapes.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/client/streaming.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/content/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/content/multimodal.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/content/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/content/thinking.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/core/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/core/catalog.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/core/spec.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/kv_sizing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/model_config_probe.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/recipe.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/steps.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/plan/vram.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/profiling/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/profiling/dataset_profile.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/profiling/sft_workload.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/profiling/tokenizer.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/result/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/result/accounting.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/result/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/entry/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/entry/opd.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/entry/rl.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/entry/sft.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/io/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/io/heartbeat.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/io/hf.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/io/prefetch.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/io/wandb_log.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/model/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/model/adapter.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/model/decoding.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/model/lora.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/model/packing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/opd_train.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/runtime/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/runtime/rng.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/score_batcher.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/teacher/client.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/teacher/encoding.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/core/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/core/child/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/core/child/glue.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/finalize.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/batching.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/bridge.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/child/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/child/bridge.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/child/plugin.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/child/structured.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/failures.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/gkd.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/prompts.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/scoring.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/opd/validation.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/child/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/child/plugin.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/config.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/inputs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/scoring.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/rl/shims.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/sft/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/sft/checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/train/sft/config.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/verl/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/verl/checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker/verl/diagnostics.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/cache_security.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/dataset_selection.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/evaluations.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/identity.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/namespace_listing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/package/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/package/limits.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/package/unpack.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/auth.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/bootstrap.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/deadline.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/http.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/instance.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/poll.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/poll_instance.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/_lifecycle/provider.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/artifacts/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/artifacts/hf.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/artifacts/preload_runpod.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/artifacts/weight_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/fit_errors.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/auth.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/gpus.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/jobs/reap.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/lambda_/pricing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/job_execution.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/resources.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/serverless/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/runpod/serverless/endpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/artifacts.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/attempts.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/costs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/deadlines.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/preparation.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/reconciliation.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/results/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/results/checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/results/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/status.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/submit.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/attach.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/deploy.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/lifecycle.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/recovery.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/seed_submission.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/supervise/transitions.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/runner/weight_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/adapter_check.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/errors.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/streaming.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/thinking.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/billing/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/billing/charges.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/billing/retry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/environment_registry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/envs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/projects.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/reconcile.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/run_registry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/teacher_broker.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/teacher_errors.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/domain/teacher_requests.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/auth.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/db.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/deps.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/internal_client.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/locks.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/platform/runtime.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/serving_completion.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/serving_revisions.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/serving_smoke.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/server/routes/teacher.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/teacher/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/teacher/limits.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/flash/teacher/retry_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/scripts/check_file_size.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/scripts/check_function_size.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/scripts/check_verl_pin_exists.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/scripts/scrub_history.sh +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/profile.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/teacher.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_adapter_shard_completeness.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_build_context_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_catalog_only_models.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_credential_shadowing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_gpus_flag.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cli_wandb_warning.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_client_import_purity.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_config_env_vars.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_dataset_profile.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_evaluations.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_list_api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_list_cli.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_list_hub.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_ref_pinning.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_freesolo_api_transport.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_grpo_resident_sizing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_grpo_reward_batching.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_infisical_secrets.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_opd_limits.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_opd_multiturn_eos_boundary.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_parasail_teacher.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_projects.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_serve_reasoning_content.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_server_standalone.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_train.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_sft_workload.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_step_floor.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_step_metrics.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_teacher_broker.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_teacher_encoding_contract.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_type_comment_prose.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_wandb_link.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_warmstart_error_attribution.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_worker_thinking.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_workflow_contracts.py +0 -0
- {freesolo_flash_dev-1.1.95 → freesolo_flash_dev-1.2.7}/tests/test_workload_profile.py +0 -0
|
@@ -57,7 +57,8 @@ RUN pip install --no-cache-dir \
|
|
|
57
57
|
"huggingface_hub>=1.2.0" \
|
|
58
58
|
"accelerate>=1.4" \
|
|
59
59
|
"wandb>=0.17" \
|
|
60
|
-
"flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@
|
|
60
|
+
"flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@9c8e42e762fce087c27b673af4922795d9edb85e" \
|
|
61
|
+
"flash-qla==0.1.2" \
|
|
61
62
|
"tilelang==0.1.11" \
|
|
62
63
|
"apache-tvm-ffi==0.1.11" \
|
|
63
64
|
"hf_transfer" \
|
|
@@ -331,7 +332,8 @@ RUN printf '%s\n' "numpy==2.2.6" "xgrammar==0.1.25" "vllm==0.19.1" "transformers
|
|
|
331
332
|
"bitsandbytes>=0.49" qwen-vl-utils \
|
|
332
333
|
"wandb>=0.17" \
|
|
333
334
|
cachetools uvicorn fastapi torchvision tqdm pyarrow \
|
|
334
|
-
"flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@
|
|
335
|
+
"flash-linear-attention @ git+https://github.com/fla-org/flash-linear-attention.git@9c8e42e762fce087c27b673af4922795d9edb85e" \
|
|
336
|
+
"flash-qla==0.1.2" \
|
|
335
337
|
"tilelang==0.1.11" \
|
|
336
338
|
"apache-tvm-ffi==0.1.11" \
|
|
337
339
|
&& rm -f /tmp/verl-overrides.txt \
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.7
|
|
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
|
|
@@ -108,7 +108,7 @@ path is self-hostable end to end — see **[SELF_HOSTING.md](SELF_HOSTING.md)**.
|
|
|
108
108
|
|
|
109
109
|
## Using the hosted service
|
|
110
110
|
|
|
111
|
-
`flash login` is not interactive
|
|
111
|
+
`flash login` is not interactive. Export `FREESOLO_API_KEY` first so the key does not appear in process listings:
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
pip install freesolo-flash
|
|
@@ -161,6 +161,7 @@ then pass `RUN_ID/step-N` as the adapter id. To copy a finished adapter into you
|
|
|
161
161
|
HuggingFace repo:
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
+
export HF_TOKEN=hf_...
|
|
164
165
|
flash models export --adapter-id RUN_ID --repository your-org/your-repo
|
|
165
166
|
```
|
|
166
167
|
|
|
@@ -44,7 +44,7 @@ path is self-hostable end to end — see **[SELF_HOSTING.md](SELF_HOSTING.md)**.
|
|
|
44
44
|
|
|
45
45
|
## Using the hosted service
|
|
46
46
|
|
|
47
|
-
`flash login` is not interactive
|
|
47
|
+
`flash login` is not interactive. Export `FREESOLO_API_KEY` first so the key does not appear in process listings:
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
50
|
pip install freesolo-flash
|
|
@@ -97,6 +97,7 @@ then pass `RUN_ID/step-N` as the adapter id. To copy a finished adapter into you
|
|
|
97
97
|
HuggingFace repo:
|
|
98
98
|
|
|
99
99
|
```bash
|
|
100
|
+
export HF_TOKEN=hf_...
|
|
100
101
|
flash models export --adapter-id RUN_ID --repository your-org/your-repo
|
|
101
102
|
```
|
|
102
103
|
|
|
@@ -36,6 +36,28 @@ export RUNPOD_API_KEY=... # or LAMBDA_API_KEY, or VAST_API_KEY
|
|
|
36
36
|
flash-server --host 0.0.0.0 --port 8080
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
`flash env test` runs a scaffolded environment **locally**, so it needs the `freesolo` SDK in the
|
|
40
|
+
interpreter that loads your `environment.py`. The `[server]` extra above already includes it. The
|
|
41
|
+
bare `pip install freesolo-flash` does not - it is client-only and pulls nothing - so on a machine
|
|
42
|
+
where you author environments without the server extra, validation fails until you add it:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install freesolo # same interpreter as the CLI
|
|
46
|
+
uv tool install freesolo-flash --with freesolo --force # existing uv tool: rewrite it with the SDK
|
|
47
|
+
pipx inject freesolo-flash freesolo # existing pipx tool
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The lower two matter if you installed the CLI with `uv tool` or `pipx`: the `flash` executable then
|
|
51
|
+
lives in its own venv, and a plain `pip install freesolo` lands in your shell's interpreter instead
|
|
52
|
+
|
|
53
|
+
- `python -c "import freesolo"` works while `flash env test` still fails. Use the line for the
|
|
54
|
+
manager you installed with; `--force` is what makes `uv tool install` update an existing tool
|
|
55
|
+
rather than no-op, and pipx has no equivalent of `--with`, so the SDK goes in via `inject`.
|
|
56
|
+
|
|
57
|
+
(`flash env eval` is not local in this sense. It evaluates a run against a **published** hub
|
|
58
|
+
environment and refuses a generic `github:` ref outright, which is the only kind a standalone plane
|
|
59
|
+
accepts - so installing the SDK does not make it usable self-hosted.)
|
|
60
|
+
|
|
39
61
|
The `server` extra pulls in `runpod-flash`, which declares its own `flash` console script.
|
|
40
62
|
Whichever distribution installs last wins, so on a plane host the bare `flash` command may launch
|
|
41
63
|
RunPod's CLI instead of this one - it exits 0 and does nothing, which is easy to miss. Use
|
|
@@ -51,10 +73,11 @@ the plane itself never terminates TLS. On the same machine, skip the proxy and u
|
|
|
51
73
|
Then point a client at it:
|
|
52
74
|
|
|
53
75
|
```bash
|
|
76
|
+
export FREESOLO_API_KEY="$FREESOLO_INTERNAL_KEY"
|
|
54
77
|
# remote: the https address of your TLS proxy, not the plane's own :8080
|
|
55
|
-
flash login --api-url https://your-plane.example
|
|
78
|
+
flash login --api-url https://your-plane.example
|
|
56
79
|
# same machine: loopback plaintext is fine
|
|
57
|
-
# flash login --api-url http://127.0.0.1:8080
|
|
80
|
+
# flash login --api-url http://127.0.0.1:8080
|
|
58
81
|
flash train run.toml
|
|
59
82
|
```
|
|
60
83
|
|
|
@@ -400,8 +423,8 @@ small run and watch it allocate.
|
|
|
400
423
|
is not set, so the plane is trying to reach a Freesolo backend. Set it to `1`.
|
|
401
424
|
|
|
402
425
|
**`401` on every request.** In standalone mode only `FREESOLO_INTERNAL_KEY` is accepted.
|
|
403
|
-
Confirm
|
|
404
|
-
|
|
426
|
+
Confirm `FREESOLO_API_KEY` contains that exact value, with no trailing newline, then run
|
|
427
|
+
`flash login` again.
|
|
405
428
|
|
|
406
429
|
**Startup says no GPU provider is configured** but you set a key. The value must be
|
|
407
430
|
non-empty and non-whitespace. For RunPod specifically, a value of `","` parses to zero
|
|
@@ -61,6 +61,10 @@ from flash.cli.ui import render
|
|
|
61
61
|
from flash.client.config import shadowed_login_warning
|
|
62
62
|
from flash.core.catalog import ALGORITHMS
|
|
63
63
|
|
|
64
|
+
# argv flags whose VALUE is a credential, so it must never be echoed back to the user. both the
|
|
65
|
+
# freesolo key (`flash login`) and the HuggingFace token (`flash models export`) use this name.
|
|
66
|
+
_CREDENTIAL_FLAGS = frozenset({"--api-key"})
|
|
67
|
+
|
|
64
68
|
# Themed `flash --help` catalog. Groups are ordered along the training workflow; each row's
|
|
65
69
|
# summary is the short one-liner the themed grid shows (the verbose per-command text stays on
|
|
66
70
|
# every subparser's own `help=` / `<cmd> --help`). test_cli_help.py asserts these rows stay in
|
|
@@ -296,8 +300,11 @@ def _add_auth_commands(sub: argparse._SubParsersAction) -> None:
|
|
|
296
300
|
)
|
|
297
301
|
login.add_argument(
|
|
298
302
|
"--api-key",
|
|
299
|
-
help=
|
|
300
|
-
|
|
303
|
+
help=(
|
|
304
|
+
"your freesolo API key (default: FREESOLO_API_KEY); prefer the environment variable "
|
|
305
|
+
"because argument values are visible in process listings; create a key at "
|
|
306
|
+
"https://freesolo.co/sign-in"
|
|
307
|
+
),
|
|
301
308
|
)
|
|
302
309
|
login.add_argument(
|
|
303
310
|
"--freesolo-url",
|
|
@@ -687,6 +694,11 @@ def _add_runs_commands(sub: argparse._SubParsersAction) -> None:
|
|
|
687
694
|
action="store_true",
|
|
688
695
|
help="poll status until the run ends without replaying logs",
|
|
689
696
|
)
|
|
697
|
+
runs_status.add_argument(
|
|
698
|
+
"--json",
|
|
699
|
+
action="store_true",
|
|
700
|
+
help="print machine-readable run status",
|
|
701
|
+
)
|
|
690
702
|
runs_status.set_defaults(func=cmd_status)
|
|
691
703
|
|
|
692
704
|
runs_log = runs_sub.add_parser(
|
|
@@ -757,8 +769,10 @@ def _add_deployment_commands(models_sub: argparse._SubParsersAction) -> None:
|
|
|
757
769
|
)
|
|
758
770
|
export.add_argument(
|
|
759
771
|
"--api-key",
|
|
760
|
-
help=
|
|
761
|
-
|
|
772
|
+
help=(
|
|
773
|
+
"HuggingFace token with write access to --repository; prefer HF_TOKEN or a local "
|
|
774
|
+
".env / .env.local because argument values are visible in process listings"
|
|
775
|
+
),
|
|
762
776
|
)
|
|
763
777
|
export.add_argument(
|
|
764
778
|
"--public",
|
|
@@ -839,6 +853,52 @@ def _warn_if_login_shadowed(args) -> None:
|
|
|
839
853
|
print(render.warn(message) if render.styled() else f"warning: {message}", file=sys.stderr)
|
|
840
854
|
|
|
841
855
|
|
|
856
|
+
def _is_credential_flag(arg: str) -> bool:
|
|
857
|
+
"""Whether `arg` is a credential flag, including the abbreviations argparse accepts.
|
|
858
|
+
|
|
859
|
+
argparse allows any unambiguous prefix of a long option, so `--api-k` and `--api-ke` both reach
|
|
860
|
+
`api_key`. Matching the full spelling exactly would leave those spellings unredacted and print
|
|
861
|
+
the key -- the redaction would look correct while missing every abbreviated invocation.
|
|
862
|
+
|
|
863
|
+
Ambiguity is deliberately NOT consulted. Whether `--api` is ambiguous depends on the SUBPARSER:
|
|
864
|
+
`flash login` also defines `--api-url` so argparse refuses it there, but `flash models export`
|
|
865
|
+
defines no such option, so `--ap`, `--api` and `--api-` are all unambiguous there and bind the
|
|
866
|
+
HuggingFace token. Judging ambiguity against a fixed rival list gets that case exactly backwards
|
|
867
|
+
and leaves the token printable. Erring the other way is free: if the parser does reject the
|
|
868
|
+
spelling, nothing was bound, and redacting an argument in an already-failing command loses
|
|
869
|
+
nothing.
|
|
870
|
+
"""
|
|
871
|
+
if not arg.startswith("--") or len(arg) <= 2:
|
|
872
|
+
return False
|
|
873
|
+
return any(flag.startswith(arg) for flag in _CREDENTIAL_FLAGS)
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
def _redacted_args(raw_args: list[str]) -> list[str]:
|
|
877
|
+
"""`raw_args` with any credential value replaced, for echoing a command back to the user.
|
|
878
|
+
|
|
879
|
+
The unexpected-error handler suggests re-running the exact command with --debug, which would
|
|
880
|
+
otherwise reproduce a `--api-key <key>` the user typed -- printing the key into a terminal, a
|
|
881
|
+
CI log or a pasted bug report. That is the same exposure `--api-key` already carries in process
|
|
882
|
+
listings, and the fix costs nothing: the value is never what makes the traceback useful.
|
|
883
|
+
"""
|
|
884
|
+
redacted: list[str] = []
|
|
885
|
+
drop_value = False
|
|
886
|
+
for arg in raw_args:
|
|
887
|
+
if drop_value:
|
|
888
|
+
redacted.append("<redacted>")
|
|
889
|
+
drop_value = False
|
|
890
|
+
continue
|
|
891
|
+
if _is_credential_flag(arg):
|
|
892
|
+
redacted.append(arg)
|
|
893
|
+
drop_value = True
|
|
894
|
+
continue
|
|
895
|
+
flag, sep, _ = arg.partition("=")
|
|
896
|
+
# `--api-key=secret` is one argv entry, so the split form has to be handled separately or
|
|
897
|
+
# the value rides along inside it.
|
|
898
|
+
redacted.append(f"{flag}=<redacted>" if sep and _is_credential_flag(flag) else arg)
|
|
899
|
+
return redacted
|
|
900
|
+
|
|
901
|
+
|
|
842
902
|
def main(argv: list[str] | None = None) -> int:
|
|
843
903
|
raw_args = list(argv) if argv is not None else sys.argv[1:]
|
|
844
904
|
parser = _build_parser()
|
|
@@ -872,7 +932,7 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
872
932
|
# point at the exact command to re-run, copy-pasteable. --debug is a root-level flag, so it
|
|
873
933
|
# must come BEFORE the subcommand (argparse rejects `flash runs --debug`); place it right
|
|
874
934
|
# after the program name. raw_args never contains --debug here — that path re-raises above.
|
|
875
|
-
cmd = " ".join([CLI_NAME, "--debug", *(shlex.quote(a) for a in raw_args)])
|
|
935
|
+
cmd = " ".join([CLI_NAME, "--debug", *(shlex.quote(a) for a in _redacted_args(raw_args))])
|
|
876
936
|
print(render.error(str(exc) or exc.__class__.__name__), file=sys.stderr)
|
|
877
937
|
print(render.arrow(f"run `{cmd}` for the full traceback"), file=sys.stderr)
|
|
878
938
|
return 1
|
|
@@ -178,6 +178,11 @@ def _plaintext_login_warnings(api_url: str | None, freesolo_url: str | None) ->
|
|
|
178
178
|
def cmd_login(args) -> int:
|
|
179
179
|
api_url = args.api_url or load_credentials()[0]
|
|
180
180
|
identity: dict | None = None
|
|
181
|
+
if args.api_key:
|
|
182
|
+
print(
|
|
183
|
+
"warning: --api-key is visible in process listings; prefer FREESOLO_API_KEY",
|
|
184
|
+
file=sys.stderr,
|
|
185
|
+
)
|
|
181
186
|
# before any request: the warning is worthless once the key has already gone over the wire.
|
|
182
187
|
# both destinations are checked here rather than at the branch below, because which one receives
|
|
183
188
|
# the key is decided after this point and the caller needs the warning while it can still abort.
|
|
@@ -637,9 +642,21 @@ def _poll_logs(client: ApiClient, run_id: str, interval: float) -> tuple[str, bo
|
|
|
637
642
|
spinner.clear()
|
|
638
643
|
|
|
639
644
|
|
|
640
|
-
def _render_status(status: dict) -> str:
|
|
641
|
-
"""One rendering of a run status: themed panel on a TTY, indented JSON on the machine path.
|
|
642
|
-
|
|
645
|
+
def _render_status(status: dict, *, force_json: bool = False, one_line: bool = False) -> str:
|
|
646
|
+
"""One rendering of a run status: themed panel on a TTY, indented JSON on the machine path.
|
|
647
|
+
|
|
648
|
+
``force_json`` is `--json`: the machine rendering even on a TTY, so a script's output does not
|
|
649
|
+
depend on whether it happens to have one. ``one_line`` keeps each object on a single line for
|
|
650
|
+
the `--follow` stream, which emits many of them: indented objects would run together into
|
|
651
|
+
something no line-by-line JSON reader can parse.
|
|
652
|
+
"""
|
|
653
|
+
if force_json and one_line:
|
|
654
|
+
return json.dumps(status, separators=(",", ":"))
|
|
655
|
+
return (
|
|
656
|
+
render.run_status(status)
|
|
657
|
+
if render.styled() and not force_json
|
|
658
|
+
else json.dumps(status, indent=2)
|
|
659
|
+
)
|
|
643
660
|
|
|
644
661
|
|
|
645
662
|
def _print_detached_note(run_id: str) -> None:
|
|
@@ -673,13 +690,15 @@ def _follow_run(client: ApiClient, run_id: str) -> int:
|
|
|
673
690
|
return 0 if state in _OK_STATES else 1
|
|
674
691
|
|
|
675
692
|
|
|
676
|
-
def _follow_status(
|
|
693
|
+
def _follow_status(
|
|
694
|
+
client: ApiClient, run_id: str, interval: float = 2.0, *, force_json: bool = False
|
|
695
|
+
) -> int:
|
|
677
696
|
"""Poll run status until terminal, without replaying worker logs."""
|
|
678
697
|
last_rendered: str | None = None
|
|
679
698
|
try:
|
|
680
699
|
while True:
|
|
681
700
|
status = client.get_run(run_id)
|
|
682
|
-
rendered = _render_status(status)
|
|
701
|
+
rendered = _render_status(status, force_json=force_json, one_line=force_json)
|
|
683
702
|
if rendered != last_rendered:
|
|
684
703
|
print(rendered)
|
|
685
704
|
last_rendered = rendered
|
|
@@ -725,9 +744,10 @@ def cmd_log(args) -> int:
|
|
|
725
744
|
|
|
726
745
|
def cmd_status(args) -> int:
|
|
727
746
|
client = client_from_config()
|
|
747
|
+
force_json = bool(getattr(args, "json", False))
|
|
728
748
|
if getattr(args, "follow", False):
|
|
729
|
-
return _follow_status(client, args.run_id)
|
|
730
|
-
print(_render_status(client.get_run(args.run_id)))
|
|
749
|
+
return _follow_status(client, args.run_id, force_json=force_json)
|
|
750
|
+
print(_render_status(client.get_run(args.run_id), force_json=force_json))
|
|
731
751
|
return 0
|
|
732
752
|
|
|
733
753
|
|
|
@@ -844,7 +864,7 @@ def cmd_deployments(args) -> int:
|
|
|
844
864
|
return 0
|
|
845
865
|
print(
|
|
846
866
|
f"{'RUN ID':<30} {'STEP':<6} {'REVISION':<40} {'STATE':<14} "
|
|
847
|
-
f"{'VERIFIED AT':<20} {'OPENAI MODEL':<30} DETAIL"
|
|
867
|
+
f"{'VERIFIED AT':<20} {'OPENAI MODEL':<30} {'OPENAI BASE URL':<48} DETAIL"
|
|
848
868
|
)
|
|
849
869
|
for row in rows:
|
|
850
870
|
deployment = row.get("deployment") or {}
|
|
@@ -858,10 +878,11 @@ def cmd_deployments(args) -> int:
|
|
|
858
878
|
revision = str(deployment.get("adapter_revision") or "-")
|
|
859
879
|
state = str(deployment.get("state") or "-")
|
|
860
880
|
openai_model = str(deployment.get("openai_model") or run_id)
|
|
881
|
+
openai_base_url = str(deployment.get("openai_base_url") or "-")
|
|
861
882
|
detail = str(deployment.get("error") or deployment.get("detail") or "")[:160]
|
|
862
883
|
print(
|
|
863
884
|
f"{run_id:<30} {step_text:<6} {revision:<40} {state:<14} "
|
|
864
|
-
f"{verified_text:<20} {openai_model:<30} {detail}"
|
|
885
|
+
f"{verified_text:<20} {openai_model:<30} {openai_base_url:<48} {detail}"
|
|
865
886
|
)
|
|
866
887
|
return 0
|
|
867
888
|
|
|
@@ -302,6 +302,264 @@ def cmd_deploy(args) -> int:
|
|
|
302
302
|
return 1 if dep.get("state") == "failed" or waited_but_unservable else 0
|
|
303
303
|
|
|
304
304
|
|
|
305
|
+
def _hub_repo_missing_errors() -> tuple[type[BaseException], ...]:
|
|
306
|
+
"""The hub errors that mean "the destination does not exist yet", not "you may not write".
|
|
307
|
+
|
|
308
|
+
Imported lazily and tolerantly for the same reason as flash/serve/export.py's `_hub_error_types`:
|
|
309
|
+
the CLI must stay importable without huggingface_hub. An empty tuple never matches, so a hub too
|
|
310
|
+
old to export these names fails closed on the strict branch rather than waving an export through.
|
|
311
|
+
"""
|
|
312
|
+
for module in ("huggingface_hub.errors", "huggingface_hub.utils"):
|
|
313
|
+
try:
|
|
314
|
+
return (
|
|
315
|
+
__import__(module, fromlist=["RepositoryNotFoundError"]).RepositoryNotFoundError,
|
|
316
|
+
)
|
|
317
|
+
except (ImportError, AttributeError):
|
|
318
|
+
continue
|
|
319
|
+
return ()
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _hf_status_code(exc: BaseException) -> int | None:
|
|
323
|
+
"""The HTTP status behind a hub error, or None when the request never got an answer.
|
|
324
|
+
|
|
325
|
+
None is the whole point: it separates "the Hub said no" from "the Hub was unreachable", which
|
|
326
|
+
the preflight must treat differently.
|
|
327
|
+
"""
|
|
328
|
+
code = getattr(getattr(exc, "response", None), "status_code", None)
|
|
329
|
+
try:
|
|
330
|
+
return int(code)
|
|
331
|
+
except (TypeError, ValueError):
|
|
332
|
+
return None
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def _hub_repo_gated_errors() -> tuple[type[BaseException], ...]:
|
|
336
|
+
"""Gated-repo errors, which the hub models as a SUBCLASS of "repository not found".
|
|
337
|
+
|
|
338
|
+
So they match the missing-repo tuple and have to be subtracted from it. A gated destination
|
|
339
|
+
exists; it is simply not writable by this token, which is the opposite of creatable.
|
|
340
|
+
"""
|
|
341
|
+
for module in ("huggingface_hub.errors", "huggingface_hub.utils"):
|
|
342
|
+
try:
|
|
343
|
+
return (__import__(module, fromlist=["GatedRepoError"]).GatedRepoError,)
|
|
344
|
+
except (ImportError, AttributeError):
|
|
345
|
+
continue
|
|
346
|
+
return ()
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def _hf_repo_confirmed_to_exist(api: object, repository: str, token: str) -> bool:
|
|
350
|
+
"""Whether the Hub affirmatively said the destination is already there.
|
|
351
|
+
|
|
352
|
+
True only on an affirmative answer. A missing `repo_exists`, an error, or any other non-answer
|
|
353
|
+
is False, meaning "not confirmed", which leaves the creation rules in charge. That asymmetry is
|
|
354
|
+
deliberate: bypassing those rules is what lets an export reach a namespace nobody verified, so
|
|
355
|
+
it must be earned by a real answer rather than granted by the absence of one.
|
|
356
|
+
"""
|
|
357
|
+
repo_exists = getattr(api, "repo_exists", None)
|
|
358
|
+
if not callable(repo_exists):
|
|
359
|
+
return False
|
|
360
|
+
try:
|
|
361
|
+
return bool(repo_exists(repository, repo_type="model", token=token))
|
|
362
|
+
except Exception:
|
|
363
|
+
return False
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
# sub-500 statuses that describe the request's transport rather than this token's access: request
|
|
367
|
+
# timeout, too-early replay, and rate limiting. 5xx is handled by the range check alongside these.
|
|
368
|
+
_HUB_TRANSIENT_STATUSES = frozenset({408, 425, 429})
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def _hf_status_is_a_verdict(status: int | None) -> bool:
|
|
372
|
+
"""Whether an HTTP status is the Hub answering the permission question about this token.
|
|
373
|
+
|
|
374
|
+
401/403/404 are answers: rejected, forbidden, or no such repo for this token. A missing status
|
|
375
|
+
(no response at all), 408, 425, 429, and 5xx are not -- they say the Hub was busy, slow or
|
|
376
|
+
broken, which is a fact about the Hub rather than about the caller's access.
|
|
377
|
+
|
|
378
|
+
408 and 425 carry a response, so they reach here rather than the statusless path, but a request
|
|
379
|
+
timeout and a too-early retry are transport outcomes: nothing about them says this token may not
|
|
380
|
+
write. Blocking on one would blame the user's permissions for the Hub being slow.
|
|
381
|
+
"""
|
|
382
|
+
if status is None:
|
|
383
|
+
return False
|
|
384
|
+
return status < 500 and status not in _HUB_TRANSIENT_STATUSES
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _without_token(text: str, token: str) -> str:
|
|
388
|
+
"""`text` with the token removed, for the warnings that quote a hub exception.
|
|
389
|
+
|
|
390
|
+
A local credential rejection quotes what it was handed: httpx raises "Illegal header value
|
|
391
|
+
b'Bearer <token>'" for a token containing a newline, so interpolating the exception prints the
|
|
392
|
+
credential to stderr and into any log or pasted bug report. The exception is still worth showing
|
|
393
|
+
-- it is the only clue to what went wrong -- so redact rather than drop it.
|
|
394
|
+
|
|
395
|
+
The escaped renderings have to go too. httpx builds that message from the header BYTES, so a
|
|
396
|
+
token holding a real newline appears as the two characters `\\` and `n`, which a literal replace
|
|
397
|
+
of the token never matches -- the redaction silently does nothing in exactly the case it was
|
|
398
|
+
written for. Each form is removed longest-first so a shorter one cannot bite a piece out of a
|
|
399
|
+
longer one and leave the rest of the credential in place.
|
|
400
|
+
"""
|
|
401
|
+
if not token:
|
|
402
|
+
return text
|
|
403
|
+
# repr() of the str and of the utf-8 bytes cover the escapings httpx and friends actually emit;
|
|
404
|
+
# the [1:-1] strips the quotes repr adds so the inner escaped text is what gets matched.
|
|
405
|
+
forms = {token, repr(token)[1:-1], repr(token.encode())[2:-1]}
|
|
406
|
+
for form in sorted(forms, key=len, reverse=True):
|
|
407
|
+
if form:
|
|
408
|
+
text = text.replace(form, "<redacted>")
|
|
409
|
+
return text
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _hf_hub_version() -> str:
|
|
413
|
+
"""The installed hub version for messages, without importing the package at module scope.
|
|
414
|
+
|
|
415
|
+
Falls back to a phrase, not a version-shaped string: this is only reached when the version could
|
|
416
|
+
not be read, and printing something that looks like a number would name a version nobody has.
|
|
417
|
+
"""
|
|
418
|
+
try:
|
|
419
|
+
from huggingface_hub import __version__
|
|
420
|
+
|
|
421
|
+
return str(__version__)
|
|
422
|
+
except Exception:
|
|
423
|
+
return "(unknown version)"
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def _hf_identity_and_write_access(repository: str, token: str) -> str | None:
|
|
427
|
+
"""return the token account after verifying the destination namespace when hub is installed."""
|
|
428
|
+
try:
|
|
429
|
+
from huggingface_hub import HfApi
|
|
430
|
+
except ModuleNotFoundError as exc:
|
|
431
|
+
if exc.name != "huggingface_hub":
|
|
432
|
+
raise
|
|
433
|
+
return None
|
|
434
|
+
|
|
435
|
+
import inspect
|
|
436
|
+
|
|
437
|
+
api = HfApi()
|
|
438
|
+
try:
|
|
439
|
+
identity = api.whoami(token=token)
|
|
440
|
+
except Exception as exc:
|
|
441
|
+
# a rejected token is the Hub answering, so refuse. a Hub that was unreachable, rate limited
|
|
442
|
+
# or broken is not an answer: the copy runs on the control plane, not here, so a CLI host
|
|
443
|
+
# without Hub egress would otherwise be unable to export at all -- while the same command
|
|
444
|
+
# skips this check entirely when the package is simply absent. degrade to that behaviour
|
|
445
|
+
# rather than invent a new hard blocker.
|
|
446
|
+
if not _hf_status_is_a_verdict(_hf_status_code(exc)):
|
|
447
|
+
print(
|
|
448
|
+
"warning: could not reach HuggingFace to verify the export namespace "
|
|
449
|
+
f"({_without_token(str(exc), token)}); proceeding without the check",
|
|
450
|
+
file=sys.stderr,
|
|
451
|
+
)
|
|
452
|
+
return None
|
|
453
|
+
raise ClientError(
|
|
454
|
+
"HuggingFace rejected the token before export. Check HF_TOKEN or --api-key and retry."
|
|
455
|
+
) from exc
|
|
456
|
+
account = str(identity.get("name") or identity.get("username") or "").strip()
|
|
457
|
+
if not account:
|
|
458
|
+
raise ClientError(
|
|
459
|
+
"HuggingFace authenticated the token but returned no account name, so Flash could not "
|
|
460
|
+
"verify the export namespace. Update huggingface-hub or verify the token manually."
|
|
461
|
+
)
|
|
462
|
+
print(f"HuggingFace token resolves to account {account}", file=sys.stderr)
|
|
463
|
+
|
|
464
|
+
owner = repository.partition("/")[0].strip()
|
|
465
|
+
|
|
466
|
+
# the exact repo first: it is the only authoritative answer, and it is the one the export
|
|
467
|
+
# actually needs. asking the org role first would refuse a `contributor` who can write this
|
|
468
|
+
# very repo, because a role is a coarser fact than the permission being checked.
|
|
469
|
+
auth_check = getattr(api, "auth_check", None)
|
|
470
|
+
exact_probe = callable(auth_check) and "write" in inspect.signature(auth_check).parameters
|
|
471
|
+
if not exact_probe and _hf_repo_confirmed_to_exist(api, repository, token):
|
|
472
|
+
# `auth_check(..., write=True)` only exists from huggingface-hub 1.5, and this package still
|
|
473
|
+
# supports >=1.2, so on 1.2-1.4 there is no exact write probe. the rules below are CREATION
|
|
474
|
+
# rules and a destination that already exists is not being created, so applying them here
|
|
475
|
+
# would reject the org `contributor` this ordering was fixed to admit. degrade to a warning,
|
|
476
|
+
# exactly as this function already does when the Hub is unreachable or the package is absent.
|
|
477
|
+
# only a CONFIRMED existing repo takes this path. an unanswered lookup keeps the creation
|
|
478
|
+
# rules, which is what stops an unverified export into someone else's namespace.
|
|
479
|
+
print(
|
|
480
|
+
f"warning: huggingface-hub {_hf_hub_version()} cannot check write access to an "
|
|
481
|
+
f"existing repo; proceeding without verifying {repository}",
|
|
482
|
+
file=sys.stderr,
|
|
483
|
+
)
|
|
484
|
+
return account
|
|
485
|
+
if exact_probe:
|
|
486
|
+
try:
|
|
487
|
+
auth_check(repository, repo_type="model", token=token, write=True)
|
|
488
|
+
return account
|
|
489
|
+
except Exception as exc:
|
|
490
|
+
# a destination that is not there yet cannot be checked directly, so fall through to the
|
|
491
|
+
# creation rules below. GatedRepoError SUBCLASSES RepositoryNotFoundError, so it must be
|
|
492
|
+
# excluded first: a gated repo exists and this token may not write it, and reading it as
|
|
493
|
+
# "absent" would hand it to the weaker create-permission paths.
|
|
494
|
+
missing = _hub_repo_missing_errors()
|
|
495
|
+
absent = bool(missing) and isinstance(exc, missing)
|
|
496
|
+
if absent and isinstance(exc, _hub_repo_gated_errors()):
|
|
497
|
+
absent = False
|
|
498
|
+
if not absent and not _hf_status_is_a_verdict(_hf_status_code(exc)):
|
|
499
|
+
# no verdict about this token: a timeout or DNS failure (no status at all), a 429,
|
|
500
|
+
# or a 5xx. reporting any of those as "cannot write" blames the user's permissions
|
|
501
|
+
# for a transport fault, and the upload runs on the control plane anyway. warn and
|
|
502
|
+
# proceed, exactly as the whoami path above already does for the same class of
|
|
503
|
+
# failure. 401/403/404 DO answer the question and still fall through to the error.
|
|
504
|
+
print(
|
|
505
|
+
f"warning: could not verify write access to {repository} "
|
|
506
|
+
f"({_without_token(str(exc), token)}); proceeding without the check",
|
|
507
|
+
file=sys.stderr,
|
|
508
|
+
)
|
|
509
|
+
return account
|
|
510
|
+
if not absent:
|
|
511
|
+
raise ClientError(
|
|
512
|
+
f"HuggingFace token resolves to account {account}, but it cannot write to "
|
|
513
|
+
f"{repository}. Grant this token write access to that model repo or set HF_TOKEN "
|
|
514
|
+
"to a token that can write there."
|
|
515
|
+
) from exc
|
|
516
|
+
|
|
517
|
+
# only reached for a destination that does not exist yet, so the question is now whether this
|
|
518
|
+
# token may CREATE it in that namespace. that is what the org role legitimately answers.
|
|
519
|
+
org_role = ""
|
|
520
|
+
for org in identity.get("orgs") or ():
|
|
521
|
+
if not isinstance(org, dict) or str(org.get("name") or "").casefold() != owner.casefold():
|
|
522
|
+
continue
|
|
523
|
+
org_role = str(org.get("role") or org.get("roleInOrg") or "").lower()
|
|
524
|
+
break
|
|
525
|
+
if owner.casefold() != account.casefold() and org_role not in {"write", "admin"}:
|
|
526
|
+
raise ClientError(
|
|
527
|
+
f"HuggingFace token resolves to account {account}, which cannot create "
|
|
528
|
+
f"{repository} in the namespace {owner}. Use --repository {account}/<repo>, choose an "
|
|
529
|
+
"org where this account has write access, or set HF_TOKEN to the intended account."
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
access_token = (identity.get("auth") or {}).get("accessToken") or {}
|
|
533
|
+
token_role = str(access_token.get("role") or "").lower()
|
|
534
|
+
if token_role == "write":
|
|
535
|
+
return account
|
|
536
|
+
if token_role != "fineGrained".lower():
|
|
537
|
+
raise ClientError(
|
|
538
|
+
f"HuggingFace token resolves to account {account}, but Flash could not verify write "
|
|
539
|
+
f"scope for the new destination {repository}. Use a write token for that namespace, "
|
|
540
|
+
"or create the repo first so Flash can check its exact write permission."
|
|
541
|
+
)
|
|
542
|
+
|
|
543
|
+
permissions = set(access_token.get("fineGrained", {}).get("global") or ())
|
|
544
|
+
for scope in access_token.get("fineGrained", {}).get("scoped") or ():
|
|
545
|
+
if not isinstance(scope, dict):
|
|
546
|
+
continue
|
|
547
|
+
entity = scope.get("entity") or {}
|
|
548
|
+
entity_name = str(entity.get("name") or entity.get("id") or "")
|
|
549
|
+
# only a scope naming the destination counts. crediting every user-typed scope would accept
|
|
550
|
+
# a token whose write grant covers some unrelated repo of its own, which is the silent
|
|
551
|
+
# wrong-namespace export this preflight exists to stop.
|
|
552
|
+
if entity_name.casefold() in {owner.casefold(), repository.casefold()}:
|
|
553
|
+
permissions.update(scope.get("permissions") or ())
|
|
554
|
+
if not ({"repo.write", "repo.content.write"} & permissions):
|
|
555
|
+
raise ClientError(
|
|
556
|
+
f"HuggingFace token resolves to account {account}, but its fine-grained scopes do not "
|
|
557
|
+
f"verify write access for {repository}. Add repository-content write access for that "
|
|
558
|
+
"namespace or use a write token."
|
|
559
|
+
)
|
|
560
|
+
return account
|
|
561
|
+
|
|
562
|
+
|
|
305
563
|
def cmd_export(args) -> int:
|
|
306
564
|
from flash.client.runtime_secrets import resolve_hf_token
|
|
307
565
|
|
|
@@ -311,9 +569,16 @@ def cmd_export(args) -> int:
|
|
|
311
569
|
"no HuggingFace token: pass `--api-key <hf_...>`, or set HF_TOKEN "
|
|
312
570
|
"(export it in your shell or put it in a local .env / .env.local)"
|
|
313
571
|
)
|
|
572
|
+
if args.api_key:
|
|
573
|
+
print(
|
|
574
|
+
"warning: --api-key is visible in process listings; prefer HF_TOKEN or a local "
|
|
575
|
+
".env / .env.local",
|
|
576
|
+
file=sys.stderr,
|
|
577
|
+
)
|
|
578
|
+
_hf_identity_and_write_access(args.repository, hf_token)
|
|
314
579
|
client = _commands().client_from_config()
|
|
315
580
|
progress = (
|
|
316
|
-
f"exporting adapter {args.adapter_id} to {args.repository}
|
|
581
|
+
f"exporting adapter {args.adapter_id} to {args.repository}; "
|
|
317
582
|
"downloading then re-uploading; this can take a minute..."
|
|
318
583
|
)
|
|
319
584
|
print(render.note(progress) if render.styled() else progress, file=sys.stderr)
|
|
@@ -25,7 +25,8 @@ command.
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
pip install freesolo-flash # installs the `flash` CLI (import name is also `flash`)
|
|
28
|
-
|
|
28
|
+
export FREESOLO_API_KEY=fslo_... # create a key at https://freesolo.co
|
|
29
|
+
flash login # validates and stores the key without exposing it in argv
|
|
29
30
|
flash whoami # confirm the identity behind your key
|
|
30
31
|
flash projects create "my project" # prints the canonical project UUID
|
|
31
32
|
flash models list # supported base model ids
|
|
@@ -544,12 +545,11 @@ current hub — both swallow paths are present in every version Flash supports.)
|
|
|
544
545
|
|
|
545
546
|
Two more details that make the difference between a probe and a placebo:
|
|
546
547
|
|
|
547
|
-
- **Pass the same token the export will use.**
|
|
548
|
-
`--api-key`
|
|
549
|
-
exactly
|
|
550
|
-
your ambient cached login, so the probe can pass on one credential
|
|
551
|
-
on a different one.
|
|
552
|
-
in `.env`, pass that literal value here.
|
|
548
|
+
- **Pass the same token the export will use.** Prefer `HF_TOKEN` in the environment or a local
|
|
549
|
+
`.env` / `.env.local`; `--api-key` still wins when supplied, but exposes the token in process
|
|
550
|
+
listings. Flash forwards exactly the resolved value. `huggingface_hub` does none of that; with
|
|
551
|
+
no `token=` it falls back to your ambient cached login, so the probe can pass on one credential
|
|
552
|
+
while the export fails on a different one. Pass the resolved token explicitly to the probe.
|
|
553
553
|
- **Ask for `private=True`.** The real export creates the repo private and only flips it
|
|
554
554
|
public afterwards if you passed `--public`. A probe that omits this can leave a brand-new
|
|
555
555
|
repo publicly visible until the export catches up, and it fails outright under an org
|
|
@@ -683,7 +683,7 @@ spending another GPU run:
|
|
|
683
683
|
| Wrong identity spends the money | Push/train lands in an org you did not expect, or a run id you know is valid comes back "unknown" | `FREESOLO_API_KEY` in the environment silently overrides `flash login`. Run `flash whoami` first. Run visibility is scoped to the key that created the run, so archive result baselines to disk rather than relying on `flash runs list` to find them later. |
|
|
684
684
|
| `flash env test` passes but the run trains on the wrong data | Local validation is green; the remote run loads a different split | `flash env test` loads `environment.py` with **no** `[environment.params]`, so a params-driven split selection is not exercised. Assert the split inside your own test, or default to the split you actually train on. |
|
|
685
685
|
| Final checkpoint regresses | Last step is worse than an earlier checkpoint | Run `flash runs checkpoint <run-id>`, deploy a specific step with `flash models deploy <run-id>/step-N`, and compare with held-out probes before exporting or relying on the final adapter. |
|
|
686
|
-
| Export fails before upload | CLI says no HuggingFace token |
|
|
686
|
+
| Export fails before upload | CLI says no HuggingFace token | Set `HF_TOKEN` in your shell, `.env`, or `.env.local`, then run `flash models export`; avoid `--api-key` because argument values are visible in process listings. Exports are private unless you pass `--public`. |
|
|
687
687
|
| Exported adapter is a silent no-op locally | peft warns about missing adapter keys and local eval matches the bare base model | The adapter's key namespace does not match the loaded model class. `model.layers.*` keys pair with `AutoModelForCausalLM`; `model.language_model.layers.*` keys pair with `Qwen3_5ForConditionalGeneration` / `Qwen3_5MoeForConditionalGeneration` (via `AutoModelForImageTextToText`). See "Loading an exported adapter locally". |
|
|
688
688
|
| SFT loss improves but quality does not | Train loss falls while held-out behavior stalls or degrades | Keep a held-out split outside training. Deploy and score that split; if quality drops, reduce epochs or improve data instead of adding more passes. |
|
|
689
689
|
| Cost surprises | A quick experiment uses more GPU time than intended | Start with `--dry-run` and `--cost`, keep `epochs` and `max_examples` small for smoke tests, and scale only after reward/data wiring is proven. Setup time is reported for observability; customer cost is based on training-loop GPU time. |
|