freesolo-flash-dev 1.2.37__tar.gz → 1.2.39__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 (542) hide show
  1. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/PKG-INFO +1 -1
  2. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/core/catalog.py +7 -3
  3. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/backend_common.py +51 -65
  4. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/failures.py +4 -0
  5. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/checkpoints.py +7 -1
  6. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/sft/checkpoints.py +18 -1
  7. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/checkpoints.py +137 -57
  8. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/preparation.py +1 -1
  9. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/pyproject.toml +2 -2
  10. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_backend_common.py +2 -2
  11. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_disk_gb.py +90 -16
  12. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_train.py +100 -226
  13. freesolo_flash_dev-1.2.39/tests/test_verl_checkpoint_export.py +495 -0
  14. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_warmstart_cross_repo.py +1 -1
  15. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/uv.lock +1 -1
  16. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.dockerignore +0 -0
  17. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.env.example +0 -0
  18. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/CODEOWNERS +0 -0
  19. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  20. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  21. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  22. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  23. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/dependabot.yml +0 -0
  24. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/auto-rebake.yml +0 -0
  25. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/bake-kernel-cache.yml +0 -0
  26. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/ci.yml +0 -0
  27. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/main-source-guard.yml +0 -0
  28. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/notify-tests-repo.yml +0 -0
  29. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/publish-dev.yml +0 -0
  30. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/publish-image.yml +0 -0
  31. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/publish.yml +0 -0
  32. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/version-parity.yml +0 -0
  33. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.github/workflows/worker-image.yml +0 -0
  34. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/.gitignore +0 -0
  35. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/CHANGELOG.md +0 -0
  36. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/CODE_OF_CONDUCT.md +0 -0
  37. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/CONTRIBUTING.md +0 -0
  38. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/Dockerfile +0 -0
  39. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/Dockerfile.worker +0 -0
  40. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/LICENSE +0 -0
  41. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/NOTICE +0 -0
  42. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/README.md +0 -0
  43. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/SECURITY.md +0 -0
  44. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/SELF_HOSTING.md +0 -0
  45. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/build/kernel_cache/.gitignore +0 -0
  46. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/build/kernel_cache/.keep +0 -0
  47. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/deploy/infisical/README.md +0 -0
  48. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/deploy/infisical/entrypoint.sh +0 -0
  49. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/Dockerfile.kernelcache +0 -0
  50. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/Dockerfile.kernelcache.relayer +0 -0
  51. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/bake_kernel_cache.py +0 -0
  52. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/bake_pod_entry.py +0 -0
  53. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/extract_cudart_fix.py +0 -0
  54. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/kernel_fingerprint.py +0 -0
  55. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/docker/make_rp_handler.py +0 -0
  56. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/__init__.py +0 -0
  57. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/__init__.py +0 -0
  58. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/channel.py +0 -0
  59. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/diagnostics.py +0 -0
  60. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/fileio.py +0 -0
  61. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/logging.py +0 -0
  62. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/_internal/paths.py +0 -0
  63. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/adapters/__init__.py +0 -0
  64. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/adapters/artifacts.py +0 -0
  65. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/adapters/lora_rank.py +0 -0
  66. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/__init__.py +0 -0
  67. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/__main__.py +0 -0
  68. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/__init__.py +0 -0
  69. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/deploy.py +0 -0
  70. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/__init__.py +0 -0
  71. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/episode.py +0 -0
  72. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/eval.py +0 -0
  73. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/eval_args.py +0 -0
  74. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/imports.py +0 -0
  75. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/list.py +0 -0
  76. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/push.py +0 -0
  77. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/retained.py +0 -0
  78. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/setup.py +0 -0
  79. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/test.py +0 -0
  80. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/test_evaluations.py +0 -0
  81. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/test_params.py +0 -0
  82. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/env/test_warnings.py +0 -0
  83. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/prompt_budget.py +0 -0
  84. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/traces.py +0 -0
  85. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/commands/train_cost.py +0 -0
  86. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/scaffold/TRAINING.md +0 -0
  87. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/scaffold/__init__.py +0 -0
  88. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/__init__.py +0 -0
  89. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/cost.py +0 -0
  90. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/env_panels.py +0 -0
  91. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/heartbeat.py +0 -0
  92. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/render.py +0 -0
  93. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/tables.py +0 -0
  94. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cli/ui/tty.py +0 -0
  95. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/__init__.py +0 -0
  96. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/config.py +0 -0
  97. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/freesolo_api.py +0 -0
  98. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/http.py +0 -0
  99. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/runtime_secrets.py +0 -0
  100. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/shapes.py +0 -0
  101. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/specs.py +0 -0
  102. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/client/streaming.py +0 -0
  103. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/content/__init__.py +0 -0
  104. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/content/multimodal.py +0 -0
  105. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/content/structured_outputs.py +0 -0
  106. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/content/thinking.py +0 -0
  107. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/core/__init__.py +0 -0
  108. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/core/spec.py +0 -0
  109. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cost/__init__.py +0 -0
  110. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cost/analytical.py +0 -0
  111. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cost/facts.py +0 -0
  112. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cost/spec.py +0 -0
  113. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/cost/types.py +0 -0
  114. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/__init__.py +0 -0
  115. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/__init__.py +0 -0
  116. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/kv_sizing.py +0 -0
  117. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/model_config_probe.py +0 -0
  118. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/prompt_budget.py +0 -0
  119. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/recipe.py +0 -0
  120. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/steps.py +0 -0
  121. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/plan/vram.py +0 -0
  122. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/__init__.py +0 -0
  123. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/dataset_profile.py +0 -0
  124. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/reasoning_render.py +0 -0
  125. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/sft_workload.py +0 -0
  126. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/tokenizer.py +0 -0
  127. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/profiling/workload_profile.py +0 -0
  128. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/result/__init__.py +0 -0
  129. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/result/accounting.py +0 -0
  130. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/result/rollout_samples.py +0 -0
  131. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/__init__.py +0 -0
  132. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/__main__.py +0 -0
  133. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/entry/__init__.py +0 -0
  134. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/entry/opd.py +0 -0
  135. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/entry/rl.py +0 -0
  136. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/entry/sft.py +0 -0
  137. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/io/__init__.py +0 -0
  138. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/io/heartbeat.py +0 -0
  139. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/io/hf.py +0 -0
  140. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/io/prefetch.py +0 -0
  141. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/io/wandb_log.py +0 -0
  142. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/model/__init__.py +0 -0
  143. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/model/adapter.py +0 -0
  144. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/model/decoding.py +0 -0
  145. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/model/lora.py +0 -0
  146. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/model/packing.py +0 -0
  147. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/opd_train.py +0 -0
  148. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/opd_train_runner.py +0 -0
  149. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/perf/__init__.py +0 -0
  150. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/perf/diagnostics.py +0 -0
  151. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/perf/lifecycle.py +0 -0
  152. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/perf/liger.py +0 -0
  153. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/perf/memory.py +0 -0
  154. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/rl_train.py +0 -0
  155. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/rl_train_runner.py +0 -0
  156. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/runtime/__init__.py +0 -0
  157. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/runtime/kernel_warmup.py +0 -0
  158. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/runtime/pkg_proxy.py +0 -0
  159. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/runtime/rng.py +0 -0
  160. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/score_batcher.py +0 -0
  161. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/sft_train.py +0 -0
  162. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/sft_train_runner.py +0 -0
  163. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/teacher/__init__.py +0 -0
  164. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/teacher/client.py +0 -0
  165. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/teacher/encoding.py +0 -0
  166. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/teacher/tokenizer_align.py +0 -0
  167. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/__init__.py +0 -0
  168. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/core/__init__.py +0 -0
  169. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/core/child/__init__.py +0 -0
  170. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/core/child/glue.py +0 -0
  171. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/core/step_timing.py +0 -0
  172. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/finalize.py +0 -0
  173. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/__init__.py +0 -0
  174. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/batching.py +0 -0
  175. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/bridge.py +0 -0
  176. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/child/__init__.py +0 -0
  177. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/child/bridge.py +0 -0
  178. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/child/multiturn.py +0 -0
  179. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/child/plugin.py +0 -0
  180. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/child/structured.py +0 -0
  181. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/gkd.py +0 -0
  182. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/multiturn_validation.py +0 -0
  183. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/overrides.py +0 -0
  184. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/prompts.py +0 -0
  185. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/reporting.py +0 -0
  186. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/scoring.py +0 -0
  187. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/state.py +0 -0
  188. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/opd/validation.py +0 -0
  189. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/__init__.py +0 -0
  190. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/child/__init__.py +0 -0
  191. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/child/multiturn.py +0 -0
  192. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/child/plugin.py +0 -0
  193. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/config.py +0 -0
  194. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/inputs.py +0 -0
  195. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/multi_turn.py +0 -0
  196. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/scoring.py +0 -0
  197. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/shims.py +0 -0
  198. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/single_turn.py +0 -0
  199. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/rl/verl_config.py +0 -0
  200. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/sft/__init__.py +0 -0
  201. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/train/sft/config.py +0 -0
  202. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/__init__.py +0 -0
  203. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/capabilities.py +0 -0
  204. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/child_io.py +0 -0
  205. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/diagnostics.py +0 -0
  206. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker/verl/parallelism.py +0 -0
  207. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/engine/worker_entrypoint.py +0 -0
  208. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/__init__.py +0 -0
  209. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/adapter.py +0 -0
  210. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/base.py +0 -0
  211. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/cache_security.py +0 -0
  212. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/dataset_selection.py +0 -0
  213. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/evaluations.py +0 -0
  214. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/identity.py +0 -0
  215. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/loader.py +0 -0
  216. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/namespace_listing.py +0 -0
  217. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/package/__init__.py +0 -0
  218. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/package/limits.py +0 -0
  219. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/package/unpack.py +0 -0
  220. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/envs/pull.py +0 -0
  221. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/__init__.py +0 -0
  222. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/__init__.py +0 -0
  223. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/auth.py +0 -0
  224. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/bootstrap.py +0 -0
  225. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/bootstrap_pip.py +0 -0
  226. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/bootstrap_secrets.py +0 -0
  227. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/deadline.py +0 -0
  228. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/http.py +0 -0
  229. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/instance.py +0 -0
  230. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/poll.py +0 -0
  231. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/poll_instance.py +0 -0
  232. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/provider.py +0 -0
  233. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/_lifecycle/worker.py +0 -0
  234. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/allocator.py +0 -0
  235. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/artifacts/__init__.py +0 -0
  236. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/artifacts/hf.py +0 -0
  237. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/artifacts/preload_runpod.py +0 -0
  238. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/artifacts/weight_cache.py +0 -0
  239. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/base.py +0 -0
  240. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/fit_errors.py +0 -0
  241. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/__init__.py +0 -0
  242. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/api.py +0 -0
  243. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/auth.py +0 -0
  244. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/gpus.py +0 -0
  245. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/jobs/__init__.py +0 -0
  246. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/jobs/builders.py +0 -0
  247. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/jobs/reap.py +0 -0
  248. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/preflight.py +0 -0
  249. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/lambda_/pricing.py +0 -0
  250. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/preflight.py +0 -0
  251. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/realized.py +0 -0
  252. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/__init__.py +0 -0
  253. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/api.py +0 -0
  254. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/auth.py +0 -0
  255. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/cost.py +0 -0
  256. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/gpus.py +0 -0
  257. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/job_execution.py +0 -0
  258. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/jobs.py +0 -0
  259. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/preflight.py +0 -0
  260. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/pricing.py +0 -0
  261. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/resources.py +0 -0
  262. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/serverless/__init__.py +0 -0
  263. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/runpod/serverless/endpoints.py +0 -0
  264. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/sharding.py +0 -0
  265. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/__init__.py +0 -0
  266. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/api.py +0 -0
  267. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/auth.py +0 -0
  268. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/jobs/__init__.py +0 -0
  269. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/jobs/builders.py +0 -0
  270. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/preflight.py +0 -0
  271. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/providers/vast/pricing.py +0 -0
  272. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/py.typed +0 -0
  273. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/__init__.py +0 -0
  274. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/artifacts.py +0 -0
  275. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/attempts.py +0 -0
  276. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/costs.py +0 -0
  277. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/deadlines.py +0 -0
  278. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/reconciliation.py +0 -0
  279. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/results/__init__.py +0 -0
  280. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/results/checkpoints.py +0 -0
  281. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/results/verified_revisions.py +0 -0
  282. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/status.py +0 -0
  283. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/submit.py +0 -0
  284. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/__init__.py +0 -0
  285. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/attach.py +0 -0
  286. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/deploy.py +0 -0
  287. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/lifecycle.py +0 -0
  288. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/recovery.py +0 -0
  289. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/retry_decision.py +0 -0
  290. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/seed_submission.py +0 -0
  291. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/supervise/transitions.py +0 -0
  292. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/runner/weight_cache.py +0 -0
  293. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/schema/__init__.py +0 -0
  294. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/schema/fields.py +0 -0
  295. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/__init__.py +0 -0
  296. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/adapter_check.py +0 -0
  297. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/deploy.py +0 -0
  298. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/errors.py +0 -0
  299. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/export.py +0 -0
  300. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/preflight.py +0 -0
  301. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/responses.py +0 -0
  302. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/streaming.py +0 -0
  303. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/thinking.py +0 -0
  304. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/serve/urls.py +0 -0
  305. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/__init__.py +0 -0
  306. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/__main__.py +0 -0
  307. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/app.py +0 -0
  308. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/billing/__init__.py +0 -0
  309. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/billing/charges.py +0 -0
  310. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/billing/retry.py +0 -0
  311. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/__init__.py +0 -0
  312. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/checkpoints.py +0 -0
  313. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/environment_registry.py +0 -0
  314. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/envs.py +0 -0
  315. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/projects.py +0 -0
  316. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/reconcile.py +0 -0
  317. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/repo_cleanup.py +0 -0
  318. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/run_registry.py +0 -0
  319. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/teacher_broker.py +0 -0
  320. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/teacher_errors.py +0 -0
  321. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/domain/teacher_requests.py +0 -0
  322. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/__init__.py +0 -0
  323. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/auth.py +0 -0
  324. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/db.py +0 -0
  325. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/deps.py +0 -0
  326. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/internal_client.py +0 -0
  327. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/locks.py +0 -0
  328. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/platform/runtime.py +0 -0
  329. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/__init__.py +0 -0
  330. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/envs.py +0 -0
  331. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/meta.py +0 -0
  332. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/runs.py +0 -0
  333. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/serving.py +0 -0
  334. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/serving_completion.py +0 -0
  335. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/serving_revisions.py +0 -0
  336. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/serving_smoke.py +0 -0
  337. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/server/routes/teacher.py +0 -0
  338. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/teacher/__init__.py +0 -0
  339. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/teacher/limits.py +0 -0
  340. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/flash/teacher/retry_contract.py +0 -0
  341. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/scripts/build_dev_dist.py +0 -0
  342. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/scripts/check_file_size.py +0 -0
  343. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/scripts/check_function_size.py +0 -0
  344. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/scripts/check_verl_pin_exists.py +0 -0
  345. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/scripts/scrub_history.sh +0 -0
  346. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/__init__.py +0 -0
  347. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/__init__.py +0 -0
  348. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/profile.py +0 -0
  349. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/runner.py +0 -0
  350. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/specs.py +0 -0
  351. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/teacher.py +0 -0
  352. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/_helpers/vast.py +0 -0
  353. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/conftest.py +0 -0
  354. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/fixtures/math_eval.jsonl +0 -0
  355. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/fixtures/math_train.jsonl +0 -0
  356. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/__init__.py +0 -0
  357. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/conftest.py +0 -0
  358. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/test_lambda_live.py +0 -0
  359. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/test_runpod_live.py +0 -0
  360. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/test_sft_thinking_render_live.py +0 -0
  361. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/live/test_vast_live.py +0 -0
  362. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_accounting_coverage.py +0 -0
  363. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_adapter_shard_completeness.py +0 -0
  364. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_agent_flash_cli_contract.py +0 -0
  365. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_algorithms.py +0 -0
  366. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_allocator.py +0 -0
  367. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_backend_jobspec_contract.py +0 -0
  368. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_bake_kernel_cache.py +0 -0
  369. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_base_model_provenance.py +0 -0
  370. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_billing_retry.py +0 -0
  371. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_build_context_contract.py +0 -0
  372. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cancel_remote.py +0 -0
  373. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_catalog_consistency.py +0 -0
  374. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_catalog_only_models.py +0 -0
  375. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_charge_pricing.py +0 -0
  376. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_checkpoints.py +0 -0
  377. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_commands.py +0 -0
  378. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_commands_coverage.py +0 -0
  379. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_credential_shadowing.py +0 -0
  380. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_errors.py +0 -0
  381. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_estimate.py +0 -0
  382. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_gpus_flag.py +0 -0
  383. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_help.py +0 -0
  384. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_main_coverage.py +0 -0
  385. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_managed.py +0 -0
  386. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_render_coverage.py +0 -0
  387. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_render_theme.py +0 -0
  388. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_traces.py +0 -0
  389. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cli_wandb_warning.py +0 -0
  390. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_client.py +0 -0
  391. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_client_import_purity.py +0 -0
  392. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_client_server_integration.py +0 -0
  393. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_client_stream_reads.py +0 -0
  394. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_config_env_vars.py +0 -0
  395. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_config_overrides.py +0 -0
  396. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_controlled_experiment_repairs.py +0 -0
  397. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cost_analytical.py +0 -0
  398. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cost_equation.py +0 -0
  399. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cost_estimate.py +0 -0
  400. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cost_hardware.py +0 -0
  401. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_cost_models.py +0 -0
  402. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_dataset_profile.py +0 -0
  403. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_deploy_alias_move_warning.py +0 -0
  404. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_deploy_latency.py +0 -0
  405. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_dev_channel.py +0 -0
  406. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_endpoint_name.py +0 -0
  407. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_cache_evict.py +0 -0
  408. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_delete.py +0 -0
  409. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_download.py +0 -0
  410. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_download_api.py +0 -0
  411. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_evaluations.py +0 -0
  412. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_list_api.py +0 -0
  413. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_list_cli.py +0 -0
  414. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_list_hub.py +0 -0
  415. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_no_install.py +0 -0
  416. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_publish.py +0 -0
  417. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_pull.py +0 -0
  418. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_pull_coverage.py +0 -0
  419. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_pull_loader_coverage.py +0 -0
  420. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_pull_managed_control_plane.py +0 -0
  421. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_push.py +0 -0
  422. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_rate_limit_resolve.py +0 -0
  423. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_ref_pinning.py +0 -0
  424. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_env_test.py +0 -0
  425. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_envs_coverage.py +0 -0
  426. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_export.py +0 -0
  427. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_flash_mvp.py +0 -0
  428. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_flash_worker.py +0 -0
  429. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_flashinfer_cache_dirs.py +0 -0
  430. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_freesolo_api_transport.py +0 -0
  431. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_github_urlopen_retry.py +0 -0
  432. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_gpu_type_single_field.py +0 -0
  433. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_gpus.py +0 -0
  434. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_grpo_params.py +0 -0
  435. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_grpo_resident_sizing.py +0 -0
  436. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_grpo_reward_batching.py +0 -0
  437. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_health_liveness.py +0 -0
  438. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_hf_retry.py +0 -0
  439. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_idle_endpoint_reaper.py +0 -0
  440. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_infisical_secrets.py +0 -0
  441. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_instance_bootstrap_coverage.py +0 -0
  442. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_internal_client.py +0 -0
  443. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_jobs.py +0 -0
  444. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_kernel_cache.py +0 -0
  445. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_kernel_fingerprint.py +0 -0
  446. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_kv_util.py +0 -0
  447. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_lambda_api_coverage.py +0 -0
  448. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_lambda_runner.py +0 -0
  449. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_logging.py +0 -0
  450. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_login_perms.py +0 -0
  451. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_lora_rank_coverage.py +0 -0
  452. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_lora_rank_preflight.py +0 -0
  453. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_managed_config_fields.py +0 -0
  454. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_managed_hf_repo.py +0 -0
  455. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_metrics_schema_agent_contract.py +0 -0
  456. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_mig_guard.py +0 -0
  457. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_multi_gpu_gate.py +0 -0
  458. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_multimodal_training.py +0 -0
  459. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_named_reward_metrics.py +0 -0
  460. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_oom_escalate_gpu.py +0 -0
  461. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_opd.py +0 -0
  462. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_opd_limits.py +0 -0
  463. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_opd_multiturn_eos_boundary.py +0 -0
  464. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_opd_resume_safety.py +0 -0
  465. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_opd_train.py +0 -0
  466. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_orchestrator_flash.py +0 -0
  467. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_packing.py +0 -0
  468. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_packing_coverage.py +0 -0
  469. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_parasail_teacher.py +0 -0
  470. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_poll_helpers.py +0 -0
  471. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_preflight.py +0 -0
  472. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_projects.py +0 -0
  473. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_prompt_budget.py +0 -0
  474. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_provider_preflight_coverage.py +0 -0
  475. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_provider_routing.py +0 -0
  476. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_provider_teardown_robustness.py +0 -0
  477. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_providers_symmetry.py +0 -0
  478. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_realized_cost.py +0 -0
  479. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_repo_cleanup.py +0 -0
  480. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_resolve_params_b.py +0 -0
  481. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_resume_on_retry.py +0 -0
  482. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_rl_train.py +0 -0
  483. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_rollout_samples.py +0 -0
  484. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_runmgmt.py +0 -0
  485. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_runpod_api_delete.py +0 -0
  486. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_runpod_key_fingerprint.py +0 -0
  487. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_runpod_key_waterfall.py +0 -0
  488. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_serve.py +0 -0
  489. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_serve_reasoning_content.py +0 -0
  490. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_api.py +0 -0
  491. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_app_coverage.py +0 -0
  492. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_auth_singleflight.py +0 -0
  493. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_billing.py +0 -0
  494. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_checkpoints_coverage.py +0 -0
  495. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_db.py +0 -0
  496. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_envs_coverage.py +0 -0
  497. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_locks_coverage.py +0 -0
  498. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_server_standalone.py +0 -0
  499. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_serving_context_preflight.py +0 -0
  500. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_serving_contract.py +0 -0
  501. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_serving_schema_coverage.py +0 -0
  502. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_chunked_nll.py +0 -0
  503. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_example_selection.py +0 -0
  504. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_gc_off.py +0 -0
  505. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_max_context.py +0 -0
  506. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_startup_block.py +0 -0
  507. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_sft_workload.py +0 -0
  508. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_spec_and_validation.py +0 -0
  509. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_step_floor.py +0 -0
  510. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_step_metrics.py +0 -0
  511. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_step_timing.py +0 -0
  512. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_structured_outputs.py +0 -0
  513. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_teacher_broker.py +0 -0
  514. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_teacher_encoding_contract.py +0 -0
  515. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_thinking_config.py +0 -0
  516. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_train_context_preflight.py +0 -0
  517. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_training_controls.py +0 -0
  518. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_type_comment_prose.py +0 -0
  519. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vast_api.py +0 -0
  520. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vast_api_coverage.py +0 -0
  521. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vast_offers.py +0 -0
  522. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vast_provider_coverage.py +0 -0
  523. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vast_runner.py +0 -0
  524. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_verified_revisions.py +0 -0
  525. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_verifiers.py +0 -0
  526. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_version.py +0 -0
  527. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vl_warmstart_adapter_keys.py +0 -0
  528. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_vram_architecture.py +0 -0
  529. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_wandb_link.py +0 -0
  530. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_wandb_naming.py +0 -0
  531. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_warmstart_adapter_download.py +0 -0
  532. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_warmstart_error_attribution.py +0 -0
  533. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_weight_cache.py +0 -0
  534. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_dryrun.py +0 -0
  535. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_hardexit.py +0 -0
  536. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_image.py +0 -0
  537. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_init_heartbeat.py +0 -0
  538. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_stack.py +0 -0
  539. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_worker_thinking.py +0 -0
  540. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_workflow_contracts.py +0 -0
  541. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_workload_profile.py +0 -0
  542. {freesolo_flash_dev-1.2.37 → freesolo_flash_dev-1.2.39}/tests/test_zero2_sharding_gate.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: freesolo-flash-dev
