freesolo-flash-dev 1.0.97__tar.gz → 1.0.99__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.
Files changed (417) hide show
  1. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/PKG-INFO +1 -1
  2. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/backend_common.py +128 -2
  3. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_train.py +11 -15
  4. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/lifecycle.py +11 -0
  5. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rl_train.py +10 -19
  6. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/lifecycle.py +27 -8
  7. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/pyproject.toml +2 -2
  8. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_backend_common.py +202 -6
  9. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_oom_escalate_gpu.py +81 -0
  10. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd.py +1 -0
  11. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_stack.py +71 -7
  12. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/uv.lock +1 -1
  13. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.dockerignore +0 -0
  14. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.env.example +0 -0
  15. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  16. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  17. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  18. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  19. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/dependabot.yml +0 -0
  20. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/auto-rebake.yml +0 -0
  21. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/bake-kernel-cache.yml +0 -0
  22. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/ci.yml +0 -0
  23. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/main-source-guard.yml +0 -0
  24. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/notify-tests-repo.yml +0 -0
  25. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish-dev.yml +0 -0
  26. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish-image.yml +0 -0
  27. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/publish.yml +0 -0
  28. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/version-parity.yml +0 -0
  29. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.github/workflows/worker-image.yml +0 -0
  30. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/.gitignore +0 -0
  31. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/CODE_OF_CONDUCT.md +0 -0
  32. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/CONTRIBUTING.md +0 -0
  33. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/Dockerfile +0 -0
  34. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/Dockerfile.worker +0 -0
  35. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/LICENSE +0 -0
  36. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/NOTICE +0 -0
  37. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/README.md +0 -0
  38. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/SECURITY.md +0 -0
  39. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/SELF_HOSTING.md +0 -0
  40. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/build/kernel_cache/.gitignore +0 -0
  41. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/build/kernel_cache/.keep +0 -0
  42. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/Dockerfile +0 -0
  43. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/README.md +0 -0
  44. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/deploy/infisical/entrypoint.sh +0 -0
  45. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/Dockerfile.kernelcache +0 -0
  46. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/Dockerfile.kernelcache.relayer +0 -0
  47. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/bake_kernel_cache.py +0 -0
  48. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/bake_pod_entry.py +0 -0
  49. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/kernel_fingerprint.py +0 -0
  50. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/docker/make_rp_handler.py +0 -0
  51. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/__init__.py +0 -0
  52. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_channel.py +0 -0
  53. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_fileio.py +0 -0
  54. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_logging.py +0 -0
  55. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/_paths.py +0 -0
  56. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/adapter_artifacts.py +0 -0
  57. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/catalog.py +0 -0
  58. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/TRAINING.md +0 -0
  59. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/__init__.py +0 -0
  60. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/__main__.py +0 -0
  61. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/_tty.py +0 -0
  62. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/commands.py +0 -0
  63. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_eval.py +0 -0
  64. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_setup.py +0 -0
  65. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/env_test.py +0 -0
  66. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/envpush.py +0 -0
  67. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/render.py +0 -0
  68. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/traces.py +0 -0
  69. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cli/training_doc.py +0 -0
  70. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/__init__.py +0 -0
  71. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/config.py +0 -0
  72. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/http.py +0 -0
  73. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/runtime_secrets.py +0 -0
  74. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/client/specs.py +0 -0
  75. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/__init__.py +0 -0
  76. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/analytical.py +0 -0
  77. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/facts.py +0 -0
  78. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/spec.py +0 -0
  79. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/cost/types.py +0 -0
  80. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/diagnostics.py +0 -0
  81. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/__init__.py +0 -0
  82. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/accounting.py +0 -0
  83. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/multiturn_reward_scoring.py +0 -0
  84. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/recipe.py +0 -0
  85. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/reward_profile.py +0 -0
  86. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/rollout_profile.py +0 -0
  87. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/sft_workload.py +0 -0
  88. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/steps.py +0 -0
  89. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/structured_outputs.py +0 -0
  90. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/vram.py +0 -0
  91. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/__init__.py +0 -0
  92. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/__main__.py +0 -0
  93. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/_pkg.py +0 -0
  94. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/adapter.py +0 -0
  95. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/decoding.py +0 -0
  96. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/finalize.py +0 -0
  97. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo.py +0 -0
  98. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo_multiturn.py +0 -0
  99. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/grpo_plugin.py +0 -0
  100. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/heartbeat.py +0 -0
  101. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/hf.py +0 -0
  102. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/kernel_warmup.py +0 -0
  103. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/lora.py +0 -0
  104. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/multiturn_glue.py +0 -0
  105. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd.py +0 -0
  106. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_gkd.py +0 -0
  107. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_multiturn.py +0 -0
  108. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_plugin.py +0 -0
  109. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/opd_structured.py +0 -0
  110. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/packing.py +0 -0
  111. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/__init__.py +0 -0
  112. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/attn.py +0 -0
  113. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/diagnostics.py +0 -0
  114. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/liger.py +0 -0
  115. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/loraplus.py +0 -0
  116. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/perf/memory.py +0 -0
  117. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rl.py +0 -0
  118. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rng.py +0 -0
  119. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/rollout_samples.py +0 -0
  120. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft.py +0 -0
  121. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft_profile.py +0 -0
  122. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/sft_train.py +0 -0
  123. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/teacher.py +0 -0
  124. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/teacher_encoding.py +0 -0
  125. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/tokenizer_align.py +0 -0
  126. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker/wandb_log.py +0 -0
  127. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/engine/worker_entrypoint.py +0 -0
  128. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/__init__.py +0 -0
  129. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/adapter.py +0 -0
  130. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/archive.py +0 -0
  131. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/archive_policy.py +0 -0
  132. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/base.py +0 -0
  133. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/evaluations.py +0 -0
  134. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/loader.py +0 -0
  135. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/pull.py +0 -0
  136. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/envs/registry.py +0 -0
  137. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/lora_rank.py +0 -0
  138. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/multimodal.py +0 -0
  139. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_limits.py +0 -0
  140. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_retry_contract.py +0 -0
  141. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/opd_validation.py +0 -0
  142. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/__init__.py +0 -0
  143. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_auth.py +0 -0
  144. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_deadline.py +0 -0
  145. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_hf_artifacts.py +0 -0
  146. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_hf_retry.py +0 -0
  147. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_http.py +0 -0
  148. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance.py +0 -0
  149. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_bootstrap.py +0 -0
  150. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_poll.py +0 -0
  151. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_instance_provider.py +0 -0
  152. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_poll.py +0 -0
  153. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/_worker.py +0 -0
  154. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/allocator.py +0 -0
  155. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/base.py +0 -0
  156. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/__init__.py +0 -0
  157. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/api.py +0 -0
  158. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/auth.py +0 -0
  159. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/gpus.py +0 -0
  160. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/jobs/__init__.py +0 -0
  161. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/jobs/builders.py +0 -0
  162. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/preflight.py +0 -0
  163. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/lambdalabs/pricing.py +0 -0
  164. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/preflight.py +0 -0
  165. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/realized.py +0 -0
  166. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/__init__.py +0 -0
  167. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/api.py +0 -0
  168. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/auth.py +0 -0
  169. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/cost.py +0 -0
  170. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/gpus.py +0 -0
  171. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/jobs.py +0 -0
  172. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/keys.py +0 -0
  173. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/preflight.py +0 -0
  174. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/pricing.py +0 -0
  175. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/slots.py +0 -0
  176. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/train/__init__.py +0 -0
  177. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/runpod/train/endpoints.py +0 -0
  178. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/__init__.py +0 -0
  179. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/api.py +0 -0
  180. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/auth.py +0 -0
  181. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/jobs/__init__.py +0 -0
  182. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/jobs/builders.py +0 -0
  183. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/preflight.py +0 -0
  184. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/vast/pricing.py +0 -0
  185. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/providers/weight_cache_preload.py +0 -0
  186. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/py.typed +0 -0
  187. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/__init__.py +0 -0
  188. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/checkpoints.py +0 -0
  189. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/deploy.py +0 -0
  190. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/runner/verified_revisions.py +0 -0
  191. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/schema/__init__.py +0 -0
  192. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/schema/fields.py +0 -0
  193. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/__init__.py +0 -0
  194. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/deploy.py +0 -0
  195. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/export.py +0 -0
  196. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/preflight.py +0 -0
  197. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/pricing.py +0 -0
  198. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/serve/urls.py +0 -0
  199. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/__init__.py +0 -0
  200. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/__main__.py +0 -0
  201. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_deps.py +0 -0
  202. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_internal_client.py +0 -0
  203. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_locks.py +0 -0
  204. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/_runtime.py +0 -0
  205. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/app.py +0 -0
  206. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/auth.py +0 -0
  207. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/billing.py +0 -0
  208. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/billing_retry.py +0 -0
  209. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/checkpoints.py +0 -0
  210. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/db.py +0 -0
  211. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/environment_registry.py +0 -0
  212. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/envs.py +0 -0
  213. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/projects.py +0 -0
  214. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/reconcile.py +0 -0
  215. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/repo_cleanup.py +0 -0
  216. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/__init__.py +0 -0
  217. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/envs.py +0 -0
  218. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/meta.py +0 -0
  219. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/runs.py +0 -0
  220. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/serving.py +0 -0
  221. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/routes/teacher.py +0 -0
  222. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/run_registry.py +0 -0
  223. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/server/teacher_broker.py +0 -0
  224. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/spec.py +0 -0
  225. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/thinking.py +0 -0
  226. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/flash/workload_profile.py +0 -0
  227. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/scripts/build_dev_dist.py +0 -0
  228. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/scripts/scrub_history.sh +0 -0
  229. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/__init__.py +0 -0
  230. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/__init__.py +0 -0
  231. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/profile.py +0 -0
  232. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/runner.py +0 -0
  233. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/specs.py +0 -0
  234. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/_helpers/vast.py +0 -0
  235. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/conftest.py +0 -0
  236. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/fixtures/math_eval.jsonl +0 -0
  237. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/fixtures/math_train.jsonl +0 -0
  238. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/__init__.py +0 -0
  239. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/conftest.py +0 -0
  240. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_lambda_live.py +0 -0
  241. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_runpod_live.py +0 -0
  242. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/live/test_vast_live.py +0 -0
  243. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_accounting_coverage.py +0 -0
  244. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_agent_flash_cli_contract.py +0 -0
  245. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_algorithms.py +0 -0
  246. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_allocator.py +0 -0
  247. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_async_uploads.py +0 -0
  248. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_backend_jobspec_contract.py +0 -0
  249. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_base_model_provenance.py +0 -0
  250. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_billing_retry.py +0 -0
  251. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cancel_remote.py +0 -0
  252. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_catalog_consistency.py +0 -0
  253. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_charge_pricing.py +0 -0
  254. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_checkpoints.py +0 -0
  255. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_commands.py +0 -0
  256. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_commands_coverage.py +0 -0
  257. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_credential_shadowing.py +0 -0
  258. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_errors.py +0 -0
  259. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_estimate.py +0 -0
  260. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_gpus_flag.py +0 -0
  261. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_help.py +0 -0
  262. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_main_coverage.py +0 -0
  263. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_managed.py +0 -0
  264. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_render_coverage.py +0 -0
  265. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_render_theme.py +0 -0
  266. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_traces.py +0 -0
  267. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cli_wandb_warning.py +0 -0
  268. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client.py +0 -0
  269. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client_server_integration.py +0 -0
  270. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_client_stream_reads.py +0 -0
  271. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_config_env_vars.py +0 -0
  272. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_config_overrides.py +0 -0
  273. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_controlled_experiment_repairs.py +0 -0
  274. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_analytical.py +0 -0
  275. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_equation.py +0 -0
  276. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_estimate.py +0 -0
  277. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_hardware.py +0 -0
  278. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_models.py +0 -0
  279. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_cost_rewards.py +0 -0
  280. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_deploy_latency.py +0 -0
  281. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_dev_channel.py +0 -0
  282. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_disk_gb.py +0 -0
  283. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_endpoint_name.py +0 -0
  284. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_cache_evict.py +0 -0
  285. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_delete.py +0 -0
  286. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_download.py +0 -0
  287. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_download_api.py +0 -0
  288. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_evaluations.py +0 -0
  289. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_no_install.py +0 -0
  290. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_publish.py +0 -0
  291. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull.py +0 -0
  292. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_coverage.py +0 -0
  293. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_loader_coverage.py +0 -0
  294. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_pull_managed_control_plane.py +0 -0
  295. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_push.py +0 -0
  296. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_rate_limit_resolve.py +0 -0
  297. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_ref_pinning.py +0 -0
  298. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_env_test.py +0 -0
  299. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_envs_coverage.py +0 -0
  300. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_export.py +0 -0
  301. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flash_mvp.py +0 -0
  302. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flash_worker.py +0 -0
  303. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_flashinfer_cache_dirs.py +0 -0
  304. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_github_urlopen_retry.py +0 -0
  305. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_gpu_type_single_field.py +0 -0
  306. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_gpus.py +0 -0
  307. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_params.py +0 -0
  308. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_resident_sizing.py +0 -0
  309. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_grpo_reward_batching.py +0 -0
  310. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_health_liveness.py +0 -0
  311. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_hf_retry.py +0 -0
  312. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_idle_endpoint_reaper.py +0 -0
  313. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_infisical_overlay.py +0 -0
  314. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_instance_bootstrap_coverage.py +0 -0
  315. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_internal_client.py +0 -0
  316. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_jobs.py +0 -0
  317. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kernel_cache.py +0 -0
  318. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kernel_fingerprint.py +0 -0
  319. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_kv_util.py +0 -0
  320. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lambda_api_coverage.py +0 -0
  321. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lambda_runner.py +0 -0
  322. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_logging.py +0 -0
  323. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_login_perms.py +0 -0
  324. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lora_rank_coverage.py +0 -0
  325. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_lora_rank_preflight.py +0 -0
  326. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_managed_config_fields.py +0 -0
  327. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_managed_hf_repo.py +0 -0
  328. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_metrics_schema_agent_contract.py +0 -0
  329. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_mig_guard.py +0 -0
  330. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multi_gpu_gate.py +0 -0
  331. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multimodal_input_grads.py +0 -0
  332. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_multimodal_training.py +0 -0
  333. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_named_reward_metrics.py +0 -0
  334. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_limits.py +0 -0
  335. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_resume_safety.py +0 -0
  336. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_opd_train.py +0 -0
  337. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_open_model_policy.py +0 -0
  338. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_orchestrator_flash.py +0 -0
  339. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_packing.py +0 -0
  340. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_packing_coverage.py +0 -0
  341. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_parasail_teacher.py +0 -0
  342. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_poll_helpers.py +0 -0
  343. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_preflight.py +0 -0
  344. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_projects.py +0 -0
  345. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_preflight_coverage.py +0 -0
  346. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_routing.py +0 -0
  347. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_provider_teardown_robustness.py +0 -0
  348. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_providers_symmetry.py +0 -0
  349. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_realized_cost.py +0 -0
  350. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_repo_cleanup.py +0 -0
  351. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_resolve_params_b.py +0 -0
  352. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_resume_on_retry.py +0 -0
  353. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_reward_profile.py +0 -0
  354. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rl_train.py +0 -0
  355. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_profile_quote.py +0 -0
  356. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_profile_sampling.py +0 -0
  357. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_samples.py +0 -0
  358. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_rollout_workload_profile.py +0 -0
  359. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runmgmt.py +0 -0
  360. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_api_delete.py +0 -0
  361. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_key_fingerprint.py +0 -0
  362. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_key_waterfall.py +0 -0
  363. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_runpod_slots.py +0 -0
  364. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serve.py +0 -0
  365. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serve_reasoning_content.py +0 -0
  366. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_api.py +0 -0
  367. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_app_coverage.py +0 -0
  368. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_auth_singleflight.py +0 -0
  369. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_billing.py +0 -0
  370. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_checkpoints_coverage.py +0 -0
  371. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_db.py +0 -0
  372. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_envs_coverage.py +0 -0
  373. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_locks_coverage.py +0 -0
  374. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_server_standalone.py +0 -0
  375. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_context_preflight.py +0 -0
  376. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_contract.py +0 -0
  377. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_pricing_coverage.py +0 -0
  378. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_serving_schema_coverage.py +0 -0
  379. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_chunked_nll.py +0 -0
  380. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_example_selection.py +0 -0
  381. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_gc_off.py +0 -0
  382. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_max_context.py +0 -0
  383. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_profile_worker.py +0 -0
  384. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_train.py +0 -0
  385. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_sft_workload.py +0 -0
  386. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_spec_and_validation.py +0 -0
  387. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_step_floor.py +0 -0
  388. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_step_metrics.py +0 -0
  389. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_structured_outputs.py +0 -0
  390. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_teacher_broker.py +0 -0
  391. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_thinking_config.py +0 -0
  392. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_train_context_preflight.py +0 -0
  393. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_training_controls.py +0 -0
  394. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_api.py +0 -0
  395. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_api_coverage.py +0 -0
  396. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_offers.py +0 -0
  397. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_provider_coverage.py +0 -0
  398. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vast_runner.py +0 -0
  399. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_verified_revisions.py +0 -0
  400. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_verifiers.py +0 -0
  401. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_version.py +0 -0
  402. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  403. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_vram_architecture.py +0 -0
  404. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_link.py +0 -0
  405. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_log_coverage.py +0 -0
  406. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_wandb_naming.py +0 -0
  407. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_adapter_download.py +0 -0
  408. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_cross_repo.py +0 -0
  409. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_warmstart_error_attribution.py +0 -0
  410. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_weight_cache.py +0 -0
  411. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_dryrun.py +0 -0
  412. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_hardexit.py +0 -0
  413. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_image.py +0 -0
  414. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_init_heartbeat.py +0 -0
  415. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_worker_thinking.py +0 -0
  416. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_workload_profile.py +0 -0
  417. {freesolo_flash_dev-1.0.97 → freesolo_flash_dev-1.0.99}/tests/test_workload_profile_lifecycle.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: freesolo-flash-dev
