freesolo-flash-dev 1.0.26__tar.gz → 1.0.28__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.0.26 → freesolo_flash_dev-1.0.28}/PKG-INFO +1 -1
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_verl.py +15 -3
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/rl_verl.py +144 -55
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/pyproject.toml +2 -2
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_opd_verl.py +5 -1
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_rl_verl.py +143 -4
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/uv.lock +1 -1
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.claude/skills/verify/SKILL.md +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.dockerignore +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.env.example +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/auto-rebake.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/bake-kernel-cache.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/ci.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/main-source-guard.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/notify-tests-repo.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/publish-dev.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/publish-image.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/publish.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/version-parity.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/worker-image.yml +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.gitignore +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/AB_PLAN.md +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/Dockerfile +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/Dockerfile.worker +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/LICENSE +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/README.md +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/build/kernel_cache/.gitignore +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/build/kernel_cache/.keep +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/Dockerfile.kernelcache +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/Dockerfile.kernelcache.relayer +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/bake_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/bake_pod_entry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/make_rp_handler.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/_channel.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/_fileio.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/_logging.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/_update_check.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/adapter_artifacts.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/catalog.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/__main__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/_tty.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/commands.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/env_setup.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/env_test.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/envpush.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/render.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/traces.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cli/training_doc.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/client/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/client/config.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/client/http.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/client/runtime_secrets.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/client/specs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cost/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cost/analytical.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cost/facts.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cost/spec.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/cost/types.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/diagnostics.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/accounting.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/chalk_kernels.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/multiturn_reward_scoring.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/multiturn_rollout.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/recipe.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/steps.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/structured_outputs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/vram.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/__main__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/_pkg.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/adapter.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/decoding.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/finalize.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/gpu_setup.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/grpo.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/grpo_multimodal.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/grpo_perturn_trainer.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/heartbeat.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/hf.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/kernel_warmup.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/lora.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_gkd.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_verl_multiturn.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_verl_plugin.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_verl_structured.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/opd_vllm.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/packing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/attn.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/diagnostics.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/lifecycle.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/liger.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/loraplus.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/perf/memory.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/rl.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/rng.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/rollout_samples.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/sft.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/sft_verl.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/teacher.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/tokenizer_align.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/verl_common.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker/wandb_log.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/engine/worker_entrypoint.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/adapter.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/archive.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/archive_policy.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/base.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/loader.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/pull.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/envs/registry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/lora_rank.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/multimodal.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/opd_retry_contract.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/opd_verl_validation.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_auth.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_deadline.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_hf_artifacts.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_hf_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_http.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_instance.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_instance_bootstrap.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_instance_poll.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_instance_provider.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_poll.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/_worker.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/allocator.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/base.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/auth.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/gpus.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/lambdalabs/pricing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/realized.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/auth.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/cost.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/gpus.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/jobs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/keys.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/pricing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/slots.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/train/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/runpod/train/endpoints.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/auth.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/jobs/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/jobs/builders.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/vast/pricing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/providers/weight_cache_preload.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/py.typed +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/runner/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/runner/checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/runner/deploy.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/runner/lifecycle.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/runner/verified_revisions.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/schema/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/schema/fields.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/deploy.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/export.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/pricing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/serve/urls.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/__main__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/_deps.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/_internal_client.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/_locks.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/_runtime.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/app.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/auth.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/billing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/billing_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/db.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/environment_registry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/envs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/reconcile.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/routes/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/routes/envs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/routes/meta.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/routes/runs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/routes/serving.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/server/run_registry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/flash/spec.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/infisical-entrypoint.sh +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/scripts/build_dev_dist.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/_helpers/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/_helpers/runner.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/_helpers/specs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/_helpers/vast.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/conftest.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/fixtures/math_eval.jsonl +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/fixtures/math_train.jsonl +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/live/__init__.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/live/conftest.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/live/test_lambda_live.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/live/test_runpod_live.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/live/test_vast_live.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_accounting_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_agent_flash_cli_contract.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_algorithms.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_allocator.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_async_uploads.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_b200_rollout_opt.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_backend_jobspec_contract.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_base_model_provenance.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_billing_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cancel_remote.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_catalog_consistency.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_chalk_kernels.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_charge_pricing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_checkpoints.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_commands.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_commands_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_errors.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_estimate.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_help.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_main_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_managed.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_render_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_render_theme.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cli_traces.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_client.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_client_server_integration.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_client_stream_reads.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_config_overrides.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_controlled_experiment_repairs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_analytical.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_equation.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_estimate.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_hardware.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_models.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_cost_rewards.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_deploy_latency.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_dev_channel.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_disk_gb.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_endpoint_name.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_cache_evict.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_delete.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_download.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_download_api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_no_install.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_publish.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_pull.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_pull_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_pull_loader_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_pull_managed_control_plane.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_push.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_rate_limit_resolve.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_env_test.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_export.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_flash_mvp.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_flash_worker.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_flashinfer_cache_dirs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_github_urlopen_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_gpu_type_single_field.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_gpus.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_grpo_cudagraphs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_grpo_mask_aware.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_grpo_params.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_grpo_perturn.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_grpo_sleep_gate.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_health_liveness.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_hf_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_idle_endpoint_reaper.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_instance_bootstrap_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_internal_client.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_jobs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_kernel_cache.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_kernel_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_kv_util.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_lambda_api_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_lambda_runner.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_logging.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_login_perms.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_lora_rank_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_lora_rank_preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_managed_config_fields.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_managed_hf_repo.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_metrics_schema_agent_contract.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_mig_guard.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multi_gpu_gate.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multimodal_input_grads.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multimodal_training.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_image_rollout.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_per_turn_reward.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_rollout.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_rollout_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_rollout_records.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_multiturn_rollout_request_policy.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_named_reward_metrics.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_oom_escalate_gpu.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_opd.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_opd_full_state_resume.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_opd_resume_safety.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_opd_vllm.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_open_model_policy.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_orchestrator_flash.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_packing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_packing_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_poll_helpers.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_provider_preflight_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_provider_routing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_provider_teardown_robustness.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_providers_symmetry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_realized_cost.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_repo_cleanup.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_resolve_params_b.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_resume_on_retry.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_rollout_samples.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_runmgmt.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_runpod_api_delete.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_runpod_key_fingerprint.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_runpod_key_waterfall.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_runpod_slots.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_serve.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_app_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_auth_singleflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_billing.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_checkpoints_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_db.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_envs_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_server_locks_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_serving_context_preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_serving_contract.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_serving_pricing_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_serving_schema_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_activation_shaping.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_chunked_nll.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_example_selection.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_gc_off.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_max_context.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_tokenize_cache.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_sft_verl.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_single_turn_multimodal_grpo.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_spec_and_validation.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_structured_outputs.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_thinking_config.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_train_context_preflight.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_training_controls.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_update_check.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vast_api.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vast_api_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vast_offers.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vast_provider_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vast_runner.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_verified_revisions.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_verifiers.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_verl_common.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_version.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vl_warmstart_adapter_keys.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_vram_architecture.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_wandb_log_coverage.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_wandb_naming.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_warmstart_adapter_download.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_warmstart_cross_repo.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_weight_cache.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_dryrun.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_hardexit.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_image.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_init_heartbeat.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_stack.py +0 -0
- {freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/tests/test_worker_thinking.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: freesolo-flash-dev
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.28
|
|
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
|
|
@@ -1437,12 +1437,22 @@ def build_opd_verl_overrides(config: dict) -> list[str]:
|
|
|
1437
1437
|
"data.truncation=error",
|
|
1438
1438
|
"data.shuffle=false",
|
|
1439
1439
|
f"data.seed={_hydra_val(config.get('seed', 42))}",
|
|
1440
|
-
|
|
1440
|
+
# rollout engine seed. NOT `rollout.seed`: verl 0.8.0's RolloutConfig declares no such field,
|
|
1441
|
+
# so a bare key fails hydra composition and a `+`/`++` prefix composes but then dies in
|
|
1442
|
+
# omega_conf_to_dataclass with an unexpected-kwarg TypeError. engine_kwargs is a declared
|
|
1443
|
+
# dict on both 0.8.0 and 0.9.x and is spread into the vllm engine args *after* verl's own
|
|
1444
|
+
# "seed" entry, so it wins. `++` because the sub-key is absent from the composed node.
|
|
1445
|
+
# per-request sampling is seeded separately by the plugin's deterministic_rollout_seed.
|
|
1446
|
+
f"++actor_rollout_ref.rollout.engine_kwargs.vllm.seed={_hydra_val(config.get('seed', 42))}",
|
|
1441
1447
|
"data.dataloader_num_workers=0",
|
|
1442
1448
|
"data.image_key=images",
|
|
1443
1449
|
"data.return_raw_chat=true",
|
|
1444
1450
|
"data.return_multi_modal_inputs=false",
|
|
1445
|
-
|
|
1451
|
+
# `++`, not a bare key: data.apply_chat_template_kwargs exists but holds an empty struct
|
|
1452
|
+
# dict, so assigning a whole dict to it is rejected as an unknown sub-key.
|
|
1453
|
+
"++data.apply_chat_template_kwargs={enable_thinking:"
|
|
1454
|
+
+ _hydra_val(config.get("thinking", False))
|
|
1455
|
+
+ "}",
|
|
1446
1456
|
f"actor_rollout_ref.model.path={_hydra_val(config['model_path'])}",
|
|
1447
1457
|
"actor_rollout_ref.model.trust_remote_code=true",
|
|
1448
1458
|
"actor_rollout_ref.model.use_remove_padding=true",
|
|
@@ -1473,7 +1483,9 @@ def build_opd_verl_overrides(config: dict) -> list[str]:
|
|
|
1473
1483
|
"actor_rollout_ref.rollout.mode=async",
|
|
1474
1484
|
f"actor_rollout_ref.rollout.tensor_model_parallel_size={_hydra_val(config['n_gpus_per_node'])}",
|
|
1475
1485
|
f"actor_rollout_ref.rollout.n={_hydra_val(config['group_size'])}",
|
|
1476
|
-
|
|
1486
|
+
# `++`, not a bare key: limit_images is a real RolloutConfig field but is absent from the
|
|
1487
|
+
# composed rollout node, so hydra rejects a bare assignment.
|
|
1488
|
+
"++actor_rollout_ref.rollout.limit_images=8",
|
|
1477
1489
|
f"actor_rollout_ref.rollout.max_model_len={_hydra_val(config.get('max_model_len', 32768))}",
|
|
1478
1490
|
f"actor_rollout_ref.rollout.temperature={_hydra_val(config.get('temperature', 1.0))}",
|
|
1479
1491
|
f"actor_rollout_ref.rollout.top_p={_hydra_val(config.get('top_p', 1.0))}",
|
|
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|
|
16
16
|
|
|
17
17
|
import contextlib
|
|
18
18
|
import json
|
|
19
|
+
import math
|
|
19
20
|
import os
|
|
20
21
|
import random
|
|
21
22
|
import re
|
|
@@ -39,6 +40,21 @@ DATA_SOURCE = "flash_env"
|
|
|
39
40
|
# --------------------------------------------------------------------------------------------
|
|
40
41
|
# pure helpers (no verl, no gpu, no network) -- unit tested directly.
|
|
41
42
|
# --------------------------------------------------------------------------------------------
|
|
43
|
+
def _verl_epochs_for_horizon(
|
|
44
|
+
*, epochs: int, prompt_count: int, prompts_per_step: int, steps: int
|
|
45
|
+
) -> int:
|
|
46
|
+
if prompt_count <= 0:
|
|
47
|
+
raise ValueError("prompt_count must be positive")
|
|
48
|
+
if prompts_per_step <= 0:
|
|
49
|
+
raise ValueError("prompts_per_step must be positive")
|
|
50
|
+
if prompt_count < prompts_per_step:
|
|
51
|
+
raise ValueError("prompt_count must be at least prompts_per_step")
|
|
52
|
+
# verl hardcodes drop_last=True, so each epoch serves floor(prompt_count / batch_size) steps.
|
|
53
|
+
# the flag cannot be configured off, and ceil here would still under-serve the requested horizon.
|
|
54
|
+
steps_per_epoch = prompt_count // prompts_per_step
|
|
55
|
+
return max(epochs, math.ceil(steps / steps_per_epoch))
|
|
56
|
+
|
|
57
|
+
|
|
42
58
|
def build_verl_dataset_rows(
|
|
43
59
|
message_prompts: list[list[dict]],
|
|
44
60
|
example_indices: list[int],
|
|
@@ -70,8 +86,9 @@ def build_verl_overrides(cfg: dict) -> list[str]:
|
|
|
70
86
|
"""build the hydra override list for `python -m verl.trainer.main_ppo` (grpo + lora + vllm).
|
|
71
87
|
|
|
72
88
|
carries the flash grpo recipe: dr-grpo advantages (no std norm, constant-length loss), the
|
|
73
|
-
job's kl coefficient (flash default 0 = no kl term), constant lr, seed, sampling top_p,
|
|
74
|
-
|
|
89
|
+
job's kl coefficient (flash default 0 = no kl term), constant lr, seed, sampling top_p, and one
|
|
90
|
+
ppo epoch so total_training_steps counts optimizer updates. unlike trl's generation-batch reuse,
|
|
91
|
+
verl samples a fresh rollout per update, so rollout volume and policy staleness still differ.
|
|
75
92
|
"""
|
|
76
93
|
kl_on = float(cfg["kl_coef"]) > 0
|
|
77
94
|
o = [
|
|
@@ -97,7 +114,13 @@ def build_verl_overrides(cfg: dict) -> list[str]:
|
|
|
97
114
|
# thread flash's thinking mode so the rollout sees the same prompt as the trl path.
|
|
98
115
|
f"+data.apply_chat_template_kwargs.enable_thinking={str(bool(cfg.get('thinking', False))).lower()}",
|
|
99
116
|
f"data.seed={cfg['seed']}",
|
|
100
|
-
|
|
117
|
+
# rollout sampling seed. NOT `rollout.seed`: verl 0.8.0's RolloutConfig declares no such
|
|
118
|
+
# field, so a bare key fails hydra composition and a `+`/`++` prefix composes but then dies
|
|
119
|
+
# in omega_conf_to_dataclass with an unexpected-kwarg TypeError. engine_kwargs is a declared
|
|
120
|
+
# dict on both 0.8.0 and 0.9.x and is spread into the vllm engine args *after* verl's own
|
|
121
|
+
# "seed" entry, so it wins. `++` because the sub-key is absent from the composed node.
|
|
122
|
+
# single replica here (tp == n_gpus, nnodes=1), so verl's replica_rank offset is always 0.
|
|
123
|
+
f"++actor_rollout_ref.rollout.engine_kwargs.vllm.seed={cfg['seed']}",
|
|
101
124
|
f"actor_rollout_ref.model.path={cfg['model_id']}",
|
|
102
125
|
f"actor_rollout_ref.model.lora_rank={cfg['lora_rank']}",
|
|
103
126
|
f"actor_rollout_ref.model.lora_alpha={cfg['lora_alpha']}",
|
|
@@ -116,12 +139,15 @@ def build_verl_overrides(cfg: dict) -> list[str]:
|
|
|
116
139
|
else []
|
|
117
140
|
),
|
|
118
141
|
f"actor_rollout_ref.actor.optim.lr={cfg['lr']}",
|
|
142
|
+
# only the lora adapter is trainable; decaying its weights toward zero is not part of grpo.
|
|
143
|
+
"actor_rollout_ref.actor.optim.weight_decay=0.0",
|
|
119
144
|
# 0 warmup -> verl's warmup+constant scheduler holds lr flat, matching the trl constant recipe.
|
|
120
145
|
"actor_rollout_ref.actor.optim.lr_warmup_steps_ratio=0.0",
|
|
121
146
|
f"actor_rollout_ref.actor.ppo_mini_batch_size={cfg['prompts_per_step']}",
|
|
122
147
|
f"actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu={cfg['micro_batch']}",
|
|
123
|
-
#
|
|
124
|
-
|
|
148
|
+
# ppo_epochs multiplies verl's update loop, so its default of 1 preserves the requested update
|
|
149
|
+
# count and on-policy baseline. unlike trl reuse, verl samples a fresh rollout for every update.
|
|
150
|
+
f"actor_rollout_ref.actor.ppo_epochs={cfg['ppo_epochs']}",
|
|
125
151
|
"actor_rollout_ref.rollout.name=vllm",
|
|
126
152
|
f"actor_rollout_ref.rollout.n={cfg['group_size']}",
|
|
127
153
|
# safetensors load format is required for lora rollout on vllm.
|
|
@@ -170,6 +196,82 @@ def build_verl_overrides(cfg: dict) -> list[str]:
|
|
|
170
196
|
return o
|
|
171
197
|
|
|
172
198
|
|
|
199
|
+
def _build_verl_training_cfg(
|
|
200
|
+
inp: dict,
|
|
201
|
+
*,
|
|
202
|
+
train_files: str,
|
|
203
|
+
val_files: str,
|
|
204
|
+
model_id: str,
|
|
205
|
+
micro_batch: int,
|
|
206
|
+
thinking: bool,
|
|
207
|
+
loggers: str,
|
|
208
|
+
fp8_kv: bool,
|
|
209
|
+
reward_path: str,
|
|
210
|
+
local_dir: str,
|
|
211
|
+
) -> dict:
|
|
212
|
+
return {
|
|
213
|
+
"train_files": train_files,
|
|
214
|
+
"val_files": val_files,
|
|
215
|
+
"model_id": model_id,
|
|
216
|
+
"lora_rank": inp["lora_rank"],
|
|
217
|
+
"lora_alpha": inp["lora_alpha"],
|
|
218
|
+
"target_modules": "all-linear",
|
|
219
|
+
"lr": inp["lr"],
|
|
220
|
+
"group_size": inp["group_size"],
|
|
221
|
+
"prompts_per_step": inp["prompts_per_step"],
|
|
222
|
+
"micro_batch": micro_batch,
|
|
223
|
+
"max_prompt_len": inp["max_prompt_len"],
|
|
224
|
+
"max_completion": inp["max_completion"],
|
|
225
|
+
"temperature": inp["temperature"],
|
|
226
|
+
"top_p": inp["top_p"],
|
|
227
|
+
"kl_coef": inp["kl_coef"],
|
|
228
|
+
"thinking": thinking,
|
|
229
|
+
"loss_agg_mode": "seq-mean-token-sum-norm",
|
|
230
|
+
"seed": inp["seed"],
|
|
231
|
+
"ppo_epochs": inp["ppo_epochs"],
|
|
232
|
+
"steps": int(inp["steps"]),
|
|
233
|
+
"warmstart_adapter": inp["warmstart_adapter"],
|
|
234
|
+
"gpu_mem_util": 0.5,
|
|
235
|
+
"tp_size": 1,
|
|
236
|
+
"loggers": loggers,
|
|
237
|
+
"fp8_kv": fp8_kv,
|
|
238
|
+
"reward_path": reward_path,
|
|
239
|
+
"reward_name": "compute_score",
|
|
240
|
+
"total_epochs": inp["verl_total_epochs"],
|
|
241
|
+
"save_freq": inp["save_every"],
|
|
242
|
+
"local_dir": local_dir,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def _build_verl_train_notes(
|
|
247
|
+
inp: dict,
|
|
248
|
+
*,
|
|
249
|
+
steps_run: int,
|
|
250
|
+
retained_prompts: int,
|
|
251
|
+
reward_history: list[float],
|
|
252
|
+
loss_curve: list[float],
|
|
253
|
+
) -> dict:
|
|
254
|
+
return {
|
|
255
|
+
"backend": "verl",
|
|
256
|
+
"steps": steps_run,
|
|
257
|
+
"epochs": inp["epochs"],
|
|
258
|
+
"retained_prompts": retained_prompts,
|
|
259
|
+
"group_size": inp["group_size"],
|
|
260
|
+
"reward_history": reward_history,
|
|
261
|
+
"loss_curve": loss_curve,
|
|
262
|
+
"grpo_recipe": {
|
|
263
|
+
"kl_coef": inp["kl_coef"],
|
|
264
|
+
"temperature": inp["temperature"],
|
|
265
|
+
"top_p": inp["top_p"],
|
|
266
|
+
"ppo_epochs": inp["ppo_epochs"],
|
|
267
|
+
"verl_total_epochs": inp["verl_total_epochs"],
|
|
268
|
+
"seed": inp["seed"],
|
|
269
|
+
"loss_agg_mode": "seq-mean-token-sum-norm",
|
|
270
|
+
"norm_adv_by_std_in_grpo": False,
|
|
271
|
+
},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
173
275
|
def render_reward_module(url_env: str = "FLASH_VERL_REWARD_URL") -> str:
|
|
174
276
|
"""source for the verl custom reward module.
|
|
175
277
|
|
|
@@ -490,10 +592,11 @@ def _resolve_single_turn_inputs():
|
|
|
490
592
|
flush=True,
|
|
491
593
|
)
|
|
492
594
|
# trl drops truncated (non-eos) completions from the grpo loss (mask_truncated_completions,
|
|
493
|
-
# default True); verl
|
|
494
|
-
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
595
|
+
# default True); verl 0.8.0 cannot express this through config. its vllm server discards the
|
|
596
|
+
# finish_reason length/stop distinction, and its rollout schemas and trainer masks never apply
|
|
597
|
+
# finish-reason-dependent response-loss masking anyway. stop_sequences (the only case that turns
|
|
598
|
+
# masking off) already fails loudly above, so this is always the default-True case. a real fix needs
|
|
599
|
+
# finish-reason propagation plus explicit zeroing of the truncated response loss mask.
|
|
497
600
|
if _w.grpo_mask_truncated_completions(_t):
|
|
498
601
|
print(
|
|
499
602
|
"[rl-verl] mask_truncated_completions=True; verl keeps truncated completions in the "
|
|
@@ -587,16 +690,15 @@ def _resolve_single_turn_inputs():
|
|
|
587
690
|
epochs=epochs, prompt_count=len(prompts), prompts_per_step=prompts_per_step
|
|
588
691
|
)
|
|
589
692
|
steps = resolve_update_horizon(derived_steps, getattr(_t, "max_steps", None) if _t else None)
|
|
590
|
-
# verl stops at
|
|
591
|
-
#
|
|
592
|
-
#
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
epochs = max(epochs, _math.ceil(int(steps) / steps_per_epoch))
|
|
693
|
+
# verl stops at both total_epochs and total_training_steps. give its hardcoded drop_last
|
|
694
|
+
# dataloader enough epoch capacity to serve the horizon, but preserve the configured epoch count
|
|
695
|
+
# for user-facing metadata. total_training_steps prevents the capacity headroom from over-training.
|
|
696
|
+
verl_total_epochs = _verl_epochs_for_horizon(
|
|
697
|
+
epochs=epochs,
|
|
698
|
+
prompt_count=len(prompts),
|
|
699
|
+
prompts_per_step=prompts_per_step,
|
|
700
|
+
steps=int(steps),
|
|
701
|
+
)
|
|
600
702
|
save_every = int(_t.save_every) if (_t and _t.save_every) else 20
|
|
601
703
|
|
|
602
704
|
return {
|
|
@@ -619,10 +721,12 @@ def _resolve_single_turn_inputs():
|
|
|
619
721
|
"lora_alpha": lora_alpha,
|
|
620
722
|
"warmstart_adapter": warmstart_adapter,
|
|
621
723
|
"epochs": epochs,
|
|
724
|
+
"verl_total_epochs": verl_total_epochs,
|
|
622
725
|
"steps": int(steps),
|
|
623
726
|
"save_every": save_every,
|
|
624
|
-
#
|
|
625
|
-
|
|
727
|
+
# verl's default preserves the update horizon and on-policy baseline; unlike trl reuse, each
|
|
728
|
+
# update gets a fresh rollout batch.
|
|
729
|
+
"ppo_epochs": 1,
|
|
626
730
|
"seed": int(backend_seed(_w.SEED)),
|
|
627
731
|
}
|
|
628
732
|
|
|
@@ -736,22 +840,18 @@ def run_rl_verl():
|
|
|
736
840
|
)
|
|
737
841
|
except Exception: # no cuda / probe failure -> conservative bf16 kv
|
|
738
842
|
fp8_kv = False
|
|
739
|
-
cfg =
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
"gpu_mem_util": 0.5, "tp_size": 1, "loggers": loggers, "fp8_kv": fp8_kv,
|
|
752
|
-
"reward_path": reward_py, "reward_name": "compute_score",
|
|
753
|
-
"total_epochs": inp["epochs"], "save_freq": inp["save_every"], "local_dir": local_dir,
|
|
754
|
-
}
|
|
843
|
+
cfg = _build_verl_training_cfg(
|
|
844
|
+
inp,
|
|
845
|
+
train_files=train_pq,
|
|
846
|
+
val_files=val_pq,
|
|
847
|
+
model_id=model_path_for_verl,
|
|
848
|
+
micro_batch=micro_batch,
|
|
849
|
+
thinking=bool(_w.THINKING),
|
|
850
|
+
loggers=loggers,
|
|
851
|
+
fp8_kv=fp8_kv,
|
|
852
|
+
reward_path=reward_py,
|
|
853
|
+
local_dir=local_dir,
|
|
854
|
+
)
|
|
755
855
|
overrides = build_verl_overrides(cfg)
|
|
756
856
|
|
|
757
857
|
setup_seconds = time.time() - t_start
|
|
@@ -867,22 +967,11 @@ def run_rl_verl():
|
|
|
867
967
|
)
|
|
868
968
|
if resp_len_history
|
|
869
969
|
else 0,
|
|
870
|
-
notes=
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
"loss_curve": loss_curve,
|
|
878
|
-
"grpo_recipe": {
|
|
879
|
-
"kl_coef": inp["kl_coef"],
|
|
880
|
-
"temperature": inp["temperature"],
|
|
881
|
-
"top_p": inp["top_p"],
|
|
882
|
-
"num_iterations": inp["num_iterations"],
|
|
883
|
-
"seed": inp["seed"],
|
|
884
|
-
"loss_agg_mode": "seq-mean-token-sum-norm",
|
|
885
|
-
"norm_adv_by_std_in_grpo": False,
|
|
886
|
-
},
|
|
887
|
-
},
|
|
970
|
+
notes=_build_verl_train_notes(
|
|
971
|
+
inp,
|
|
972
|
+
steps_run=steps_run,
|
|
973
|
+
retained_prompts=len(prompts),
|
|
974
|
+
reward_history=reward_history,
|
|
975
|
+
loss_curve=loss_curve,
|
|
976
|
+
),
|
|
888
977
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "freesolo-flash-dev"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.28"
|
|
4
4
|
description = "Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
# RunPod Flash supports Python 3.11-3.12 (not 3.13 yet).
|
|
@@ -116,7 +116,7 @@ artifacts = ["flash/py.typed"]
|
|
|
116
116
|
# auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
|
|
117
117
|
# PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
|
|
118
118
|
# dev-channel release = bump this (and [project].version) and merge to `dev`.
|
|
119
|
-
version = "1.0.
|
|
119
|
+
version = "1.0.28"
|
|
120
120
|
|
|
121
121
|
[tool.pytest.ini_options]
|
|
122
122
|
pythonpath = ["."]
|
|
@@ -4389,7 +4389,11 @@ def test_overrides_match_verl_0_8_sync_distillation_contract():
|
|
|
4389
4389
|
assert overrides["data.image_key"] == "images"
|
|
4390
4390
|
assert overrides["data.return_raw_chat"] == "true"
|
|
4391
4391
|
assert overrides["data.return_multi_modal_inputs"] == "false"
|
|
4392
|
-
|
|
4392
|
+
# `++`-prefixed: these keys are absent from the composed node, so a bare assignment would abort
|
|
4393
|
+
# the run at hydra composition. see build_opd_verl_overrides for the per-key reasoning.
|
|
4394
|
+
assert overrides["++actor_rollout_ref.rollout.limit_images"] == "8"
|
|
4395
|
+
assert overrides["++actor_rollout_ref.rollout.engine_kwargs.vllm.seed"] == "42"
|
|
4396
|
+
assert "actor_rollout_ref.rollout.seed" not in overrides
|
|
4393
4397
|
assert "actor.engine.ulysses_sequence_parallel_size" not in overrides
|
|
4394
4398
|
assert "ref_log_prob" not in " ".join(overrides)
|
|
4395
4399
|
assert not any("structured_outputs_config" in key for key in overrides)
|
|
@@ -60,7 +60,7 @@ def _overrides_cfg(**over):
|
|
|
60
60
|
"target_modules": "all-linear", "lr": 1e-5, "group_size": 8,
|
|
61
61
|
"prompts_per_step": 16, "micro_batch": 2, "max_prompt_len": 2048,
|
|
62
62
|
"max_completion": 320, "temperature": 1.0, "top_p": 0.95, "kl_coef": 0.0,
|
|
63
|
-
"loss_agg_mode": "seq-mean-token-sum-norm", "seed": 42, "
|
|
63
|
+
"loss_agg_mode": "seq-mean-token-sum-norm", "seed": 42, "ppo_epochs": 1,
|
|
64
64
|
"steps": 60, "gpu_mem_util": 0.5, "tp_size": 1, "loggers": "console", "fp8_kv": False,
|
|
65
65
|
"warmstart_adapter": "", "reward_path": "/w/reward.py", "reward_name": "compute_score",
|
|
66
66
|
"total_epochs": 1, "save_freq": 20, "local_dir": "/w/ckpt",
|
|
@@ -79,12 +79,16 @@ def test_build_verl_overrides_carries_dr_grpo_recipe():
|
|
|
79
79
|
assert "actor_rollout_ref.rollout.n=8" in o
|
|
80
80
|
assert "actor_rollout_ref.rollout.load_format=safetensors" in o
|
|
81
81
|
assert "actor_rollout_ref.rollout.top_p=0.95" in o
|
|
82
|
-
# constant lr,
|
|
82
|
+
# constant lr, on-policy updates, gradient checkpointing, seed, max-steps horizon, save schedule.
|
|
83
|
+
assert "actor_rollout_ref.actor.optim.weight_decay=0.0" in o
|
|
83
84
|
assert "actor_rollout_ref.actor.optim.lr_warmup_steps_ratio=0.0" in o
|
|
84
|
-
assert "actor_rollout_ref.actor.ppo_epochs=
|
|
85
|
+
assert "actor_rollout_ref.actor.ppo_epochs=1" in o
|
|
85
86
|
assert "actor_rollout_ref.model.enable_gradient_checkpointing=True" in o
|
|
86
87
|
assert "data.seed=42" in o
|
|
87
|
-
|
|
88
|
+
# the rollout engine seed rides engine_kwargs, not `rollout.seed`, which verl 0.8.0's
|
|
89
|
+
# RolloutConfig does not declare. see build_verl_overrides for the full reasoning.
|
|
90
|
+
assert "++actor_rollout_ref.rollout.engine_kwargs.vllm.seed=42" in o
|
|
91
|
+
assert "actor_rollout_ref.rollout.seed=42" not in o
|
|
88
92
|
assert "trainer.total_training_steps=60" in o
|
|
89
93
|
assert "trainer.save_freq=20" in o
|
|
90
94
|
assert "trainer.max_actor_ckpt_to_keep=1" in o
|
|
@@ -95,6 +99,141 @@ def test_build_verl_overrides_carries_dr_grpo_recipe():
|
|
|
95
99
|
assert "algorithm.rollout_correction.rollout_is_threshold=2.0" in o
|
|
96
100
|
|
|
97
101
|
|
|
102
|
+
def test_build_verl_overrides_does_not_emit_inert_drop_last_override():
|
|
103
|
+
# this guards only against flash emitting a misleading no-op; it does not prove verl reads the key.
|
|
104
|
+
o = rl_verl.build_verl_overrides(_overrides_cfg())
|
|
105
|
+
assert not any("drop_last" in override for override in o)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@pytest.mark.parametrize(
|
|
109
|
+
("prompt_count", "prompts_per_step", "epochs", "max_steps", "expected_steps", "expected_epochs"),
|
|
110
|
+
[
|
|
111
|
+
pytest.param(33, 16, 2, None, 5, 3, id="partial-batch-derived-horizon"),
|
|
112
|
+
pytest.param(32, 16, 2, 7, 7, 4, id="explicit-horizon-beyond-derived"),
|
|
113
|
+
pytest.param(32, 16, 2, None, 4, 2, id="exactly-divisible"),
|
|
114
|
+
],
|
|
115
|
+
)
|
|
116
|
+
def test_verl_epoch_capacity_reaches_update_horizon(
|
|
117
|
+
prompt_count, prompts_per_step, epochs, max_steps, expected_steps, expected_epochs
|
|
118
|
+
):
|
|
119
|
+
derived_steps = rl_verl.on_policy_steps(
|
|
120
|
+
epochs=epochs, prompt_count=prompt_count, prompts_per_step=prompts_per_step
|
|
121
|
+
)
|
|
122
|
+
steps = rl_verl.resolve_update_horizon(derived_steps, max_steps)
|
|
123
|
+
resolved_epochs = rl_verl._verl_epochs_for_horizon(
|
|
124
|
+
epochs=epochs,
|
|
125
|
+
prompt_count=prompt_count,
|
|
126
|
+
prompts_per_step=prompts_per_step,
|
|
127
|
+
steps=steps,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
assert steps == expected_steps
|
|
131
|
+
assert resolved_epochs == expected_epochs
|
|
132
|
+
assert (prompt_count // prompts_per_step) * resolved_epochs >= steps
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
@pytest.mark.parametrize(
|
|
136
|
+
("prompt_count", "prompts_per_step", "message"),
|
|
137
|
+
[
|
|
138
|
+
pytest.param(0, 16, "prompt_count must be positive", id="no-prompts"),
|
|
139
|
+
pytest.param(5, 0, "prompts_per_step must be positive", id="zero-batch"),
|
|
140
|
+
pytest.param(5, 16, "prompt_count must be at least", id="batch-exceeds-prompts"),
|
|
141
|
+
],
|
|
142
|
+
)
|
|
143
|
+
def test_verl_epoch_capacity_rejects_invalid_batch_inputs(
|
|
144
|
+
prompt_count, prompts_per_step, message
|
|
145
|
+
):
|
|
146
|
+
with pytest.raises(ValueError, match=message):
|
|
147
|
+
rl_verl._verl_epochs_for_horizon(
|
|
148
|
+
epochs=2,
|
|
149
|
+
prompt_count=prompt_count,
|
|
150
|
+
prompts_per_step=prompts_per_step,
|
|
151
|
+
steps=3,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_verl_epoch_capacity_invariant_across_valid_inputs():
|
|
156
|
+
for prompt_count in range(1, 34):
|
|
157
|
+
for prompts_per_step in range(1, prompt_count + 1):
|
|
158
|
+
for epochs in (1, 2, 4):
|
|
159
|
+
for steps in (1, epochs, epochs + 5):
|
|
160
|
+
resolved_epochs = rl_verl._verl_epochs_for_horizon(
|
|
161
|
+
epochs=epochs,
|
|
162
|
+
prompt_count=prompt_count,
|
|
163
|
+
prompts_per_step=prompts_per_step,
|
|
164
|
+
steps=steps,
|
|
165
|
+
)
|
|
166
|
+
assert (prompt_count // prompts_per_step) * resolved_epochs >= steps
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_verl_resolver_builds_capacity_overrides_and_configured_metadata(monkeypatch):
|
|
170
|
+
from flash.engine.worker._pkg import W
|
|
171
|
+
from flash.spec import JobSpec
|
|
172
|
+
|
|
173
|
+
class _Env:
|
|
174
|
+
multi_turn = False
|
|
175
|
+
is_tool_env = False
|
|
176
|
+
|
|
177
|
+
def dataset(self):
|
|
178
|
+
return [{"index": i} for i in range(33)]
|
|
179
|
+
|
|
180
|
+
def prompt_messages(self, ex):
|
|
181
|
+
return [{"role": "user", "content": f"question {ex['index']}"}]
|
|
182
|
+
|
|
183
|
+
class _Tokenizer:
|
|
184
|
+
pad_token = None
|
|
185
|
+
eos_token = "<eos>"
|
|
186
|
+
|
|
187
|
+
def apply_chat_template(self, messages, **kwargs):
|
|
188
|
+
return messages[0]["content"]
|
|
189
|
+
|
|
190
|
+
def __call__(self, text, **kwargs):
|
|
191
|
+
return SimpleNamespace(input_ids=[1])
|
|
192
|
+
|
|
193
|
+
spec = JobSpec.from_dict(
|
|
194
|
+
{
|
|
195
|
+
"model": "Qwen/Qwen3.5-0.8B",
|
|
196
|
+
"algorithm": "grpo",
|
|
197
|
+
"train": {"batch_size": 16, "epochs": 2},
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
monkeypatch.setattr(W, "JOB_SPEC", spec, raising=False)
|
|
201
|
+
monkeypatch.setattr(W, "SEED", 42, raising=False)
|
|
202
|
+
monkeypatch.setattr(W, "THINKING", False, raising=False)
|
|
203
|
+
monkeypatch.setattr(W, "require_active_env", lambda: _Env(), raising=False)
|
|
204
|
+
monkeypatch.setattr(W, "grpo_overrides", lambda: {}, raising=False)
|
|
205
|
+
monkeypatch.setattr(W, "grpo_mask_truncated_completions", lambda train: False, raising=False)
|
|
206
|
+
monkeypatch.setattr(W, "load_tokenizer", lambda *args, **kwargs: _Tokenizer(), raising=False)
|
|
207
|
+
monkeypatch.setattr(rl_verl, "seed_training_rngs", lambda seed: None)
|
|
208
|
+
|
|
209
|
+
inp = rl_verl._resolve_single_turn_inputs()
|
|
210
|
+
cfg = rl_verl._build_verl_training_cfg(
|
|
211
|
+
inp,
|
|
212
|
+
train_files="/w/train.parquet",
|
|
213
|
+
val_files="/w/val.parquet",
|
|
214
|
+
model_id=inp["model_id"],
|
|
215
|
+
micro_batch=1,
|
|
216
|
+
thinking=False,
|
|
217
|
+
loggers="console",
|
|
218
|
+
fp8_kv=False,
|
|
219
|
+
reward_path="/w/reward.py",
|
|
220
|
+
local_dir="/w/ckpt",
|
|
221
|
+
)
|
|
222
|
+
overrides = rl_verl.build_verl_overrides(cfg)
|
|
223
|
+
notes = rl_verl._build_verl_train_notes(
|
|
224
|
+
inp,
|
|
225
|
+
steps_run=5,
|
|
226
|
+
retained_prompts=len(inp["prompts"]),
|
|
227
|
+
reward_history=[],
|
|
228
|
+
loss_curve=[],
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
assert "trainer.total_training_steps=5" in overrides
|
|
232
|
+
assert "trainer.total_epochs=3" in overrides
|
|
233
|
+
assert notes["epochs"] == 2
|
|
234
|
+
assert notes["grpo_recipe"]["verl_total_epochs"] == 3
|
|
235
|
+
|
|
236
|
+
|
|
98
237
|
def test_build_verl_overrides_wandb_logger_when_enabled():
|
|
99
238
|
o = rl_verl.build_verl_overrides(_overrides_cfg(loggers="console,wandb"))
|
|
100
239
|
assert "trainer.logger=[console,wandb]" in o
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/bake-kernel-cache.yml
RENAMED
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/main-source-guard.yml
RENAMED
|
File without changes
|
{freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/notify-tests-repo.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/.github/workflows/version-parity.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{freesolo_flash_dev-1.0.26 → freesolo_flash_dev-1.0.28}/docker/Dockerfile.kernelcache.relayer
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|