3
- Version: 1.2.37
3
+ Version: 1.2.39
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
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from dataclasses import asdict, dataclass, replace
6
+ from math import ceil
6
7
  from typing import Any
7
8
 
8
9
  ALGORITHMS = ("sft", "grpo", "opd")
@@ -622,6 +623,10 @@ def resolve_vocab_size(model_id: str, revision: str = "") -> int:
622
623
  return vocab_size_for(model_id)
623
624
 
624
625
 
626
+ def _with_merge_disk_floor(info: ModelInfo) -> ModelInfo:
627
+ return replace(info, min_disk_gb=max(info.min_disk_gb, ceil(info.params_b * 2) + 64))
628
+
629
+
625
630
  def resolve_model(model_id: str, algorithm: str, model_revision: str = "") -> ModelInfo:
626
631
  """Resolve a curated model, validated for ``algorithm``; anything uncataloged is rejected.
627
632
 
@@ -643,9 +648,8 @@ def resolve_model(model_id: str, algorithm: str, model_revision: str = "") -> Mo
643
648
  params_b=params_b,
644
649
  params=f"{params_b:.1f}B",
645
650
  vocab_size=vocab_size,
646
- min_disk_gb=max(info.min_disk_gb, int(params_b * 2) + 64),
647
651
  )
648
- return info
652
+ return _with_merge_disk_floor(info)
649
653
 
650
654
 
651
655
  def validate_model_for_algorithm(model_id: str, algorithm: str) -> ModelInfo:
@@ -660,4 +664,4 @@ def validate_model_for_algorithm(model_id: str, algorithm: str) -> ModelInfo:
660
664
 
661
665
 
662
666
  def public_model_rows() -> list[dict[str, Any]]:
663
- return [m.to_dict() for m in list_models()]
667
+ return [_with_merge_disk_floor(model).to_dict() for model in list_models()]
@@ -471,29 +471,14 @@ def ray_num_cpus(gpu_count: int = 1, *, cap: int = 16) -> int:
471
471
  return max(floor, min(affinity, cap))
472
472
 
473
473
 
474
- def run_verl_training(
474
+ def _run_streaming_verl_subprocess(
475
475
  cmd: list[str],
476
476
  *,
477
477
  env: dict[str, str],
478
- on_step: Callable[[int], None] | None = None,
479
- on_line: Callable[[str], None] | None = None,
480
- heartbeat: Callable[[], None] | None = None,
481
- step_pattern: str = r"step:\s*(\d+)",
482
- heartbeat_interval_s: float = 20.0,
483
- tail: ChildOutputTail | None = None,
478
+ on_line: Callable[[str], None],
479
+ errors: str | None = None,
484
480
  ) -> int:
485
- """run a verl trainer subprocess, streaming stdout and surfacing step progress.
486
-
487
- returns the process exit code. stdout+stderr are merged and scanned line by line: ``on_line``
488
- receives every line, ``on_step`` receives each parsed training step, and ``heartbeat`` is called
489
- at most once per ``heartbeat_interval_s``. callback failures terminate the child before they are
490
- re-raised so a failed required checkpoint upload cannot leave paid training running unattended.
491
- """
492
- step_re = re.compile(step_pattern)
493
- child_tail = tail if tail is not None else ChildOutputTail()
494
- # before the child exists, so any grandchild it orphans reparents here and can actually be
495
- # reaped. this process is not pid 1 -- the runpod handler is -- so without it every wait below
496
- # answers ChildProcessError for a zombie nobody will collect.
481
+ """stream a verl subprocess under the shared process-group lifecycle supervisor."""
497
482
  adopt_orphaned_descendants()
498
483
  proc = subprocess.Popen(
499
484
  cmd,
@@ -501,87 +486,88 @@ def run_verl_training(
501
486
  stdout=subprocess.PIPE,
502
487
  stderr=subprocess.STDOUT,
503
488
  text=True,
489
+ errors=errors,
504
490
  bufsize=1,
505
491
  start_new_session=True,
506
492
  )
507
- # start_new_session makes the leader pid the stable group id even after that leader is reaped.
493
+ # start_new_session keeps the group addressable after the leader is reaped.
508
494
  process_group_id = proc.pid
509
- last_hb = 0.0
510
495
  try:
511
- # the child's exit is watched independently of pipe EOF. a grandchild holding the inherited
512
- # pipe open after the trainer dies would otherwise keep the loop below running forever, on a
513
- # paid gpu, having already lost the process whose output it is waiting for.
514
496
  with _ChildExitWatchdog(
515
497
  proc, process_group_id=process_group_id, grace_s=_ORPHANED_PIPE_GRACE_S
516
498
  ) as watchdog:
517
499
  assert proc.stdout is not None
518
500
  for line in proc.stdout:
519
- # held across the callbacks, not just the arrival: on_step uploads a checkpoint, and
520
- # a reader inside one is working, not stuck.
521
501
  with watchdog.handling_line():
522
- print(line, end="", flush=True)
523
- child_tail.record(line)
524
- if on_line is not None:
525
- on_line(line)
526
- m = step_re.search(line)
527
- if m and on_step is not None:
528
- on_step(int(m.group(1)))
529
- if heartbeat is not None:
530
- now = time.monotonic()
531
- if now - last_hb >= heartbeat_interval_s:
532
- heartbeat()
533
- last_hb = now
502
+ on_line(line)
534
503
  except BaseException:
535
504
  kill_process_group(proc, process_group_id=process_group_id)
536
505
  raise
537
506
  finally:
538
507
  if proc.poll() is None:
539
- # BOUNDED. EOF is not the child's exit, so a child that outlives its own stdout would
540
- # park the attempt here. one that has not exited within the grace after its stdout closed
541
- # is not going to, so tear the group down and let the wait inside that call collect it.
542
508
  try:
543
509
  proc.wait(timeout=_TEARDOWN_GRACE_S)
544
510
  except subprocess.TimeoutExpired:
545
511
  kill_process_group(proc, process_group_id=process_group_id)
546
- # every job boundary, not just the failing ones. a straggler an earlier teardown SIGKILLed
547
- # but could not drain in time exits shortly after, and `kill_process_group` -- the only
548
- # other caller of this -- runs on exceptions alone: a worker whose later jobs all succeed
549
- # would hold that zombie for its whole life, as pid 1 with nothing else to reap it.
550
512
  reap_stragglers()
551
- collected = proc.returncode
552
- if collected is None:
553
- # the bounded wait above can end with nothing collected, which the unbounded one it replaced
554
- # could not: a group member wedged in uninterruptible io outlives even the SIGKILL inside
555
- # teardown. `int(None)` would replace that diagnosis with a TypeError, so name the survivor
556
- # instead -- callers already handle a RuntimeError from here.
513
+ if proc.returncode is None:
557
514
  raise RuntimeError(
558
515
  f"verl subprocess {proc.pid} did not exit after teardown; its process group is still "
559
516
  "holding the gpu"
560
517
  )
561
- return_code = int(collected)
518
+ return_code = int(proc.returncode)
562
519
  if watchdog.tore_down and return_code == 0:
563
- # the child exited 0 but a descendant held the pipe open past the grace, so the group was
564
- # killed to release it. reporting success here would upload whatever partial artifacts exist
565
- # as a completed run: the trainer's own exit status says nothing about the descendant that
566
- # was still running, and that descendant is why the pipe never closed.
567
520
  raise RuntimeError(
568
521
  f"verl subprocess {proc.pid} exited 0 but a descendant held its output pipe open for "
569
522
  f"{_ORPHANED_PIPE_GRACE_S:.0f}s; the process group was torn down to release the gpu"
570
523
  )
571
- try:
572
- raise_for_classified_verl_exit(return_code, child_tail)
573
- except BaseException:
574
- kill_process_group(proc, process_group_id=process_group_id)
575
- raise
576
524
  if return_code != 0:
577
- # a nonzero exit that carried no recognized signature RETURNS from the classifier rather
578
- # than raising, so this is the one failing path that reached neither teardown above. the
579
- # direct child is gone but its group need not be: a surviving EngineCore keeps its cuda
580
- # context, and a reusable worker then hands the next attempt an occupied gpu.
581
525
  kill_process_group(proc, process_group_id=process_group_id)
582
526
  return return_code
583
527
 
584
528
 
529
+ def run_verl_training(
530
+ cmd: list[str],
531
+ *,
532
+ env: dict[str, str],
533
+ on_step: Callable[[int], None] | None = None,
534
+ on_line: Callable[[str], None] | None = None,
535
+ heartbeat: Callable[[], None] | None = None,
536
+ step_pattern: str = r"step:\s*(\d+)",
537
+ heartbeat_interval_s: float = 20.0,
538
+ tail: ChildOutputTail | None = None,
539
+ ) -> int:
540
+ """run a verl trainer subprocess, streaming stdout and surfacing step progress.
541
+
542
+ returns the process exit code. stdout+stderr are merged and scanned line by line: ``on_line``
543
+ receives every line, ``on_step`` receives each parsed training step, and ``heartbeat`` is called
544
+ at most once per ``heartbeat_interval_s``. callback failures terminate the process group before
545
+ they are re-raised.
546
+ """
547
+ step_re = re.compile(step_pattern)
548
+ child_tail = tail if tail is not None else ChildOutputTail()
549
+ last_hb = 0.0
550
+
551
+ def handle_line(line: str) -> None:
552
+ nonlocal last_hb
553
+ print(line, end="", flush=True)
554
+ child_tail.record(line)
555
+ if on_line is not None:
556
+ on_line(line)
557
+ match = step_re.search(line)
558
+ if match and on_step is not None:
559
+ on_step(int(match.group(1)))
560
+ if heartbeat is not None:
561
+ now = time.monotonic()
562
+ if now - last_hb >= heartbeat_interval_s:
563
+ heartbeat()
564
+ last_hb = now
565
+
566
+ return_code = _run_streaming_verl_subprocess(cmd, env=env, on_line=handle_line)
567
+ raise_for_classified_verl_exit(return_code, child_tail)
568
+ return return_code
569
+
570
+
585
571
  _TEARDOWN_GRACE_S = 10.0
586
572
 
587
573
  # grace for a descendant holding stdout open after the trainer exits. observe child exit separately
@@ -291,6 +291,10 @@ class _OpdVerlCheckpointWatcher(_VerlCheckpointWatcher):
291
291
  def _should_publish(self, step: int) -> bool:
292
292
  return True
293
293
 
294
+ def _publishable(self, pending: list[tuple[int, str]]) -> list[tuple[int, str]]:
295
+ """keep every pending retry state because each checkpoint carries distinct accounting."""
296
+ return pending
297
+
294
298
  def _publish(self, step: int, checkpoint_dir: str) -> None:
295
299
  actor_dir = os.path.join(checkpoint_dir, "actor")
296
300
  adapter_dir = os.path.join(self.export_root, f"step-{step}")
@@ -23,7 +23,11 @@ from flash.engine.worker.backend_common import (
23
23
  )
24
24
  from flash.engine.worker.io.heartbeat import join_while_draining
25
25
  from flash.engine.worker.runtime.pkg_proxy import W as _w
26
- from flash.engine.worker.verl.checkpoints import resume_checkpoint_is_loadable
26
+ from flash.engine.worker.verl.checkpoints import (
27
+ MergeDiskExhaustedError,
28
+ MergeDiskHeadroomError,
29
+ resume_checkpoint_is_loadable,
30
+ )
27
31
 
28
32
 
29
33
  def _rl_train():
@@ -121,6 +125,8 @@ class _VerlResumeUploader:
121
125
  called only after training finished cleanly: on a crash or cancel the missing steps are a
122
126
  symptom of the real failure, and raising here would mask it.
123
127
  """