3
- Version: 1.0.97
3
+ Version: 1.0.99
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
@@ -21,9 +21,12 @@ import re
21
21
  import shutil
22
22
  import signal
23
23
  import subprocess
24
+ import threading
24
25
  import time
26
+ import weakref
25
27
  from collections.abc import Callable
26
28
  from concurrent.futures import ThreadPoolExecutor
29
+ from concurrent.futures import thread as _thread_module
27
30
  from http.server import ThreadingHTTPServer
28
31
 
29
32
  from flash.diagnostics import sanitize_diagnostic
@@ -192,6 +195,49 @@ def agent_loop_workers(rollout_batch: int, *, cap: int = 8) -> int:
192
195
  _BRIDGE_WORKER_THREADS = 16
193
196
 
194
197
 
198
+ class _DaemonBridgeThreadPool(ThreadPoolExecutor):
199
+ """A ``ThreadPoolExecutor`` whose workers cannot hold the interpreter open.
200
+
201
+ The stock executor registers every worker in ``concurrent.futures.thread._threads_queues``,
202
+ which an interpreter-exit hook joins. ``shutdown(wait=False, cancel_futures=True)`` does not
203
+ change that: cancelling drops only the QUEUED futures, and a handler already running keeps its
204
+ thread alive, so exit blocks on it. Measured: a 30-second handler delays exit by the full 30
205
+ seconds even after ``shutdown(wait=False)`` returns.
206
+
207
+ That is the opposite of what a bridge needs. A hung environment reward or teacher callback must
208
+ not stop the worker from publishing its terminal result and releasing a paid GPU -- and it is
209
+ also the property the old daemon ``ThreadingHTTPServer`` had before requests moved onto a pool.
210
+
211
+ So: start the workers as daemons and skip the exit-hook registration. Only the thread creation
212
+ differs from the stdlib; queueing, idle reuse, and shutdown are inherited unchanged.
213
+ """
214
+
215
+ def _adjust_thread_count(self) -> None:
216
+ if self._idle_semaphore.acquire(timeout=0):
217
+ return
218
+
219
+ def weakref_cb(_, q=self._work_queue):
220
+ q.put(None)
221
+
222
+ num_threads = len(self._threads)
223
+ if num_threads < self._max_workers:
224
+ thread = threading.Thread(
225
+ name=f"{self._thread_name_prefix or self}_{num_threads}",
226
+ target=_thread_module._worker,
227
+ args=(
228
+ weakref.ref(self, weakref_cb),
229
+ self._work_queue,
230
+ self._initializer,
231
+ self._initargs,
232
+ ),
233
+ daemon=True,
234
+ )
235
+ thread.start()
236
+ self._threads.add(thread)
237
+ # deliberately NOT added to _thread_module._threads_queues: that mapping is exactly
238
+ # what the interpreter-exit hook walks to join workers.
239
+
240
+
195
241
  class BoundedThreadingHTTPServer(ThreadingHTTPServer):
196
242
  """an http server that serves requests from a fixed thread pool instead of one thread each.
197
243
 
@@ -212,13 +258,16 @@ class BoundedThreadingHTTPServer(ThreadingHTTPServer):
212
258
  """
213
259
 
214
260
  # daemon threads so a stuck handler can never keep the worker process alive at shutdown.
261
+ # `daemon_threads` is a ThreadingMixIn flag, read only by the `process_request` this class
262
+ # overrides, so it does nothing here on its own -- _DaemonBridgeThreadPool below is what
263
+ # actually delivers the property it names.
215
264
  daemon_threads = True
216
265
 
217
266
  # measured: at the socketserver default of 5, 13 of 64 simultaneous callers were reset by peer.
218
267
  request_queue_size = 128
219
268
 
220
269
  def __init__(self, *args, worker_threads: int = _BRIDGE_WORKER_THREADS, **kwargs):
221
- self._bridge_pool = ThreadPoolExecutor(
270
+ self._bridge_pool = _DaemonBridgeThreadPool(
222
271
  max_workers=worker_threads, thread_name_prefix="flash-bridge"
223
272
  )
224
273
  super().__init__(*args, **kwargs)
@@ -438,8 +487,31 @@ if %(gdn_module)r:
438
487
  torch.zeros(4, 3, device="cuda", dtype=torch.bfloat16),
439
488
  )