128
+ if isinstance(self._error, (MergeDiskHeadroomError, MergeDiskExhaustedError)):
129
+ raise self._error
124
130
  if self._error is not None:
125
131
  raise RuntimeError("verl resume uploader failed") from self._error
126
132
  missing = sorted(self.required_steps - self.published_steps)
@@ -23,6 +23,7 @@ from flash.engine.worker.backend_common import (
23
23
  )
24
24
  from flash.engine.worker.io.heartbeat import join_while_draining
25
25
  from flash.engine.worker.runtime.pkg_proxy import W as _w
26
+ from flash.engine.worker.verl.checkpoints import MergeDiskExhaustedError, MergeDiskHeadroomError
26
27
 
27
28
 
28
29
  def _sft_train():
@@ -113,6 +114,8 @@ class _VerlCheckpointWatcher:
113
114
  self._thread.start()
114
115
 
115
116
  def raise_if_failed(self) -> None:
117
+ if isinstance(self._error, (MergeDiskHeadroomError, MergeDiskExhaustedError)):
118
+ raise self._error
116
119
  if self._error is not None:
117
120
  raise RuntimeError("verl checkpoint watcher failed") from self._error
118
121
 
@@ -141,6 +144,20 @@ class _VerlCheckpointWatcher:
141
144
  def _should_publish(self, step: int) -> bool:
142
145
  return not self.required_steps or step in self.required_steps
143
146
 
147
+ def _publishable(self, pending: list[tuple[int, str]]) -> list[tuple[int, str]]:
148
+ """coalesce only an optional multi-checkpoint backlog to its newest save."""
149
+ if self.required_steps or len(pending) <= 1:
150
+ return pending
151
+ superseded = pending[:-1]
152
+ self.processed_steps.update(step for step, _ in superseded)
153
+ print(
154
+ f"[ckpt] publishing step {pending[-1][0]} and skipping superseded periodic "
155
+ f"checkpoint(s) {', '.join(str(step) for step, _ in superseded)}: the publisher is "
156
+ "behind training, and each export writes a full model copy to the same disk",
157
+ flush=True,
158
+ )
159
+ return pending[-1:]
160
+
144
161
  def _staged_source(self, step: int, checkpoint_dir: str) -> str:
145
162
  """hardlink a completed checkpoint before verl retention can prune it.
146
163
 
@@ -220,7 +237,7 @@ class _VerlCheckpointWatcher:
220
237
  def _run(self) -> None:
221
238
  try:
222
239
  while True:
223
- for step, checkpoint_dir in self._pending():
240
+ for step, checkpoint_dir in self._publishable(self._pending()):
224
241
  self._publish(step, checkpoint_dir)
225
242
  # re-read rather than reusing the sweep above: verl advances the tracker right up to
226
243
  # the moment the child exits, so a step can become visible during that sweep.
@@ -9,6 +9,7 @@ Split out of `flash.engine.worker.backend_common` to keep that module under the
9
9
 
10
10
  from __future__ import annotations
11
11
 
12
+ import errno
12
13
  import json
13
14
  import os
14
15
  import re
@@ -20,24 +21,37 @@ class MergeDiskHeadroomError(RuntimeError):
20
21
  """the merged model this export must write does not fit beside the checkpoint it reads."""
21
22
 
22
23
 
24
+ class MergeDiskExhaustedError(RuntimeError):
25
+ """the merge started with room and then ran the disk out partway through writing its output."""
26
+
27
+
28
+ # a genuine short write leaves almost no free space; keep the fallback absolute so a normal partial
29
+ # merge is not misclassified merely because its output is large.
30
+ _MERGE_DISK_EXHAUSTED_FREE_BYTES = 64 * 1024 * 1024
31
+
32
+ # quota exhaustion can leave the underlying filesystem reporting free space, so preserve both errno
33
+ # and text forms emitted by torch and safetensors.
34
+ _DISK_EXHAUSTED_ERRNOS = (errno.ENOSPC, errno.EDQUOT)
35
+ _DISK_EXHAUSTED_MARKERS = (
36
+ "no space left on device",
37
+ "errno 28",
38
+ "os error 28",
39
+ "disk quota exceeded",
40
+ "errno 122",
41
+ "os error 122",
42
+ )
43
+ _SHORT_WRITE_MARKERS = ("unexpected pos",)
44
+
45
+ # disk size is platform-managed, so checkpoint frequency is the reachable remedy.
46
+ _FEWER_CHECKPOINTS_ADVICE = (
47
+ "publish fewer checkpoints: raise train.save_every (save_every == the run's total steps "
48
+ "publishes only the final adapter), or drop entries from train.save_at_steps if the run sets "
49
+ "them -- exact steps override save_every and are always published."
50
+ )
51
+
52
+
23
53
  def _model_shard_bytes(path: str) -> int:
24
- """total size of the fsdp model shards directly in `path`.
25
-
26
- only `model_world_size_*_rank_*.pt` is measured, because only those files become merge output:
27
- `_load_and_merge_state_dicts` loads exactly those names, and the merged dict is what
28
- `save_pretrained` writes back out. the `optim_*` and `extra_state_*` files sitting beside them
29
- are read by resume, never by the merger, so including them would inflate the requirement by the
30
- whole optimizer state -- ~7.6 GB of adam moments on a 35b rank-32 run -- and refuse merges that
31
- would have fit.
32
-
33
- a flat scan, not a walk, because the merger's read is flat: it opens
34
- `Path(local_dir) / f"model_world_size_{W}_rank_{r}.pt"` per rank and never recurses. walking
35
- would add up nested files it will never read, which is the same over-estimate in a new form.
36
-
37
- shares `_FSDP_SHARD_RE` with `checkpoint_world_size` rather than matching the name a second way:
38
- one definition of what a shard filename is, so a future change to verl's layout cannot leave the
39
- two disagreeing about which files a merge reads.
40
- """
54
+ """total size of the top-level fsdp model shards the merger reads."""
41
55
  try:
42
56
  names = os.listdir(path)
43
57
  except OSError:
@@ -54,37 +68,12 @@ def _model_shard_bytes(path: str) -> int:
54
68
 
55
69
 
56
70
  def require_merge_headroom(ckpt_actor_dir: str, merge_out: str) -> None:
57
- """Fail before `verl.model_merger` runs if its output cannot fit on the container disk.
58
-
59
- `model_merger merge` does NOT write only the small lora adapter. `save_hf_model_and_tokenizer`
60
- materializes the full base model and calls `model.save_pretrained(target_dir, state_dict=...)`
61
- (verl `model_merger/base_model_merger.py`), so exporting one 35b checkpoint writes ~70 GB into
62
- `<adapter>_merge` beside the ~60 GB checkpoint it is reading. That is the single largest
63
- transient on the disk, and it recurs on EVERY publish, not just at finalization.
64
-
65
- Without this guard the merger dies partway through `save_pretrained` with ENOSPC, and the run
66
- fails after training has already succeeded. Checking first turns a silent late disk death into
67
- an actionable error naming the shortfall, while the checkpoint is still intact and resumable.
68
-
69
- The requirement is derived from what the merger actually moves rather than from the checkpoint's
70
- total size: it loads the `model_world_size_*_rank_*.pt` shards, casts every tensor to bf16, and
71
- writes that same state back out as base model plus adapter (`fsdp_model_merger.py`,
72
- `base_model_merger.py`). Shard bytes in, shard bytes out. Sizing the whole directory instead
73
- would add the `optim_*` and `extra_state_*` files, which resume reads and the merger never
74
- materializes -- on a 35b rank-32 run that is ~7.6 GB of adam moments, enough to refuse a merge
75
- that had room.
76
-
77
- The two error directions are not symmetric, which is why no safety margin is added on top.
78
- Underestimating leaves the merger to hit ENOSPC exactly as it does today, so the guard is merely
79
- absent. Overestimating fails a run that would have completed, which is a regression this guard
80
- would have introduced. When in doubt, let the merge proceed.
81
- """
71
+ """fail before the merger when its full-bf16 output cannot fit beside its input shards."""
82
72
  need = _model_shard_bytes(ckpt_actor_dir)
83
73
  if need <= 0:
84
74
  return
85
- try:
86
- free = shutil.disk_usage(os.path.dirname(merge_out.rstrip("/")) or ".").free
87
- except OSError:
75
+ free = _free_bytes(merge_out)
76
+ if free is None:
88
77
  # an unreadable mount is not evidence of exhaustion; let the merger run and report for real.
89
78
  return
90
79
  if free >= need:
@@ -92,10 +81,99 @@ def require_merge_headroom(ckpt_actor_dir: str, merge_out: str) -> None:
92
81
  raise MergeDiskHeadroomError(
93
82
  f"cannot export the adapter: merging {ckpt_actor_dir} needs about "
94
83
  f"{need / 1e9:.1f} GB beside it but only {free / 1e9:.1f} GB is free. "
95
- "raise [gpu] disk_gb, or save fewer checkpoints with a larger save_every."
84
+ + _FEWER_CHECKPOINTS_ADVICE
85
+ )
86
+
87
+
88
+ def _run_merger(cmd: list[str], env: dict[str, str]) -> None:
89
+ """stream merger output and prefer direct disk evidence over a short-write marker."""
90
+ from flash.engine.worker import backend_common
91
+
92
+ disk_line = ""
93
+ short_write_line = ""
94
+
95
+ def handle_line(line: str) -> None:
96
+ nonlocal disk_line, short_write_line
97
+ print(line, end="", flush=True)
98
+ lowered = line.lower()
99
+ if not disk_line and any(marker in lowered for marker in _DISK_EXHAUSTED_MARKERS):
100
+ disk_line = line.strip()
101
+ elif not short_write_line and any(marker in lowered for marker in _SHORT_WRITE_MARKERS):
102
+ short_write_line = line.strip()
103
+
104
+ merger_env = {**env, "PYTHONUNBUFFERED": "1"}
105
+ return_code = backend_common._run_streaming_verl_subprocess(
106
+ cmd, env=merger_env, on_line=handle_line, errors="replace"
107
+ )
108
+ if return_code != 0:
109
+ raise subprocess.CalledProcessError(
110
+ return_code, cmd, output=disk_line or short_write_line or None
111
+ )
112
+
113
+
114
+ def _free_bytes(path: str) -> int | None:
115
+ """free bytes on the filesystem holding ``path``, or none when it cannot be read."""
116
+ try:
117
+ return shutil.disk_usage(os.path.dirname(path.rstrip("/")) or ".").free
118
+ except OSError:
119
+ return None
120
+
121
+
122
+ def _error_chain_matches(
123
+ error: BaseException, *, errnos: tuple[int, ...] = (), markers: tuple[str, ...] = ()
124
+ ) -> bool:
125
+ """whether an error chain contains any requested errno or text marker."""
126
+ seen: set[int] = set()
127
+ current: BaseException | None = error
128
+ while current is not None and id(current) not in seen:
129
+ seen.add(id(current))
130
+ if isinstance(current, OSError) and current.errno in errnos:
131
+ return True
132
+ for evidence in (
133
+ current,
134
+ getattr(current, "output", None),
135
+ getattr(current, "stderr", None),
136
+ ):
137
+ if isinstance(evidence, bytes):
138
+ evidence = evidence.decode("utf-8", "replace")
139
+ if evidence is not None and any(marker in str(evidence).lower() for marker in markers):
140
+ return True
141
+ current = current.__cause__ or current.__context__
142
+ return False
143
+
144
+
145
+ def _disk_exhausted_error(error: BaseException) -> bool:
146
+ """whether an error chain contains direct volume or quota exhaustion evidence."""
147
+ return _error_chain_matches(
148
+ error, errnos=_DISK_EXHAUSTED_ERRNOS, markers=_DISK_EXHAUSTED_MARKERS
96
149
  )
97
150
 
98
151
 
152
+ def raise_for_merge_disk_exhaustion(
153
+ error: BaseException, ckpt_actor_dir: str, merge_out: str, *, merger_succeeded: bool = False
154
+ ) -> None:
155
+ """classify direct disk evidence or a low-space short write before cleanup."""
156
+ direct_evidence = _disk_exhausted_error(error)
157
+ if not direct_evidence and isinstance(error, OSError):
158
+ return
159
+ if merger_succeeded and not direct_evidence:
160
+ return
161
+ short_write_evidence = _error_chain_matches(error, markers=_SHORT_WRITE_MARKERS)
162
+ if not direct_evidence and not short_write_evidence:
163
+ return
164
+ free = _free_bytes(merge_out)
165
+ if not direct_evidence and (free is None or free > _MERGE_DISK_EXHAUSTED_FREE_BYTES):
166
+ return
167
+ free_text = "unknown" if free is None else f"{free / 1e9:.2f} GB"
168
+ raise MergeDiskExhaustedError(
169
+ f"ran out of disk while merging {ckpt_actor_dir} into {merge_out}: "
170
+ f"{free_text} free on that filesystem. publishing a checkpoint materializes the FULL base "
171
+ "model beside the checkpoint it reads, so a small lora adapter still needs room for a whole "
172
+ "model copy. the underlying error is a short write, not a corrupt checkpoint. "
173
+ + _FEWER_CHECKPOINTS_ADVICE
174
+ ) from error
175
+
176
+
99
177
  def resolve_checkpoint_actor_dir(step_dir: str) -> str:
100
178
  """return the directory inside ``global_step_N`` that holds the saved model + ``huggingface/``.