440
489
  torch.cuda.synchronize()
490
+ if not ok:
491
+ # say WHY on a clean negative too: which of the three checks failed is the difference
492
+ # between "install fla" and "rebuild causal_conv1d for this arch".
493
+ print(
494
+ "[verl] gdn boundary resets unavailable in the child: fla="
495
+ + str(is_flash_linear_attention_available())
496
+ + " causal_conv1d="
497
+ + str(is_causal_conv1d_available()),
498
+ flush=True,
499
+ )
441
500
  emit("gdn_boundary_resets", bool(ok))
442
- except Exception:
501
+ except Exception as e:
502
+ # a bare False here is what made this invisible. the caller raises on a hybrid that cannot
503
+ # reset, and an operator reading only that has no way back to which check fell over --
504
+ # a missing wheel, a broken ABI, or a conv kernel compiled without this arch all look
505
+ # identical from the parent. printed to STDOUT, which probe_verl_capabilities forwards
506
+ # on the '[verl] ' prefix -- stderr would be dropped, it is only reported when the
507
+ # child answers nothing at all.
508
+ import traceback
509
+
510
+ print(
511
+ "[verl] gdn boundary resets unavailable in the child: "
512
+ + " | ".join(traceback.format_exc(limit=3).strip().splitlines()),
513
+ flush=True,
514
+ )
443
515
  emit("gdn_boundary_resets", False)
444
516
  """
445
517
 
@@ -523,6 +595,14 @@ def probe_verl_capabilities(python_bin: str, gdn_module: str = "") -> dict:
523
595
  # fail-closed default rather than vanishing from the dict.
524
596
  caps.update({k: v for k, v in answered.items() if k in caps})
525
597
  answered_any = True
598
+ # the child's own diagnostics, forwarded BEFORE the early return. the gdn question prints why it
599
+ # answered no, and it is answered LAST -- so every real run answers something earlier, and a
600
+ # bare `return caps` here would discard the one line the gate's raise tells operators to read.
601
+ # matched on the prefix rather than forwarded wholesale: the child's stdout also carries verl's
602
+ # own import chatter, which is not worth a parent log line.
603
+ for line in (stdout or "").splitlines():
604
+ if line.startswith("[verl] "):
605
+ print(line, flush=True)
526
606
  if answered_any:
527
607
  return caps
528
608
  if not timed_out:
@@ -609,6 +689,52 @@ def gdn_reset_arch_from_caps(caps: dict, gdn_module: str) -> str | None:
609
689
  return gdn_module.split(".")[2]
610
690
 
611
691
 
692
+ def require_gdn_boundary_resets(caps: dict, gdn_module: str) -> str | None:
693
+ """The arch to patch for a gdn hybrid, raising if the child cannot honor boundary resets.
694
+
695
+ A thin gate over ``gdn_reset_arch_from_caps``: same answer for the two cases that have one, but
696
+ a raise where that returns None for a gdn model. Returns None only for a NON-gdn model, which
697
+ is what an empty ``gdn_module`` means -- the parent never asked the child, because there was
698
+ nothing to ask about.
699
+
700
+ There is no third outcome for a gdn hybrid. One whose child lacks fla/causal_conv1d used to fall
701
+ back to verl's padded path (``use_remove_padding=False``), which is boundary-correct but cannot
702
+ complete a single training step on grpo or opd: flash sets ``use_fused_kernels=True``
703
+ unconditionally, and verl's fsdp engine has no guard for that pair (its megatron engine does,
704
+ ``megatron/transformer_impl.py:869-874``). The padded+fused branch returns a dense
705
+ ``[bsz, response_len]`` where every sibling path re-nests via ``cu_seqlens``, so
706
+ ``no_padding_2_padding`` asserts ``sequence_offsets[-1] == values.shape[0]`` -- total tokens
707
+ against batch size, which fails at EVERY batch size. Measured on four matched real-gpu arms, all
708
+ four dead at ``padding.py:144``.
709
+
710
+ So the run cannot finish, and the failure names neither gdn nor this decision -- letting it
711
+ launch spends the full gpu rental on an untraceable shape error. Raise here instead. Dropping
712
+ ``use_fused_kernels`` is NOT the alternative fix: ``engine/vram.py:386-392`` sizes on the
713
+ assumption that no dense ``[b, s, vocab]`` logits tensor exists (~130 GB at 32k on a 248k
714
+ vocab), so that would trade this crash for an OOM. The fix is to give the child the kernels.
715
+
716
+ SFT is deliberately not a caller. It reaches the same padded+fused branch but is safe without
717
+ resets for a different reason: every gdn model profiles as exact-unpacked, which pins
718
+ ``examples_per_update`` to 1 (``sft_workload.py:410``), so there are no packed neighbours to
719
+ contaminate -- and its remove-padding flag stays on regardless, because that is the only tensor
720
+ layout ``FlashTokenizedSFTDataset`` fits. Grpo and opd have no such profile: their batch size is
721
+ the user's ``prompts_per_step``, routinely greater than 1, so they genuinely pack.
722
+ """
723
+ if not gdn_module:
724
+ return None
725
+ arch = gdn_reset_arch_from_caps(caps, gdn_module)
726
+ if arch is None:
727
+ raise RuntimeError(
728
+ "gdn hybrid without child-side boundary resets: the padded fallback "
729
+ "(use_remove_padding=False) is incompatible with the use_fused_kernels=True this "
730
+ "recipe sets, and cannot complete a training step on verl's fsdp engine. see the "
731
+ "'[verl] gdn boundary resets unavailable' line above for why the child could not "
732
+ "honor resets -- installing fla + causal_conv1d in the verl interpreter is the fix, "
733
+ "not disabling fused kernels."
734
+ )
735
+ return arch
736
+
737
+
612
738
  def resolve_verl_python(workdir: str, *, install_wandb: bool = False) -> str:
613
739
  """return an interpreter that can import verl.
614
740
 