101
179
 
@@ -302,12 +380,10 @@ def export_peft_adapter(
302
380
  merge_env["HF_HUB_OFFLINE"] = "1"
303
381
  merge_env["TRANSFORMERS_OFFLINE"] = "1"
304
382
  merge_env["HF_HUB_DISABLE_XET"] = "1"
305
- # the merge tree is this function's to clean up for its whole lifetime, not just on success.
306
- # it holds the full merged model -- the largest transient on the disk -- so leaving it behind
307
- # when the merger dies or writes an unexpected layout would strand tens of gb on the exact
308
- # disk this guard exists to protect, and the next save would inherit less room than this one.
383
+ # after a successful merge, low free space is expected and cannot classify placement failures.
384
+ merger_succeeded = False
309
385
  try:
310
- subprocess.run(
386
+ _run_merger(
311
387
  [
312
388
  python_bin,
313
389
  "-m",
@@ -320,21 +396,25 @@ def export_peft_adapter(
320
396
  "--target_dir",
321
397
  merge_out,
322
398
  ],
323
- check=True,
324
- env=merge_env,
399
+ merge_env,
325
400
  )
401
+ merger_succeeded = True
326
402
  lora_dir = os.path.join(merge_out, "lora_adapter")
327
403
  if not os.path.exists(os.path.join(lora_dir, "adapter_config.json")):
328
404
  raise RuntimeError(
329
405
  f"verl model_merger did not produce a peft adapter at {lora_dir} (no adapter_config.json); "
330
406
  "the merger output layout must be adjusted for this verl version."
331
407
  )
332
- # rename rather than copy: every caller builds `out_adapter_dir` and `merge_out` as siblings
333
- # in one run workdir, so the two are on one filesystem and `os.replace` is a metadata
334
- # operation that moves no bytes. copying would hold a second copy of the adapter beside the
335
- # still-undeleted merge tree, a peak this function's own headroom check does not budget for.
408
+ # move within the shared filesystem so placement does not create another adapter copy.
336
409
  for name in os.listdir(lora_dir):
337
410
  os.replace(os.path.join(lora_dir, name), os.path.join(out_adapter_dir, name))
411
+ except Exception as error:
412
+ # classify before cleanup frees the merge tree and its low-space evidence.
413
+ # cancellation remains a base exception and is never relabelled as disk exhaustion.
414
+ raise_for_merge_disk_exhaustion(
415
+ error, ckpt_actor_dir, merge_out, merger_succeeded=merger_succeeded
416
+ )
417
+ raise
338
418
  finally:
339
419
  shutil.rmtree(merge_out, ignore_errors=True)
340
420
 
@@ -92,7 +92,7 @@ def _inherit_warmstart_revision(
92
92
  """Adopt a warm-start source's pin BEFORE the spec is sized against it.
93
93
 
94
94
  Sizing reads the revision: ``resolve_model`` re-derives params/vocab/disk from the pinned
95
- commit's geometry, and ``min_disk_gb`` becomes ``params_b * 2 + 64``, which for half of today's
95
+ commit's geometry, and ``min_disk_gb`` becomes ``ceil(2 * params_b) + 64``, which for half of today's
96
96
  catalog is strictly larger than the catalog default. Adopting the pin only inside
97
97
  ``_prepare_init_from_adapter`` -- which runs after ``resolve_model``, ``_with_model_disk``, and
98
98
  ``_assign_weight_cache_volume`` -- would provision the child as if unpinned while training it
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "freesolo-flash-dev"
3
- version = "1.2.37"
3
+ version = "1.2.39"
4
4
  description ="Flash — managed LoRA post-training (SFT/GRPO/OPD) for Freesolo environments, driven by the `flash` CLI"
5
5
  readme = "README.md"
6
6
  # RunPod Flash supports Python 3.11-3.12 (not 3.13 yet).
@@ -137,7 +137,7 @@ artifacts = ["flash/py.typed"]
137
137
  # auto-published by .github/workflows/publish-dev.yml: a push to `dev` whose version isn't yet on
138
138
  # PyPI publishes it; pushes that don't change it find it already published and no-op. So cutting a
139
139
  # dev-channel release = bump this (and [project].version) and merge to `dev`.
140
- version = "1.2.37"
140
+ version = "1.2.39"
141
141
 
142
142
  [tool.pytest.ini_options]
143
143
  pythonpath = ["."]
@@ -3711,13 +3711,13 @@ def test_without_the_claim_the_orphan_reparents_past_this_process():
3711
3711
 
3712
3712
 
3713
3713
  @_needs_process_teardown
3714
- def test_the_claim_is_made_before_the_trainer_is_spawned():
3714
+ def test_the_claim_is_made_before_each_verl_process_is_spawned():
3715
3715
  """Order matters: the kernel only reparents to a process that was ALREADY a subreaper.
3716
3716
 
3717
3717
  Claiming after the child exists leaves any grandchild it has already orphaned parented
3718
3718
  elsewhere, so the fix would work only for the second job onward on a reused worker.
3719
3719
  """
3720
- for fn in (vc.run_verl_training, rl_train._execute_rl_child):
3720
+ for fn in (vc._run_streaming_verl_subprocess, rl_train._execute_rl_child):
3721
3721
  src = " ".join(inspect.getsource(fn).split())
3722
3722
  assert "adopt_orphaned_descendants()" in src, f"{fn.__name__} never claims its orphans"
3723
3723
  assert src.index("adopt_orphaned_descendants()") < src.index("subprocess.Popen("), (