@@ -38,7 +38,6 @@ from flash.engine.worker.backend_common import (
38
38
  agent_loop_workers,
39
39
  clamp_engine_len,
40
40
  gdn_probe_module,
41
- gdn_reset_arch_from_caps,
42
41
  latest_global_step_dir,
43
42
  model_max_position_embeddings,
44
43
  parse_verl_metric,
@@ -48,6 +47,7 @@ from flash.engine.worker.backend_common import (
48
47
  render_gdn_varlen_shim,
49
48
  render_tf32_shim,
50
49
  render_wandb_link_shim,
50
+ require_gdn_boundary_resets,
51
51
  resolve_blackwell_attention_backends,
52
52
  resolve_rollout_enforce_eager,
53
53
  resolve_verl_loggers,
@@ -1551,9 +1551,10 @@ def build_opd_overrides(config: dict) -> list[str]:
1551
1551
  f"actor_rollout_ref.model.path={_hydra_val(config['model_path'])}",
1552
1552
  "actor_rollout_ref.model.trust_remote_code=true",
1553
1553
  # packing the micro-batch into one row is only safe for a gdn hybrid when the child can
1554
- # reset linear-attention state at the example boundaries; see the caller's gdn gate.
1555
- "actor_rollout_ref.model.use_remove_padding="
1556
- + _hydra_val(config.get("use_remove_padding", True)),
1554
+ # reset linear-attention state at the example boundaries -- and the caller's gdn gate now
1555
+ # RAISES when it cannot, because the padded alternative cannot complete a step alongside the
1556
+ # fused kernels below. always true by the time we get here.
1557
+ "actor_rollout_ref.model.use_remove_padding=true",
1557
1558
  # 32k contexts: the fused linear-CE forward computes per-token log_probs from hidden states
1558
1559
  # + lm_head in chunks (FusedLinearForPPO), never materializing the [tokens, vocab] logits
1559
1560
  # tensor (~130 GB at 32k on a 248k vocab). the distillation loss consumes exactly
@@ -2480,15 +2481,11 @@ def run_opd_train(spec=None) -> None:
2480
2481
 
2481
2482
  # a gdn hybrid may only pack when the CHILD can honor seq_idx + cu_seqlens; the no-fla fallbacks
2482
2483
  # accept both and discard them, which silently bleeds state across packed example boundaries.
2483
- gdn_reset_arch = gdn_reset_arch_from_caps(caps, gdn_module) if gdn_hybrid else None
2484
- gdn_boundary_resets = gdn_reset_arch is not None
2485
- use_remove_padding = not gdn_hybrid or gdn_boundary_resets
2486
- if gdn_hybrid and not gdn_boundary_resets:
2487
- print(
2488
- "[opd] gdn hybrid without child-side boundary resets: disabling remove-padding so "
2489
- "packed examples cannot contaminate each other (slower, correct)",
2490
- flush=True,
2491
- )
2484
+ # raises when the child cannot -- opd reaches no_padding_2_padding through
2485
+ # trainer/distillation/losses.py exactly as grpo reaches it through ray_trainer, so the padded
2486
+ # fallback that used to handle this cannot complete a step either. see
2487
+ # require_gdn_boundary_resets.
2488
+ gdn_reset_arch = require_gdn_boundary_resets(caps, gdn_module)
2492
2489
 
2493
2490
  # sm86's vllm 0.19.1 graph capture degenerates, so only that arch runs the rollout eagerly. grpo
2494
2491
  # has resolved this since the trl driver; opd never did, and opd is the MORE exposed of the two
@@ -2581,7 +2578,6 @@ def run_opd_train(spec=None) -> None:
2581
2578
  bridge.start()
2582
2579
  try:
2583
2580
  config = {
2584
- "use_remove_padding": use_remove_padding,
2585
2581
  "train_files": [train_file],
2586
2582
  "val_files": [val_file],
2587
2583
  "train_batch_size": prompts_per_step,
@@ -2912,7 +2908,7 @@ def run_opd_train(spec=None) -> None:
2912
2908
  # whether it packed with resets or took the padded fallback. for a gate whose failure
2913
2909
  # mode is silent contamination that is the one thing worth recording. None for a
2914
2910
  # non-gdn model, where the question does not arise.
2915
- "gdn_boundary_resets": gdn_boundary_resets if gdn_hybrid else None,
2911
+ "gdn_boundary_resets": gdn_hybrid or None,
2916
2912
  "peak_gpu_gb": peak_gpu_gb,
2917
2913
  "warm_started": bool(warmstart_adapter),
2918
2914
  "resumed": bool(resume_step),
@@ -10,6 +10,14 @@ _CUDA_OOM_PREFLIGHT_RE = re.compile(
10
10
  r"free memory on device\s+cuda:\d+.*less than desired gpu memory utilization"
11
11
  )
12
12
  _CUDA_OOM_CACHE_BLOCKS = "no available memory for the cache blocks"
13
+ # torch's own allocator OOM, which the two vllm STARTUP signatures above do not cover. the parent
14
+ # classifies an in-process OOM off `torch.cuda.OutOfMemoryError` and the allocator counter, but a
15
+ # verl child is a separate process: neither the exception type nor its `num_ooms` crosses, and the
16
+ # terminal raise carries only "subprocess exited with status N". without this the one OOM shape that
17
+ # happens DURING training reads as a permanent job_failed, so the lifecycle never retries it on a
18
+ # larger gpu. anchored on torch's exact wording rather than a bare "out of memory", which a host-ram
19
+ # OOM or an env's own error text would also match -- and those must not escalate the gpu.
20
+ _CUDA_OOM_TORCH_RE = re.compile(r"(?:torch\.)?(?:cuda\.)?outofmemoryerror|cuda out of memory")
13
21
 
14
22
 
15
23
  class RetriableInfraError(RuntimeError):
@@ -42,6 +50,9 @@ def cuda_oom_message_evidence(message: str) -> str | None:
42
50
  return preflight.group(0)
43
51
  if _CUDA_OOM_CACHE_BLOCKS in normalized:
44
52
  return _CUDA_OOM_CACHE_BLOCKS
53
+ torch_oom = _CUDA_OOM_TORCH_RE.search(normalized)
54
+ if torch_oom is not None:
55
+ return torch_oom.group(0)
45
56
  return None
46
57
 
47
58
 
@@ -60,7 +60,6 @@ from flash.engine.worker.backend_common import (
60
60
  clamp_engine_len,
61
61
  export_peft_adapter,
62
62
  gdn_probe_module,
63
- gdn_reset_arch_from_caps,
64
63
  kill_process_group,
65
64
  latest_global_step_dir,
66
65
  model_max_position_embeddings,
@@ -74,6 +73,7 @@ from flash.engine.worker.backend_common import (
74
73
  render_gdn_varlen_shim,
75
74
  render_tf32_shim,
76
75
  render_wandb_link_shim,
76
+ require_gdn_boundary_resets,
77
77
  resolve_blackwell_attention_backends,
78
78
  resolve_rollout_enforce_eager,
79
79
  resolve_verl_loggers,
@@ -387,8 +387,10 @@ def build_verl_overrides(cfg: dict) -> list[str]:
387
387
  # chunks (FusedLinearForPPO), never materializing the [tokens, vocab] logits tensor
388
388
  # (~130 GB at 32k on a 248k vocab). torch backend = numerically exact, no extra deps.
389
389
  # packing the micro-batch into one row is only boundary-safe for a gdn hybrid when the child
390
- # can honor seq_idx + cu_seqlens; see the gdn gate in run_rl_train.
391
- f"actor_rollout_ref.model.use_remove_padding={cfg.get('use_remove_padding', True)}",
390
+ # can honor seq_idx + cu_seqlens -- and run_rl_train now RAISES when it cannot, because the
391
+ # padded alternative cannot complete a step alongside the fused kernels below. so this is
392
+ # always true by the time we get here; there is no longer a configuration that turns it off.
393
+ "actor_rollout_ref.model.use_remove_padding=True",
392
394
  "actor_rollout_ref.model.use_fused_kernels=True",
393
395
  "actor_rollout_ref.model.fused_kernel_options.impl_backend=torch",
394
396
  *(
@@ -665,12 +667,10 @@ def _build_verl_training_cfg(
665
667
  experiment_name: str,
666
668
  gpu_type: str = "",
667
669
  n_gpus: int = 1,
668
- use_remove_padding: bool = True,
669
670
  ) -> dict:
670
671
  engine_len = int(inp["engine_len"])
671
672
  sleep_unsupported = rollout_sleep_unsupported(inp["model_id"])
672
673
  return {
673
- "use_remove_padding": use_remove_padding,
674
674
  "train_files": train_files,
675
675
  "val_files": val_files,
676
676
  "model_id": model_id,
@@ -3470,18 +3470,12 @@ def run_rl_train():
3470
3470
  # the shim is appended here rather than with the shims above because the answer needs
3471
3471
  # python_bin, resolved in the block above; sitecustomize is imported by the child, which has
3472
3472
  # not started yet.
3473
- gdn_reset_arch = gdn_reset_arch_from_caps(caps, gdn_module) if gdn_hybrid else None
3474
- gdn_boundary_resets = gdn_reset_arch is not None
3475
- use_remove_padding = not gdn_hybrid or gdn_boundary_resets
3473
+ # raises when a gdn child cannot honor resets: the padded fallback that used to handle that
3474
+ # case cannot complete a step on verl's fsdp engine. see require_gdn_boundary_resets.
3475
+ gdn_reset_arch = require_gdn_boundary_resets(caps, gdn_module)
3476
3476
  if gdn_reset_arch is not None:
3477
3477
  with open(shim_py, "a") as f:
3478
3478
  f.write(render_gdn_varlen_shim(gdn_reset_arch))
3479
- elif gdn_hybrid:
3480
- print(
3481
- "[grpo] gdn hybrid without child-side boundary resets: disabling remove-padding so "
3482
- "packed examples cannot contaminate each other (slower, correct)",
3483
- flush=True,
3484
- )
3485
3479
 
3486
3480
  expected_steps = int(inp["steps"])
3487
3481
  # verl logs from its own interpreter; gate wandb on that env (see resolve_verl_loggers).
@@ -3500,9 +3494,7 @@ def run_rl_train():
3500
3494
  )
3501
3495
  except Exception: # no cuda / probe failure -> conservative bf16 kv
3502
3496
  _cc_ok = False
3503
- # reuse the gdn answer resolved above rather than re-probing: model_is_gdn_hybrid returns
3504
- # False when its own probe raises, so a second call can disagree with the first and turn
3505
- # fp8 kv ON for the very hybrid the comment above says it crashes.
3497
+ # reuse the gdn answer resolved above rather than re-probing; see gdn_hybrid.
3506
3498
  fp8_kv = _cc_ok and not gdn_hybrid
3507
3499
  # one capability probe, both rollout decisions below. asked of the verl interpreter, whose
3508
3500
  # torch/vllm stack is the one that has to run the rollout.
@@ -3528,7 +3520,6 @@ def run_rl_train():
3528
3520
  enforce_eager=enforce_eager,
3529
3521
  attention_backend=attention_backend,
3530
3522
  mm_encoder_attn_backend=mm_encoder_attn_backend,
3531
- use_remove_padding=use_remove_padding,
3532
3523
  reward_path=reward_py,
3533
3524
  local_dir=local_dir,
3534
3525
  project_name=project_name,
@@ -3865,6 +3856,6 @@ def run_rl_train():
3865
3856
  reward_profile=reward_profile,
3866
3857
  step_intervals=_step_intervals(step_line_times),
3867
3858
  reward_bridge_batching=not inp["multi_turn"],
3868
- gdn_boundary_resets=gdn_boundary_resets if gdn_hybrid else None,
3859
+ gdn_boundary_resets=gdn_hybrid or None,
3869
3860
  ),
3870
3861
  )
@@ -558,13 +558,31 @@ def _projected_retry_class(
558
558
  )
559
559
 
560
560
 
561
- def _oom_escalated(candidates, oom_vram_floor: int):
561
+ def _candidate_usable_vram_gb(candidate) -> float:
562
+ """Run-usable VRAM for a candidate, under the same fit model the allocator selected it with.
563
+
564
+ `combined_vram_gb` is documented as THE single fit model, and every sizing path calls it. The raw
565
+ `gpu_count * vram_gb` product is NOT interchangeable with it for a sharded shape: it ignores the
566
+ replicated-per-card floor and the shard efficiency, so it overstates a multi-card box. Comparing
567
+ the two measures is what let an OOM retry move SIDEWAYS or DOWNWARDS -- 2x80 raw-counts as 160 GB
568
+ against a 141 GB single card that just OOM'd, but the allocator models that pair as 130.4 GB
569
+ usable, i.e. smaller than the shape that already failed.
570
+ """
571
+ from flash.providers.base import combined_vram_gb
572
+
573
+ return combined_vram_gb(candidate.vram_gb, int(getattr(candidate, "gpu_count", 1) or 1))
574
+
575
+
576
+ def _oom_escalated(candidates, oom_vram_floor: float):
562
577
  """Candidates strictly LARGER than the VRAM that just OOM'd. ``oom_vram_floor == 0`` (no prior OOM)
563
578
  leaves the list unchanged; otherwise an 80GB OOM leaves only the >80GB classes (a same-size retry
564
- would just OOM again). EMPTY means the run already OOM'd the largest available class."""
579
+ would just OOM again). EMPTY means the run already OOM'd the largest available class.
580
+
581
+ Both sides are measured with `_candidate_usable_vram_gb`, and the floor recorded on OOM uses it
582
+ too -- the filter is only meaningful if the floor and the candidates are on one scale."""
565
583
  if not oom_vram_floor:
566
584
  return list(candidates)
567
- return [c for c in candidates if getattr(c, "gpu_count", 1) * c.vram_gb > oom_vram_floor]
585
+ return [c for c in candidates if _candidate_usable_vram_gb(c) > oom_vram_floor]
568
586
 
569
587
 
570
588
  def _await_runpod_completed_metrics(
@@ -743,7 +761,7 @@ def _submit_seed_supervised(
743
761
  # Grow only when an attempt actually provisioned a class and lost it to infra.
744
762
  failed_providers: set[str] = set()
745
763
  tried_classes: set[tuple[str, str, int]] = set()
746
- oom_vram_floor = 0
764
+ oom_vram_floor = 0.0
747
765
  # Pin the environment ref ONCE, here, before any attempt runs -- not per attempt. Submit's pin
748
766
  # is best-effort, so a GitHub blip there leaves resolved_sha empty, and a managed slug points at
749
767
  # environment-hub@main, which moves. attempt_start > 0 means a previous invocation already ran an
@@ -906,9 +924,9 @@ def _submit_seed_supervised(
906
924
  raise _cancel()
907
925
  cands = _oom_escalated(alloc.candidates, oom_vram_floor)
908
926
  if not cands:
909
- last_detail = f"oom: exceeded the largest available GPU ({oom_vram_floor} GB)"
927
+ last_detail = f"oom: exceeded the largest available GPU ({oom_vram_floor:g} GB)"
910
928
  print(
911
- f"seed={seed} OOM on the largest GPU class ({oom_vram_floor} GB); not retrying",
929
+ f"seed={seed} OOM on the largest GPU class ({oom_vram_floor:g} GB); not retrying",
912
930
  file=log,
913
931
  flush=True,
914
932
  )
@@ -1112,7 +1130,8 @@ def _submit_seed_supervised(
1112
1130
  last_detail = f"{res.failure}: {res.detail}"
1113
1131
  oom_shaped = res.failure == "oom"
1114
1132
  if oom_shaped and chosen is not None:
1115
- oom_vram_floor = max(oom_vram_floor, getattr(chosen, "gpu_count", 1) * chosen.vram_gb)
1133
+ # same measure the filter compares against, see _candidate_usable_vram_gb
1134
+ oom_vram_floor = max(oom_vram_floor, _candidate_usable_vram_gb(chosen))
1116
1135
  run_had_cache = bool(
1117
1136
  chosen is not None
1118
1137
  and getattr(get_provider(chosen.provider), "supports_weight_cache", False)
@@ -1166,7 +1185,7 @@ def _submit_seed_supervised(
1166
1185
  else:
1167
1186
  retry_target = "retrying (resume from last checkpoint)"
1168
1187
  action = (
1169
- f"retrying on a larger GPU (> {oom_vram_floor} GB)"
1188
+ f"retrying on a larger GPU (> {oom_vram_floor:g} GB)"
1170
1189
  if (will_retry and oom_mode)
1171
1190
  else retry_target
1172
1191
  if will_retry
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "freesolo-flash-dev"
3
- version = "1.0.97"
3
+ version = "1.0.99"
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).
@@ -121,7 +121,7 @@ artifacts = ["flash/py.typed"]
121
121
  # auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
122
122
  # PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
123
123
  # dev-channel release = bump this (and [project].version) and merge to `dev`.
124
- version = "1.0.97"
124
+ version = "1.0.99"
125
125
 
126
126
  [tool.pytest.ini_options]
127
127
  pythonpath = ["."]